diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 11:58:26 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 11:58:26 +0300 |
commit | 765c7494b3dac62207e6cd57fb839997e237f292 (patch) | |
tree | f7da12ffdb85d9f82671cb3122775b2ce73f7ad9 /missing/strtod.c | |
parent | cce5115e21db1702e0617afdca36633e7e2c9eae (diff) | |
download | egawk-765c7494b3dac62207e6cd57fb839997e237f292.tar.gz egawk-765c7494b3dac62207e6cd57fb839997e237f292.tar.bz2 egawk-765c7494b3dac62207e6cd57fb839997e237f292.zip |
Moving to 2.13.2.
Diffstat (limited to 'missing/strtod.c')
-rw-r--r-- | missing/strtod.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/missing/strtod.c b/missing/strtod.c new file mode 100644 index 00000000..79350a1e --- /dev/null +++ b/missing/strtod.c @@ -0,0 +1,117 @@ +/* + * strtod.c + * + * Stupid version of System V strtod(3) library routine. + * Does no overflow/underflow checking. + * + * A real number is defined to be + * optional leading white space + * optional sign + * string of digits with optional decimal point + * optional 'e' or 'E' + * followed by optional sign or space + * followed by an integer + * + * if ptr is not NULL a pointer to the character terminating the + * scan is returned in *ptr. If no number formed, *ptr is set to str + * and 0 is returned. + * + * For speed, we don't do the conversion ourselves. Instead, we find + * the end of the number and then call atof() to do the dirty work. + * This bought us a 10% speedup on a sample program at uunet.uu.net. + */ + +#include <ctype.h> + +extern double atof(); + +double +strtod (s, ptr) +register char *s, **ptr; +{ + double ret = 0.0; + char *start = s; + char *begin = NULL; + int success = 0; + + /* optional white space */ + while (isspace(*s)) + s++; + + /* optional sign */ + if (*s == '+' || *s == '-') { + s++; + if (*(s-1) == '-') + begin = s - 1; + else + begin = s; + } + + /* string of digits with optional decimal point */ + if (isdigit(*s) && ! begin) + begin = s; + + while (isdigit(*s)) { + s++; + success++; + } + + if (*s == '.') { + if (! begin) + begin = s; + s++; + while (isdigit(*s)) + s++; + success++; + } + + if (s == start || success == 0) /* nothing there */ + goto out; + + /* + * optional 'e' or 'E' + * followed by optional sign or space + * followed by an integer + */ + + if (*s == 'e' || *s == 'E') { + s++; + + /* XXX - atof probably doesn't allow spaces here */ + while (isspace(*s)) + s++; + + if (*s == '+' || *s == '-') + s++; + + while (isdigit(*s)) + s++; + } + + /* go for it */ + ret = atof(begin); + +out: + if (! success) + s = start; /* in case all we did was skip whitespace */ + + if (ptr) + *ptr = s; + + return ret; +} + +#ifdef TEST +main (argc, argv) +int argc; +char **argv; +{ + double d; + char *p; + + for (argc--, argv++; argc; argc--, argv++) { + d = strtod (*argv, & p); + printf ("%lf [%s]\n", d, p); + } +} +#endif |