summaryrefslogtreecommitdiffstats
path: root/funtools/util/strtod.c
diff options
context:
space:
mode:
Diffstat (limited to 'funtools/util/strtod.c')
-rw-r--r--funtools/util/strtod.c190
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;
+}
+