123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include <u.h>
- #include <libc.h>
- #include "dat.h"
- Place nowhere = {
- Undef, Undef
- };
- static void
- setlat(Place *p, double lat)
- {
- p->lat = lat;
- }
- static void
- setlon(Place *p, double lon)
- {
- p->lon = lon;
- }
- static int
- printlatlon(char *p, int n, double lat, char po, char ne)
- {
- char c;
- double d;
- int deg, min, sec;
- if(lat > 0)
- c = po;
- else if(lat < 0){
- c = ne;
- lat = -lat;
- } else
- c = ' ';
- sec = 3600 * modf(lat, &d);
- deg = d;
- min = sec/60;
- sec = sec % 60;
- return snprint(p, n, "%#3.3d°%#2.2d′%#2.2d″%c", deg, min, sec, c);
- }
- int
- placeconv(Fmt *fp)
- {
- char str[256];
- int n;
- Place pl;
- pl = va_arg(fp->args, Place);
- n = 0;
- n += printlatlon(str+n, sizeof(str)-n, pl.lat, 'N', 'S');
- n += snprint(str+n, sizeof(str)-n, ", ");
- printlatlon(str+n, sizeof(str)-n, pl.lon, 'E', 'W');
- return fmtstrcpy(fp, str);
- }
- int
- strtolatlon(char *p, char **ep, Place *pl)
- {
- double latlon;
- int neg = 0;
- while(*p == '0') p++;
- latlon = strtod(p, &p);
- if(latlon < 0){
- latlon = -latlon;
- neg = 1;
- }
- if(*p == ':'){
- p++;
- while(*p == '0') p++;
- latlon += strtod(p, &p)/60.0;
- if(*p == ':'){
- p++;
- while(*p == '0') p++;
- latlon += strtod(p, &p)/3600.0;
- }
- }
- switch (*p++){
- case 'N':
- case 'n':
- if(neg) latlon = -latlon;
- if(pl->lat != Undef)
- return -1;
- setlat(pl, latlon);
- break;
- case 'S':
- case 's':
- if(!neg) latlon = -latlon;
- if(pl->lat != Undef)
- return -1;
- setlat(pl, latlon);
- break;
- case 'E':
- case 'e':
- if(neg) latlon = -latlon;
- if(pl->lon != Undef)
- return -1;
- setlon(pl, latlon);
- break;
- case 'W':
- case 'w':
- if(!neg) latlon = -latlon;
- if(pl->lon != Undef)
- return -1;
- setlon(pl, latlon);
- break;
- case '\0':
- case ' ':
- case '\t':
- case '\n':
- p--;
- if(neg) latlon = -latlon;
- if(pl->lat == Undef){
- setlat(pl, latlon);
- } else if(pl->lon == Undef){
- latlon = -latlon;
- setlon(pl, latlon);
- } else return -1;
- break;
- default:
- return -1;
- }
- if(ep)
- *ep = p;
- return 0;
- }
- Place
- strtopos(char *p, char **ep)
- {
- Place pl = nowhere;
- if(strtolatlon(p, &p, &pl) < 0)
- return nowhere;
- while(*p == ' ' || *p == '\t' || *p == '\n')
- p++;
- if(strtolatlon(p, &p, &pl) < 0)
- return nowhere;
- if(ep)
- *ep = p;
- return pl;
- }
- #if 0
- static void
- rtcset(int32_t t) /* We may use this some day */
- {
- static int fd;
- int32_t r;
- int n;
- char buf[32];
- if(fd <= 0 && (fd = open("#r/rtc", ORDWR)) < 0){
- fprint(2, "Can't open #r/rtc: %r\n");
- return;
- }
- n = read(fd, buf, sizeof buf - 1);
- if(n <= 0){
- fprint(2, "Can't read #r/rtc: %r\n");
- return;
- }
- buf[n] = '\0';
- r = strtol(buf, nil, 0);
- if(r <= 0){
- fprint(2, "ridiculous #r/rtc: %ld\n", r);
- return;
- }
- if(r - t > 1 || t - r > 0){
- seek(fd, 0, 0);
- fprint(fd, "%ld", t);
- fprint(2, "correcting #r/rtc: %ld → %ld\n", r, t);
- }
- seek(fd, 0, 0);
- }
- #endif
|