charstod.c (1357B)
1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */ 2 #include "fmt.h" 3 #include "fmtdef.h" 4 #include "plan9.h" 5 6 #include <stdarg.h> 7 #include <string.h> 8 9 /* 10 * Reads a floating-point number by interpreting successive characters 11 * returned by (*f)(vp). The last call it makes to f terminates the 12 * scan, so is not a character in the number. It may therefore be 13 * necessary to back up the input stream up one byte after calling charstod. 14 */ 15 16 double 17 fmtcharstod(int (*f)(void*), void* vp) { 18 double num, dem; 19 int neg, eneg, dig, exp, c; 20 21 num = 0; 22 neg = 0; 23 dig = 0; 24 exp = 0; 25 eneg = 0; 26 27 c = (*f)(vp); 28 while (c == ' ' || c == '\t') 29 c = (*f)(vp); 30 if (c == '-' || c == '+') { 31 if (c == '-') 32 neg = 1; 33 c = (*f)(vp); 34 } 35 while (c >= '0' && c <= '9') { 36 num = num * 10 + c - '0'; 37 c = (*f)(vp); 38 } 39 if (c == '.') 40 c = (*f)(vp); 41 while (c >= '0' && c <= '9') { 42 num = num * 10 + c - '0'; 43 dig++; 44 c = (*f)(vp); 45 } 46 if (c == 'e' || c == 'E') { 47 c = (*f)(vp); 48 if (c == '-' || c == '+') { 49 if (c == '-') { 50 dig = -dig; 51 eneg = 1; 52 } 53 c = (*f)(vp); 54 } 55 while (c >= '0' && c <= '9') { 56 exp = exp * 10 + c - '0'; 57 c = (*f)(vp); 58 } 59 } 60 exp -= dig; 61 if (exp < 0) { 62 exp = -exp; 63 eneg = !eneg; 64 } 65 dem = __fmtpow10(exp); 66 if (eneg) 67 num /= dem; 68 else 69 num *= dem; 70 if (neg) 71 return -num; 72 return num; 73 }