]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libc/port/charstod.c
libregexp: improve the transition to next available thread, instruction, and generation
[plan9front.git] / sys / src / libc / port / charstod.c
1 #include <u.h>
2 #include <libc.h>
3
4 /*
5  * Reads a floating-point number by interpreting successive characters
6  * returned by (*f)(vp).  The last call it makes to f terminates the
7  * scan, so is not a character in the number.  It may therefore be
8  * necessary to back up the input stream up one byte after calling charstod.
9  */
10
11 #define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp)
12
13 double
14 charstod(int(*f)(void*), void *vp)
15 {
16         char str[400], *s, *e, *start;
17         int c;
18
19         s = str;
20         e = str + sizeof str - 1;
21         c = (*f)(vp);
22         while(c == ' ' || c == '\t')
23                 c = (*f)(vp);
24         if(c == '-' || c == '+'){
25                 ADVANCE;
26         }
27         start = s;
28         while(c >= '0' && c <= '9'){
29                 ADVANCE;
30         }
31         if(c == '.'){
32                 ADVANCE;
33                 while(c >= '0' && c <= '9'){
34                         ADVANCE;
35                 }
36         }
37         if(s > start && (c == 'e' || c == 'E')){
38                 ADVANCE;
39                 if(c == '-' || c == '+'){
40                         ADVANCE;
41                 }
42                 while(c >= '0' && c <= '9'){
43                         ADVANCE;
44                 }
45         }else if(s == start && (c == 'i' || c == 'I')){
46                 ADVANCE;
47                 if(c != 'n' && c != 'N')
48                         return NaN();
49                 ADVANCE;
50                 if(c != 'f' && c != 'F')
51                         return NaN();
52                 ADVANCE;
53                 if(c != 'i' && c != 'I')
54                         return NaN();
55                 ADVANCE;
56                 if(c != 'n' && c != 'N')
57                         return NaN();
58                 ADVANCE;
59                 if(c != 'i' && c != 'I')
60                         return NaN();
61                 ADVANCE;
62                 if(c != 't' && c != 'T')
63                         return NaN();
64                 ADVANCE;
65                 if(c != 'y' && c != 'Y')
66                         return NaN();
67                 ADVANCE;  /* so caller can back up uniformly */
68                 USED(c);
69         }else if(s == str && (c == 'n' || c == 'N')){
70                 ADVANCE;
71                 if(c != 'a' && c != 'A')
72                         return NaN();
73                 ADVANCE;
74                 if(c != 'n' && c != 'N')
75                         return NaN();
76                 ADVANCE;  /* so caller can back up uniformly */
77                 USED(c);
78         }
79         *s = 0;
80         return strtod(str, &s);
81 }