[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: new module 'vasnprintf-posix'
From: |
Bruno Haible |
Subject: |
Re: new module 'vasnprintf-posix' |
Date: |
Mon, 5 Mar 2007 04:23:40 +0100 |
User-agent: |
KMail/1.5.4 |
Portability would be easy if each platform didn't have its own quirks.
It turns out that the implementations of hexadecimal float printing
in glibc <= 2.4 and MacOS X 10.3 are buggy. Both produce control characters
in the output in some case: glibc sometimes outputs \001 and MacOS X sometimes
outputs \377. This works around it.
2007-03-04 Bruno Haible <address@hidden>
* m4/printf.m4 (gl_PRINTF_DIRECTIVE_A): Exclude two buggy
implementations: glibc-2.4 and MacOS X 10.3.
* tests/test-vasnprintf-posix.c (test_function): Test also the case
that exhibits the bugs in glibc-2.4 and MacOS X 10.3.
* tests/test-vasprintf-posix.c (test_function): Likewise.
*** ./m4/printf.m4 4 Mar 2007 23:28:59 -0000 1.1
--- ./m4/printf.m4 5 Mar 2007 03:13:46 -0000
***************
*** 87,92 ****
--- 87,93 ----
AC_DEFUN([gl_PRINTF_DIRECTIVE_A],
[
AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([gt_TYPE_LONGDOUBLE])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives],
[gl_cv_func_printf_directive_a],
***************
*** 98,121 ****
int main ()
{
if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
! || strcmp (buf, "0x1.922p+1 33") != 0)
return 1;
if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
! || strcmp (buf, "-0X1.922P+1 33") != 0)
return 1;
return 0;
}], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
[
- changequote(,)dnl
case "$host_os" in
! dnl Guess yes on glibc systems.
! *-gnu*) gl_cv_func_printf_directive_a="guessing yes";;
dnl Guess yes on FreeBSD >= 5.
freebsd[1-4]*) gl_cv_func_printf_directive_a="guessing no";;
freebsd* | kfreebsd*) gl_cv_func_printf_directive_a="guessing yes";;
- dnl Gusss yes on MacOS X >= 10.3.
- darwin[1-6].*) gl_cv_func_printf_directive_a="guessing no";;
- darwin*) gl_cv_func_printf_directive_a="guessing yes";;
dnl If we don't know, assume the worst.
*) gl_cv_func_printf_directive_a="guessing no";;
esac
--- 99,153 ----
int main ()
{
if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
! || (strcmp (buf, "0x1.922p+1 33") != 0
! && strcmp (buf, "0x3.244p+0 33") != 0
! && strcmp (buf, "0x6.488p-1 33") != 0
! && strcmp (buf, "0xc.91p-2 33") != 0))
return 1;
if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
! || (strcmp (buf, "-0X1.922P+1 33") != 0
! && strcmp (buf, "-0X3.244P+0 33") != 0
! && strcmp (buf, "-0X6.488P-1 33") != 0
! && strcmp (buf, "-0XC.91P-2 33") != 0))
return 1;
+ /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ if (sprintf (buf, "%.1a", 1.999) < 0
+ || (strcmp (buf, "0x1.0p+1") != 0
+ && strcmp (buf, "0x2.0p+0") != 0
+ && strcmp (buf, "0x4.0p-1") != 0
+ && strcmp (buf, "0x8.0p-2") != 0))
+ return 1;
+ #if HAVE_LONG_DOUBLE
+ /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
+ if (sprintf (buf, "%.1La", 1.999L) < 0
+ || (strcmp (buf, "0x1.0p+1") != 0
+ && strcmp (buf, "0x2.0p+0") != 0
+ && strcmp (buf, "0x4.0p-1") != 0
+ && strcmp (buf, "0x8.0p-2") != 0))
+ return 1;
+ #endif
return 0;
}], [gl_cv_func_printf_directive_a=yes], [gl_cv_func_printf_directive_a=no],
[
case "$host_os" in
! dnl Guess yes on glibc >= 2.5 systems.
! *-gnu*)
! AC_EGREP_CPP([BZ2908], [
! #include <features.h>
! #ifdef __GNU_LIBRARY__
! #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)
! BZ2908
! #endif
! #endif
! ],
! [gl_cv_func_printf_directive_a="guessing yes"],
! [gl_cv_func_printf_directive_a="guessing no"])
! ;;
! changequote(,)dnl
dnl Guess yes on FreeBSD >= 5.
freebsd[1-4]*) gl_cv_func_printf_directive_a="guessing no";;
freebsd* | kfreebsd*) gl_cv_func_printf_directive_a="guessing yes";;
dnl If we don't know, assume the worst.
*) gl_cv_func_printf_directive_a="guessing no";;
esac
***************
*** 338,346 ****
dnl . = yes, # = no.
dnl
dnl 1 2 3 4 5 6 7
! dnl glibc 2.3.6 . . . . . . .
dnl FreeBSD 5.4, 6.1 . . . . . . .
! dnl MacOS X 10.3.9 . . . . . . .
dnl Cygwin 2007 . # . . . . .
dnl Solaris 10 . # . . . . .
dnl Solaris 2.6 ... 9 # # . . . . .
--- 370,378 ----
dnl . = yes, # = no.
dnl
dnl 1 2 3 4 5 6 7
! dnl glibc 2.3.6 . # . . . . .
dnl FreeBSD 5.4, 6.1 . . . . . . .
! dnl MacOS X 10.3.9 . # . . . . .
dnl Cygwin 2007 . # . . . . .
dnl Solaris 10 . # . . . . .
dnl Solaris 2.6 ... 9 # # . . . . .
*** ./tests/test-vasnprintf-posix.c 4 Mar 2007 23:30:21 -0000 1.1
--- ./tests/test-vasnprintf-posix.c 5 Mar 2007 03:13:46 -0000
***************
*** 267,272 ****
--- 267,286 ----
free (result);
}
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.1a %d", 1.999, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
{ /* Width. */
size_t length;
char *result =
***************
*** 560,565 ****
--- 574,594 ----
free (result);
}
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.
*/
+ size_t length;
+ char *result =
+ my_asnprintf (NULL, &length, "%.1La %d", 1.999L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (length == strlen (result));
+ free (result);
+ }
+
{ /* Width. */
size_t length;
char *result =
*** ./tests/test-vasprintf-posix.c 5 Mar 2007 00:39:01 -0000 1.1
--- ./tests/test-vasprintf-posix.c 5 Mar 2007 03:13:46 -0000
***************
*** 34,40 ****
static void
test_function (int (*my_asprintf) (char **, const char *, ...))
{
- char buf[8];
int repeat;
/* Test return value convention. */
--- 34,39 ----
***************
*** 250,255 ****
--- 249,268 ----
free (result);
}
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.1a %d", 1.999, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
{ /* Width. */
char *result;
int retval =
***************
*** 543,548 ****
--- 556,576 ----
free (result);
}
+ { /* Rounding can turn a ...FFF into a ...000.
+ This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
+ glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.
*/
+ char *result;
+ int retval =
+ my_asprintf (&result, "%.1La %d", 1.999L, 33, 44, 55);
+ ASSERT (result != NULL);
+ ASSERT (strcmp (result, "0x1.0p+1 33") == 0
+ || strcmp (result, "0x2.0p+0 33") == 0
+ || strcmp (result, "0x4.0p-1 33") == 0
+ || strcmp (result, "0x8.0p-2 33") == 0);
+ ASSERT (retval == strlen (result));
+ free (result);
+ }
+
{ /* Width. */
char *result;
int retval =