13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier 43e12c5d1SDavid du Colombier /* 53e12c5d1SDavid du Colombier * Reads a floating-point number by interpreting successive characters 63e12c5d1SDavid du Colombier * returned by (*f)(vp). The last call it makes to f terminates the 73e12c5d1SDavid du Colombier * scan, so is not a character in the number. It may therefore be 83e12c5d1SDavid du Colombier * necessary to back up the input stream up one byte after calling charstod. 93e12c5d1SDavid du Colombier */ 103e12c5d1SDavid du Colombier 1159cc4ca5SDavid du Colombier #define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp) 1259cc4ca5SDavid du Colombier 133e12c5d1SDavid du Colombier double charstod(int (* f)(void *),void * vp)143e12c5d1SDavid du Colombiercharstod(int(*f)(void*), void *vp) 153e12c5d1SDavid du Colombier { 16*9a747e4fSDavid du Colombier char str[400], *s, *e, *start; 1759cc4ca5SDavid du Colombier int c; 183e12c5d1SDavid du Colombier 1959cc4ca5SDavid du Colombier s = str; 2059cc4ca5SDavid du Colombier e = str + sizeof str - 1; 213e12c5d1SDavid du Colombier c = (*f)(vp); 223e12c5d1SDavid du Colombier while(c == ' ' || c == '\t') 233e12c5d1SDavid du Colombier c = (*f)(vp); 243e12c5d1SDavid du Colombier if(c == '-' || c == '+'){ 2559cc4ca5SDavid du Colombier ADVANCE; 263e12c5d1SDavid du Colombier } 27*9a747e4fSDavid du Colombier start = s; 283e12c5d1SDavid du Colombier while(c >= '0' && c <= '9'){ 2959cc4ca5SDavid du Colombier ADVANCE; 303e12c5d1SDavid du Colombier } 3159cc4ca5SDavid du Colombier if(c == '.'){ 3259cc4ca5SDavid du Colombier ADVANCE; 333e12c5d1SDavid du Colombier while(c >= '0' && c <= '9'){ 3459cc4ca5SDavid du Colombier ADVANCE; 3559cc4ca5SDavid du Colombier } 363e12c5d1SDavid du Colombier } 37*9a747e4fSDavid du Colombier if(s > start && (c == 'e' || c == 'E')){ 3859cc4ca5SDavid du Colombier ADVANCE; 393e12c5d1SDavid du Colombier if(c == '-' || c == '+'){ 4059cc4ca5SDavid du Colombier ADVANCE; 413e12c5d1SDavid du Colombier } 423e12c5d1SDavid du Colombier while(c >= '0' && c <= '9'){ 4359cc4ca5SDavid du Colombier ADVANCE; 443e12c5d1SDavid du Colombier } 45*9a747e4fSDavid du Colombier }else if(s == start && (c == 'i' || c == 'I')){ 4659cc4ca5SDavid du Colombier ADVANCE; 4759cc4ca5SDavid du Colombier if(c != 'n' && c != 'N') 4859cc4ca5SDavid du Colombier return NaN(); 4959cc4ca5SDavid du Colombier ADVANCE; 5059cc4ca5SDavid du Colombier if(c != 'f' && c != 'F') 5159cc4ca5SDavid du Colombier return NaN(); 5259cc4ca5SDavid du Colombier ADVANCE; 5359cc4ca5SDavid du Colombier if(c != 'i' && c != 'I') 5459cc4ca5SDavid du Colombier return NaN(); 5559cc4ca5SDavid du Colombier ADVANCE; 5659cc4ca5SDavid du Colombier if(c != 'n' && c != 'N') 5759cc4ca5SDavid du Colombier return NaN(); 5859cc4ca5SDavid du Colombier ADVANCE; 5959cc4ca5SDavid du Colombier if(c != 'i' && c != 'I') 6059cc4ca5SDavid du Colombier return NaN(); 6159cc4ca5SDavid du Colombier ADVANCE; 6259cc4ca5SDavid du Colombier if(c != 't' && c != 'T') 6359cc4ca5SDavid du Colombier return NaN(); 6459cc4ca5SDavid du Colombier ADVANCE; 6559cc4ca5SDavid du Colombier if(c != 'y' && c != 'Y') 6659cc4ca5SDavid du Colombier return NaN(); 6759cc4ca5SDavid du Colombier ADVANCE; /* so caller can back up uniformly */ 6859cc4ca5SDavid du Colombier USED(c); 69*9a747e4fSDavid du Colombier }else if(s == str && (c == 'n' || c == 'N')){ 7059cc4ca5SDavid du Colombier ADVANCE; 7159cc4ca5SDavid du Colombier if(c != 'a' && c != 'A') 7259cc4ca5SDavid du Colombier return NaN(); 7359cc4ca5SDavid du Colombier ADVANCE; 7459cc4ca5SDavid du Colombier if(c != 'n' && c != 'N') 7559cc4ca5SDavid du Colombier return NaN(); 7659cc4ca5SDavid du Colombier ADVANCE; /* so caller can back up uniformly */ 7759cc4ca5SDavid du Colombier USED(c); 783e12c5d1SDavid du Colombier } 7959cc4ca5SDavid du Colombier *s = 0; 8059cc4ca5SDavid du Colombier return strtod(str, &s); 813e12c5d1SDavid du Colombier } 82