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