bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]