1 /* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2023 Free Software
2 Foundation, Inc.
3
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation, either version 3 of the
7 License, or (at your option) any later version.
8
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 #if ! defined USE_LONG_DOUBLE
18 # include <config.h>
19 #endif
20
21 /* Specification. */
22 #include <stdlib.h>
23
24 #include <ctype.h> /* isspace() */
25 #include <errno.h>
26 #include <float.h> /* {DBL,LDBL}_{MIN,MAX} */
27 #include <limits.h> /* LONG_{MIN,MAX} */
28 #include <locale.h> /* localeconv() */
29 #include <math.h> /* NAN */
30 #include <stdio.h> /* sprintf() */
31 #include <string.h> /* strdup() */
32 #if HAVE_NL_LANGINFO
33 # include <langinfo.h>
34 #endif
35
36 #include "c-ctype.h"
37
38 #undef MIN
39 #undef MAX
40 #ifdef USE_LONG_DOUBLE
41 # define STRTOD strtold
42 # define LDEXP ldexpl
43 # if defined __hpux && defined __hppa
44 /* We cannot call strtold on HP-UX/hppa, because its return type is a struct,
45 not a 'long double'. */
46 # define HAVE_UNDERLYING_STRTOD 0
47 # elif STRTOLD_HAS_UNDERFLOW_BUG
48 /* strtold would not set errno=ERANGE upon underflow. */
49 # define HAVE_UNDERLYING_STRTOD 0
50 # else
51 # define HAVE_UNDERLYING_STRTOD HAVE_STRTOLD
52 # endif
53 # define DOUBLE long double
54 # define MIN LDBL_MIN
55 # define MAX LDBL_MAX
56 # define L_(literal) literal##L
57 #else
58 # define STRTOD strtod
59 # define LDEXP ldexp
60 # define HAVE_UNDERLYING_STRTOD 1
61 # define DOUBLE double
62 # define MIN DBL_MIN
63 # define MAX DBL_MAX
64 # define L_(literal) literal
65 #endif
66
67 #if (defined USE_LONG_DOUBLE ? HAVE_LDEXPM_IN_LIBC : HAVE_LDEXP_IN_LIBC)
68 # define USE_LDEXP 1
69 #else
70 # define USE_LDEXP 0
71 #endif
72
73 /* Return true if C is a space in the current locale, avoiding
74 problems with signed char and isspace. */
75 static bool
76 locale_isspace (char c)
77 {
78 unsigned char uc = c;
79 return isspace (uc) != 0;
80 }
81
82 /* Determine the decimal-point character according to the current locale. */
83 static char
84 decimal_point_char (void)
85 {
86 const char *point;
87 /* Determine it in a multithread-safe way. We know nl_langinfo is
88 multithread-safe on glibc systems and Mac OS X systems, but is not required
89 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
90 localeconv() is rarely multithread-safe. */
91 #if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
92 point = nl_langinfo (RADIXCHAR);
93 #elif 1
94 char pointbuf[5];
95 sprintf (pointbuf, "%#.0f", 1.0);
96 point = &pointbuf[1];
97 #else
98 point = localeconv () -> decimal_point;
99 #endif
100 /* The decimal point is always a single byte: either '.' or ','. */
101 return (point[0] != '\0' ? point[0] : '.');
102 }
103
104 #if !USE_LDEXP
105 #undef LDEXP
106 #define LDEXP dummy_ldexp
107 /* A dummy definition that will never be invoked. */
108 static DOUBLE LDEXP (_GL_UNUSED DOUBLE x, _GL_UNUSED int exponent)
109 {
110 abort ();
111 return L_(0.0);
112 }
113 #endif
114
115 /* Return X * BASE**EXPONENT. Return an extreme value and set errno
116 to ERANGE if underflow or overflow occurs. */
117 static DOUBLE
118 scale_radix_exp (DOUBLE x, int radix, long int exponent)
119 {
120 /* If RADIX == 10, this code is neither precise nor fast; it is
121 merely a straightforward and relatively portable approximation.
122 If N == 2, this code is precise on a radix-2 implementation,
123 albeit perhaps not fast if ldexp is not in libc. */
124
125 long int e = exponent;
126
127 if (USE_LDEXP && radix == 2)
128 return LDEXP (x, e < INT_MIN ? INT_MIN : INT_MAX < e ? INT_MAX : e);
129 else
130 {
131 DOUBLE r = x;
132
133 if (r != 0)
134 {
135 if (e < 0)
136 {
137 while (e++ != 0)
138 {
139 r /= radix;
140 if (r == 0 && x != 0)
141 {
142 errno = ERANGE;
143 break;
144 }
145 }
146 }
147 else
148 {
149 while (e-- != 0)
150 {
151 if (r < -MAX / radix)
152 {
153 errno = ERANGE;
154 return -HUGE_VAL;
155 }
156 else if (MAX / radix < r)
157 {
158 errno = ERANGE;
159 return HUGE_VAL;
160 }
161 else
162 r *= radix;
163 }
164 }
165 }
166
167 return r;
168 }
169 }
170
171 /* Parse a number at NPTR; this is a bit like strtol (NPTR, ENDPTR)
172 except there are no leading spaces or signs or "0x", and ENDPTR is
173 nonnull. The number uses a base BASE (either 10 or 16) fraction, a
174 radix RADIX (either 10 or 2) exponent, and exponent character
175 EXPCHAR. BASE is RADIX**RADIX_MULTIPLIER. */
176 static DOUBLE
177 parse_number (const char *nptr,
178 int base, int radix, int radix_multiplier, char radixchar,
179 char expchar,
180 char **endptr)
181 {
182 const char *s = nptr;
183 const char *digits_start;
184 const char *digits_end;
185 const char *radixchar_ptr;
186 long int exponent;
187 DOUBLE num;
188
189 /* First, determine the start and end of the digit sequence. */
190 digits_start = s;
191 radixchar_ptr = NULL;
192 for (;; ++s)
193 {
194 if (base == 16 ? c_isxdigit (*s) : c_isdigit (*s))
195 ;
196 else if (radixchar_ptr == NULL && *s == radixchar)
197 {
198 /* Record that we have found the decimal point. */
199 radixchar_ptr = s;
200 }
201 else
202 /* Any other character terminates the digit sequence. */
203 break;
204 }
205 digits_end = s;
206 /* Now radixchar_ptr == NULL or
207 digits_start <= radixchar_ptr < digits_end. */
208
209 if (false)
210 { /* Unoptimized. */
211 exponent =
212 (radixchar_ptr != NULL
213 ? - (long int) (digits_end - radixchar_ptr - 1)
214 : 0);
215 }
216 else
217 { /* Remove trailing zero digits. This reduces rounding errors for
218 inputs such as 1.0000000000 or 10000000000e-10. */
219 while (digits_end > digits_start)
220 {
221 if (digits_end - 1 == radixchar_ptr || *(digits_end - 1) == '0')
222 digits_end--;
223 else
224 break;
225 }
226 exponent =
227 (radixchar_ptr != NULL
228 ? (digits_end > radixchar_ptr
229 ? - (long int) (digits_end - radixchar_ptr - 1)
230 : (long int) (radixchar_ptr - digits_end))
231 : (long int) (s - digits_end));
232 }
233
234 /* Then, convert the digit sequence to a number. */
235 {
236 const char *dp;
237 num = 0;
238 for (dp = digits_start; dp < digits_end; dp++)
239 if (dp != radixchar_ptr)
240 {
241 int digit;
242
243 /* Make sure that multiplication by BASE will not overflow. */
244 if (!(num <= MAX / base))
245 {
246 /* The value of the digit and all subsequent digits don't matter,
247 since we have already gotten as many digits as can be
248 represented in a 'DOUBLE'. This doesn't necessarily mean that
249 the result will overflow: The exponent may reduce it to within
250 range. */
251 exponent +=
252 (digits_end - dp)
253 - (radixchar_ptr >= dp && radixchar_ptr < digits_end ? 1 : 0);
254 break;
255 }
256
257 /* Eat the next digit. */
258 if (c_isdigit (*dp))
259 digit = *dp - '0';
260 else if (base == 16 && c_isxdigit (*dp))
261 digit = c_tolower (*dp) - ('a' - 10);
262 else
263 abort ();
264 num = num * base + digit;
265 }
266 }
267
268 exponent = exponent * radix_multiplier;
269
270 /* Finally, parse the exponent. */
271 if (c_tolower (*s) == expchar && ! locale_isspace (s[1]))
272 {
273 /* Add any given exponent to the implicit one. */
274 int saved_errno = errno;
275 char *end;
276 long int value = strtol (s + 1, &end, 10);
277 errno = saved_errno;
278
279 if (s + 1 != end)
280 {
281 /* Skip past the exponent, and add in the implicit exponent,
282 resulting in an extreme value on overflow. */
283 s = end;
284 exponent =
285 (exponent < 0
286 ? (value < LONG_MIN - exponent ? LONG_MIN : exponent + value)
287 : (LONG_MAX - exponent < value ? LONG_MAX : exponent + value));
288 }
289 }
290
291 *endptr = (char *) s;
292 return scale_radix_exp (num, radix, exponent);
293 }
294
295 /* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
296 ICC 10.0 has a bug when optimizing the expression -zero.
297 The expression -MIN * MIN does not work when cross-compiling
298 to PowerPC on Mac OS X 10.5. */
299 static DOUBLE
300 minus_zero (void)
301 {
302 #if defined __hpux || defined __sgi || defined __ICC
303 return -MIN * MIN;
304 #else
305 return -0.0;
306 #endif
307 }
308
309 /* Convert NPTR to a DOUBLE. If ENDPTR is not NULL, a pointer to the
310 character after the last one used in the number is put in *ENDPTR. */
311 DOUBLE
312 STRTOD (const char *nptr, char **endptr)
313 #if HAVE_UNDERLYING_STRTOD
314 # ifdef USE_LONG_DOUBLE
315 # undef strtold
316 # else
317 # undef strtod
318 # endif
319 #else
320 # undef STRTOD
321 # define STRTOD(NPTR,ENDPTR) \
322 parse_number (NPTR, 10, 10, 1, radixchar, 'e', ENDPTR)
323 #endif
324 /* From here on, STRTOD refers to the underlying implementation. It needs
325 to handle only finite unsigned decimal numbers with non-null ENDPTR. */
326 {
327 char radixchar;
328 bool negative = false;
329
330 /* The number so far. */
331 DOUBLE num;
332
333 const char *s = nptr;
334 const char *end;
335 char *endbuf;
336 int saved_errno = errno;
337
338 radixchar = decimal_point_char ();
339
340 /* Eat whitespace. */
341 while (locale_isspace (*s))
342 ++s;
343
344 /* Get the sign. */
345 negative = *s == '-';
346 if (*s == '-' || *s == '+')
347 ++s;
348
349 num = STRTOD (s, &endbuf);
350 end = endbuf;
351
352 if (c_isdigit (s[*s == radixchar]))
353 {
354 /* If a hex float was converted incorrectly, do it ourselves.
355 If the string starts with "0x" but does not contain digits,
356 consume the "0" ourselves. If a hex float is followed by a
357 'p' but no exponent, then adjust the end pointer. */
358 if (*s == '0' && c_tolower (s[1]) == 'x')
359 {
360 if (! c_isxdigit (s[2 + (s[2] == radixchar)]))
361 {
362 end = s + 1;
363
364 /* strtod() on z/OS returns ERANGE for "0x". */
365 errno = saved_errno;
366 }
367 else if (end <= s + 2)
368 {
369 num = parse_number (s + 2, 16, 2, 4, radixchar, 'p', &endbuf);
370 end = endbuf;
371 }
372 else
373 {
374 const char *p = s + 2;
375 while (p < end && c_tolower (*p) != 'p')
376 p++;
377 if (p < end && ! c_isdigit (p[1 + (p[1] == '-' || p[1] == '+')]))
378 {
379 char *dup = strdup (s);
380 errno = saved_errno;
381 if (!dup)
382 {
383 /* Not really our day, is it. Rounding errors are
384 better than outright failure. */
385 num =
386 parse_number (s + 2, 16, 2, 4, radixchar, 'p', &endbuf);
387 }
388 else
389 {
390 dup[p - s] = '\0';
391 num = STRTOD (dup, &endbuf);
392 saved_errno = errno;
393 free (dup);
394 errno = saved_errno;
395 }
396 end = p;
397 }
398 }
399 }
400 else
401 {
402 /* If "1e 1" was misparsed as 10.0 instead of 1.0, re-do the
403 underlying STRTOD on a copy of the original string
404 truncated to avoid the bug. */
405 const char *e = s + 1;
406 while (e < end && c_tolower (*e) != 'e')
407 e++;
408 if (e < end && ! c_isdigit (e[1 + (e[1] == '-' || e[1] == '+')]))
409 {
410 char *dup = strdup (s);
411 errno = saved_errno;
412 if (!dup)
413 {
414 /* Not really our day, is it. Rounding errors are
415 better than outright failure. */
416 num = parse_number (s, 10, 10, 1, radixchar, 'e', &endbuf);
417 }
418 else
419 {
420 dup[e - s] = '\0';
421 num = STRTOD (dup, &endbuf);
422 saved_errno = errno;
423 free (dup);
424 errno = saved_errno;
425 }
426 end = e;
427 }
428 }
429
430 s = end;
431 }
432
433 /* Check for infinities and NaNs. */
434 else if (c_tolower (*s) == 'i'
435 && c_tolower (s[1]) == 'n'
436 && c_tolower (s[2]) == 'f')
437 {
438 s += 3;
439 if (c_tolower (*s) == 'i'
440 && c_tolower (s[1]) == 'n'
441 && c_tolower (s[2]) == 'i'
442 && c_tolower (s[3]) == 't'
443 && c_tolower (s[4]) == 'y')
444 s += 5;
445 num = HUGE_VAL;
446 errno = saved_errno;
447 }
448 else if (c_tolower (*s) == 'n'
449 && c_tolower (s[1]) == 'a'
450 && c_tolower (s[2]) == 'n')
451 {
452 s += 3;
453 if (*s == '(')
454 {
455 const char *p = s + 1;
456 while (c_isalnum (*p))
457 p++;
458 if (*p == ')')
459 s = p + 1;
460 }
461
462 /* If the underlying implementation misparsed the NaN, assume
463 its result is incorrect, and return a NaN. Normally it's
464 better to use the underlying implementation's result, since a
465 nice implementation populates the bits of the NaN according
466 to interpreting n-char-sequence as a hexadecimal number. */
467 if (s != end || num == num)
468 num = NAN;
469 errno = saved_errno;
470 }
471 else
472 {
473 /* No conversion could be performed. */
474 errno = EINVAL;
475 s = nptr;
476 }
477
478 if (endptr != NULL)
479 *endptr = (char *) s;
480 /* Special case -0.0, since at least ICC miscompiles negation. We
481 can't use copysign(), as that drags in -lm on some platforms. */
482 if (!num && negative)
483 return minus_zero ();
484 return negative ? -num : num;
485 }