~ubuntu-branches/ubuntu/vivid/emscripten/vivid-proposed

« back to all changes in this revision

Viewing changes to system/lib/libc/stdlib/strtod.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2014-01-19 14:12:40 UTC
  • mfrom: (4.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140119141240-nfiw0p8033oitpfz
Tags: 1.9.0~20140119~7dc8c2f-1
* New snapshot release (Closes: #733714)
* Provide sources for javascript and flash. Done in orig-tar.sh
  Available in third_party/websockify/include/web-socket-js/src/
  (Closes: #735903)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * strtod.c --
3
 
 *
4
 
 *      Source code for the "strtod" library procedure.
5
 
 *
6
 
 * Copyright (c) 1988-1993 The Regents of the University of California.
7
 
 * Copyright (c) 1994 Sun Microsystems, Inc.
8
 
 *
9
 
 * Permission to use, copy, modify, and distribute this
10
 
 * software and its documentation for any purpose and without
11
 
 * fee is hereby granted, provided that the above copyright
12
 
 * notice appear in all copies.  The University of California
13
 
 * makes no representations about the suitability of this
14
 
 * software for any purpose.  It is provided "as is" without
15
 
 * express or implied warranty.
16
 
 *
17
 
 * RCS: @(#) $Id$
18
 
 *
19
 
 * Taken from http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8/missing/strtod.c
20
 
 */
21
 
 
22
 
#include <stdlib.h>
23
 
#include <ctype.h>
24
 
#include <errno.h>
25
 
#include <locale.h>
26
 
extern  int     errno;
27
 
 
28
 
#ifndef __STDC__
29
 
# ifdef __GNUC__
30
 
#  define const __const__
31
 
# else
32
 
#  define const
33
 
# endif
34
 
#endif
35
 
 
36
 
#ifndef TRUE
37
 
#define TRUE 1
38
 
#define FALSE 0
39
 
#endif
40
 
#ifndef NULL
41
 
#define NULL 0
42
 
#endif
43
 
 
44
 
static int maxExponent = 511;   /* Largest possible base 10 exponent.  Any
45
 
                                 * exponent larger than this will already
46
 
                                 * produce underflow or overflow, so there's
47
 
                                 * no need to worry about additional digits.
48
 
                                 */
49
 
static double powersOf10[] = {  /* Table giving binary powers of 10.  Entry */
50
 
    10.,                        /* is 10^2^i.  Used to convert decimal */
51
 
    100.,                       /* exponents into floating-point numbers. */
52
 
    1.0e4,
53
 
    1.0e8,
54
 
    1.0e16,
55
 
    1.0e32,
56
 
    1.0e64,
57
 
    1.0e128,
58
 
    1.0e256
59
 
};
60
 
 
61
 
/*
62
 
 *----------------------------------------------------------------------
63
 
 *
64
 
 * strtod --
65
 
 *
66
 
 *      This procedure converts a floating-point number from an ASCII
67
 
 *      decimal representation to internal double-precision format.
68
 
 *
69
 
 * Results:
70
 
 *      The return value is the double-precision floating-point
71
 
 *      representation of the characters in string.  If endPtr isn't
72
 
 *      NULL, then *endPtr is filled in with the address of the
73
 
 *      next character after the last one that was part of the
74
 
 *      floating-point number.
75
 
 *
76
 
 * Side effects:
77
 
 *      None.
78
 
 *
79
 
 *----------------------------------------------------------------------
80
 
 */
81
 
 
82
 
double
83
 
strtod(string, endPtr)
84
 
    const char *string;         /* A decimal ASCII floating-point number,
85
 
                                 * optionally preceded by white space.
86
 
                                 * Must have form "-I.FE-X", where I is the
87
 
                                 * integer part of the mantissa, F is the
88
 
                                 * fractional part of the mantissa, and X
89
 
                                 * is the exponent.  Either of the signs
90
 
                                 * may be "+", "-", or omitted.  Either I
91
 
                                 * or F may be omitted, or both.  The decimal
92
 
                                 * point isn't necessary unless F is present.
93
 
                                 * The "E" may actually be an "e".  E and X
94
 
                                 * may both be omitted (but not just one).
95
 
                                 */
96
 
    char **endPtr;              /* If non-NULL, store terminating character's
97
 
                                 * address here. */
98
 
{
99
 
    int sign, expSign = FALSE;
100
 
    double fraction, dblExp, *d;
101
 
    register const char *p;
102
 
    register int c;
103
 
    int exp = 0;                /* Exponent read from "EX" field. */
104
 
    int fracExp = 0;            /* Exponent that derives from the fractional
105
 
                                 * part.  Under normal circumstatnces, it is
106
 
                                 * the negative of the number of digits in F.
107
 
                                 * However, if I is very long, the last digits
108
 
                                 * of I get dropped (otherwise a long I with a
109
 
                                 * large negative exponent could cause an
110
 
                                 * unnecessary overflow on I alone).  In this
111
 
                                 * case, fracExp is incremented one for each
112
 
                                 * dropped digit. */
113
 
    int mantSize;               /* Number of digits in mantissa. */
114
 
    int decPt;                  /* Number of mantissa digits BEFORE decimal
115
 
                                 * point. */
116
 
    const char *pExp;           /* Temporarily holds location of exponent
117
 
                                 * in string. */
118
 
 
119
 
    /*
120
 
     * Strip off leading blanks and check for a sign.
121
 
     */
122
 
 
123
 
    p = string;
124
 
    while (isspace(*p)) {
125
 
        p += 1;
126
 
    }
127
 
    if (*p == '-') {
128
 
        sign = TRUE;
129
 
        p += 1;
130
 
    } else {
131
 
        if (*p == '+') {
132
 
            p += 1;
133
 
        }
134
 
        sign = FALSE;
135
 
    }
136
 
 
137
 
    /*
138
 
     * Count the number of digits in the mantissa (including the decimal
139
 
     * point), and also locate the decimal point.
140
 
     */
141
 
 
142
 
    decPt = -1;
143
 
    for (mantSize = 0; ; mantSize += 1)
144
 
    {
145
 
        c = *p;
146
 
        if (!isdigit(c)) {
147
 
            if ((c != '.') || (decPt >= 0)) {
148
 
                break;
149
 
            }
150
 
            decPt = mantSize;
151
 
        }
152
 
        p += 1;
153
 
    }
154
 
 
155
 
    /*
156
 
     * Now suck up the digits in the mantissa.  Use two integers to
157
 
     * collect 9 digits each (this is faster than using floating-point).
158
 
     * If the mantissa has more than 18 digits, ignore the extras, since
159
 
     * they can't affect the value anyway.
160
 
     */
161
 
    
162
 
    pExp  = p;
163
 
    p -= mantSize;
164
 
    if (decPt < 0) {
165
 
        decPt = mantSize;
166
 
    } else {
167
 
        mantSize -= 1;                  /* One of the digits was the point. */
168
 
    }
169
 
    if (mantSize > 18) {
170
 
        fracExp = decPt - 18;
171
 
        mantSize = 18;
172
 
    } else {
173
 
        fracExp = decPt - mantSize;
174
 
    }
175
 
    if (mantSize == 0) {
176
 
        fraction = 0.0;
177
 
        p = string;
178
 
        goto done;
179
 
    } else {
180
 
        int frac1, frac2;
181
 
        frac1 = 0;
182
 
        for ( ; mantSize > 9; mantSize -= 1)
183
 
        {
184
 
            c = *p;
185
 
            p += 1;
186
 
            if (c == '.') {
187
 
                c = *p;
188
 
                p += 1;
189
 
            }
190
 
            frac1 = 10*frac1 + (c - '0');
191
 
        }
192
 
        frac2 = 0;
193
 
        for (; mantSize > 0; mantSize -= 1)
194
 
        {
195
 
            c = *p;
196
 
            p += 1;
197
 
            if (c == '.') {
198
 
                c = *p;
199
 
                p += 1;
200
 
            }
201
 
            frac2 = 10*frac2 + (c - '0');
202
 
        }
203
 
        fraction = (1.0e9 * frac1) + frac2;
204
 
    }
205
 
 
206
 
    /*
207
 
     * Skim off the exponent.
208
 
     */
209
 
 
210
 
    p = pExp;
211
 
    if ((*p == 'E') || (*p == 'e')) {
212
 
        p += 1;
213
 
        if (*p == '-') {
214
 
            expSign = TRUE;
215
 
            p += 1;
216
 
        } else {
217
 
            if (*p == '+') {
218
 
                p += 1;
219
 
            }
220
 
            expSign = FALSE;
221
 
        }
222
 
        while (isdigit(*p)) {
223
 
            exp = exp * 10 + (*p - '0');
224
 
            p += 1;
225
 
        }
226
 
    }
227
 
    if (expSign) {
228
 
        exp = fracExp - exp;
229
 
    } else {
230
 
        exp = fracExp + exp;
231
 
    }
232
 
 
233
 
    /*
234
 
     * Generate a floating-point number that represents the exponent.
235
 
     * Do this by processing the exponent one bit at a time to combine
236
 
     * many powers of 2 of 10. Then combine the exponent with the
237
 
     * fraction.
238
 
     */
239
 
    
240
 
    if (exp < 0) {
241
 
        expSign = TRUE;
242
 
        exp = -exp;
243
 
    } else {
244
 
        expSign = FALSE;
245
 
    }
246
 
    if (exp > maxExponent) {
247
 
        exp = maxExponent;
248
 
        errno = ERANGE;
249
 
    }
250
 
    dblExp = 1.0;
251
 
    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
252
 
        if (exp & 01) {
253
 
            dblExp *= *d;
254
 
        }
255
 
    }
256
 
    if (expSign) {
257
 
        fraction /= dblExp;
258
 
    } else {
259
 
        fraction *= dblExp;
260
 
    }
261
 
 
262
 
done:
263
 
    if (endPtr != NULL) {
264
 
        *endPtr = (char *) p;
265
 
    }
266
 
 
267
 
    if (sign) {
268
 
        return -fraction;
269
 
    }
270
 
    return fraction;
271
 
}
272
 
 
273
 
/*
274
 
 * Implementations added for emscripten.
275
 
 */
276
 
// XXX add real support for long double
277
 
long double
278
 
strtold(const char* nptr, char **endptr)
279
 
{
280
 
  return (long double) strtod(nptr, endptr);
281
 
}
282
 
 
283
 
// use stdtod to handle strtof
284
 
float
285
 
strtof(const char* nptr, char **endptr)
286
 
{
287
 
  return (float) strtod(nptr, endptr);
288
 
}
289
 
 
290
 
// XXX no locale support yet
291
 
double
292
 
strtod_l(const char* nptr, char **endptr, locale_t loc)
293
 
{
294
 
  return strtod(nptr, endptr);
295
 
}
296
 
long double
297
 
strtold_l(const char* nptr, char **endptr, locale_t loc)
298
 
{
299
 
  return strtold(nptr, endptr);
300
 
}
301
 
 
302
 
double atof(const char* str)
303
 
{
304
 
  return strtod(str, (char **) NULL);
305
 
}