From b0ec19ce6e64c405fdd95c90a5d4212f86abea1f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 10 Dec 2006 10:38:56 +0000 Subject: Updated to fedora-glibc-20061210T1006 --- ChangeLog | 45 ++++++++++++++++++ fedora/branch.mk | 4 +- fedora/glibc.spec.in | 10 +++- include/features.h | 2 +- malloc/memusage.c | 38 ++++++++++++--- malloc/memusagestat.c | 4 +- misc/Makefile | 2 +- misc/getusershell.c | 12 +++-- misc/mntent_r.c | 12 ++--- misc/tst-mntent2.c | 41 ++++++++++++++++ nptl/ChangeLog | 14 ++++++ nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h | 2 +- .../unix/sysv/linux/s390/s390-32/sysdep-cancel.h | 21 ++++++++- .../unix/sysv/linux/s390/s390-64/sysdep-cancel.h | 21 ++++++++- stdlib/Makefile | 3 +- stdlib/strtod_l.c | 36 +++++++------- stdlib/tst-atof1.c | 19 ++++++++ stdlib/tst-atof2.c | 55 ++++++++++++++++++++++ 18 files changed, 294 insertions(+), 47 deletions(-) create mode 100644 misc/tst-mntent2.c create mode 100644 stdlib/tst-atof1.c create mode 100644 stdlib/tst-atof2.c diff --git a/ChangeLog b/ChangeLog index 80fa9c5050..0e8507a668 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2006-12-09 Ulrich Drepper + + [BZ #3632] + * include/features.h: Fix comment about default value for + _POSIX_C_SOURCE. + + [BZ #3664] + * stdlib/strtod_l.c (____STRTOF_INTERNAL): Fix test to recognize + empty parsed strings. + * stdlib/Makefile (tests): Add tst-strtod2. + * stdlib/tst-strtod2.c: New file. + + [BZ #3673] + * stdlib/strtod_l.c (____STRTOF_INTERNAL): Fix exp_limit + computation. + * stdlib/Makefile (tests): Add tst-atof2. + * stdlib/tst-atof2.c: New file. + + [BZ #3674] + * stdlib/strtod_l.c (____STRTOF_INTERNAL): Adjust exponent value + correctly if removing trailing zero of hex-float. + * stdlib/Makefile (tests): Add tst-atof1. + * stdlib/tst-atof1.c: New file. + +2006-12-09 Jakub Jelinek + + * misc/mntent_r.c (__hasmntopt): Check p[optlen] even when p == rest. + Start searching for next comma at p rather than rest. + * misc/Makefile (tests): Add tst-mntent2. + * misc/tst-mntent2.c: New test. + + * misc/getusershell.c (initshells): Check for integer overflows. + Make strings buffer one bigger as fgets always succeeds when second + argument is 1. Don't use calloc for shells array. Disallow + / as shell. + +2006-12-08 Ulrich Drepper + + * malloc/memusage.c: Handle realloc with new size of zero and + non-NULL pointer correctly. + (me): Really write first record twice. + (struct entry): Make format bi-arch safe. + (dest): Write out more realloc statistics. + * malloc/memusagestat.c (struct entry): Make format bi-arch safe. + 2006-12-05 Jakub Jelinek * nis/nis_subr.c (nis_getnames): Revert last change. diff --git a/fedora/branch.mk b/fedora/branch.mk index b61ceaaa5f..41c73b2907 100644 --- a/fedora/branch.mk +++ b/fedora/branch.mk @@ -3,5 +3,5 @@ glibc-branch := fedora glibc-base := HEAD DIST_BRANCH := devel COLLECTION := dist-fc7 -fedora-sync-date := 2006-12-05 21:41 UTC -fedora-sync-tag := fedora-glibc-20061205T2141 +fedora-sync-date := 2006-12-10 10:06 UTC +fedora-sync-tag := fedora-glibc-20061210T1006 diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in index d1b7f560af..7d39fbcdf3 100644 --- a/fedora/glibc.spec.in +++ b/fedora/glibc.spec.in @@ -1,4 +1,4 @@ -%define glibcrelease 11 +%define glibcrelease 12 %define auxarches i586 i686 athlon sparcv9 alphaev6 %define xenarches i686 athlon %ifarch %{xenarches} @@ -1544,8 +1544,14 @@ rm -f *.filelist* %endif %changelog +* Sun Dec 10 2006 Jakub Jelinek 2.5.90-12 +- fix hasmntopt (#218802) +- fix setusershell and getusershell (#218782) +- strtod fixes (BZ#3664, BZ#3673, BZ#3674) +- fix memusage with realloc (x, 0) + * Tue Dec 5 2006 Jakub Jelinek 2.5.90-11 -- allow suid apps to setenv NIS_PATH and incluence through that +- allow suid apps to setenv NIS_PATH and influence through that nis_list and nis_lookup (#209155) - fix ttyname and ttyname_r with invalid file descriptor (#218276) - cs_CZ LC_TIME fixes (#218438) diff --git a/include/features.h b/include/features.h index aeeb3a578a..4eb49a92b1 100644 --- a/include/features.h +++ b/include/features.h @@ -49,7 +49,7 @@ The `-ansi' switch to the GNU C compiler defines __STRICT_ANSI__. If none of these are defined, the default is to have _SVID_SOURCE, _BSD_SOURCE, and _POSIX_SOURCE set to one and _POSIX_C_SOURCE set to - 199506L. If more than one of these are defined, they accumulate. + 200112L. If more than one of these are defined, they accumulate. For example __STRICT_ANSI__, _POSIX_SOURCE and _POSIX_C_SOURCE together give you ISO C, 1003.1, and 1003.2, but nothing else. diff --git a/malloc/memusage.c b/malloc/memusage.c index bf2978ef02..d11e9e6ed5 100644 --- a/malloc/memusage.c +++ b/malloc/memusage.c @@ -80,6 +80,7 @@ static memusage_cntr_t large; static memusage_cntr_t calls_total; static memusage_cntr_t inplace; static memusage_cntr_t decreasing; +static memusage_cntr_t realloc_free; static memusage_cntr_t inplace_mremap; static memusage_cntr_t decreasing_mremap; static memusage_size_t current_heap; @@ -103,8 +104,8 @@ extern const char *__progname; struct entry { - size_t heap; - size_t stack; + uint64_t heap; + uint64_t stack; uint32_t time_low; uint32_t time_high; }; @@ -267,6 +268,7 @@ me (void) GETTIME (first.time_low, first.time_high); /* Write it two times since we need the starting and end time. */ write (fd, &first, sizeof (first)); + write (fd, &first, sizeof (first)); /* Determine the buffer size. We use the default if the environment variable is not present. */ @@ -411,6 +413,23 @@ realloc (void *old, size_t len) /* Keep track of total memory requirement. */ catomic_add (&grand_total, len - old_len); } + + if (len == 0 && old != NULL) + { + /* Special case. */ + catomic_increment (&realloc_free); + /* Keep track of total memory freed using `free'. */ + catomic_add (&total[idx_free], real->length); + + /* Update the allocation data and write out the records if necessary. */ + update_data (NULL, 0, old_len); + + /* Do the real work. */ + (*freep) (real); + + return NULL; + } + /* Remember the size of the request. */ if (len < 65536) catomic_increment (&histogram[len / 16]); @@ -770,7 +789,12 @@ dest (void) if (fd != -1) { /* Write the partially filled buffer. */ - write (fd, buffer, buffer_cnt * sizeof (struct entry)); + if (buffer_cnt > buffer_size) + write (fd, buffer + buffer_size, + (buffer_cnt - buffer_size) * sizeof (struct entry)); + else + write (fd, buffer, buffer_cnt * sizeof (struct entry)); + /* Go back to the beginning of the file. We allocated two records here when we opened the file. */ lseek (fd, 0, SEEK_SET); @@ -794,7 +818,7 @@ dest (void) \e[01;32mMemory usage summary:\e[0;0m heap total: %llu, heap peak: %lu, stack peak: %lu\n\ \e[04;34m total calls total memory failed calls\e[0m\n\ \e[00;34m malloc|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\ -\e[00;34mrealloc|\e[0m %10lu %12llu %s%12lu\e[00;00m (in place: %ld, dec: %ld)\n\ +\e[00;34mrealloc|\e[0m %10lu %12llu %s%12lu\e[00;00m (nomove:%ld, dec:%ld, free:%ld)\n\ \e[00;34m calloc|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\ \e[00;34m free|\e[0m %10lu %12llu\n", (unsigned long long int) grand_total, (unsigned long int) peak_heap, @@ -807,7 +831,9 @@ dest (void) (unsigned long long int) total[idx_realloc], failed[idx_realloc] ? "\e[01;41m" : "", (unsigned long int) failed[idx_realloc], - (unsigned long int) inplace, (unsigned long int) decreasing, + (unsigned long int) inplace, + (unsigned long int) decreasing, + (unsigned long int) realloc_free, (unsigned long int) calls[idx_calloc], (unsigned long long int) total[idx_calloc], failed[idx_calloc] ? "\e[01;41m" : "", @@ -820,7 +846,7 @@ dest (void) \e[00;34mmmap(r)|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\ \e[00;34mmmap(w)|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\ \e[00;34mmmap(a)|\e[0m %10lu %12llu %s%12lu\e[00;00m\n\ -\e[00;34m mremap|\e[0m %10lu %12llu %s%12lu\e[00;00m (in place: %ld, dec: %ld)\n\ +\e[00;34m mremap|\e[0m %10lu %12llu %s%12lu\e[00;00m (nomove: %ld, dec:%ld)\n\ \e[00;34m munmap|\e[0m %10lu %12llu %s%12lu\e[00;00m\n", (unsigned long int) calls[idx_mmap_r], (unsigned long long int) total[idx_mmap_r], diff --git a/malloc/memusagestat.c b/malloc/memusagestat.c index d8fc71b729..93ac2cd744 100644 --- a/malloc/memusagestat.c +++ b/malloc/memusagestat.c @@ -81,8 +81,8 @@ static struct argp argp = struct entry { - size_t heap; - size_t stack; + uint64_t heap; + uint64_t stack; uint32_t time_low; uint32_t time_high; }; diff --git a/misc/Makefile b/misc/Makefile index f9ad0b76fc..9eac1b6275 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -78,7 +78,7 @@ endif gpl2lgpl := error.c error.h tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ - tst-error1 tst-pselect tst-insremque + tst-error1 tst-pselect tst-insremque tst-mntent2 ifeq (no,$(cross-compiling)) tests: $(objpfx)tst-error1-mem endif diff --git a/misc/getusershell.c b/misc/getusershell.c index 255b579b1a..636da322f9 100644 --- a/misc/getusershell.c +++ b/misc/getusershell.c @@ -98,7 +98,7 @@ initshells() register char **sp, *cp; register FILE *fp; struct stat64 statb; - int flen; + size_t flen; free(shells); shells = NULL; @@ -114,9 +114,11 @@ initshells() okshells[1] = _PATH_CSHELL; return (char **) okshells; } - if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) + if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3) goto init_okshells; - shells = calloc((unsigned)statb.st_size / 3, sizeof (char *)); + if ((strings = malloc(statb.st_size + 2)) == NULL) + goto init_okshells; + shells = malloc(statb.st_size / 3 * sizeof (char *)); if (shells == NULL) { free(strings); strings = NULL; @@ -124,11 +126,11 @@ initshells() } sp = shells; cp = strings; - flen = statb.st_size; + flen = statb.st_size + 2; while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) { while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; - if (*cp == '#' || *cp == '\0') + if (*cp == '#' || *cp == '\0' || cp[1] == '\0') continue; *sp++ = cp; while (!isspace(*cp) && *cp != '#' && *cp != '\0') diff --git a/misc/mntent_r.c b/misc/mntent_r.c index 1476c86ee2..829750b395 100644 --- a/misc/mntent_r.c +++ b/misc/mntent_r.c @@ -1,5 +1,6 @@ /* Utilities for reading/writing fstab, mtab, etc. - Copyright (C) 1995-2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1995-2000, 2001, 2002, 2003, 2006 + 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 @@ -278,14 +279,11 @@ __hasmntopt (const struct mntent *mnt, const char *opt) while ((p = strstr (rest, opt)) != NULL) { - if (p == rest - || (p[-1] == ',' - && (p[optlen] == '\0' || - p[optlen] == '=' || - p[optlen] == ','))) + if ((p == rest || p[-1] == ',') + && (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ',')) return p; - rest = strchr (rest, ','); + rest = strchr (p, ','); if (rest == NULL) break; ++rest; diff --git a/misc/tst-mntent2.c b/misc/tst-mntent2.c new file mode 100644 index 0000000000..6c25e0127c --- /dev/null +++ b/misc/tst-mntent2.c @@ -0,0 +1,41 @@ +#include +#include +#include + + +int +main (void) +{ + int result = 0; + struct mntent mef; + + mef.mnt_fsname = strdupa ("/dev/sdf6"); + mef.mnt_dir = strdupa ("/some dir"); + mef.mnt_type = strdupa ("ext3"); + mef.mnt_opts = strdupa ("opt1,opt2,noopt=6,rw,norw,brw"); + mef.mnt_freq = 1; + mef.mnt_passno = 2; + +#define TEST(opt, found) \ + if (!!hasmntopt (&mef, (opt)) != (found)) \ + { \ + printf ("Option %s was %sfound\n", (opt), (found) ? "not " : ""); \ + result = 1; \ + } + + TEST ("opt1", 1) + TEST ("opt2", 1) + TEST ("noopt", 1) + TEST ("rw", 1) + TEST ("norw", 1) + TEST ("brw", 1) + TEST ("opt", 0) + TEST ("oopt", 0) + TEST ("w", 0) + TEST ("r", 0) + TEST ("br", 0) + TEST ("nor", 0) + TEST ("or", 0) + + return result; +} diff --git a/nptl/ChangeLog b/nptl/ChangeLog index ac3ddfff9b..a237c5e080 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,17 @@ +2006-12-06 Jakub Jelinek + + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Handle + 6 argument cancellable syscalls. + (STM_6, LM_6, LR7_0, LR7_1, LR7_2, LR7_3, LR7_4, LR7_5, LR7_6): Define. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Handle + 6 argument cancellable syscalls. + (STM_6, LM_6, LR7_0, LR7_1, LR7_2, LR7_3, LR7_4, LR7_5, LR7_6): Define. + +2006-12-09 Ulrich Drepper + + * sysdeps/unix/sysv/linux/rtld-lowlevel.h + (__rtld_mrlock_initialize): Add missing closing parenthesis. + 2006-10-30 Jakub Jelinek * sysdeps/ia64/pthread_spin_unlock.c (pthread_spin_unlock): Use diff --git a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h index bc7a6454ea..6b3d3682da 100644 --- a/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h +++ b/nptl/sysdeps/unix/sysv/linux/rtld-lowlevel.h @@ -43,7 +43,7 @@ typedef int __rtld_mrlock_t; #define _RTLD_MRLOCK_INITIALIZER 0 #define __rtld_mrlock_initialize(NAME) \ - (void) ((NAME) = 0 + (void) ((NAME) = 0) #define __rtld_mrlock_lock(lock) \ diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h index 17ab562daa..6b0240243a 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h @@ -45,7 +45,13 @@ L(pseudo_cancel): \ bas %r14,0(%r1,%r13); \ lr %r0,%r2; \ LM_##args \ - DO_CALL(syscall_name, args); \ + .if SYS_ify (syscall_name) < 256; \ + svc SYS_ify (syscall_name); \ + .else; \ + lhi %r1,SYS_ify (syscall_name); \ + svc 0; \ + .endif; \ + LR7_##args \ l %r1,2f-0b(%r13); \ lr %r12,%r2; \ lr %r2,%r0; \ @@ -89,6 +95,7 @@ L(pseudo_end): #define STM_3 stm %r2,%r4,8(%r15); #define STM_4 stm %r2,%r5,8(%r15); #define STM_5 stm %r2,%r5,8(%r15); +#define STM_6 stm %r2,%r7,8(%r15); #define LM_0 /* Nothing */ #define LM_1 l %r2,8+96(%r15); @@ -96,6 +103,18 @@ L(pseudo_end): #define LM_3 lm %r2,%r4,8+96(%r15); #define LM_4 lm %r2,%r5,8+96(%r15); #define LM_5 lm %r2,%r5,8+96(%r15); +#define LM_6 lm %r2,%r5,8+96(%r15); \ + cfi_offset (%r7, -68); \ + l %r7,96+96(%r15); + +#define LR7_0 /* Nothing */ +#define LR7_1 /* Nothing */ +#define LR7_2 /* Nothing */ +#define LR7_3 /* Nothing */ +#define LR7_4 /* Nothing */ +#define LR7_5 /* Nothing */ +#define LR7_6 l %r7,28+96(%r15); \ + cfi_restore (%r7); # ifndef __ASSEMBLER__ # define SINGLE_THREAD_P \ diff --git a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h index 77ce742495..70d5a86429 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +++ b/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h @@ -42,7 +42,13 @@ L(pseudo_cancel): \ brasl %r14,CENABLE; \ lgr %r0,%r2; \ LM_##args \ - DO_CALL(syscall_name, args); \ + .if SYS_ify (syscall_name) < 256; \ + svc SYS_ify (syscall_name); \ + .else; \ + lghi %r1,SYS_ify (syscall_name); \ + svc 0; \ + .endif; \ + LR7_##args \ lgr %r13,%r2; \ lgr %r2,%r0; \ brasl %r14,CDISABLE; \ @@ -85,6 +91,7 @@ L(pseudo_end): #define STM_3 stmg %r2,%r4,16(%r15); #define STM_4 stmg %r2,%r5,16(%r15); #define STM_5 stmg %r2,%r5,16(%r15); +#define STM_6 stmg %r2,%r7,16(%r15); #define LM_0 /* Nothing */ #define LM_1 lg %r2,16+160(%r15); @@ -92,6 +99,18 @@ L(pseudo_end): #define LM_3 lmg %r2,%r4,16+160(%r15); #define LM_4 lmg %r2,%r5,16+160(%r15); #define LM_5 lmg %r2,%r5,16+160(%r15); +#define LM_6 lmg %r2,%r5,16+160(%r15); \ + cfi_offset (%r7, -104); \ + lg %r7,160+160(%r15); + +#define LR7_0 /* Nothing */ +#define LR7_1 /* Nothing */ +#define LR7_2 /* Nothing */ +#define LR7_3 /* Nothing */ +#define LR7_4 /* Nothing */ +#define LR7_5 /* Nothing */ +#define LR7_6 lg %r7,56+160(%r15); \ + cfi_restore (%r7); # if defined IS_IN_libpthread || !defined NOT_IN_libc # ifndef __ASSEMBLER__ diff --git a/stdlib/Makefile b/stdlib/Makefile index a0ff427b7e..37400ec547 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -66,7 +66,8 @@ 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 bug-strtod2 + test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ + tst-atof1 tst-atof2 tst-strtod2 include ../Makeconfig diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index e13f1086da..b926aeba56 100644 --- a/stdlib/strtod_l.c +++ b/stdlib/strtod_l.c @@ -662,20 +662,20 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) /* If no other digit but a '0' is found the result is 0.0. Return current read pointer. */ - if ((c < L_('0') || c > L_('9')) - && (base == 16 && (c < (CHAR_TYPE) TOLOWER (L_('a')) - || c > (CHAR_TYPE) TOLOWER (L_('f')))) + if (!((c >= L_('0') && c <= L_('9')) + || (base == 16 && ((CHAR_TYPE) TOLOWER (c) >= L_('a') + && (CHAR_TYPE) TOLOWER (c) <= L_('f'))) #ifdef USE_WIDE_CHAR - && c != (wint_t) decimal + || c == (wint_t) decimal #else - && ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) + || ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) if (decimal[cnt] != cp[cnt]) break; - decimal[cnt] != '\0'; }) + decimal[cnt] == '\0'; }) #endif - && (base == 16 && (cp == start_of_digits - || (CHAR_TYPE) TOLOWER (c) != L_('p'))) - && (base != 16 && (CHAR_TYPE) TOLOWER (c) != L_('e'))) + || (base == 16 && (cp != start_of_digits + && (CHAR_TYPE) TOLOWER (c) == L_('p'))) + || (base != 16 && (CHAR_TYPE) TOLOWER (c) == L_('e')))) { #ifdef USE_WIDE_CHAR tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands, @@ -759,13 +759,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) } } - /* We have the number digits in the integer part. Whether these are all or - any is really a fractional digit will be decided later. */ + /* We have the number of digits in the integer part. Whether these + are all or any is really a fractional digit will be decided + later. */ int_no = dig_no; lead_zero = int_no == 0 ? -1 : 0; - /* Read the fractional digits. A special case are the 'american style' - numbers like `16.' i.e. with decimal but without trailing digits. */ + /* Read the fractional digits. A special case are the 'american + style' numbers like `16.' i.e. with decimal point but without + trailing digits. */ if ( #ifdef USE_WIDE_CHAR c == (wint_t) decimal @@ -815,15 +817,16 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) if (base == 16) exp_limit = (exp_negative ? -MIN_EXP + MANT_DIG + 4 * int_no : - MAX_EXP - 4 * int_no + lead_zero); + MAX_EXP - 4 * int_no + 4 * lead_zero + 3); else exp_limit = (exp_negative ? -MIN_10_EXP + MANT_DIG + int_no : - MAX_10_EXP - int_no + lead_zero); + MAX_10_EXP - int_no + lead_zero + 1); do { exponent *= 10; + exponent += c - L_('0'); if (exponent > exp_limit) /* The exponent is too large/small to represent a valid @@ -853,7 +856,6 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) /* NOTREACHED */ } - exponent += c - L_('0'); c = *++cp; } while (c >= L_('0') && c <= L_('9')); @@ -888,7 +890,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) --expp; --dig_no; --int_no; - ++exponent; + exponent += base == 16 ? 4 : 1; } while (dig_no > 0 && exponent < 0); diff --git a/stdlib/tst-atof1.c b/stdlib/tst-atof1.c new file mode 100644 index 0000000000..879d866558 --- /dev/null +++ b/stdlib/tst-atof1.c @@ -0,0 +1,19 @@ +#include +#include +#include + +static int +do_test (void) +{ + char buf[100]; + snprintf (buf, sizeof (buf), "%g", atof ("0x10p-1")); + if (strcmp (buf, "8") != 0) + { + printf ("got \"%s\", expected \"8\"\n", buf); + return 1; + } + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/stdlib/tst-atof2.c b/stdlib/tst-atof2.c new file mode 100644 index 0000000000..74dac87b0d --- /dev/null +++ b/stdlib/tst-atof2.c @@ -0,0 +1,55 @@ +#include +#include +#include + + +static const struct +{ + const char *str; + const char *expected; +} tests[] = + { + { "1e308", "1e+308" }, + { "100000000e300", "1e+308" }, + { "0x1p1023", "8.98847e+307" }, + { "0x1000p1011", "8.98847e+307" }, + { "0x1p1020", "1.12356e+307" }, + { "0x0.00001p1040", "1.12356e+307" }, + { "1e-307", "1e-307" }, + { "0.000001e-301", "1e-307" }, + { "0.0000001e-300", "1e-307" }, + { "0.00000001e-299", "1e-307" }, + { "1000000e-313", "1e-307" }, + { "10000000e-314", "1e-307" }, + { "100000000e-315", "1e-307" }, + { "0x1p-1021", "4.45015e-308" }, + { "0x1000p-1033", "4.45015e-308" }, + { "0x10000p-1037", "4.45015e-308" }, + { "0x0.001p-1009", "4.45015e-308" }, + { "0x0.0001p-1005", "4.45015e-308" }, + }; +#define NTESTS (sizeof (tests) / sizeof (tests[0])) + + +static int +do_test (void) +{ + int status = 0; + + for (int i = 0; i < NTESTS; ++i) + { + char buf[100]; + snprintf (buf, sizeof (buf), "%g", atof (tests[i].str)); + if (strcmp (buf, tests[i].expected) != 0) + { + printf ("%d: got \"%s\", expected \"%s\"\n", + i, buf, tests[i].expected); + status = 1; + } + } + + return status; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" -- cgit 1.4.1