diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-09-28 06:09:24 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-09-28 06:09:24 +0000 |
commit | 1873e3cd1a7f5173d20d9060f3be825f31a53a39 (patch) | |
tree | d741711c2683919648a9fab68ded25c3a2ba4fc2 /stdlib | |
parent | eb793d1e84fe39243b246e24e0a835ccc6a4b1bb (diff) | |
download | glibc-1873e3cd1a7f5173d20d9060f3be825f31a53a39.zip glibc-1873e3cd1a7f5173d20d9060f3be825f31a53a39.tar.gz glibc-1873e3cd1a7f5173d20d9060f3be825f31a53a39.tar.bz2 |
[BZ #1230]
2005-09-27 Ulrich Drepper <drepper@redhat.com>
[BZ #1230]
* stdlib/strtod_l.c (STRNCASECMP): Always use C locale object.
(TOLOWER_C): Define. Use it when recognizing inf and nan.
* stdlib/Makefile (tests): Add bug-strtod2.
* stdlib/bug-strtod2.c: New file.
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/Depend | 1 | ||||
-rw-r--r-- | stdlib/Makefile | 2 | ||||
-rw-r--r-- | stdlib/bug-strtod2.c | 46 | ||||
-rw-r--r-- | stdlib/strtod_l.c | 14 |
4 files changed, 57 insertions, 6 deletions
diff --git a/stdlib/Depend b/stdlib/Depend new file mode 100644 index 0000000..f3e1156 --- /dev/null +++ b/stdlib/Depend @@ -0,0 +1 @@ +localedata diff --git a/stdlib/Makefile b/stdlib/Makefile index 509a7b2..9a9ff8b 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -63,7 +63,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ test-canon test-canon2 tst-strtoll tst-environ \ tst-xpg-basename tst-random tst-random2 tst-bsearch \ tst-limits tst-rand48 bug-strtod tst-setcontext \ - test-a64l tst-qsort tst-system testmb2 + test-a64l tst-qsort tst-system testmb2 bug-strtod2 include ../Makeconfig diff --git a/stdlib/bug-strtod2.c b/stdlib/bug-strtod2.c new file mode 100644 index 0000000..a1f037c --- /dev/null +++ b/stdlib/bug-strtod2.c @@ -0,0 +1,46 @@ +#include <locale.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +static const char *tests[] = + { + "inf", "Inf", "iNf", "inF", "INf", "iNF", "INF", "InF", + "infinity", "Infinity", "InfInity", "INFINITY" + }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + +static int +do_test (void) +{ + /* The Turkish locale is notorious because tolower() maps 'I' to the + dotless lowercase 'i' and toupper() maps 'i' to an 'I' with a dot + above. */ + if (setlocale (LC_ALL, "tr_TR.UTF-8") == NULL) + { + puts ("cannot set locale"); + return 0; + } + + int res = 0; + for (int i = 0; i < ntests; ++i) + { + char *endp; + double d = strtod (tests[i], &endp); + if (*endp != '\0') + { + printf ("did not consume all of '%s'\n", tests[i]); + res = 1; + } + if (!isinf (d)) + { + printf ("'%s' does not pass isinf\n", tests[i]); + res = 1; + } + } + + return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index a656789..3a1c1eb 100644 --- a/stdlib/strtod_l.c +++ b/stdlib/strtod_l.c @@ -1,5 +1,5 @@ /* Convert string representing a number to float value, using given locale. - Copyright (C) 1997,98,2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1997,98,2002,2004,2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -100,7 +100,9 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **, # define ISDIGIT(Ch) __iswdigit_l ((Ch), loc) # define ISXDIGIT(Ch) __iswxdigit_l ((Ch), loc) # define TOLOWER(Ch) __towlower_l ((Ch), loc) -# define STRNCASECMP(S1, S2, N) __wcsncasecmp_l ((S1), (S2), (N), loc) +# define TOLOWER_C(Ch) __towlower_l ((Ch), &_nl_C_locobj) +# define STRNCASECMP(S1, S2, N) \ + __wcsncasecmp_l ((S1), (S2), (N), &_nl_C_locobj) # define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc) #else # define STRING_TYPE char @@ -110,7 +112,9 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **, # define ISDIGIT(Ch) __isdigit_l ((Ch), loc) # define ISXDIGIT(Ch) __isxdigit_l ((Ch), loc) # define TOLOWER(Ch) __tolower_l ((Ch), loc) -# define STRNCASECMP(S1, S2, N) __strncasecmp_l ((S1), (S2), (N), loc) +# define TOLOWER_C(Ch) __tolower_l ((Ch), &_nl_C_locobj) +# define STRNCASECMP(S1, S2, N) \ + __strncasecmp_l ((S1), (S2), (N), &_nl_C_locobj) # define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc) #endif @@ -554,7 +558,7 @@ INTERNAL (__STRTOF) (nptr, endptr, group, loc) else if (c < L_('0') || c > L_('9')) { /* Check for `INF' or `INFINITY'. */ - if (TOLOWER (c) == L_('i') && STRNCASECMP (cp, L_("inf"), 3) == 0) + if (TOLOWER_C (c) == L_('i') && STRNCASECMP (cp, L_("inf"), 3) == 0) { /* Return +/- infinity. */ if (endptr != NULL) @@ -565,7 +569,7 @@ INTERNAL (__STRTOF) (nptr, endptr, group, loc) return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL; } - if (TOLOWER (c) == L_('n') && STRNCASECMP (cp, L_("nan"), 3) == 0) + if (TOLOWER_C (c) == L_('n') && STRNCASECMP (cp, L_("nan"), 3) == 0) { /* Return NaN. */ FLOAT retval = NAN; |