Fix *printf so that it recognizes non-IEEE numbers on i386, x86_64, ia64.
authorBruno Haible <bruno@clisp.org>
Wed, 6 Jun 2007 02:20:57 +0000 (02:20 +0000)
committerBruno Haible <bruno@clisp.org>
Wed, 6 Jun 2007 02:20:57 +0000 (02:20 +0000)
19 files changed:
ChangeLog
modules/fprintf-posix
modules/printf-posix
modules/snprintf-posix
modules/sprintf-posix
modules/vasnprintf-posix
modules/vasprintf-posix
modules/vfprintf-posix
modules/vprintf-posix
modules/vsnprintf-posix
modules/vsprintf-posix
tests/test-snprintf-posix.c
tests/test-snprintf-posix.h
tests/test-sprintf-posix.c
tests/test-sprintf-posix.h
tests/test-vasnprintf-posix.c
tests/test-vasprintf-posix.c
tests/test-vsnprintf-posix.c
tests/test-vsprintf-posix.c

index 8637249..5db2619 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,45 @@
 2007-06-05  Bruno Haible  <bruno@clisp.org>
 
+       Fix *printf so that it recognizes non-IEEE numbers on i386, x86_64,
+       ia64.
+       * modules/printf-safe: New file.
+       * modules/fprintf-posix (Depends-on): Add printf-safe.
+       * modules/printf-posix (Depends-on): Likewise.
+       * modules/snprintf-posix (Depends-on): Likewise.
+       * modules/sprintf-posix (Depends-on): Likewise.
+       * modules/vasnprintf-posix (Depends-on): Likewise.
+       * modules/vasprintf-posix (Depends-on): Likewise.
+       * modules/vfprintf-posix (Depends-on): Likewise.
+       * modules/vprintf-posix (Depends-on): Likewise.
+       * modules/vsnprintf-posix (Depends-on): Likewise.
+       * modules/vsprintf-posix (Depends-on): Likewise.
+       * m4/printf.m4 (gl_PRINTF_INFINITE_LONG_DOUBLE): Require
+       AC_C_BIGENDIAN. Define CHECK_PRINTF_SAFE if printf-safe is used. Test
+       non-IEEE numbers on i386, x86_64, ia64. When cross-compiling, guess
+       "no" on i386, x86_64, ia64.
+       * tests/test-snprintf-posix.h (LDBL80_WORDS): New macro.
+       (test_function): Check result of %La, %Lf, %Le, %Lg on non-IEEE numbers
+       on i386, x86_64, ia64.
+       * tests/test-sprintf-posix.h (LDBL80_WORDS): New macro.
+       (test_function): Check result of %La, %Lf, %Le, %Lg on non-IEEE numbers
+       on i386, x86_64, ia64.
+       * tests/test-vasnprintf-posix.c: Include float.h.
+       (LDBL80_WORDS): New macro.
+       (test_function): Check result of %La, %Lf, %Le, %Lg on non-IEEE numbers
+       on i386, x86_64, ia64.
+       * tests/test-vasprintf-posix.c: Include float.h.
+       (LDBL80_WORDS): New macro.
+       (test_function): Check result of %La, %Lf, %Le, %Lg on non-IEEE numbers
+       on i386, x86_64, ia64.
+       * tests/test-snprintf-posix.c: Include float.h.
+       * tests/test-sprintf-posix.c: Likewise.
+       * tests/test-vsnprintf-posix.c: Likewise.
+       * tests/test-vsprintf-posix.c: Likewise.
+
+2007-06-05  Bruno Haible  <bruno@clisp.org>
+
        Fix isnanl so that it recognizes non-IEEE numbers on i386, x86_64, ia64.
-       * m4/isnanl.m4 (gl_FUNC_ISNANL_WORKS): Require AC_C_BIGENDIAN. Tested
+       * m4/isnanl.m4 (gl_FUNC_ISNANL_WORKS): Require AC_C_BIGENDIAN. Test
        non-IEEE numbers on i386, x86_64, ia64.
        (gl_LONG_DOUBLE_EXPONENT_LOCATION): Require AC_C_BIGENDIAN.
        * lib/isnan.c (FUNC): Add special code for i386, x86_64, ia64.
index 42109be..40e606c 100644 (file)
@@ -17,6 +17,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_FPRINTF_POSIX
index ba56fa0..b690c72 100644 (file)
@@ -9,6 +9,7 @@ m4/printf.m4
 Depends-on:
 stdio
 vfprintf-posix
+printf-safe
 
 configure.ac:
 gl_FUNC_PRINTF_POSIX
index c480835..0a5e8d6 100644 (file)
@@ -16,6 +16,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_SNPRINTF_POSIX
index fceae7b..7bfa94b 100644 (file)
@@ -16,6 +16,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_SPRINTF_POSIX
index 9d693af..b701718 100644 (file)
@@ -15,6 +15,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_VASNPRINTF_POSIX
index 48f902f..2b75dff 100644 (file)
@@ -15,6 +15,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_VASPRINTF_POSIX
index 539d525..7d0b8cd 100644 (file)
@@ -17,6 +17,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_VFPRINTF_POSIX
index 4e8601a..2007000 100644 (file)
@@ -9,6 +9,7 @@ m4/printf.m4
 Depends-on:
 stdio
 vfprintf-posix
+printf-safe
 
 configure.ac:
 gl_FUNC_VPRINTF_POSIX
index f1a5674..fc49999 100644 (file)
@@ -16,6 +16,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_VSNPRINTF_POSIX
index 4fc6886..ba79781 100644 (file)
@@ -16,6 +16,7 @@ printf-frexp
 printf-frexpl
 signbit
 fpucw
+printf-safe
 
 configure.ac:
 gl_FUNC_VSPRINTF_POSIX
index 9015256..593f20f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 
+#include <float.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdint.h>
index 346d32e..46412ba 100644 (file)
@@ -38,6 +38,19 @@ have_minus_zero ()
   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
 }
 
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+   of 'unsigned int' words.  */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+      ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
+      (unsigned int) (mantlo) << 16                                        \
+    }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { mantlo, manthi, exponent }
+#endif
+
 static int
 strmatch (const char *pattern, const char *string)
 {
@@ -465,6 +478,93 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Rounding near the decimal point.  */
     char result[100];
@@ -1073,6 +1173,93 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Width.  */
     char result[100];
@@ -1787,6 +1974,93 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Width.  */
     char result[100];
@@ -2301,6 +2575,93 @@ test_function (int (*my_snprintf) (char *, size_t, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[100];
+    int retval =
+      my_snprintf (result, sizeof (result), "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Width.  */
     char result[100];
index 07a556f..6416d85 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 
+#include <float.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdint.h>
index f178803..df0adcc 100644 (file)
@@ -38,6 +38,19 @@ have_minus_zero ()
   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
 }
 
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+   of 'unsigned int' words.  */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+      ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
+      (unsigned int) (mantlo) << 16                                        \
+    }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { mantlo, manthi, exponent }
+#endif
+
 static int
 strmatch (const char *pattern, const char *string)
 {
@@ -69,7 +82,7 @@ strisnan (const char *string, size_t start_index, size_t end_index, int uppercas
     }
   return 0;
 }
-         
+
 static void
 test_function (int (*my_sprintf) (char *, const char *, ...))
 {
@@ -451,6 +464,93 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Rounding near the decimal point.  */
     char result[1000];
@@ -1053,6 +1153,93 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Width.  */
     char result[1000];
@@ -1761,6 +1948,93 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Width.  */
     char result[1000];
@@ -2275,6 +2549,93 @@ test_function (int (*my_sprintf) (char *, const char *, ...))
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char result[1000];
+    int retval =
+      my_sprintf (result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+  }
+#endif
 
   { /* Width.  */
     char result[1000];
index 3d20a83..53b6799 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "vasnprintf.h"
 
+#include <float.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -61,6 +62,19 @@ have_minus_zero ()
   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
 }
 
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+   of 'unsigned int' words.  */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+      ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
+      (unsigned int) (mantlo) << 16                                        \
+    }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { mantlo, manthi, exponent }
+#endif
+
 static int
 strmatch (const char *pattern, const char *string)
 {
@@ -566,6 +580,107 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     ASSERT (length == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Rounding near the decimal point.  */
     size_t length;
@@ -1260,6 +1375,107 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     ASSERT (length == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Width.  */
     size_t length;
@@ -2089,6 +2305,107 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     ASSERT (length == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Width.  */
     size_t length;
@@ -2683,6 +3000,107 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     ASSERT (length == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    size_t length;
+    char *result =
+      my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (length == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Width.  */
     size_t length;
index 7ff05da..3d7aa43 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 
+#include <float.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -61,6 +62,19 @@ have_minus_zero ()
   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
 }
 
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+   of 'unsigned int' words.  */
+#ifdef WORDS_BIGENDIAN
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+      ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
+      (unsigned int) (mantlo) << 16                                        \
+    }
+#else
+# define LDBL80_WORDS(exponent,manthi,mantlo) \
+    { mantlo, manthi, exponent }
+#endif
+
 static int
 strmatch (const char *pattern, const char *string)
 {
@@ -547,6 +561,107 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     ASSERT (retval == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Rounding near the decimal point.  */
     char *result;
@@ -1241,6 +1356,107 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     ASSERT (retval == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Width.  */
     char *result;
@@ -2070,6 +2286,107 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     ASSERT (retval == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Width.  */
     char *result;
@@ -2664,6 +2981,107 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     ASSERT (retval == strlen (result));
     free (result);
   }
+#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
+  { /* Quiet NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  {
+    /* Signalling NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Infinity.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Zero.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Unnormalized number.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+  { /* Pseudo-Denormal.  */
+    static union { unsigned int word[4]; long double value; } x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    char *result;
+    int retval =
+      my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
+    ASSERT (result != NULL);
+    ASSERT (strlen (result) >= 3 + 3
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    ASSERT (retval == strlen (result));
+    free (result);
+  }
+#endif
 
   { /* Width.  */
     char *result;
index 0c3d807..aa2c9a9 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 
+#include <float.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
index d0297bb..6aa1d5c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 
+#include <float.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>