diff options
Diffstat (limited to 'funtools/util/strtod.c')
-rw-r--r-- | funtools/util/strtod.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/funtools/util/strtod.c b/funtools/util/strtod.c new file mode 100644 index 0000000..ce69a37 --- /dev/null +++ b/funtools/util/strtod.c @@ -0,0 +1,190 @@ +#if HAVE_CONFIG_H +#include <conf.h> +#endif +#include <stdio.h> +#include <ctype.h> +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#if HAVE_STDLIB_H +#include <stdlib.h> +#else +double strtod(); +#endif +#include <math.h> + +int SAOdtype=0; + +double SAOstrtod(str, ptr) + char *str; + char **ptr; +{ + double d = 0.0; + double m = 0.0; + double s = 0.0; + char *p, *px; + char c; + + SAOdtype = 0; + + if ( ptr == NULL ) ptr = &p; + while ( *str == ' ' ) str++; + + + /* No base implied (yet). + */ + d = strtod(str, ptr); + px = *ptr; + + if( strchr(str, (int)'.') ) + SAOdtype = '.'; + + if ( ( c = **ptr ) + && ( c == 'h' || c == 'd' || c == ':' || c == ' ' || c == 'm' ) + && ( (*ptr - str) <= 4 ) + && ( ( isdigit((int)*((*ptr)+1)) ) + || ( (*((*ptr)+1)) == ' ' && isdigit((int)*((*ptr)+2)) ) ) ) { + double sign = 1.0; + + SAOdtype = c; + (*ptr)++; + + if ( *str == '-' ) { + sign = -1.0; + d = -d; + } + + m = strtod(*ptr, ptr); + + if ( c == 'm' ) { + s = m; + m = d; + d = 0.0; + } else + if ( ( c = **ptr ) + && ( c == ':' || c == ' ' || c == 'm' ) + && ( (*ptr - px) <= 3 ) + && ( ( isdigit((int)*((*ptr)+1)) ) + || ( (*((*ptr)+1)) == ' ' && isdigit((int)*((*ptr)+2))))) { + + (*ptr)++; + + s = strtod(*ptr, ptr); + } + + return sign * (d + m / 60 + s / 3600); + } + + /* I guess that there wern't really any units. + */ + return d; +} + +char *SAOconvert(buff, val, type, prec) + char *buff; + double val; + int type; + int prec; +{ + char fmt[32]; + char *sign = ""; + + float degrees = val; + float minutes; + float seconds; + + char ch1, ch2; + + switch ( type ) { + case 'b': { + int v = val; + unsigned int i; + int c = 2; + + buff[0] = '0'; + buff[1] = 'b'; + + for ( i = 0x8000; i; i /= 2 ) { + if ( v & i || c > 2 ) { + buff[c] = v & i ? '1' : '0'; + c++; + } + } + + buff[c] = '\0'; + return buff; + } + case 'o': + sprintf(buff, "0o%o", (int) val); + return buff; + + case 'x': + sprintf(buff, "0x%x", (int) val); + return buff; + + case ':': ch1 = ':'; ch2 = ':'; break; + case ' ': ch1 = ' '; ch2 = ' '; break; + case 'h': ch1 = 'h'; ch2 = 'm'; break; + case 'd': ch1 = 'd'; ch2 = 'm'; break; + case 'm': ch1 = 'm'; ch2 = 'm'; break; + default: return 0; + } + + if ( degrees < 0.0 ) { + sign = "-"; + degrees = - degrees; + } + + minutes = (degrees - ((int) degrees)) * 60; + if ( minutes < 0 ) minutes = 0.0; + seconds = (minutes - ((int) minutes)) * 60; + if ( seconds < 0 ) seconds = 0.0; + + if ( prec == -1 ){ + if ( type == 'h' ) prec = 4; + else prec = 3; + } + if ( prec == -2 ) { + if ( type == 'm' ){ + if ( seconds < 10.0 ) + sprintf(buff, "%s%d%c0%g" + , sign, (int)(minutes+degrees*60), ch2, seconds); + else + sprintf(buff, "%s%d%c%g" + , sign, (int)(minutes+degrees*60), ch2, seconds); + } + else if ( seconds < 10.0 ) + sprintf(buff, "%s%d%c0%2d%c0%g" + , sign, (int) (degrees) + , ch1 , (int) (minutes) + , ch2, seconds); + else + sprintf(buff, "%s%d%c%2d%c%g" + , sign, (int) (degrees) + , ch1 , (int) (minutes) + , ch2, seconds); + } else { + double p = pow(10.0, (double) prec); + int m = minutes; + int d = degrees; + + if ( (((int)(seconds * p + .5))/ p) >= 60 ) { + seconds = 0.0; + m++; + if ( m >= 60 ) { + m = 0; + d++; + } + } + + if ( (((int)(seconds * p + .5))/ p) < 10.0 ) + sprintf(fmt, "%%s%%d%c%%2.2d%c0%%.%df", ch1, ch2, prec); + else + sprintf(fmt, "%%s%%d%c%%2.2d%c%%.%df" , ch1, ch2, prec); + + sprintf(buff, fmt, sign, d, m, seconds); + } + + return buff; +} + |