18ccd4a63SDavid du Colombier #include <u.h> 28ccd4a63SDavid du Colombier #include <libc.h> 3*0d601874SDavid du Colombier #include "fmtdef.h" 48ccd4a63SDavid du Colombier 58ccd4a63SDavid du Colombier /* 68ccd4a63SDavid du Colombier * Reads a floating-point number by interpreting successive characters 78ccd4a63SDavid du Colombier * returned by (*f)(vp). The last call it makes to f terminates the 88ccd4a63SDavid du Colombier * scan, so is not a character in the number. It may therefore be 98ccd4a63SDavid du Colombier * necessary to back up the input stream up one byte after calling charstod. 108ccd4a63SDavid du Colombier */ 118ccd4a63SDavid du Colombier 128ccd4a63SDavid du Colombier double fmtcharstod(int (* f)(void *),void * vp)13*0d601874SDavid du Colombierfmtcharstod(int(*f)(void*), void *vp) 148ccd4a63SDavid du Colombier { 15*0d601874SDavid du Colombier double num, dem; 16*0d601874SDavid du Colombier int neg, eneg, dig, exp, c; 178ccd4a63SDavid du Colombier 18*0d601874SDavid du Colombier num = 0; 19*0d601874SDavid du Colombier neg = 0; 20*0d601874SDavid du Colombier dig = 0; 21*0d601874SDavid du Colombier exp = 0; 22*0d601874SDavid du Colombier eneg = 0; 23*0d601874SDavid du Colombier 248ccd4a63SDavid du Colombier c = (*f)(vp); 258ccd4a63SDavid du Colombier while(c == ' ' || c == '\t') 268ccd4a63SDavid du Colombier c = (*f)(vp); 278ccd4a63SDavid du Colombier if(c == '-' || c == '+'){ 28*0d601874SDavid du Colombier if(c == '-') 29*0d601874SDavid du Colombier neg = 1; 30*0d601874SDavid du Colombier c = (*f)(vp); 318ccd4a63SDavid du Colombier } 328ccd4a63SDavid du Colombier while(c >= '0' && c <= '9'){ 33*0d601874SDavid du Colombier num = num*10 + c-'0'; 34*0d601874SDavid du Colombier c = (*f)(vp); 358ccd4a63SDavid du Colombier } 36*0d601874SDavid du Colombier if(c == '.') 37*0d601874SDavid du Colombier c = (*f)(vp); 388ccd4a63SDavid du Colombier while(c >= '0' && c <= '9'){ 39*0d601874SDavid du Colombier num = num*10 + c-'0'; 40*0d601874SDavid du Colombier dig++; 41*0d601874SDavid du Colombier c = (*f)(vp); 428ccd4a63SDavid du Colombier } 43*0d601874SDavid du Colombier if(c == 'e' || c == 'E'){ 44*0d601874SDavid du Colombier c = (*f)(vp); 458ccd4a63SDavid du Colombier if(c == '-' || c == '+'){ 46*0d601874SDavid du Colombier if(c == '-'){ 47*0d601874SDavid du Colombier dig = -dig; 48*0d601874SDavid du Colombier eneg = 1; 49*0d601874SDavid du Colombier } 50*0d601874SDavid du Colombier c = (*f)(vp); 518ccd4a63SDavid du Colombier } 528ccd4a63SDavid du Colombier while(c >= '0' && c <= '9'){ 53*0d601874SDavid du Colombier exp = exp*10 + c-'0'; 54*0d601874SDavid du Colombier c = (*f)(vp); 558ccd4a63SDavid du Colombier } 568ccd4a63SDavid du Colombier } 57*0d601874SDavid du Colombier exp -= dig; 58*0d601874SDavid du Colombier if(exp < 0){ 59*0d601874SDavid du Colombier exp = -exp; 60*0d601874SDavid du Colombier eneg = !eneg; 61*0d601874SDavid du Colombier } 62*0d601874SDavid du Colombier dem = __fmtpow10(exp); 63*0d601874SDavid du Colombier if(eneg) 64*0d601874SDavid du Colombier num /= dem; 65*0d601874SDavid du Colombier else 66*0d601874SDavid du Colombier num *= dem; 67*0d601874SDavid du Colombier if(neg) 68*0d601874SDavid du Colombier return -num; 69*0d601874SDavid du Colombier return num; 708ccd4a63SDavid du Colombier } 71