util.c 2.7 KB

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