vCalendar: Honor VTIMEZONE component if present
[claws.git] / src / plugins / litehtml_viewer / litehtml / strtod.cpp
blob22392c494369857fb27ac9c5f38f2e63de2828b9
1 /*
2 * strtod.c --
4 * Source code for the "strtod" library procedure.
6 * Copyright (c) 1988-1993 The Regents of the University of California.
7 * Copyright (c) 1994 Sun Microsystems, Inc.
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.
17 * RCS: @(#) $Id$
20 #include "html.h"
21 #include <cstdlib>
22 #include <cctype>
23 #include <cerrno>
25 #ifndef TRUE
26 #define TRUE 1
27 #define FALSE 0
28 #endif
29 #ifndef NULL
30 #define NULL 0
31 #endif
33 static int maxExponent = 511; /* Largest possible base 10 exponent. Any
34 * exponent larger than this will already
35 * produce underflow or overflow, so there's
36 * no need to worry about additional digits.
38 static double powersOf10[] = { /* Table giving binary powers of 10. Entry */
39 10., /* is 10^2^i. Used to convert decimal */
40 100., /* exponents into floating-point numbers. */
41 1.0e4,
42 1.0e8,
43 1.0e16,
44 1.0e32,
45 1.0e64,
46 1.0e128,
47 1.0e256
51 *----------------------------------------------------------------------
53 * strtod --
55 * This procedure converts a floating-point number from an ASCII
56 * decimal representation to internal double-precision format.
58 * Results:
59 * The return value is the double-precision floating-point
60 * representation of the characters in string. If endPtr isn't
61 * NULL, then *endPtr is filled in with the address of the
62 * next character after the last one that was part of the
63 * floating-point number.
65 * Side effects:
66 * None.
68 *----------------------------------------------------------------------
71 double litehtml::t_strtod(const char* string, char** endPtr)
73 int sign, expSign = FALSE;
74 double fraction, dblExp, *d;
75 const char *p;
76 int c;
77 int exp = 0; /* Exponent read from "EX" field. */
78 int fracExp = 0; /* Exponent that derives from the fractional
79 * part. Under normal circumstatnces, it is
80 * the negative of the number of digits in F.
81 * However, if I is very long, the last digits
82 * of I get dropped (otherwise a long I with a
83 * large negative exponent could cause an
84 * unnecessary overflow on I alone). In this
85 * case, fracExp is incremented one for each
86 * dropped digit. */
87 int mantSize; /* Number of digits in mantissa. */
88 int decPt; /* Number of mantissa digits BEFORE decimal
89 * point. */
90 const char *pExp; /* Temporarily holds location of exponent
91 * in string. */
94 * Strip off leading blanks and check for a sign.
97 p = string;
98 while (isspace(*p))
100 p += 1;
102 if (*p == '-')
104 sign = TRUE;
105 p += 1;
106 } else
108 if (*p == '+')
110 p += 1;
112 sign = FALSE;
116 * Count the number of digits in the mantissa (including the decimal
117 * point), and also locate the decimal point.
120 decPt = -1;
121 for (mantSize = 0; ; mantSize += 1)
123 c = *p;
124 if (!t_isdigit(c))
126 if ((c != '.') || (decPt >= 0))
128 break;
130 decPt = mantSize;
132 p += 1;
136 * Now suck up the digits in the mantissa. Use two integers to
137 * collect 9 digits each (this is faster than using floating-point).
138 * If the mantissa has more than 18 digits, ignore the extras, since
139 * they can't affect the value anyway.
142 pExp = p;
143 p -= mantSize;
144 if (decPt < 0)
146 decPt = mantSize;
147 } else
149 mantSize -= 1; /* One of the digits was the point. */
151 if (mantSize > 18)
153 fracExp = decPt - 18;
154 mantSize = 18;
155 } else
157 fracExp = decPt - mantSize;
159 if (mantSize == 0)
161 fraction = 0.0;
162 p = string;
163 goto done;
164 } else
166 int frac1, frac2;
167 frac1 = 0;
168 for ( ; mantSize > 9; mantSize -= 1)
170 c = *p;
171 p += 1;
172 if (c == '.')
174 c = *p;
175 p += 1;
177 frac1 = 10*frac1 + (c - '0');
179 frac2 = 0;
180 for (; mantSize > 0; mantSize -= 1)
182 c = *p;
183 p += 1;
184 if (c == '.')
186 c = *p;
187 p += 1;
189 frac2 = 10*frac2 + (c - '0');
191 fraction = (1.0e9 * frac1) + frac2;
195 * Skim off the exponent.
198 p = pExp;
199 if ((*p == 'E') || (*p == 'e'))
201 p += 1;
202 if (*p == '-')
204 expSign = TRUE;
205 p += 1;
206 } else
208 if (*p == '+')
210 p += 1;
212 expSign = FALSE;
214 while (isdigit(*p))
216 exp = exp * 10 + (*p - '0');
217 p += 1;
220 if (expSign)
222 exp = fracExp - exp;
223 } else
225 exp = fracExp + exp;
229 * Generate a floating-point number that represents the exponent.
230 * Do this by processing the exponent one bit at a time to combine
231 * many powers of 2 of 10. Then combine the exponent with the
232 * fraction.
235 if (exp < 0)
237 expSign = TRUE;
238 exp = -exp;
239 } else
241 expSign = FALSE;
243 if (exp > maxExponent)
245 exp = maxExponent;
246 errno = ERANGE;
248 dblExp = 1.0;
249 for (d = powersOf10; exp != 0; exp >>= 1, d += 1)
251 if (exp & 01)
253 dblExp *= *d;
256 if (expSign)
258 fraction /= dblExp;
259 } else
261 fraction *= dblExp;
264 done:
265 if (endPtr != nullptr)
267 *endPtr = (char *) p;
270 if (sign)
272 return -fraction;
274 return fraction;