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