1*3cd4f1d1SCharles Forsyth #include "lib9.h" 237da2899SCharles.Forsyth 337da2899SCharles.Forsyth /* 437da2899SCharles.Forsyth * Reads a floating-point number by interpreting successive characters 537da2899SCharles.Forsyth * returned by (*f)(vp). The last call it makes to f terminates the 637da2899SCharles.Forsyth * scan, so is not a character in the number. It may therefore be 737da2899SCharles.Forsyth * necessary to back up the input stream up one byte after calling charstod. 837da2899SCharles.Forsyth */ 937da2899SCharles.Forsyth 10*3cd4f1d1SCharles Forsyth #define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp) 11*3cd4f1d1SCharles Forsyth 1237da2899SCharles.Forsyth double charstod(int (* f)(void *),void * vp)1337da2899SCharles.Forsythcharstod(int(*f)(void*), void *vp) 1437da2899SCharles.Forsyth { 15*3cd4f1d1SCharles Forsyth char str[400], *s, *e, *start; 16*3cd4f1d1SCharles Forsyth int c; 1737da2899SCharles.Forsyth 18*3cd4f1d1SCharles Forsyth s = str; 19*3cd4f1d1SCharles Forsyth e = str + sizeof str - 1; 2037da2899SCharles.Forsyth c = (*f)(vp); 2137da2899SCharles.Forsyth while(c == ' ' || c == '\t') 2237da2899SCharles.Forsyth c = (*f)(vp); 2337da2899SCharles.Forsyth if(c == '-' || c == '+'){ 24*3cd4f1d1SCharles Forsyth ADVANCE; 2537da2899SCharles.Forsyth } 26*3cd4f1d1SCharles Forsyth start = s; 2737da2899SCharles.Forsyth while(c >= '0' && c <= '9'){ 28*3cd4f1d1SCharles Forsyth ADVANCE; 2937da2899SCharles.Forsyth } 30*3cd4f1d1SCharles Forsyth if(c == '.'){ 31*3cd4f1d1SCharles Forsyth ADVANCE; 3237da2899SCharles.Forsyth while(c >= '0' && c <= '9'){ 33*3cd4f1d1SCharles Forsyth ADVANCE; 3437da2899SCharles.Forsyth } 35*3cd4f1d1SCharles Forsyth } 36*3cd4f1d1SCharles Forsyth if(s > start && (c == 'e' || c == 'E')){ 37*3cd4f1d1SCharles Forsyth ADVANCE; 3837da2899SCharles.Forsyth if(c == '-' || c == '+'){ 39*3cd4f1d1SCharles Forsyth ADVANCE; 4037da2899SCharles.Forsyth } 4137da2899SCharles.Forsyth while(c >= '0' && c <= '9'){ 42*3cd4f1d1SCharles Forsyth ADVANCE; 4337da2899SCharles.Forsyth } 44*3cd4f1d1SCharles Forsyth }else if(s == start && (c == 'i' || c == 'I')){ 45*3cd4f1d1SCharles Forsyth ADVANCE; 46*3cd4f1d1SCharles Forsyth if(c != 'n' && c != 'N') 47*3cd4f1d1SCharles Forsyth return NaN(); 48*3cd4f1d1SCharles Forsyth ADVANCE; 49*3cd4f1d1SCharles Forsyth if(c != 'f' && c != 'F') 50*3cd4f1d1SCharles Forsyth return NaN(); 51*3cd4f1d1SCharles Forsyth ADVANCE; 52*3cd4f1d1SCharles Forsyth if(c != 'i' && c != 'I') 53*3cd4f1d1SCharles Forsyth return NaN(); 54*3cd4f1d1SCharles Forsyth ADVANCE; 55*3cd4f1d1SCharles Forsyth if(c != 'n' && c != 'N') 56*3cd4f1d1SCharles Forsyth return NaN(); 57*3cd4f1d1SCharles Forsyth ADVANCE; 58*3cd4f1d1SCharles Forsyth if(c != 'i' && c != 'I') 59*3cd4f1d1SCharles Forsyth return NaN(); 60*3cd4f1d1SCharles Forsyth ADVANCE; 61*3cd4f1d1SCharles Forsyth if(c != 't' && c != 'T') 62*3cd4f1d1SCharles Forsyth return NaN(); 63*3cd4f1d1SCharles Forsyth ADVANCE; 64*3cd4f1d1SCharles Forsyth if(c != 'y' && c != 'Y') 65*3cd4f1d1SCharles Forsyth return NaN(); 66*3cd4f1d1SCharles Forsyth ADVANCE; /* so caller can back up uniformly */ 67*3cd4f1d1SCharles Forsyth USED(c); 68*3cd4f1d1SCharles Forsyth }else if(s == str && (c == 'n' || c == 'N')){ 69*3cd4f1d1SCharles Forsyth ADVANCE; 70*3cd4f1d1SCharles Forsyth if(c != 'a' && c != 'A') 71*3cd4f1d1SCharles Forsyth return NaN(); 72*3cd4f1d1SCharles Forsyth ADVANCE; 73*3cd4f1d1SCharles Forsyth if(c != 'n' && c != 'N') 74*3cd4f1d1SCharles Forsyth return NaN(); 75*3cd4f1d1SCharles Forsyth ADVANCE; /* so caller can back up uniformly */ 76*3cd4f1d1SCharles Forsyth USED(c); 7737da2899SCharles.Forsyth } 78*3cd4f1d1SCharles Forsyth *s = 0; 79*3cd4f1d1SCharles Forsyth return strtod(str, &s); 8037da2899SCharles.Forsyth } 81