printf,seq,sleep,tail,timeout: accept current-locale floats
[coreutils.git] / gl / lib / cl-strtod.c
blobfa77235ba8c0568c55730be7f5acd387aca72df7
1 /* Convert string to double in the current locale, falling back on the C locale.
3 Copyright 2019 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 /* Written by Paul Eggert. */
20 #include <config.h>
22 #include "cl-strtod.h"
24 #include <c-strtod.h>
26 #include <errno.h>
27 #include <stdlib.h>
29 #if LONG
30 # define CL_STRTOD cl_strtold
31 # define DOUBLE long double
32 # define C_STRTOD c_strtold
33 #else
34 # define CL_STRTOD cl_strtod
35 # define DOUBLE double
36 # define C_STRTOD c_strtod
37 #endif
39 /* This function acts like strtod or strtold, except that it falls
40 back on the C locale if the initial prefix is not parsable in
41 the current locale. If the prefix is parsable in both locales,
42 it uses the longer parse, breaking ties in favor of the current locale.
44 Parse the initial prefix of NPTR as a floating-point number in the
45 current locale or in the C locale (preferring the locale that
46 yields the longer parse, or the current locale if there is a tie).
47 If ENDPTR is not NULL, set *ENDPTR to the first unused byte, or to
48 NPTR if the prefix cannot be parsed.
50 If successful, return a number without changing errno.
51 If the prefix cannot be parsed, return 0 and possibly set errno to EINVAL.
52 If the number overflows, return an extreme value and set errno to ERANGE.
53 If the number underflows, return a value close to 0 and set errno to ERANGE.
54 If there is some other error, return 0 and set errno. */
56 DOUBLE
57 CL_STRTOD (char const *nptr, char **restrict endptr)
59 char *end;
60 DOUBLE d = strtod (nptr, &end);
61 if (*end)
63 int strtod_errno = errno;
64 char *c_end;
65 DOUBLE c = C_STRTOD (nptr, &c_end);
66 if (end < c_end)
67 d = c, end = c_end;
68 else
69 errno = strtod_errno;
71 if (endptr)
72 *endptr = end;
73 return d;