source: trunk/essentials/sys-apps/gawk/missing_d/strtod.c

Last change on this file was 3076, checked in by bird, 18 years ago

gawk 3.1.5

File size: 2.6 KB
Line 
1/*
2 * gawk wrapper for strtod
3 */
4/*
5 * Stupid version of System V strtod(3) library routine.
6 * Does no overflow/underflow checking.
7 *
8 * A real number is defined to be
9 * optional leading white space
10 * optional sign
11 * string of digits with optional decimal point
12 * optional 'e' or 'E'
13 * followed by optional sign or space
14 * followed by an integer
15 *
16 * if ptr is not NULL a pointer to the character terminating the
17 * scan is returned in *ptr. If no number formed, *ptr is set to str
18 * and 0 is returned.
19 *
20 * For speed, we don't do the conversion ourselves. Instead, we find
21 * the end of the number and then call atof() to do the dirty work.
22 * This bought us a 10% speedup on a sample program at uunet.uu.net.
23 *
24 * Fall 2000: Changed to enforce C89 semantics, so that 0x... returns 0.
25 * C99 has hexadecimal floating point numbers.
26 *
27 * Summer 2001. Try to make it smarter, so that a string like "0000"
28 * doesn't look like we failed. Sigh.
29 *
30 * Xmass 2002. Fix a bug in ptr determination, eg. for "0e0".
31 *
32 * Spring 2004. Update for I18N. Oh joy.
33 */
34
35#if 0
36#include <ctype.h>
37#endif
38
39extern double atof();
40
41double
42gawk_strtod(s, ptr)
43register const char *s;
44register const char **ptr;
45{
46 const char *start = s; /* save original start of string */
47 const char *begin = NULL; /* where the number really begins */
48 int dig = 0;
49 int dig0 = 0;
50
51 /* optional white space */
52 while (isspace(*s))
53 s++;
54
55 begin = s;
56
57 /* optional sign */
58 if (*s == '+' || *s == '-')
59 s++;
60
61 /* string of digits with optional decimal point */
62 while (*s == '0') {
63 s++;
64 dig0++;
65 }
66 while (isdigit(*s)) {
67 s++;
68 dig++;
69 }
70
71 if (
72#if defined(HAVE_LOCALE_H)
73 loc.decimal_point != NULL
74 ? *s == loc.decimal_point[0]
75 : *s == '.'
76#else
77 *s == '.'
78#endif
79 ) {
80 s++;
81 while (*s == '0') {
82 s++;
83 dig0++;
84 }
85 while (isdigit(*s)) {
86 s++;
87 dig++;
88 }
89 }
90
91 dig0 += dig; /* any digit has appeared */
92
93 /*
94 * optional 'e' or 'E'
95 * if a digit (or at least zero) was seen
96 * followed by optional sign
97 * followed by an integer
98 */
99 if (dig0
100 && (*s == 'e' || *s == 'E')
101 && (isdigit(s[1])
102 || ((s[1] == '-' || s[1] == '+') && isdigit(s[2])))) {
103 s++;
104 if (*s == '+' || *s == '-')
105 s++;
106 while (isdigit(*s))
107 s++;
108 }
109
110 /* In case we haven't found a number, set ptr to start. */
111 if (ptr)
112 *ptr = (dig0 ? s : start);
113
114 /* Go for it. */
115 return (dig ? atof(begin) : 0.0);
116}
117
118#ifdef TEST
119int
120main(argc, argv)
121int argc;
122char **argv;
123{
124 double d;
125 char *p;
126
127 for (argc--, argv++; argc; argc--, argv++) {
128 d = strtod (*argv, & p);
129 printf ("%lf [%s]\n", d, p);
130 }
131
132 return 0;
133}
134#endif
Note: See TracBrowser for help on using the repository browser.