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