diff options
author | Holger Weiss <holger@zedat.fu-berlin.de> | 2009-05-20 00:32:10 +0200 |
---|---|---|
committer | Holger Weiss <holger@zedat.fu-berlin.de> | 2009-05-20 00:32:10 +0200 |
commit | 50b3ff7b91e78a61aca93247bee586d6d7eb27c8 (patch) | |
tree | db4c7eee24479ac7ee6888ce1562facf60159b71 /gl/c-strtod.c | |
parent | 2701ccd500e60537a8c2977a81549ff33eeaef3f (diff) | |
download | monitoring-plugins-50b3ff7b91e78a61aca93247bee586d6d7eb27c8.tar.gz |
Sync with the latest Gnulib code (cb75dc5)
Signed-off-by: Holger Weiss <holger@zedat.fu-berlin.de>
Diffstat (limited to 'gl/c-strtod.c')
-rw-r--r-- | gl/c-strtod.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/gl/c-strtod.c b/gl/c-strtod.c index 95624ccc..51e996e5 100644 --- a/gl/c-strtod.c +++ b/gl/c-strtod.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* Convert string to double, using the C locale. | 1 | /* Convert string to double, using the C locale. |
2 | 2 | ||
3 | Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. | 3 | Copyright (C) 2003, 2004, 2006, 2009 Free Software Foundation, Inc. |
4 | 4 | ||
5 | This program is free software: you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published by |
@@ -21,10 +21,10 @@ | |||
21 | 21 | ||
22 | #include "c-strtod.h" | 22 | #include "c-strtod.h" |
23 | 23 | ||
24 | #include <errno.h> | ||
24 | #include <locale.h> | 25 | #include <locale.h> |
25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
26 | 27 | #include <string.h> | |
27 | #include "xalloc.h" | ||
28 | 28 | ||
29 | #if LONG | 29 | #if LONG |
30 | # define C_STRTOD c_strtold | 30 | # define C_STRTOD c_strtold |
@@ -43,6 +43,25 @@ | |||
43 | # define STRTOD strtod | 43 | # define STRTOD strtod |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #ifdef LC_ALL_MASK | ||
47 | |||
48 | /* Cache for the C locale object. | ||
49 | Marked volatile so that different threads see the same value | ||
50 | (avoids locking). */ | ||
51 | static volatile locale_t c_locale_cache; | ||
52 | |||
53 | /* Return the C locale object, or (locale_t) 0 with errno set | ||
54 | if it cannot be created. */ | ||
55 | static inline locale_t | ||
56 | c_locale (void) | ||
57 | { | ||
58 | if (!c_locale_cache) | ||
59 | c_locale_cache = newlocale (LC_ALL_MASK, "C", (locale_t) 0); | ||
60 | return c_locale_cache; | ||
61 | } | ||
62 | |||
63 | #endif | ||
64 | |||
46 | DOUBLE | 65 | DOUBLE |
47 | C_STRTOD (char const *nptr, char **endptr) | 66 | C_STRTOD (char const *nptr, char **endptr) |
48 | { | 67 | { |
@@ -50,9 +69,15 @@ C_STRTOD (char const *nptr, char **endptr) | |||
50 | 69 | ||
51 | #ifdef LC_ALL_MASK | 70 | #ifdef LC_ALL_MASK |
52 | 71 | ||
53 | locale_t c_locale = newlocale (LC_ALL_MASK, "C", 0); | 72 | locale_t locale = c_locale (); |
54 | r = STRTOD_L (nptr, endptr, c_locale); | 73 | if (!locale) |
55 | freelocale (c_locale); | 74 | { |
75 | if (endptr) | ||
76 | *endptr = (char *) nptr; | ||
77 | return 0; /* errno is set here */ | ||
78 | } | ||
79 | |||
80 | r = STRTOD_L (nptr, endptr, locale); | ||
56 | 81 | ||
57 | #else | 82 | #else |
58 | 83 | ||
@@ -60,7 +85,13 @@ C_STRTOD (char const *nptr, char **endptr) | |||
60 | 85 | ||
61 | if (saved_locale) | 86 | if (saved_locale) |
62 | { | 87 | { |
63 | saved_locale = xstrdup (saved_locale); | 88 | saved_locale = strdup (saved_locale); |
89 | if (saved_locale == NULL) | ||
90 | { | ||
91 | if (endptr) | ||
92 | *endptr = (char *) nptr; | ||
93 | return 0; /* errno is set here */ | ||
94 | } | ||
64 | setlocale (LC_NUMERIC, "C"); | 95 | setlocale (LC_NUMERIC, "C"); |
65 | } | 96 | } |
66 | 97 | ||
@@ -68,8 +99,11 @@ C_STRTOD (char const *nptr, char **endptr) | |||
68 | 99 | ||
69 | if (saved_locale) | 100 | if (saved_locale) |
70 | { | 101 | { |
102 | int saved_errno = errno; | ||
103 | |||
71 | setlocale (LC_NUMERIC, saved_locale); | 104 | setlocale (LC_NUMERIC, saved_locale); |
72 | free (saved_locale); | 105 | free (saved_locale); |
106 | errno = saved_errno; | ||
73 | } | 107 | } |
74 | 108 | ||
75 | #endif | 109 | #endif |