aboutsummaryrefslogtreecommitdiffstats
path: root/missing.d/strtod.c
diff options
context:
space:
mode:
Diffstat (limited to 'missing.d/strtod.c')
-rw-r--r--missing.d/strtod.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/missing.d/strtod.c b/missing.d/strtod.c
new file mode 100644
index 00000000..79350a1e
--- /dev/null
+++ b/missing.d/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