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.
@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:
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;
ASSERT (ptr == input + 1); /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, AIX 7.1 */
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;
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. */
{
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+";
+ 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;
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+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;