diff options
| author | Charles Forsyth <charles.forsyth@gmail.com> | 2014-06-30 10:57:08 +0100 |
|---|---|---|
| committer | Charles Forsyth <charles.forsyth@gmail.com> | 2014-06-30 10:57:08 +0100 |
| commit | 3cd4f1d15146c08f05206d6328ecbc1c7fdc8dfa (patch) | |
| tree | a546acadca10b43d6b5eafc6d85f4aed361e9988 /libkern/charstod.c | |
| parent | ee030d07b2cf167be70f1dc36f56bdf3012860ae (diff) | |
update to match lib9
Diffstat (limited to 'libkern/charstod.c')
| -rw-r--r-- | libkern/charstod.c | 96 |
1 files changed, 54 insertions, 42 deletions
diff --git a/libkern/charstod.c b/libkern/charstod.c index 203e5379..10d0b220 100644 --- a/libkern/charstod.c +++ b/libkern/charstod.c @@ -1,4 +1,4 @@ -#include <lib9.h> +#include "lib9.h" /* * Reads a floating-point number by interpreting successive characters @@ -7,62 +7,74 @@ * necessary to back up the input stream up one byte after calling charstod. */ +#define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp) + double charstod(int(*f)(void*), void *vp) { - double num, dem; - int neg, eneg, dig, exp, c; - - num = 0; - neg = 0; - dig = 0; - exp = 0; - eneg = 0; + char str[400], *s, *e, *start; + int c; + s = str; + e = str + sizeof str - 1; c = (*f)(vp); while(c == ' ' || c == '\t') c = (*f)(vp); if(c == '-' || c == '+'){ - if(c == '-') - neg = 1; - c = (*f)(vp); + ADVANCE; } + start = s; while(c >= '0' && c <= '9'){ - num = num*10 + c-'0'; - c = (*f)(vp); + ADVANCE; } - if(c == '.') - c = (*f)(vp); - while(c >= '0' && c <= '9'){ - num = num*10 + c-'0'; - dig++; - c = (*f)(vp); + if(c == '.'){ + ADVANCE; + while(c >= '0' && c <= '9'){ + ADVANCE; + } } - if(c == 'e' || c == 'E'){ - c = (*f)(vp); + if(s > start && (c == 'e' || c == 'E')){ + ADVANCE; if(c == '-' || c == '+'){ - if(c == '-'){ - dig = -dig; - eneg = 1; - } - c = (*f)(vp); + ADVANCE; } while(c >= '0' && c <= '9'){ - exp = exp*10 + c-'0'; - c = (*f)(vp); + ADVANCE; } + }else if(s == start && (c == 'i' || c == 'I')){ + ADVANCE; + if(c != 'n' && c != 'N') + return NaN(); + ADVANCE; + if(c != 'f' && c != 'F') + return NaN(); + ADVANCE; + if(c != 'i' && c != 'I') + return NaN(); + ADVANCE; + if(c != 'n' && c != 'N') + return NaN(); + ADVANCE; + if(c != 'i' && c != 'I') + return NaN(); + ADVANCE; + if(c != 't' && c != 'T') + return NaN(); + ADVANCE; + if(c != 'y' && c != 'Y') + return NaN(); + ADVANCE; /* so caller can back up uniformly */ + USED(c); + }else if(s == str && (c == 'n' || c == 'N')){ + ADVANCE; + if(c != 'a' && c != 'A') + return NaN(); + ADVANCE; + if(c != 'n' && c != 'N') + return NaN(); + ADVANCE; /* so caller can back up uniformly */ + USED(c); } - exp -= dig; - if(exp < 0){ - exp = -exp; - eneg = !eneg; - } - dem = pow10(exp); - if(eneg) - num /= dem; - else - num *= dem; - if(neg) - return -num; - return num; + *s = 0; + return strtod(str, &s); } |
