This source file includes following definitions.
- c_locale
- C_STRTOD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include "c-strtod.h"
23
24 #include <errno.h>
25 #include <locale.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #if LONG
30 # define C_STRTOD c_strtold
31 # define DOUBLE long double
32 # define STRTOD_L strtold_l
33 # define HAVE_GOOD_STRTOD_L (HAVE_STRTOLD_L && !GNULIB_defined_strtold_function)
34 # define STRTOD strtold
35 #else
36 # define C_STRTOD c_strtod
37 # define DOUBLE double
38 # define STRTOD_L strtod_l
39 # define HAVE_GOOD_STRTOD_L (HAVE_STRTOD_L && !GNULIB_defined_strtod_function)
40 # define STRTOD strtod
41 #endif
42
43 #if defined LC_ALL_MASK \
44 && ((LONG ? HAVE_GOOD_STRTOLD_L : HAVE_GOOD_STRTOD_L) \
45 || HAVE_WORKING_USELOCALE)
46
47
48
49
50 static volatile locale_t c_locale_cache;
51
52
53
54 static locale_t
55 c_locale (void)
56 {
57 if (!c_locale_cache)
58 c_locale_cache = newlocale (LC_ALL_MASK, "C", (locale_t) 0);
59 return c_locale_cache;
60 }
61
62 #endif
63
64 DOUBLE
65 C_STRTOD (char const *nptr, char **endptr)
66 {
67 DOUBLE r;
68
69 #if defined LC_ALL_MASK \
70 && ((LONG ? HAVE_GOOD_STRTOLD_L : HAVE_GOOD_STRTOD_L) \
71 || HAVE_WORKING_USELOCALE)
72
73 locale_t locale = c_locale ();
74 if (!locale)
75 {
76 if (endptr)
77 *endptr = (char *) nptr;
78 return 0;
79 }
80
81 # if (LONG ? HAVE_GOOD_STRTOLD_L : HAVE_GOOD_STRTOD_L)
82
83 r = STRTOD_L (nptr, endptr, locale);
84
85 # else
86
87 locale_t old_locale = uselocale (locale);
88 if (old_locale == (locale_t)0)
89 {
90 if (endptr)
91 *endptr = (char *) nptr;
92 return 0;
93 }
94
95 r = STRTOD (nptr, endptr);
96
97 int saved_errno = errno;
98 if (uselocale (old_locale) == (locale_t)0)
99
100 abort ();
101 errno = saved_errno;
102
103 # endif
104
105 #else
106
107 char *saved_locale = setlocale (LC_NUMERIC, NULL);
108
109 if (saved_locale)
110 {
111 saved_locale = strdup (saved_locale);
112 if (saved_locale == NULL)
113 {
114 if (endptr)
115 *endptr = (char *) nptr;
116 return 0;
117 }
118 setlocale (LC_NUMERIC, "C");
119 }
120
121 r = STRTOD (nptr, endptr);
122
123 if (saved_locale)
124 {
125 int saved_errno = errno;
126
127 setlocale (LC_NUMERIC, saved_locale);
128 free (saved_locale);
129 errno = saved_errno;
130 }
131
132 #endif
133
134 return r;
135 }