PageRenderTime 29ms CodeModel.GetById 2ms app.highlight 20ms RepoModel.GetById 2ms app.codeStats 0ms

/Proj4/dmstor.c

http://github.com/route-me/route-me
C | 111 lines | 103 code | 3 blank | 5 comment | 16 complexity | 9f8c6074076af9b3e61479f73ce6ebd0 MD5 | raw file
  1/* Convert DMS string to radians */
  2#ifndef lint
  3static const char SCCSID[]="@(#)dmstor.c	4.4	93/06/16	GIE	REL";
  4#endif
  5#include "projects.h"
  6#include <string.h>
  7#include <ctype.h>
  8
  9static double proj_strtod(char *nptr, char **endptr);
 10
 11/* following should be sufficient for all but the rediculous */
 12#define MAX_WORK 64
 13	static const char
 14*sym = "NnEeSsWw";
 15	static const double
 16vm[] = {
 17	.0174532925199433,
 18	.0002908882086657216,
 19	.0000048481368110953599
 20};
 21	double
 22dmstor(const char *is, char **rs) {
 23	int sign, n, nl;
 24	char *p, *s, work[MAX_WORK];
 25	double v, tv;
 26
 27	if (rs)
 28		*rs = (char *)is;
 29	/* copy sting into work space */
 30	while (isspace(*is)) ++is;
 31	for (n = MAX_WORK, s = work, p = (char *)is; isgraph(*p) && --n ; )
 32		*s++ = *p++;
 33	*s = '\0';
 34	/* it is possible that a really odd input (like lots of leading
 35		zeros) could be truncated in copying into work.  But ... */
 36	sign = *(s = work);
 37	if (sign == '+' || sign == '-') s++;
 38	else sign = '+';
 39	for (v = 0., nl = 0 ; nl < 3 ; nl = n + 1 ) {
 40		if (!(isdigit(*s) || *s == '.')) break;
 41		if ((tv = proj_strtod(s, &s)) == HUGE_VAL)
 42			return tv;
 43		switch (*s) {
 44		case 'D': case 'd':
 45			n = 0; break;
 46		case '\'':
 47			n = 1; break;
 48		case '"':
 49			n = 2; break;
 50		case 'r': case 'R':
 51			if (nl) {
 52				pj_errno = -16;
 53				return HUGE_VAL;
 54			}
 55			++s;
 56			v = tv;
 57			goto skip;
 58		default:
 59			v += tv * vm[nl];
 60		skip:	n = 4;
 61			continue;
 62		}
 63		if (n < nl) {
 64			pj_errno = -16;
 65			return HUGE_VAL;
 66		}
 67		v += tv * vm[n];
 68		++s;
 69	}
 70		/* postfix sign */
 71	if (*s && (p = strchr(sym, *s))) {
 72		sign = (p - sym) >= 4 ? '-' : '+';
 73		++s;
 74	}
 75	if (sign == '-')
 76		v = -v;
 77	if (rs) /* return point of next char after valid string */
 78		*rs = (char *)is + (s - work);
 79	return v;
 80}
 81
 82static double
 83proj_strtod(char *nptr, char **endptr) 
 84
 85{
 86    char c, *cp = nptr;
 87    double result;
 88
 89    /*
 90     * Scan for characters which cause problems with VC++ strtod()
 91     */
 92    while ((c = *cp) != '\0') {
 93        if (c == 'd' || c == 'D') {
 94
 95            /*
 96             * Found one, so NUL it out, call strtod(),
 97             * then restore it and return
 98             */
 99            *cp = '\0';
100            result = strtod(nptr, endptr);
101            *cp = c;
102            return result;
103        }
104        ++cp;
105    }
106
107    /* no offending characters, just handle normally */
108
109    return strtod(nptr, endptr);
110}
111