diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-10-03 20:44:20 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2005-10-03 20:44:20 +0000 |
commit | a5a11654ea5ea89bfffb295fbb2f17cbb45839b6 (patch) | |
tree | 2078fd7b828ae3b4c030e6722c53bdc81542a511 /stdlib | |
parent | 6543cff055c298ea3ec718b356f6c2115e8797ae (diff) | |
download | glibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.tar glibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.tar.gz glibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.tar.bz2 glibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.zip |
Updated to fedora-glibc-20051003T2040
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/cxa_atexit.c | 61 | ||||
-rw-r--r-- | stdlib/stdlib.h | 2 | ||||
-rw-r--r-- | stdlib/strtod_l.c | 14 |
6 files changed, 97 insertions, 29 deletions
diff --git a/stdlib/Depend b/stdlib/Depend new file mode 100644 index 0000000000..f3e1156a4e --- /dev/null +++ b/stdlib/Depend @@ -0,0 +1 @@ +localedata diff --git a/stdlib/Makefile b/stdlib/Makefile index 509a7b2228..9a9ff8bd45 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 0000000000..a1f037cdc8 --- /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/cxa_atexit.c b/stdlib/cxa_atexit.c index a3d4c5037d..490776105f 100644 --- a/stdlib/cxa_atexit.c +++ b/stdlib/cxa_atexit.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2001, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,8 +16,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <bits/libc-lock.h> +#include <assert.h> #include <stdlib.h> + +#include <bits/libc-lock.h> #include "exit.h" #undef __cxa_atexit @@ -52,45 +54,60 @@ struct exit_function_list *__exit_funcs = &initial; struct exit_function * __new_exitfn (void) { + struct exit_function_list *p = NULL; struct exit_function_list *l; + struct exit_function *r = NULL; size_t i = 0; __libc_lock_lock (lock); - for (l = __exit_funcs; l != NULL; l = l->next) + for (l = __exit_funcs; l != NULL; p = l, l = l->next) { - for (i = 0; i < l->idx; ++i) - if (l->fns[i].flavor == ef_free) + for (i = l->idx; i > 0; --i) + if (l->fns[i - 1].flavor != ef_free) break; - if (i < l->idx) + + if (i > 0) break; - if (l->idx < sizeof (l->fns) / sizeof (l->fns[0])) - { - i = l->idx++; - break; - } + /* This block is completely unused. */ + l->idx = 0; } - if (l == NULL) + if (l == NULL || i == sizeof (l->fns) / sizeof (l->fns[0])) { - l = (struct exit_function_list *) - malloc (sizeof (struct exit_function_list)); - if (l != NULL) + /* The last entry in a block is used. Use the first entry in + the previous block if it exists. Otherwise create a new one. */ + if (p == NULL) { - l->next = __exit_funcs; - __exit_funcs = l; + assert (l != NULL); + p = (struct exit_function_list *) + calloc (1, sizeof (struct exit_function_list)); + if (p != NULL) + { + p->next = __exit_funcs; + __exit_funcs = p; + } + } - l->idx = 1; - i = 0; + if (p != NULL) + { + r = &p->fns[0]; + p->idx = 1; } } + else + { + /* There is more room in the block. */ + r = &l->fns[i]; + l->idx = i + 1; + } /* Mark entry as used, but we don't know the flavor now. */ - if (l != NULL) - l->fns[i].flavor = ef_us; + if (r != NULL) + r->flavor = ef_us; __libc_lock_unlock (lock); - return l == NULL ? NULL : &l->fns[i]; + return r; } diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h index bff7722e2c..085130cafa 100644 --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h @@ -188,7 +188,7 @@ extern long int strtol (__const char *__restrict __nptr, extern unsigned long int strtoul (__const char *__restrict __nptr, char **__restrict __endptr, int __base) __THROW __nonnull ((1)) __wur; -__END_NAMESPACE_C99 +__END_NAMESPACE_STD #if defined __GLIBC_HAVE_LONG_LONG && defined __USE_BSD /* Convert a string to a quadword integer. */ diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index a656789f4c..3a1c1ebd4b 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; |