[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] strtod: next round of AIX fixes
From: |
Eric Blake |
Subject: |
[PATCH] strtod: next round of AIX fixes |
Date: |
Fri, 30 Jul 2010 16:06:23 -0600 |
* lib/strtod.c (strtod): Work around AIX bug of parsing p with no
exponent.
* tests/test-strtod.c (main): Enhance tests.
* doc/posix-functions/strtod.texi (strtod): Document next bug.
Signed-off-by: Eric Blake <address@hidden>
---
I think this should solve the remaining strtod bugs. I also noticed
that the testsuite wasn't doing any coverage of 'P' in an exponent;
I nearly introduced a bug by using strchr(s,'p') until I realized that
I have to check for both cases.
ChangeLog | 8 +++++++
doc/posix-functions/strtod.texi | 8 ++++++-
lib/strtod.c | 18 +++++++++++++---
tests/test-strtod.c | 41 +++++++++++++++++++++++++++++++++++++++
4 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 4942775..07fc5a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-07-30 Eric Blake <address@hidden>
+
+ strtod: next round of AIX fixes
+ * lib/strtod.c (strtod): Work around AIX bug of parsing p with no
+ exponent.
+ * tests/test-strtod.c (main): Enhance tests.
+ * doc/posix-functions/strtod.texi (strtod): Document next bug.
+
2010-02-17 Eric Blake <address@hidden>
manywarnings: add more warnings
diff --git a/doc/posix-functions/strtod.texi b/doc/posix-functions/strtod.texi
index 7674967..38d6875 100644
--- a/doc/posix-functions/strtod.texi
+++ b/doc/posix-functions/strtod.texi
@@ -58,7 +58,13 @@ strtod
@item
This function fails to parse C99 hexadecimal floating point on some
platforms:
-NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris
10, mingw.
+NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1,
+Solaris 10, mingw.
+
address@hidden
+This function returns the wrong end pointer for @samp{0x1p} on some
+platforms:
+AIX 7.1.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/lib/strtod.c b/lib/strtod.c
index bd0ff43..94eb817 100644
--- a/lib/strtod.c
+++ b/lib/strtod.c
@@ -216,13 +216,23 @@ strtod (const char *nptr, char **endptr)
if (c_isdigit (s[*s == '.']))
{
/* If a hex float was converted incorrectly, do it ourselves.
- If the string starts with "0x", consume the "0" ourselves. */
- if (*s == '0' && c_tolower (s[1]) == 'x' && end <= s + 2)
+ If the string starts with "0x" but does not contain digits,
+ consume the "0" ourselves. If a hex float is followed by a
+ 'p' but no exponent, then adjust the end pointer. */
+ if (*s == '0' && c_tolower (s[1]) == 'x')
{
- if (c_isxdigit (s[2 + (s[2] == '.')]))
+ if (! c_isxdigit (s[2 + (s[2] == '.')]))
+ end = s + 1;
+ else if (end <= s + 2)
num = parse_number (s + 2, 16, 2, 4, 'p', &end);
else
- end = s + 1;
+ {
+ const char *p = s + 2;
+ while (p < end && c_tolower (*p) != 'p')
+ p++;
+ if (p < end && ! c_isdigit (p[1 + (p[1] == '-' || p[1] == '+')]))
+ end = p;
+ }
}
s = end;
diff --git a/tests/test-strtod.c b/tests/test-strtod.c
index 03ec502..694e15d 100644
--- a/tests/test-strtod.c
+++ b/tests/test-strtod.c
@@ -434,6 +434,17 @@ main (void)
ASSERT (errno == 0);
}
{
+ const char input[] = "0XP";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 0.0);
+ ASSERT (!signbit (result));
+ ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD
6.2, AIX 7.1 */
+ ASSERT (errno == 0);
+ }
+ {
const char input[] = "0x.";
char *ptr;
double result;
@@ -487,6 +498,16 @@ main (void)
ASSERT (ptr == input + 1);
ASSERT (errno == 0);
}
+ {
+ const char input[] = "1P+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0);
+ ASSERT (ptr == input + 1);
+ ASSERT (errno == 0);
+ }
/* Overflow/underflow. */
{
@@ -771,6 +792,16 @@ main (void)
ASSERT (errno == 0);
}
{
+ const char input[] = "0x1P+";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1,
HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1,
HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
const char input[] = "0x1p+1";
char *ptr;
double result;
@@ -781,6 +812,16 @@ main (void)
ASSERT (errno == 0);
}
{
+ const char input[] = "0X1P+1";
+ char *ptr;
+ double result;
+ errno = 0;
+ result = strtod (input, &ptr);
+ ASSERT (result == 2.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1,
HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (ptr == input + 6); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1,
HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
+ ASSERT (errno == 0);
+ }
+ {
const char input[] = "0x1p+1a";
char *ptr;
double result;
--
1.7.2