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