~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/sfio/sfstrtod.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include        "sfhdr.h"
 
2
 
 
3
/*      Convert a Sfdouble_t value represented in an ASCII format into
 
4
**      the internal Sfdouble_t representation.
 
5
**
 
6
**      Written by Kiem-Phong Vo.
 
7
*/
 
8
 
 
9
#define BATCH   (2*sizeof(int)) /* accumulate this many digits at a time */
 
10
#define IPART           0       /* doing integer part */
 
11
#define FPART           1       /* doing fractional part */
 
12
#define EPART           2       /* doing exponent part */
 
13
 
 
14
#if __STD_C
 
15
static Sfdouble_t sfpow10(reg int n)
 
16
#else
 
17
static Sfdouble_t sfpow10(n)
 
18
reg int n;
 
19
#endif
 
20
{
 
21
        Sfdouble_t      dval;
 
22
 
 
23
        switch(n)
 
24
        {       case -3:        return .001;
 
25
                case -2:        return .01;
 
26
                case -1:        return .1;
 
27
                case  0:        return 1.;
 
28
                case  1:        return 10.;
 
29
                case  2:        return 100.;
 
30
                case  3:        return 1000.;
 
31
        }
 
32
 
 
33
        if(n < 0)
 
34
        {       dval = .0001;
 
35
                for(n += 4; n < 0; n += 1)
 
36
                        dval /= 10.;
 
37
        }
 
38
        else
 
39
        {       dval = 10000.;
 
40
                for(n -= 4; n > 0; n -= 1)
 
41
                        dval *= 10.;
 
42
        }
 
43
 
 
44
        return dval;
 
45
}
 
46
 
 
47
#if __STD_C
 
48
Sfdouble_t _sfstrtod(reg const char* s, char** retp)
 
49
#else
 
50
Sfdouble_t _sfstrtod(s,retp)
 
51
reg char*       s;      /* string to convert */
 
52
char**          retp;   /* to return the remainder of string */
 
53
#endif
 
54
{
 
55
        reg int         n, c, m;
 
56
        reg int         mode, fexp, sign, expsign;
 
57
        Sfdouble_t      dval;
 
58
#if _lib_locale
 
59
        int             decpoint = 0;
 
60
        SFSETLOCALE(&decpoint,NIL(int*));
 
61
#else
 
62
#define decpoint        '.'
 
63
#endif
 
64
 
 
65
        /* skip initial blanks */
 
66
        while(isspace(*s))
 
67
                ++s;
 
68
 
 
69
        /* get the sign */
 
70
        if((sign = (*s == '-')) || *s == '+')
 
71
                s += 1;
 
72
 
 
73
        mode = IPART;
 
74
        fexp = expsign = 0;
 
75
        dval = 0.;
 
76
        while(*s)
 
77
        {       /* accumulate a handful of the digits */
 
78
                for(m = BATCH, n = 0; m > 0; --m, ++s)
 
79
                {       /* get and process a char */
 
80
                        c = *s;
 
81
                        if(isdigit(c))
 
82
                                n = 10*n + (c - '0');
 
83
                        else    break;
 
84
                }
 
85
 
 
86
                /* number of digits accumulated */
 
87
                m = BATCH-m;
 
88
 
 
89
                if(mode == IPART)
 
90
                {       /* doing the integer part */
 
91
                        if(dval == 0.)
 
92
                                dval = (Sfdouble_t)n;
 
93
                        else    dval = dval*sfpow10(m) + (Sfdouble_t)n;
 
94
                }
 
95
                else if(mode == FPART)
 
96
                {       /* doing the fractional part */
 
97
                        fexp -= m;
 
98
                        if(n > 0)
 
99
                                dval += n*sfpow10(fexp);
 
100
                }
 
101
                else if(n)
 
102
                {       /* doing the exponent part */
 
103
                        if(expsign)
 
104
                                n = -n;
 
105
                        dval *= sfpow10(n);
 
106
                }
 
107
 
 
108
                if(!c)
 
109
                        break;
 
110
 
 
111
                if(m < BATCH)
 
112
                {       /* detected a non-digit */
 
113
                        if(c == decpoint)
 
114
                        {       /* start the fractional part or no match */
 
115
                                if(mode != IPART)
 
116
                                        break;
 
117
                                mode = FPART;
 
118
                                s += 1;
 
119
                        }
 
120
                        else if(c == 'e' || c == 'E')
 
121
                        {       if(mode == EPART)
 
122
                                        break;
 
123
                                mode = EPART;
 
124
                                c = *++s;
 
125
                                if((expsign = (c == '-')) || c == '+')
 
126
                                        s += 1;
 
127
                        }
 
128
                        else    break;
 
129
                }
 
130
        }
 
131
 
 
132
        if(retp)
 
133
                *retp = (char*)s;
 
134
        return sign ? -dval : dval;
 
135
}