aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-01-12 18:07:19 +0000
committerJakub Jelinek <jakub@redhat.com>2007-01-12 18:07:19 +0000
commite8cb3d798129dae67a9e3316c70358306b06f010 (patch)
tree7e19a65a2ccc1732caedd1800107cfa520395d28
parent2d54f6629ee35529977ac7d742ab0c8f2c1c28a0 (diff)
downloadglibc-e8cb3d798129dae67a9e3316c70358306b06f010.tar
glibc-e8cb3d798129dae67a9e3316c70358306b06f010.tar.gz
glibc-e8cb3d798129dae67a9e3316c70358306b06f010.tar.bz2
glibc-e8cb3d798129dae67a9e3316c70358306b06f010.zip
* stdlib/Makefile (tst-strtod3-ENV): Define.
* stdlib/strtod_l.c (____STRTOF_INTERNAL): Parse thousand separators also if no non-zero digits found. * stdlib/Makefile (tests): Add tst-strtod3. [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.
-rw-r--r--ChangeLog30
-rw-r--r--stdlib/Makefile6
-rw-r--r--stdlib/strtod_l.c38
-rw-r--r--stdlib/tst-strtod2.c41
4 files changed, 65 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 6697b048b2..15408da2ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
2007-01-03 Ulrich Drepper <drepper@redhat.com>
+ * stdlib/Makefile (tst-strtod3-ENV): Define.
+
+2006-12-11 Ulrich Drepper <drepper@redhat.com>
+
+ * stdlib/strtod_l.c (____STRTOF_INTERNAL): Parse thousand
+ separators also if no non-zero digits found.
+ * stdlib/Makefile (tests): Add tst-strtod3.
+
+2006-12-09 Ulrich Drepper <drepper@redhat.com>
+
+ [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.
+
+2007-01-03 Ulrich Drepper <drepper@redhat.com>
+
* string/Makefile (tst-strxfrm2-ENV): Define.
2006-11-10 Jakub Jelinek <jakub@redhat.com>
diff --git a/stdlib/Makefile b/stdlib/Makefile
index e9917c1af4..c5a2cbd066 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1991-2006, 2007 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
@@ -67,7 +67,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
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 \
- tst-rand48-2 tst-makecontext
+ tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
+ tst-makecontext
include ../Makeconfig
@@ -116,6 +117,7 @@ include ../Rules
test-canon-ARGS = --test-dir=${common-objpfx}stdlib
tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata
+tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata
testmb2-ENV = LOCPATH=$(common-objpfx)localedata
# Run a test on the header files we use.
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index e13f1086da..b4e4819c87 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,
@@ -721,7 +721,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
c = *++cp;
}
- if (grouping && dig_no > 0)
+ if (grouping && cp > start_of_digits)
{
/* Check the grouping of the digits. */
#ifdef USE_WIDE_CHAR
@@ -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-strtod2.c b/stdlib/tst-strtod2.c
index 30d8d9df65..925ea9cafa 100644
--- a/stdlib/tst-strtod2.c
+++ b/stdlib/tst-strtod2.c
@@ -1,41 +1,22 @@
#include <stdio.h>
#include <stdlib.h>
-struct test
-{
- const char *str;
- double result;
- size_t offset;
-} tests[] =
-{
- { "0xy", 0.0, 1 },
- { "0x.y", 0.0, 1 },
- { "0x0.y", 0.0, 4 },
- { "0x.0y", 0.0, 4 },
- { ".y", 0.0, 0 },
- { "0.y", 0.0, 2 },
- { ".0y", 0.0, 2 }
-};
-
static int
do_test (void)
{
int status = 0;
- for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+ const char s[] = "0x";
+ char *ep;
+ double r = strtod (s, &ep);
+ if (r != 0)
+ {
+ printf ("r = %g, expect 0\n", r);
+ status = 1;
+ }
+ if (ep != s + 1)
{
- char *ep;
- double r = strtod (tests[i].str, &ep);
- if (r != tests[i].result)
- {
- printf ("test %zu r = %g, expect %g\n", i, r, tests[i].result);
- status = 1;
- }
- if (ep != tests[i].str + tests[i].offset)
- {
- printf ("test %zu strtod parsed %ju characters, expected %zu\n",
- i, ep - tests[i].str, tests[i].offset);
- status = 1;
- }
+ printf ("strtod parsed %ju characters, expected 1\n", ep - s);
+ status = 1;
}
return status;
}