charstod.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
charstod.c (1309B) | |
--- | |
1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */ | |
2 #include <stdarg.h> | |
3 #include <string.h> | |
4 #include "plan9.h" | |
5 #include "fmt.h" | |
6 #include "fmtdef.h" | |
7 | |
8 /* | |
9 * Reads a floating-point number by interpreting successive characters | |
10 * returned by (*f)(vp). The last call it makes to f terminates the | |
11 * scan, so is not a character in the number. It may therefore be | |
12 * necessary to back up the input stream up one byte after calling chars… | |
13 */ | |
14 | |
15 double | |
16 fmtcharstod(int(*f)(void*), void *vp) | |
17 { | |
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 } |