* m4/include_next.m4 (gl_CHECK_NEXT_HEADERS): Check some typos
[gnulib.git] / tests / test-vasprintf-posix.c
index eb55ab4..3d7aa43 100644 (file)
 
 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
 
 #include <stdio.h>
 
+#include <float.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -63,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)
 {
@@ -74,6 +86,27 @@ strmatch (const char *pattern, const char *string)
   return 1;
 }
 
+/* Test whether string[start_index..end_index-1] is a valid textual
+   representation of NaN.  */
+static int
+strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
+{
+  if (start_index < end_index)
+    {
+      if (string[start_index] == '-')
+       start_index++;
+      if (start_index + 3 <= end_index
+         && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
+       {
+         start_index += 3;
+         if (start_index == end_index
+             || (string[start_index] == '(' && string[end_index - 1] == ')'))
+           return 1;
+       }
+    }
+  return 0;
+}
+         
 static void
 test_function (int (*my_asprintf) (char **, const char *, ...))
 {
@@ -209,7 +242,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%a %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -439,12 +472,12 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
   { /* FLAG_ZERO with NaN.  */
     char *result;
     int retval =
-      my_asprintf (&result, "%020a %d", NaN (), 33, 44, 55);
+      my_asprintf (&result, "%050a %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
     /* "0000000nan 33" is not a valid result; see
        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -523,11 +556,112 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%La %d", 0.0L / 0.0L, 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    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;
@@ -754,12 +888,12 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
   { /* FLAG_ZERO with NaN.  */
     char *result;
     int retval =
-      my_asprintf (&result, "%020La %d", 0.0L / 0.0L, 33, 44, 55);
+      my_asprintf (&result, "%050La %d", 0.0L / 0.0L, 33, 44, 55);
     ASSERT (result != NULL);
     /* "0000000nan 33" is not a valid result; see
        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -937,7 +1071,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%f %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -1027,10 +1161,10 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
   { /* FLAG_ZERO with NaN.  */
     char *result;
     int retval =
-      my_asprintf (&result, "%020f %d", NaN (), 33, 44, 55);
+      my_asprintf (&result, "%050f %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -1217,11 +1351,112 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%Lf %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    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;
@@ -1308,10 +1543,10 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     static long double zero = 0.0L;
     char *result;
     int retval =
-      my_asprintf (&result, "%020Lf %d", zero / zero, 33, 44, 55);
+      my_asprintf (&result, "%050Lf %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -1408,7 +1643,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%F %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "NAN", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 1)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -1525,7 +1760,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%LF %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "NAN", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 1)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -1747,7 +1982,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%e %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -1855,10 +2090,10 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
   { /* FLAG_ZERO with NaN.  */
     char *result;
     int retval =
-      my_asprintf (&result, "%020e %d", NaN (), 33, 44, 55);
+      my_asprintf (&result, "%050e %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -2046,11 +2281,112 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%Le %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    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;
@@ -2147,10 +2483,10 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     static long double zero = 0.0L;
     char *result;
     int retval =
-      my_asprintf (&result, "%020Le %d", zero / zero, 33, 44, 55);
+      my_asprintf (&result, "%050Le %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -2348,7 +2684,7 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%g %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -2449,10 +2785,10 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
   { /* FLAG_ZERO with NaN.  */
     char *result;
     int retval =
-      my_asprintf (&result, "%020g %d", NaN (), 33, 44, 55);
+      my_asprintf (&result, "%050g %d", NaN (), 33, 44, 55);
     ASSERT (result != NULL);
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);
@@ -2640,11 +2976,112 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
       my_asprintf (&result, "%Lg %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
     ASSERT (strlen (result) >= 3 + 3
-           && memcmp (result, "nan", 3) == 0
+           && strisnan (result, 0, strlen (result) - 3, 0)
+           && strcmp (result + strlen (result) - 3, " 33") == 0);
+    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;
@@ -2741,10 +3178,10 @@ test_function (int (*my_asprintf) (char **, const char *, ...))
     static long double zero = 0.0L;
     char *result;
     int retval =
-      my_asprintf (&result, "%020Lg %d", zero / zero, 33, 44, 55);
+      my_asprintf (&result, "%050Lg %d", zero / zero, 33, 44, 55);
     ASSERT (result != NULL);
-    ASSERT (strlen (result) == 20 + 3
-           && memcmp (result + strspn (result, " "), "nan", 3) == 0
+    ASSERT (strlen (result) == 50 + 3
+           && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
            && strcmp (result + strlen (result) - 3, " 33") == 0);
     ASSERT (retval == strlen (result));
     free (result);