shithub: map

ref: a0578c7de4163344d936ea78191a836556495bba
dir: /parse.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"

static double
s2d(char *s, char **r)
{
	char buf[32];
	char *bptr;
	
	bptr = buf;
	while ((*s >= '0' && *s <= '9') || *s == '.') {
		*bptr = *s;
		bptr++;
		s++;
	}
	*bptr = 0; /* paranoid */
	*r = s;
	return atof(buf);
}

static int
parseinto(char c, double n, double *lon, double *lat)
{
	switch (c) {
	default:
		return 0;
	case 'N': case 'n':
	case 'S': case 's':
		*lat = n;
		break;
	case 'W': case 'w':
	case 'E': case 'e':
		*lon = n;
		break;
	}
	return 1;
}

int
parsepos(char *data, int ndata, GPos *pos, int *zoom)
{
	char *str, *s;
	int ret;
	double num;
	double lon, lat;
	
	ret = 0;
	*zoom = -1;
	
	str = mallocz(sizeof(char) * (ndata + 1), 1);
	memcpy(str, data, ndata);
	
	/* invalid numbers for validation */
	lon = -1.;
	lat = -1.;
	
	/* stage 1: first number */
	num = s2d(str, &s);
	if (!parseinto(*s, num, &lon, &lat))
		goto Out;
	s++;
	
	/* stage 2: second number */
	num = s2d(s, &s);
	if (!parseinto(*s, num, &lon, &lat))
		goto Out;
	s++;
	
	/* stage 3: zoom level (optional) */
	if (*s)
		*zoom = atoi(s);
	
	/* stage 4: validate */
	if (lon < 0. || lon > 360.)
		goto Out;
	if (lat < 0. || lat > 180.)
		goto Out;
	
	pos->lon = lon;
	pos->lat = lat;
	ret = 1;
	
Out:
	free(str);
	return ret;
}