Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}