Mercurial > hg > octave-kai > gnulib-hg
changeset 13507:be8a41115d44
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.
Reported by Rainer Tammer.
Signed-off-by: Eric Blake <eblake@redhat.com>
author | Eric Blake <eblake@redhat.com> |
---|---|
date | Fri, 30 Jul 2010 16:01:41 -0600 |
parents | 780394a8b4cf |
children | abc6ebd285a3 |
files | ChangeLog doc/posix-functions/strtod.texi lib/strtod.c tests/test-strtod.c |
diffstat | 4 files changed, 69 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2010-07-30 Eric Blake <eblake@redhat.com> + 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. + Reported by Rainer Tammer. + futimens: fix configure check * m4/futimens.m4 (gl_FUNC_FUTIMENS): Use correct logic. Reported by Bruno Haible.
--- a/doc/posix-functions/strtod.texi +++ b/doc/posix-functions/strtod.texi @@ -58,7 +58,13 @@ @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. + +@item +This function returns the wrong end pointer for @samp{0x1p} on some +platforms: +AIX 7.1. @end itemize Portability problems not fixed by Gnulib:
--- a/lib/strtod.c +++ b/lib/strtod.c @@ -216,13 +216,23 @@ 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;
--- a/tests/test-strtod.c +++ b/tests/test-strtod.c @@ -434,6 +434,17 @@ 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 @@ 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 @@ 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 @@ 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;