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 charstod(int (* f)(void *),void * vp)14charstod(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 } 82