Blob


1 /*
2 * The authors of this software are Rob Pike and Ken Thompson.
3 * Copyright (c) 2002 by Lucent Technologies.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose without fee is hereby granted, provided that this entire notice
6 * is included in all copies of any software which is or includes a copy
7 * or modification of this software and in all copies of the supporting
8 * documentation for such software.
9 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
11 * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
13 */
14 #include <stdarg.h>
15 #include <string.h>
16 #include "plan9.h"
17 #include "fmt.h"
18 #include "fmtdef.h"
20 /*
21 * Reads a floating-point number by interpreting successive characters
22 * returned by (*f)(vp). The last call it makes to f terminates the
23 * scan, so is not a character in the number. It may therefore be
24 * necessary to back up the input stream up one byte after calling charstod.
25 */
27 double
28 fmtcharstod(int(*f)(void*), void *vp)
29 {
30 double num, dem;
31 int neg, eneg, dig, exp, c;
33 num = 0;
34 neg = 0;
35 dig = 0;
36 exp = 0;
37 eneg = 0;
39 c = (*f)(vp);
40 while(c == ' ' || c == '\t')
41 c = (*f)(vp);
42 if(c == '-' || c == '+'){
43 if(c == '-')
44 neg = 1;
45 c = (*f)(vp);
46 }
47 while(c >= '0' && c <= '9'){
48 num = num*10 + c-'0';
49 c = (*f)(vp);
50 }
51 if(c == '.')
52 c = (*f)(vp);
53 while(c >= '0' && c <= '9'){
54 num = num*10 + c-'0';
55 dig++;
56 c = (*f)(vp);
57 }
58 if(c == 'e' || c == 'E'){
59 c = (*f)(vp);
60 if(c == '-' || c == '+'){
61 if(c == '-'){
62 dig = -dig;
63 eneg = 1;
64 }
65 c = (*f)(vp);
66 }
67 while(c >= '0' && c <= '9'){
68 exp = exp*10 + c-'0';
69 c = (*f)(vp);
70 }
71 }
72 exp -= dig;
73 if(exp < 0){
74 exp = -exp;
75 eneg = !eneg;
76 }
77 dem = __fmtpow10(exp);
78 if(eneg)
79 num /= dem;
80 else
81 num *= dem;
82 if(neg)
83 return -num;
84 return num;
85 }