util.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include "dat.h"
  12. Place nowhere = {
  13. Undef, Undef
  14. };
  15. static void
  16. setlat(Place *p, double lat)
  17. {
  18. p->lat = lat;
  19. }
  20. static void
  21. setlon(Place *p, double lon)
  22. {
  23. p->lon = lon;
  24. }
  25. static int
  26. printlatlon(char *p, int n, double lat, char po, char ne)
  27. {
  28. char c;
  29. double d;
  30. int deg, min, sec;
  31. if(lat > 0)
  32. c = po;
  33. else if(lat < 0){
  34. c = ne;
  35. lat = -lat;
  36. } else
  37. c = ' ';
  38. sec = 3600 * modf(lat, &d);
  39. deg = d;
  40. min = sec/60;
  41. sec = sec % 60;
  42. return snprint(p, n, "%#3.3d°%#2.2d′%#2.2d″%c", deg, min, sec, c);
  43. }
  44. int
  45. placeconv(Fmt *fp)
  46. {
  47. char str[256];
  48. int n;
  49. Place pl;
  50. pl = va_arg(fp->args, Place);
  51. n = 0;
  52. n += printlatlon(str+n, sizeof(str)-n, pl.lat, 'N', 'S');
  53. n += snprint(str+n, sizeof(str)-n, ", ");
  54. printlatlon(str+n, sizeof(str)-n, pl.lon, 'E', 'W');
  55. return fmtstrcpy(fp, str);
  56. }
  57. int
  58. strtolatlon(char *p, char **ep, Place *pl)
  59. {
  60. double latlon;
  61. int neg = 0;
  62. while(*p == '0') p++;
  63. latlon = strtod(p, &p);
  64. if(latlon < 0){
  65. latlon = -latlon;
  66. neg = 1;
  67. }
  68. if(*p == ':'){
  69. p++;
  70. while(*p == '0') p++;
  71. latlon += strtod(p, &p)/60.0;
  72. if(*p == ':'){
  73. p++;
  74. while(*p == '0') p++;
  75. latlon += strtod(p, &p)/3600.0;
  76. }
  77. }
  78. switch (*p++){
  79. case 'N':
  80. case 'n':
  81. if(neg) latlon = -latlon;
  82. if(pl->lat != Undef)
  83. return -1;
  84. setlat(pl, latlon);
  85. break;
  86. case 'S':
  87. case 's':
  88. if(!neg) latlon = -latlon;
  89. if(pl->lat != Undef)
  90. return -1;
  91. setlat(pl, latlon);
  92. break;
  93. case 'E':
  94. case 'e':
  95. if(neg) latlon = -latlon;
  96. if(pl->lon != Undef)
  97. return -1;
  98. setlon(pl, latlon);
  99. break;
  100. case 'W':
  101. case 'w':
  102. if(!neg) latlon = -latlon;
  103. if(pl->lon != Undef)
  104. return -1;
  105. setlon(pl, latlon);
  106. break;
  107. case '\0':
  108. case ' ':
  109. case '\t':
  110. case '\n':
  111. p--;
  112. if(neg) latlon = -latlon;
  113. if(pl->lat == Undef){
  114. setlat(pl, latlon);
  115. } else if(pl->lon == Undef){
  116. latlon = -latlon;
  117. setlon(pl, latlon);
  118. } else return -1;
  119. break;
  120. default:
  121. return -1;
  122. }
  123. if(ep)
  124. *ep = p;
  125. return 0;
  126. }
  127. Place
  128. strtopos(char *p, char **ep)
  129. {
  130. Place pl = nowhere;
  131. if(strtolatlon(p, &p, &pl) < 0)
  132. return nowhere;
  133. while(*p == ' ' || *p == '\t' || *p == '\n')
  134. p++;
  135. if(strtolatlon(p, &p, &pl) < 0)
  136. return nowhere;
  137. if(ep)
  138. *ep = p;
  139. return pl;
  140. }
  141. #if 0
  142. static void
  143. rtcset(int32_t t) /* We may use this some day */
  144. {
  145. static int fd;
  146. int32_t r;
  147. int n;
  148. char buf[32];
  149. if(fd <= 0 && (fd = open("#r/rtc", ORDWR)) < 0){
  150. fprint(2, "Can't open #r/rtc: %r\n");
  151. return;
  152. }
  153. n = read(fd, buf, sizeof buf - 1);
  154. if(n <= 0){
  155. fprint(2, "Can't read #r/rtc: %r\n");
  156. return;
  157. }
  158. buf[n] = '\0';
  159. r = strtol(buf, nil, 0);
  160. if(r <= 0){
  161. fprint(2, "ridiculous #r/rtc: %ld\n", r);
  162. return;
  163. }
  164. if(r - t > 1 || t - r > 0){
  165. seek(fd, 0, 0);
  166. fprint(fd, "%ld", t);
  167. fprint(2, "correcting #r/rtc: %ld → %ld\n", r, t);
  168. }
  169. seek(fd, 0, 0);
  170. }
  171. #endif