root/maint/gnulib/tests/test-vasnprintf-posix.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. have_minus_zero
  2. strmatch
  3. strisnan
  4. test_function
  5. my_asnprintf
  6. test_vasnprintf
  7. test_asnprintf
  8. main

   1 /* Test of POSIX compatible vasnprintf() and asnprintf() functions.
   2    Copyright (C) 2007-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
  18 
  19 #include <config.h>
  20 
  21 #include "vasnprintf.h"
  22 
  23 #include <errno.h>
  24 #include <float.h>
  25 #include <stdarg.h>
  26 #include <stddef.h>
  27 #include <stdint.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 
  31 #include "macros.h"
  32 #include "minus-zero.h"
  33 #include "infinity.h"
  34 #include "nan.h"
  35 
  36 /* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0.  */
  37 static int
  38 have_minus_zero ()
     /* [previous][next][first][last][top][bottom][index][help] */
  39 {
  40   static double plus_zero = 0.0;
  41   double minus_zero = minus_zerod;
  42   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
  43 }
  44 
  45 /* Representation of an 80-bit 'long double' as an initializer for a sequence
  46    of 'unsigned int' words.  */
  47 #ifdef WORDS_BIGENDIAN
  48 # define LDBL80_WORDS(exponent,manthi,mantlo) \
  49     { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
  50       ((unsigned int) (manthi) << 16) | ((unsigned int) (mantlo) >> 16),   \
  51       (unsigned int) (mantlo) << 16                                        \
  52     }
  53 #else
  54 # define LDBL80_WORDS(exponent,manthi,mantlo) \
  55     { mantlo, manthi, exponent }
  56 #endif
  57 
  58 static int
  59 strmatch (const char *pattern, const char *string)
     /* [previous][next][first][last][top][bottom][index][help] */
  60 {
  61   if (strlen (pattern) != strlen (string))
  62     return 0;
  63   for (; *pattern != '\0'; pattern++, string++)
  64     if (*pattern != '*' && *string != *pattern)
  65       return 0;
  66   return 1;
  67 }
  68 
  69 /* Test whether string[start_index..end_index-1] is a valid textual
  70    representation of NaN.  */
  71 static int
  72 strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74   if (start_index < end_index)
  75     {
  76       if (string[start_index] == '-')
  77         start_index++;
  78       if (start_index + 3 <= end_index
  79           && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
  80         {
  81           start_index += 3;
  82           if (start_index == end_index
  83               || (string[start_index] == '(' && string[end_index - 1] == ')'))
  84             return 1;
  85         }
  86     }
  87   return 0;
  88 }
  89 
  90 static void
  91 test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   char buf[8];
  94   int size;
  95 
  96   /* Test return value convention.  */
  97 
  98   for (size = 0; size <= 8; size++)
  99     {
 100       size_t length = size;
 101       char *result = my_asnprintf (NULL, &length, "%d", 12345);
 102       ASSERT (result != NULL);
 103       ASSERT (strcmp (result, "12345") == 0);
 104       ASSERT (length == 5);
 105       free (result);
 106     }
 107 
 108   for (size = 0; size <= 8; size++)
 109     {
 110       size_t length;
 111       char *result;
 112 
 113       memcpy (buf, "DEADBEEF", 8);
 114       length = size;
 115       result = my_asnprintf (buf, &length, "%d", 12345);
 116       ASSERT (result != NULL);
 117       ASSERT (strcmp (result, "12345") == 0);
 118       ASSERT (length == 5);
 119       if (size < 6)
 120         ASSERT (result != buf);
 121       ASSERT (memcmp (buf + size, &"DEADBEEF"[size], 8 - size) == 0);
 122       if (result != buf)
 123         free (result);
 124     }
 125 
 126   /* Test support of size specifiers as in C99.  */
 127 
 128   {
 129     size_t length;
 130     char *result =
 131       my_asnprintf (NULL, &length, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
 132     ASSERT (result != NULL);
 133     ASSERT (strcmp (result, "12345671 33") == 0);
 134     ASSERT (length == strlen (result));
 135     free (result);
 136   }
 137 
 138   {
 139     size_t length;
 140     char *result =
 141       my_asnprintf (NULL, &length, "%zu %d", (size_t) 12345672, 33, 44, 55);
 142     ASSERT (result != NULL);
 143     ASSERT (strcmp (result, "12345672 33") == 0);
 144     ASSERT (length == strlen (result));
 145     free (result);
 146   }
 147 
 148   {
 149     size_t length;
 150     char *result =
 151       my_asnprintf (NULL, &length, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
 152     ASSERT (result != NULL);
 153     ASSERT (strcmp (result, "12345673 33") == 0);
 154     ASSERT (length == strlen (result));
 155     free (result);
 156   }
 157 
 158   {
 159     size_t length;
 160     char *result =
 161       my_asnprintf (NULL, &length, "%Lg %d", (long double) 1.5, 33, 44, 55);
 162     ASSERT (result != NULL);
 163     ASSERT (strcmp (result, "1.5 33") == 0);
 164     ASSERT (length == strlen (result));
 165     free (result);
 166   }
 167 
 168   /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
 169      output of floating-point numbers.  */
 170 
 171   { /* A positive number.  */
 172     size_t length;
 173     char *result =
 174       my_asnprintf (NULL, &length, "%a %d", 3.1416015625, 33, 44, 55);
 175     ASSERT (result != NULL);
 176     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
 177             || strcmp (result, "0x3.244p+0 33") == 0
 178             || strcmp (result, "0x6.488p-1 33") == 0
 179             || strcmp (result, "0xc.91p-2 33") == 0);
 180     ASSERT (length == strlen (result));
 181     free (result);
 182   }
 183 
 184   { /* A negative number.  */
 185     size_t length;
 186     char *result =
 187       my_asnprintf (NULL, &length, "%A %d", -3.1416015625, 33, 44, 55);
 188     ASSERT (result != NULL);
 189     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
 190             || strcmp (result, "-0X3.244P+0 33") == 0
 191             || strcmp (result, "-0X6.488P-1 33") == 0
 192             || strcmp (result, "-0XC.91P-2 33") == 0);
 193     ASSERT (length == strlen (result));
 194     free (result);
 195   }
 196 
 197   { /* Positive zero.  */
 198     size_t length;
 199     char *result =
 200       my_asnprintf (NULL, &length, "%a %d", 0.0, 33, 44, 55);
 201     ASSERT (result != NULL);
 202     ASSERT (strcmp (result, "0x0p+0 33") == 0);
 203     ASSERT (length == strlen (result));
 204     free (result);
 205   }
 206 
 207   { /* Negative zero.  */
 208     size_t length;
 209     char *result =
 210       my_asnprintf (NULL, &length, "%a %d", minus_zerod, 33, 44, 55);
 211     ASSERT (result != NULL);
 212     if (have_minus_zero ())
 213       ASSERT (strcmp (result, "-0x0p+0 33") == 0);
 214     ASSERT (length == strlen (result));
 215     free (result);
 216   }
 217 
 218   { /* Positive infinity.  */
 219     size_t length;
 220     char *result =
 221       my_asnprintf (NULL, &length, "%a %d", Infinityd (), 33, 44, 55);
 222     ASSERT (result != NULL);
 223     ASSERT (strcmp (result, "inf 33") == 0);
 224     ASSERT (length == strlen (result));
 225     free (result);
 226   }
 227 
 228   { /* Negative infinity.  */
 229     size_t length;
 230     char *result =
 231       my_asnprintf (NULL, &length, "%a %d", - Infinityd (), 33, 44, 55);
 232     ASSERT (result != NULL);
 233     ASSERT (strcmp (result, "-inf 33") == 0);
 234     ASSERT (length == strlen (result));
 235     free (result);
 236   }
 237 
 238   { /* NaN.  */
 239     size_t length;
 240     char *result =
 241       my_asnprintf (NULL, &length, "%a %d", NaNd (), 33, 44, 55);
 242     ASSERT (result != NULL);
 243     ASSERT (strlen (result) >= 3 + 3
 244             && strisnan (result, 0, strlen (result) - 3, 0)
 245             && strcmp (result + strlen (result) - 3, " 33") == 0);
 246     ASSERT (length == strlen (result));
 247     free (result);
 248   }
 249 
 250   { /* Rounding near the decimal point.  */
 251     size_t length;
 252     char *result =
 253       my_asnprintf (NULL, &length, "%.0a %d", 1.5, 33, 44, 55);
 254     ASSERT (result != NULL);
 255     ASSERT (strcmp (result, "0x1p+0 33") == 0
 256             || strcmp (result, "0x2p+0 33") == 0
 257             || strcmp (result, "0x3p-1 33") == 0
 258             || strcmp (result, "0x6p-2 33") == 0
 259             || strcmp (result, "0xcp-3 33") == 0);
 260     ASSERT (length == strlen (result));
 261     free (result);
 262   }
 263 
 264   { /* Rounding with precision 0.  */
 265     size_t length;
 266     char *result =
 267       my_asnprintf (NULL, &length, "%.0a %d", 1.51, 33, 44, 55);
 268     ASSERT (result != NULL);
 269     ASSERT (strcmp (result, "0x2p+0 33") == 0
 270             || strcmp (result, "0x3p-1 33") == 0
 271             || strcmp (result, "0x6p-2 33") == 0
 272             || strcmp (result, "0xcp-3 33") == 0);
 273     ASSERT (length == strlen (result));
 274     free (result);
 275   }
 276 
 277   { /* Rounding with precision 1.  */
 278     size_t length;
 279     char *result =
 280       my_asnprintf (NULL, &length, "%.1a %d", 1.51, 33, 44, 55);
 281     ASSERT (result != NULL);
 282     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
 283             || strcmp (result, "0x3.0p-1 33") == 0
 284             || strcmp (result, "0x6.1p-2 33") == 0
 285             || strcmp (result, "0xc.1p-3 33") == 0);
 286     ASSERT (length == strlen (result));
 287     free (result);
 288   }
 289 
 290   { /* Rounding with precision 2.  */
 291     size_t length;
 292     char *result =
 293       my_asnprintf (NULL, &length, "%.2a %d", 1.51, 33, 44, 55);
 294     ASSERT (result != NULL);
 295     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
 296             || strcmp (result, "0x3.05p-1 33") == 0
 297             || strcmp (result, "0x6.0ap-2 33") == 0
 298             || strcmp (result, "0xc.14p-3 33") == 0);
 299     ASSERT (length == strlen (result));
 300     free (result);
 301   }
 302 
 303   { /* Rounding with precision 3.  */
 304     size_t length;
 305     char *result =
 306       my_asnprintf (NULL, &length, "%.3a %d", 1.51, 33, 44, 55);
 307     ASSERT (result != NULL);
 308     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
 309             || strcmp (result, "0x3.052p-1 33") == 0
 310             || strcmp (result, "0x6.0a4p-2 33") == 0
 311             || strcmp (result, "0xc.148p-3 33") == 0);
 312     ASSERT (length == strlen (result));
 313     free (result);
 314   }
 315 
 316   { /* Rounding can turn a ...FFF into a ...000.  */
 317     size_t length;
 318     char *result =
 319       my_asnprintf (NULL, &length, "%.3a %d", 1.49999, 33, 44, 55);
 320     ASSERT (result != NULL);
 321     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
 322             || strcmp (result, "0x3.000p-1 33") == 0
 323             || strcmp (result, "0x6.000p-2 33") == 0
 324             || strcmp (result, "0xc.000p-3 33") == 0);
 325     ASSERT (length == strlen (result));
 326     free (result);
 327   }
 328 
 329   { /* Rounding can turn a ...FFF into a ...000.
 330        This shows a Mac OS X 10.3.9 (Darwin 7.9) bug.  */
 331     size_t length;
 332     char *result =
 333       my_asnprintf (NULL, &length, "%.1a %d", 1.999, 33, 44, 55);
 334     ASSERT (result != NULL);
 335     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
 336             || strcmp (result, "0x2.0p+0 33") == 0
 337             || strcmp (result, "0x4.0p-1 33") == 0
 338             || strcmp (result, "0x8.0p-2 33") == 0);
 339     ASSERT (length == strlen (result));
 340     free (result);
 341   }
 342 
 343   { /* Width.  */
 344     size_t length;
 345     char *result =
 346       my_asnprintf (NULL, &length, "%10a %d", 1.75, 33, 44, 55);
 347     ASSERT (result != NULL);
 348     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
 349             || strcmp (result, "  0x3.8p-1 33") == 0
 350             || strcmp (result, "    0x7p-2 33") == 0
 351             || strcmp (result, "    0xep-3 33") == 0);
 352     ASSERT (length == strlen (result));
 353     free (result);
 354   }
 355 
 356   { /* Small precision.  */
 357     size_t length;
 358     char *result =
 359       my_asnprintf (NULL, &length, "%.10a %d", 1.75, 33, 44, 55);
 360     ASSERT (result != NULL);
 361     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
 362             || strcmp (result, "0x3.8000000000p-1 33") == 0
 363             || strcmp (result, "0x7.0000000000p-2 33") == 0
 364             || strcmp (result, "0xe.0000000000p-3 33") == 0);
 365     ASSERT (length == strlen (result));
 366     free (result);
 367   }
 368 
 369   { /* Large precision.  */
 370     size_t length;
 371     char *result =
 372       my_asnprintf (NULL, &length, "%.50a %d", 1.75, 33, 44, 55);
 373     ASSERT (result != NULL);
 374     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
 375             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
 376             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
 377             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
 378     ASSERT (length == strlen (result));
 379     free (result);
 380   }
 381 
 382   { /* FLAG_LEFT.  */
 383     size_t length;
 384     char *result =
 385       my_asnprintf (NULL, &length, "%-10a %d", 1.75, 33, 44, 55);
 386     ASSERT (result != NULL);
 387     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
 388             || strcmp (result, "0x3.8p-1   33") == 0
 389             || strcmp (result, "0x7p-2     33") == 0
 390             || strcmp (result, "0xep-3     33") == 0);
 391     ASSERT (length == strlen (result));
 392     free (result);
 393   }
 394 
 395   { /* FLAG_SHOWSIGN.  */
 396     size_t length;
 397     char *result =
 398       my_asnprintf (NULL, &length, "%+a %d", 1.75, 33, 44, 55);
 399     ASSERT (result != NULL);
 400     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
 401             || strcmp (result, "+0x3.8p-1 33") == 0
 402             || strcmp (result, "+0x7p-2 33") == 0
 403             || strcmp (result, "+0xep-3 33") == 0);
 404     ASSERT (length == strlen (result));
 405     free (result);
 406   }
 407 
 408   { /* FLAG_SPACE.  */
 409     size_t length;
 410     char *result =
 411       my_asnprintf (NULL, &length, "% a %d", 1.75, 33, 44, 55);
 412     ASSERT (result != NULL);
 413     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
 414             || strcmp (result, " 0x3.8p-1 33") == 0
 415             || strcmp (result, " 0x7p-2 33") == 0
 416             || strcmp (result, " 0xep-3 33") == 0);
 417     ASSERT (length == strlen (result));
 418     free (result);
 419   }
 420 
 421   { /* FLAG_ALT.  */
 422     size_t length;
 423     char *result =
 424       my_asnprintf (NULL, &length, "%#a %d", 1.75, 33, 44, 55);
 425     ASSERT (result != NULL);
 426     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
 427             || strcmp (result, "0x3.8p-1 33") == 0
 428             || strcmp (result, "0x7.p-2 33") == 0
 429             || strcmp (result, "0xe.p-3 33") == 0);
 430     ASSERT (length == strlen (result));
 431     free (result);
 432   }
 433 
 434   { /* FLAG_ALT.  */
 435     size_t length;
 436     char *result =
 437       my_asnprintf (NULL, &length, "%#a %d", 1.0, 33, 44, 55);
 438     ASSERT (result != NULL);
 439     ASSERT (strcmp (result, "0x1.p+0 33") == 0
 440             || strcmp (result, "0x2.p-1 33") == 0
 441             || strcmp (result, "0x4.p-2 33") == 0
 442             || strcmp (result, "0x8.p-3 33") == 0);
 443     ASSERT (length == strlen (result));
 444     free (result);
 445   }
 446 
 447   { /* FLAG_ZERO with finite number.  */
 448     size_t length;
 449     char *result =
 450       my_asnprintf (NULL, &length, "%010a %d", 1.75, 33, 44, 55);
 451     ASSERT (result != NULL);
 452     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
 453             || strcmp (result, "0x003.8p-1 33") == 0
 454             || strcmp (result, "0x00007p-2 33") == 0
 455             || strcmp (result, "0x0000ep-3 33") == 0);
 456     ASSERT (length == strlen (result));
 457     free (result);
 458   }
 459 
 460   { /* FLAG_ZERO with infinite number.  */
 461     size_t length;
 462     char *result =
 463       my_asnprintf (NULL, &length, "%010a %d", Infinityd (), 33, 44, 55);
 464     ASSERT (result != NULL);
 465     /* "0000000inf 33" is not a valid result; see
 466        <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
 467     ASSERT (strcmp (result, "       inf 33") == 0);
 468     ASSERT (length == strlen (result));
 469     free (result);
 470   }
 471 
 472   { /* FLAG_ZERO with NaN.  */
 473     size_t length;
 474     char *result =
 475       my_asnprintf (NULL, &length, "%050a %d", NaNd (), 33, 44, 55);
 476     ASSERT (result != NULL);
 477     /* "0000000nan 33" is not a valid result; see
 478        <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
 479     ASSERT (strlen (result) == 50 + 3
 480             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
 481             && strcmp (result + strlen (result) - 3, " 33") == 0);
 482     ASSERT (length == strlen (result));
 483     free (result);
 484   }
 485 
 486   { /* A positive number.  */
 487     size_t length;
 488     char *result =
 489       my_asnprintf (NULL, &length, "%La %d", 3.1416015625L, 33, 44, 55);
 490     ASSERT (result != NULL);
 491     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
 492             || strcmp (result, "0x3.244p+0 33") == 0
 493             || strcmp (result, "0x6.488p-1 33") == 0
 494             || strcmp (result, "0xc.91p-2 33") == 0);
 495     ASSERT (length == strlen (result));
 496     free (result);
 497   }
 498 
 499   { /* A negative number.  */
 500     size_t length;
 501     char *result =
 502       my_asnprintf (NULL, &length, "%LA %d", -3.1416015625L, 33, 44, 55);
 503     ASSERT (result != NULL);
 504     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
 505             || strcmp (result, "-0X3.244P+0 33") == 0
 506             || strcmp (result, "-0X6.488P-1 33") == 0
 507             || strcmp (result, "-0XC.91P-2 33") == 0);
 508     ASSERT (length == strlen (result));
 509     free (result);
 510   }
 511 
 512   { /* Positive zero.  */
 513     size_t length;
 514     char *result =
 515       my_asnprintf (NULL, &length, "%La %d", 0.0L, 33, 44, 55);
 516     ASSERT (result != NULL);
 517     ASSERT (strcmp (result, "0x0p+0 33") == 0);
 518     ASSERT (length == strlen (result));
 519     free (result);
 520   }
 521 
 522   { /* Negative zero.  */
 523     size_t length;
 524     char *result =
 525       my_asnprintf (NULL, &length, "%La %d", minus_zerol, 33, 44, 55);
 526     ASSERT (result != NULL);
 527     if (have_minus_zero ())
 528       ASSERT (strcmp (result, "-0x0p+0 33") == 0);
 529     ASSERT (length == strlen (result));
 530     free (result);
 531   }
 532 
 533   { /* Positive infinity.  */
 534     size_t length;
 535     char *result =
 536       my_asnprintf (NULL, &length, "%La %d", Infinityl (), 33, 44, 55);
 537     ASSERT (result != NULL);
 538     ASSERT (strcmp (result, "inf 33") == 0);
 539     ASSERT (length == strlen (result));
 540     free (result);
 541   }
 542 
 543   { /* Negative infinity.  */
 544     size_t length;
 545     char *result =
 546       my_asnprintf (NULL, &length, "%La %d", - Infinityl (), 33, 44, 55);
 547     ASSERT (result != NULL);
 548     ASSERT (strcmp (result, "-inf 33") == 0);
 549     ASSERT (length == strlen (result));
 550     free (result);
 551   }
 552 
 553   { /* NaN.  */
 554     size_t length;
 555     char *result =
 556       my_asnprintf (NULL, &length, "%La %d", NaNl (), 33, 44, 55);
 557     ASSERT (result != NULL);
 558     ASSERT (strlen (result) >= 3 + 3
 559             && strisnan (result, 0, strlen (result) - 3, 0)
 560             && strcmp (result + strlen (result) - 3, " 33") == 0);
 561     ASSERT (length == strlen (result));
 562     free (result);
 563   }
 564 #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_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
 565   { /* Quiet NaN.  */
 566     static union { unsigned int word[4]; long double value; } x =
 567       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
 568     size_t length;
 569     char *result =
 570       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 571     ASSERT (result != NULL);
 572     ASSERT (strlen (result) >= 3 + 3
 573             && strisnan (result, 0, strlen (result) - 3, 0)
 574             && strcmp (result + strlen (result) - 3, " 33") == 0);
 575     ASSERT (length == strlen (result));
 576     free (result);
 577   }
 578   {
 579     /* Signalling NaN.  */
 580     static union { unsigned int word[4]; long double value; } x =
 581       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
 582     size_t length;
 583     char *result =
 584       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 585     ASSERT (result != NULL);
 586     ASSERT (strlen (result) >= 3 + 3
 587             && strisnan (result, 0, strlen (result) - 3, 0)
 588             && strcmp (result + strlen (result) - 3, " 33") == 0);
 589     ASSERT (length == strlen (result));
 590     free (result);
 591   }
 592   /* asnprintf should print something for noncanonical values.  */
 593   { /* Pseudo-NaN.  */
 594     static union { unsigned int word[4]; long double value; } x =
 595       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
 596     size_t length;
 597     char *result =
 598       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 599     ASSERT (result != NULL);
 600     ASSERT (length == strlen (result));
 601     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
 602     free (result);
 603   }
 604   { /* Pseudo-Infinity.  */
 605     static union { unsigned int word[4]; long double value; } x =
 606       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
 607     size_t length;
 608     char *result =
 609       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 610     ASSERT (result != NULL);
 611     ASSERT (length == strlen (result));
 612     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
 613     free (result);
 614   }
 615   { /* Pseudo-Zero.  */
 616     static union { unsigned int word[4]; long double value; } x =
 617       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
 618     size_t length;
 619     char *result =
 620       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 621     ASSERT (result != NULL);
 622     ASSERT (length == strlen (result));
 623     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
 624     free (result);
 625   }
 626   { /* Unnormalized number.  */
 627     static union { unsigned int word[4]; long double value; } x =
 628       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
 629     size_t length;
 630     char *result =
 631       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 632     ASSERT (result != NULL);
 633     ASSERT (length == strlen (result));
 634     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
 635     free (result);
 636   }
 637   { /* Pseudo-Denormal.  */
 638     static union { unsigned int word[4]; long double value; } x =
 639       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
 640     size_t length;
 641     char *result =
 642       my_asnprintf (NULL, &length, "%La %d", x.value, 33, 44, 55);
 643     ASSERT (result != NULL);
 644     ASSERT (length == strlen (result));
 645     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
 646     free (result);
 647   }
 648 #endif
 649 
 650   { /* Rounding near the decimal point.  */
 651     size_t length;
 652     char *result =
 653       my_asnprintf (NULL, &length, "%.0La %d", 1.5L, 33, 44, 55);
 654     ASSERT (result != NULL);
 655     ASSERT (strcmp (result, "0x2p+0 33") == 0
 656             || strcmp (result, "0x3p-1 33") == 0
 657             || strcmp (result, "0x6p-2 33") == 0
 658             || strcmp (result, "0xcp-3 33") == 0);
 659     ASSERT (length == strlen (result));
 660     free (result);
 661   }
 662 
 663   { /* Rounding with precision 0.  */
 664     size_t length;
 665     char *result =
 666       my_asnprintf (NULL, &length, "%.0La %d", 1.51L, 33, 44, 55);
 667     ASSERT (result != NULL);
 668     ASSERT (strcmp (result, "0x2p+0 33") == 0
 669             || strcmp (result, "0x3p-1 33") == 0
 670             || strcmp (result, "0x6p-2 33") == 0
 671             || strcmp (result, "0xcp-3 33") == 0);
 672     ASSERT (length == strlen (result));
 673     free (result);
 674   }
 675 
 676   { /* Rounding with precision 1.  */
 677     size_t length;
 678     char *result =
 679       my_asnprintf (NULL, &length, "%.1La %d", 1.51L, 33, 44, 55);
 680     ASSERT (result != NULL);
 681     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
 682             || strcmp (result, "0x3.0p-1 33") == 0
 683             || strcmp (result, "0x6.1p-2 33") == 0
 684             || strcmp (result, "0xc.1p-3 33") == 0);
 685     ASSERT (length == strlen (result));
 686     free (result);
 687   }
 688 
 689   { /* Rounding with precision 2.  */
 690     size_t length;
 691     char *result =
 692       my_asnprintf (NULL, &length, "%.2La %d", 1.51L, 33, 44, 55);
 693     ASSERT (result != NULL);
 694     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
 695             || strcmp (result, "0x3.05p-1 33") == 0
 696             || strcmp (result, "0x6.0ap-2 33") == 0
 697             || strcmp (result, "0xc.14p-3 33") == 0);
 698     ASSERT (length == strlen (result));
 699     free (result);
 700   }
 701 
 702   { /* Rounding with precision 3.  */
 703     size_t length;
 704     char *result =
 705       my_asnprintf (NULL, &length, "%.3La %d", 1.51L, 33, 44, 55);
 706     ASSERT (result != NULL);
 707     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
 708             || strcmp (result, "0x3.052p-1 33") == 0
 709             || strcmp (result, "0x6.0a4p-2 33") == 0
 710             || strcmp (result, "0xc.148p-3 33") == 0);
 711     ASSERT (length == strlen (result));
 712     free (result);
 713   }
 714 
 715   { /* Rounding can turn a ...FFF into a ...000.  */
 716     size_t length;
 717     char *result =
 718       my_asnprintf (NULL, &length, "%.3La %d", 1.49999L, 33, 44, 55);
 719     ASSERT (result != NULL);
 720     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
 721             || strcmp (result, "0x3.000p-1 33") == 0
 722             || strcmp (result, "0x6.000p-2 33") == 0
 723             || strcmp (result, "0xc.000p-3 33") == 0);
 724     ASSERT (length == strlen (result));
 725     free (result);
 726   }
 727 
 728   { /* Rounding can turn a ...FFF into a ...000.
 729        This shows a Mac OS X 10.3.9 (Darwin 7.9) bug and a
 730        glibc 2.4 bug <https://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
 731     size_t length;
 732     char *result =
 733       my_asnprintf (NULL, &length, "%.1La %d", 1.999L, 33, 44, 55);
 734     ASSERT (result != NULL);
 735     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
 736             || strcmp (result, "0x2.0p+0 33") == 0
 737             || strcmp (result, "0x4.0p-1 33") == 0
 738             || strcmp (result, "0x8.0p-2 33") == 0);
 739     ASSERT (length == strlen (result));
 740     free (result);
 741   }
 742 
 743   { /* Width.  */
 744     size_t length;
 745     char *result =
 746       my_asnprintf (NULL, &length, "%10La %d", 1.75L, 33, 44, 55);
 747     ASSERT (result != NULL);
 748     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
 749             || strcmp (result, "  0x3.8p-1 33") == 0
 750             || strcmp (result, "    0x7p-2 33") == 0
 751             || strcmp (result, "    0xep-3 33") == 0);
 752     ASSERT (length == strlen (result));
 753     free (result);
 754   }
 755 
 756   { /* Small precision.  */
 757     size_t length;
 758     char *result =
 759       my_asnprintf (NULL, &length, "%.10La %d", 1.75L, 33, 44, 55);
 760     ASSERT (result != NULL);
 761     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
 762             || strcmp (result, "0x3.8000000000p-1 33") == 0
 763             || strcmp (result, "0x7.0000000000p-2 33") == 0
 764             || strcmp (result, "0xe.0000000000p-3 33") == 0);
 765     ASSERT (length == strlen (result));
 766     free (result);
 767   }
 768 
 769   { /* Large precision.  */
 770     size_t length;
 771     char *result =
 772       my_asnprintf (NULL, &length, "%.50La %d", 1.75L, 33, 44, 55);
 773     ASSERT (result != NULL);
 774     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
 775             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
 776             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
 777             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
 778     ASSERT (length == strlen (result));
 779     free (result);
 780   }
 781 
 782   { /* FLAG_LEFT.  */
 783     size_t length;
 784     char *result =
 785       my_asnprintf (NULL, &length, "%-10La %d", 1.75L, 33, 44, 55);
 786     ASSERT (result != NULL);
 787     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
 788             || strcmp (result, "0x3.8p-1   33") == 0
 789             || strcmp (result, "0x7p-2     33") == 0
 790             || strcmp (result, "0xep-3     33") == 0);
 791     ASSERT (length == strlen (result));
 792     free (result);
 793   }
 794 
 795   { /* FLAG_SHOWSIGN.  */
 796     size_t length;
 797     char *result =
 798       my_asnprintf (NULL, &length, "%+La %d", 1.75L, 33, 44, 55);
 799     ASSERT (result != NULL);
 800     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
 801             || strcmp (result, "+0x3.8p-1 33") == 0
 802             || strcmp (result, "+0x7p-2 33") == 0
 803             || strcmp (result, "+0xep-3 33") == 0);
 804     ASSERT (length == strlen (result));
 805     free (result);
 806   }
 807 
 808   { /* FLAG_SPACE.  */
 809     size_t length;
 810     char *result =
 811       my_asnprintf (NULL, &length, "% La %d", 1.75L, 33, 44, 55);
 812     ASSERT (result != NULL);
 813     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
 814             || strcmp (result, " 0x3.8p-1 33") == 0
 815             || strcmp (result, " 0x7p-2 33") == 0
 816             || strcmp (result, " 0xep-3 33") == 0);
 817     ASSERT (length == strlen (result));
 818     free (result);
 819   }
 820 
 821   { /* FLAG_ALT.  */
 822     size_t length;
 823     char *result =
 824       my_asnprintf (NULL, &length, "%#La %d", 1.75L, 33, 44, 55);
 825     ASSERT (result != NULL);
 826     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
 827             || strcmp (result, "0x3.8p-1 33") == 0
 828             || strcmp (result, "0x7.p-2 33") == 0
 829             || strcmp (result, "0xe.p-3 33") == 0);
 830     ASSERT (length == strlen (result));
 831     free (result);
 832   }
 833 
 834   { /* FLAG_ALT.  */
 835     size_t length;
 836     char *result =
 837       my_asnprintf (NULL, &length, "%#La %d", 1.0L, 33, 44, 55);
 838     ASSERT (result != NULL);
 839     ASSERT (strcmp (result, "0x1.p+0 33") == 0
 840             || strcmp (result, "0x2.p-1 33") == 0
 841             || strcmp (result, "0x4.p-2 33") == 0
 842             || strcmp (result, "0x8.p-3 33") == 0);
 843     ASSERT (length == strlen (result));
 844     free (result);
 845   }
 846 
 847   { /* FLAG_ZERO with finite number.  */
 848     size_t length;
 849     char *result =
 850       my_asnprintf (NULL, &length, "%010La %d", 1.75L, 33, 44, 55);
 851     ASSERT (result != NULL);
 852     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
 853             || strcmp (result, "0x003.8p-1 33") == 0
 854             || strcmp (result, "0x00007p-2 33") == 0
 855             || strcmp (result, "0x0000ep-3 33") == 0);
 856     ASSERT (length == strlen (result));
 857     free (result);
 858   }
 859 
 860   { /* FLAG_ZERO with infinite number.  */
 861     size_t length;
 862     char *result =
 863       my_asnprintf (NULL, &length, "%010La %d", Infinityl (), 33, 44, 55);
 864     ASSERT (result != NULL);
 865     /* "0000000inf 33" is not a valid result; see
 866        <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
 867     ASSERT (strcmp (result, "       inf 33") == 0);
 868     ASSERT (length == strlen (result));
 869     free (result);
 870   }
 871 
 872   { /* FLAG_ZERO with NaN.  */
 873     size_t length;
 874     char *result =
 875       my_asnprintf (NULL, &length, "%050La %d", NaNl (), 33, 44, 55);
 876     ASSERT (result != NULL);
 877     /* "0000000nan 33" is not a valid result; see
 878        <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
 879     ASSERT (strlen (result) == 50 + 3
 880             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
 881             && strcmp (result + strlen (result) - 3, " 33") == 0);
 882     ASSERT (length == strlen (result));
 883     free (result);
 884   }
 885 
 886   /* Test the support of the %f format directive.  */
 887 
 888   { /* A positive number.  */
 889     size_t length;
 890     char *result =
 891       my_asnprintf (NULL, &length, "%f %d", 12.75, 33, 44, 55);
 892     ASSERT (result != NULL);
 893     ASSERT (strcmp (result, "12.750000 33") == 0);
 894     ASSERT (length == strlen (result));
 895     free (result);
 896   }
 897 
 898   { /* A larger positive number.  */
 899     size_t length;
 900     char *result =
 901       my_asnprintf (NULL, &length, "%f %d", 1234567.0, 33, 44, 55);
 902     ASSERT (result != NULL);
 903     ASSERT (strcmp (result, "1234567.000000 33") == 0);
 904     ASSERT (length == strlen (result));
 905     free (result);
 906   }
 907 
 908   { /* Small and large positive numbers.  */
 909     static struct { double value; const char *string; } data[] =
 910       {
 911         { 1.234321234321234e-37, "0.000000" },
 912         { 1.234321234321234e-36, "0.000000" },
 913         { 1.234321234321234e-35, "0.000000" },
 914         { 1.234321234321234e-34, "0.000000" },
 915         { 1.234321234321234e-33, "0.000000" },
 916         { 1.234321234321234e-32, "0.000000" },
 917         { 1.234321234321234e-31, "0.000000" },
 918         { 1.234321234321234e-30, "0.000000" },
 919         { 1.234321234321234e-29, "0.000000" },
 920         { 1.234321234321234e-28, "0.000000" },
 921         { 1.234321234321234e-27, "0.000000" },
 922         { 1.234321234321234e-26, "0.000000" },
 923         { 1.234321234321234e-25, "0.000000" },
 924         { 1.234321234321234e-24, "0.000000" },
 925         { 1.234321234321234e-23, "0.000000" },
 926         { 1.234321234321234e-22, "0.000000" },
 927         { 1.234321234321234e-21, "0.000000" },
 928         { 1.234321234321234e-20, "0.000000" },
 929         { 1.234321234321234e-19, "0.000000" },
 930         { 1.234321234321234e-18, "0.000000" },
 931         { 1.234321234321234e-17, "0.000000" },
 932         { 1.234321234321234e-16, "0.000000" },
 933         { 1.234321234321234e-15, "0.000000" },
 934         { 1.234321234321234e-14, "0.000000" },
 935         { 1.234321234321234e-13, "0.000000" },
 936         { 1.234321234321234e-12, "0.000000" },
 937         { 1.234321234321234e-11, "0.000000" },
 938         { 1.234321234321234e-10, "0.000000" },
 939         { 1.234321234321234e-9, "0.000000" },
 940         { 1.234321234321234e-8, "0.000000" },
 941         { 1.234321234321234e-7, "0.000000" },
 942         { 1.234321234321234e-6, "0.000001" },
 943         { 1.234321234321234e-5, "0.000012" },
 944         { 1.234321234321234e-4, "0.000123" },
 945         { 1.234321234321234e-3, "0.001234" },
 946         { 1.234321234321234e-2, "0.012343" },
 947         { 1.234321234321234e-1, "0.123432" },
 948         { 1.234321234321234, "1.234321" },
 949         { 1.234321234321234e1, "12.343212" },
 950         { 1.234321234321234e2, "123.432123" },
 951         { 1.234321234321234e3, "1234.321234" },
 952         { 1.234321234321234e4, "12343.212343" },
 953         { 1.234321234321234e5, "123432.123432" },
 954         { 1.234321234321234e6, "1234321.234321" },
 955         { 1.234321234321234e7, "12343212.343212" },
 956         { 1.234321234321234e8, "123432123.432123" },
 957         { 1.234321234321234e9, "1234321234.321234" },
 958         { 1.234321234321234e10, "12343212343.2123**" },
 959         { 1.234321234321234e11, "123432123432.123***" },
 960         { 1.234321234321234e12, "1234321234321.23****" },
 961         { 1.234321234321234e13, "12343212343212.3*****" },
 962         { 1.234321234321234e14, "123432123432123.******" },
 963         { 1.234321234321234e15, "1234321234321234.000000" },
 964         { 1.234321234321234e16, "123432123432123**.000000" },
 965         { 1.234321234321234e17, "123432123432123***.000000" },
 966         { 1.234321234321234e18, "123432123432123****.000000" },
 967         { 1.234321234321234e19, "123432123432123*****.000000" },
 968         { 1.234321234321234e20, "123432123432123******.000000" },
 969         { 1.234321234321234e21, "123432123432123*******.000000" },
 970         { 1.234321234321234e22, "123432123432123********.000000" },
 971         { 1.234321234321234e23, "123432123432123*********.000000" },
 972         { 1.234321234321234e24, "123432123432123**********.000000" },
 973         { 1.234321234321234e25, "123432123432123***********.000000" },
 974         { 1.234321234321234e26, "123432123432123************.000000" },
 975         { 1.234321234321234e27, "123432123432123*************.000000" },
 976         { 1.234321234321234e28, "123432123432123**************.000000" },
 977         { 1.234321234321234e29, "123432123432123***************.000000" },
 978         { 1.234321234321234e30, "123432123432123****************.000000" },
 979         { 1.234321234321234e31, "123432123432123*****************.000000" },
 980         { 1.234321234321234e32, "123432123432123******************.000000" },
 981         { 1.234321234321234e33, "123432123432123*******************.000000" },
 982         { 1.234321234321234e34, "123432123432123********************.000000" },
 983         { 1.234321234321234e35, "123432123432123*********************.000000" },
 984         { 1.234321234321234e36, "123432123432123**********************.000000" }
 985       };
 986     size_t k;
 987     for (k = 0; k < SIZEOF (data); k++)
 988       {
 989         size_t length;
 990         char *result =
 991           my_asnprintf (NULL, &length, "%f", data[k].value);
 992         ASSERT (result != NULL);
 993         ASSERT (strmatch (data[k].string, result));
 994         ASSERT (length == strlen (result));
 995         free (result);
 996       }
 997   }
 998 
 999   { /* A negative number.  */
1000     size_t length;
1001     char *result =
1002       my_asnprintf (NULL, &length, "%f %d", -0.03125, 33, 44, 55);
1003     ASSERT (result != NULL);
1004     ASSERT (strcmp (result, "-0.031250 33") == 0);
1005     ASSERT (length == strlen (result));
1006     free (result);
1007   }
1008 
1009   { /* Positive zero.  */
1010     size_t length;
1011     char *result =
1012       my_asnprintf (NULL, &length, "%f %d", 0.0, 33, 44, 55);
1013     ASSERT (result != NULL);
1014     ASSERT (strcmp (result, "0.000000 33") == 0);
1015     ASSERT (length == strlen (result));
1016     free (result);
1017   }
1018 
1019   { /* Negative zero.  */
1020     size_t length;
1021     char *result =
1022       my_asnprintf (NULL, &length, "%f %d", minus_zerod, 33, 44, 55);
1023     ASSERT (result != NULL);
1024     if (have_minus_zero ())
1025       ASSERT (strcmp (result, "-0.000000 33") == 0);
1026     ASSERT (length == strlen (result));
1027     free (result);
1028   }
1029 
1030   { /* Positive infinity.  */
1031     size_t length;
1032     char *result =
1033       my_asnprintf (NULL, &length, "%f %d", Infinityd (), 33, 44, 55);
1034     ASSERT (result != NULL);
1035     ASSERT (strcmp (result, "inf 33") == 0
1036             || strcmp (result, "infinity 33") == 0);
1037     ASSERT (length == strlen (result));
1038     free (result);
1039   }
1040 
1041   { /* Negative infinity.  */
1042     size_t length;
1043     char *result =
1044       my_asnprintf (NULL, &length, "%f %d", - Infinityd (), 33, 44, 55);
1045     ASSERT (result != NULL);
1046     ASSERT (strcmp (result, "-inf 33") == 0
1047             || strcmp (result, "-infinity 33") == 0);
1048     ASSERT (length == strlen (result));
1049     free (result);
1050   }
1051 
1052   { /* NaN.  */
1053     size_t length;
1054     char *result =
1055       my_asnprintf (NULL, &length, "%f %d", NaNd (), 33, 44, 55);
1056     ASSERT (result != NULL);
1057     ASSERT (strlen (result) >= 3 + 3
1058             && strisnan (result, 0, strlen (result) - 3, 0)
1059             && strcmp (result + strlen (result) - 3, " 33") == 0);
1060     ASSERT (length == strlen (result));
1061     free (result);
1062   }
1063 
1064   { /* Width.  */
1065     size_t length;
1066     char *result =
1067       my_asnprintf (NULL, &length, "%10f %d", 1.75, 33, 44, 55);
1068     ASSERT (result != NULL);
1069     ASSERT (strcmp (result, "  1.750000 33") == 0);
1070     ASSERT (length == strlen (result));
1071     free (result);
1072   }
1073 
1074   { /* FLAG_LEFT.  */
1075     size_t length;
1076     char *result =
1077       my_asnprintf (NULL, &length, "%-10f %d", 1.75, 33, 44, 55);
1078     ASSERT (result != NULL);
1079     ASSERT (strcmp (result, "1.750000   33") == 0);
1080     ASSERT (length == strlen (result));
1081     free (result);
1082   }
1083 
1084   { /* FLAG_SHOWSIGN.  */
1085     size_t length;
1086     char *result =
1087       my_asnprintf (NULL, &length, "%+f %d", 1.75, 33, 44, 55);
1088     ASSERT (result != NULL);
1089     ASSERT (strcmp (result, "+1.750000 33") == 0);
1090     ASSERT (length == strlen (result));
1091     free (result);
1092   }
1093 
1094   { /* FLAG_SPACE.  */
1095     size_t length;
1096     char *result =
1097       my_asnprintf (NULL, &length, "% f %d", 1.75, 33, 44, 55);
1098     ASSERT (result != NULL);
1099     ASSERT (strcmp (result, " 1.750000 33") == 0);
1100     ASSERT (length == strlen (result));
1101     free (result);
1102   }
1103 
1104   { /* FLAG_ALT.  */
1105     size_t length;
1106     char *result =
1107       my_asnprintf (NULL, &length, "%#f %d", 1.75, 33, 44, 55);
1108     ASSERT (result != NULL);
1109     ASSERT (strcmp (result, "1.750000 33") == 0);
1110     ASSERT (length == strlen (result));
1111     free (result);
1112   }
1113 
1114   { /* FLAG_ALT.  */
1115     size_t length;
1116     char *result =
1117       my_asnprintf (NULL, &length, "%#.f %d", 1.75, 33, 44, 55);
1118     ASSERT (result != NULL);
1119     ASSERT (strcmp (result, "2. 33") == 0);
1120     ASSERT (length == strlen (result));
1121     free (result);
1122   }
1123 
1124   { /* FLAG_ZERO with finite number.  */
1125     size_t length;
1126     char *result =
1127       my_asnprintf (NULL, &length, "%015f %d", 1234.0, 33, 44, 55);
1128     ASSERT (result != NULL);
1129     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1130     ASSERT (length == strlen (result));
1131     free (result);
1132   }
1133 
1134   { /* FLAG_ZERO with infinite number.  */
1135     size_t length;
1136     char *result =
1137       my_asnprintf (NULL, &length, "%015f %d", - Infinityd (), 33, 44, 55);
1138     ASSERT (result != NULL);
1139     ASSERT (strcmp (result, "           -inf 33") == 0
1140             || strcmp (result, "      -infinity 33") == 0);
1141     ASSERT (length == strlen (result));
1142     free (result);
1143   }
1144 
1145   { /* FLAG_ZERO with NaN.  */
1146     size_t length;
1147     char *result =
1148       my_asnprintf (NULL, &length, "%050f %d", NaNd (), 33, 44, 55);
1149     ASSERT (result != NULL);
1150     ASSERT (strlen (result) == 50 + 3
1151             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1152             && strcmp (result + strlen (result) - 3, " 33") == 0);
1153     ASSERT (length == strlen (result));
1154     free (result);
1155   }
1156 
1157   { /* Precision.  */
1158     size_t length;
1159     char *result =
1160       my_asnprintf (NULL, &length, "%.f %d", 1234.0, 33, 44, 55);
1161     ASSERT (result != NULL);
1162     ASSERT (strcmp (result, "1234 33") == 0);
1163     ASSERT (length == strlen (result));
1164     free (result);
1165   }
1166 
1167   { /* Precision with no rounding.  */
1168     size_t length;
1169     char *result =
1170       my_asnprintf (NULL, &length, "%.2f %d", 999.951, 33, 44, 55);
1171     ASSERT (result != NULL);
1172     ASSERT (strcmp (result, "999.95 33") == 0);
1173     ASSERT (length == strlen (result));
1174     free (result);
1175   }
1176 
1177   { /* Precision with rounding.  */
1178     size_t length;
1179     char *result =
1180       my_asnprintf (NULL, &length, "%.2f %d", 999.996, 33, 44, 55);
1181     ASSERT (result != NULL);
1182     ASSERT (strcmp (result, "1000.00 33") == 0);
1183     ASSERT (length == strlen (result));
1184     free (result);
1185   }
1186 
1187   { /* A positive number.  */
1188     size_t length;
1189     char *result =
1190       my_asnprintf (NULL, &length, "%Lf %d", 12.75L, 33, 44, 55);
1191     ASSERT (result != NULL);
1192     ASSERT (strcmp (result, "12.750000 33") == 0);
1193     ASSERT (length == strlen (result));
1194     free (result);
1195   }
1196 
1197   { /* A larger positive number.  */
1198     size_t length;
1199     char *result =
1200       my_asnprintf (NULL, &length, "%Lf %d", 1234567.0L, 33, 44, 55);
1201     ASSERT (result != NULL);
1202     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1203     ASSERT (length == strlen (result));
1204     free (result);
1205   }
1206 
1207   { /* Small and large positive numbers.  */
1208     static struct { long double value; const char *string; } data[] =
1209       {
1210         { 1.234321234321234e-37L, "0.000000" },
1211         { 1.234321234321234e-36L, "0.000000" },
1212         { 1.234321234321234e-35L, "0.000000" },
1213         { 1.234321234321234e-34L, "0.000000" },
1214         { 1.234321234321234e-33L, "0.000000" },
1215         { 1.234321234321234e-32L, "0.000000" },
1216         { 1.234321234321234e-31L, "0.000000" },
1217         { 1.234321234321234e-30L, "0.000000" },
1218         { 1.234321234321234e-29L, "0.000000" },
1219         { 1.234321234321234e-28L, "0.000000" },
1220         { 1.234321234321234e-27L, "0.000000" },
1221         { 1.234321234321234e-26L, "0.000000" },
1222         { 1.234321234321234e-25L, "0.000000" },
1223         { 1.234321234321234e-24L, "0.000000" },
1224         { 1.234321234321234e-23L, "0.000000" },
1225         { 1.234321234321234e-22L, "0.000000" },
1226         { 1.234321234321234e-21L, "0.000000" },
1227         { 1.234321234321234e-20L, "0.000000" },
1228         { 1.234321234321234e-19L, "0.000000" },
1229         { 1.234321234321234e-18L, "0.000000" },
1230         { 1.234321234321234e-17L, "0.000000" },
1231         { 1.234321234321234e-16L, "0.000000" },
1232         { 1.234321234321234e-15L, "0.000000" },
1233         { 1.234321234321234e-14L, "0.000000" },
1234         { 1.234321234321234e-13L, "0.000000" },
1235         { 1.234321234321234e-12L, "0.000000" },
1236         { 1.234321234321234e-11L, "0.000000" },
1237         { 1.234321234321234e-10L, "0.000000" },
1238         { 1.234321234321234e-9L, "0.000000" },
1239         { 1.234321234321234e-8L, "0.000000" },
1240         { 1.234321234321234e-7L, "0.000000" },
1241         { 1.234321234321234e-6L, "0.000001" },
1242         { 1.234321234321234e-5L, "0.000012" },
1243         { 1.234321234321234e-4L, "0.000123" },
1244         { 1.234321234321234e-3L, "0.001234" },
1245         { 1.234321234321234e-2L, "0.012343" },
1246         { 1.234321234321234e-1L, "0.123432" },
1247         { 1.234321234321234L, "1.234321" },
1248         { 1.234321234321234e1L, "12.343212" },
1249         { 1.234321234321234e2L, "123.432123" },
1250         { 1.234321234321234e3L, "1234.321234" },
1251         { 1.234321234321234e4L, "12343.212343" },
1252         { 1.234321234321234e5L, "123432.123432" },
1253         { 1.234321234321234e6L, "1234321.234321" },
1254         { 1.234321234321234e7L, "12343212.343212" },
1255         { 1.234321234321234e8L, "123432123.432123" },
1256         { 1.234321234321234e9L, "1234321234.321234" },
1257         { 1.234321234321234e10L, "12343212343.2123**" },
1258         { 1.234321234321234e11L, "123432123432.123***" },
1259         { 1.234321234321234e12L, "1234321234321.23****" },
1260         { 1.234321234321234e13L, "12343212343212.3*****" },
1261         { 1.234321234321234e14L, "123432123432123.******" },
1262         { 1.234321234321234e15L, "1234321234321234.000000" },
1263         { 1.234321234321234e16L, "123432123432123**.000000" },
1264         { 1.234321234321234e17L, "123432123432123***.000000" },
1265         { 1.234321234321234e18L, "123432123432123****.000000" },
1266         { 1.234321234321234e19L, "123432123432123*****.000000" },
1267         { 1.234321234321234e20L, "123432123432123******.000000" },
1268         { 1.234321234321234e21L, "123432123432123*******.000000" },
1269         { 1.234321234321234e22L, "123432123432123********.000000" },
1270         { 1.234321234321234e23L, "123432123432123*********.000000" },
1271         { 1.234321234321234e24L, "123432123432123**********.000000" },
1272         { 1.234321234321234e25L, "123432123432123***********.000000" },
1273         { 1.234321234321234e26L, "123432123432123************.000000" },
1274         { 1.234321234321234e27L, "123432123432123*************.000000" },
1275         { 1.234321234321234e28L, "123432123432123**************.000000" },
1276         { 1.234321234321234e29L, "123432123432123***************.000000" },
1277         { 1.234321234321234e30L, "123432123432123****************.000000" },
1278         { 1.234321234321234e31L, "123432123432123*****************.000000" },
1279         { 1.234321234321234e32L, "123432123432123******************.000000" },
1280         { 1.234321234321234e33L, "123432123432123*******************.000000" },
1281         { 1.234321234321234e34L, "123432123432123********************.000000" },
1282         { 1.234321234321234e35L, "123432123432123*********************.000000" },
1283         { 1.234321234321234e36L, "123432123432123**********************.000000" }
1284       };
1285     size_t k;
1286     for (k = 0; k < SIZEOF (data); k++)
1287       {
1288         size_t length;
1289         char *result =
1290           my_asnprintf (NULL, &length, "%Lf", data[k].value);
1291         ASSERT (result != NULL);
1292         ASSERT (strmatch (data[k].string, result));
1293         ASSERT (length == strlen (result));
1294         free (result);
1295       }
1296   }
1297 
1298   { /* A negative number.  */
1299     size_t length;
1300     char *result =
1301       my_asnprintf (NULL, &length, "%Lf %d", -0.03125L, 33, 44, 55);
1302     ASSERT (result != NULL);
1303     ASSERT (strcmp (result, "-0.031250 33") == 0);
1304     ASSERT (length == strlen (result));
1305     free (result);
1306   }
1307 
1308   { /* Positive zero.  */
1309     size_t length;
1310     char *result =
1311       my_asnprintf (NULL, &length, "%Lf %d", 0.0L, 33, 44, 55);
1312     ASSERT (result != NULL);
1313     ASSERT (strcmp (result, "0.000000 33") == 0);
1314     ASSERT (length == strlen (result));
1315     free (result);
1316   }
1317 
1318   { /* Negative zero.  */
1319     size_t length;
1320     char *result =
1321       my_asnprintf (NULL, &length, "%Lf %d", minus_zerol, 33, 44, 55);
1322     ASSERT (result != NULL);
1323     if (have_minus_zero ())
1324       ASSERT (strcmp (result, "-0.000000 33") == 0);
1325     ASSERT (length == strlen (result));
1326     free (result);
1327   }
1328 
1329   { /* Positive infinity.  */
1330     size_t length;
1331     char *result =
1332       my_asnprintf (NULL, &length, "%Lf %d", Infinityl (), 33, 44, 55);
1333     ASSERT (result != NULL);
1334     ASSERT (strcmp (result, "inf 33") == 0
1335             || strcmp (result, "infinity 33") == 0);
1336     ASSERT (length == strlen (result));
1337     free (result);
1338   }
1339 
1340   { /* Negative infinity.  */
1341     size_t length;
1342     char *result =
1343       my_asnprintf (NULL, &length, "%Lf %d", - Infinityl (), 33, 44, 55);
1344     ASSERT (result != NULL);
1345     ASSERT (strcmp (result, "-inf 33") == 0
1346             || strcmp (result, "-infinity 33") == 0);
1347     ASSERT (length == strlen (result));
1348     free (result);
1349   }
1350 
1351   { /* NaN.  */
1352     size_t length;
1353     char *result =
1354       my_asnprintf (NULL, &length, "%Lf %d", NaNl (), 33, 44, 55);
1355     ASSERT (result != NULL);
1356     ASSERT (strlen (result) >= 3 + 3
1357             && strisnan (result, 0, strlen (result) - 3, 0)
1358             && strcmp (result + strlen (result) - 3, " 33") == 0);
1359     ASSERT (length == strlen (result));
1360     free (result);
1361   }
1362 #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_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
1363   { /* Quiet NaN.  */
1364     static union { unsigned int word[4]; long double value; } x =
1365       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
1366     size_t length;
1367     char *result =
1368       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1369     ASSERT (result != NULL);
1370     ASSERT (strlen (result) >= 3 + 3
1371             && strisnan (result, 0, strlen (result) - 3, 0)
1372             && strcmp (result + strlen (result) - 3, " 33") == 0);
1373     ASSERT (length == strlen (result));
1374     free (result);
1375   }
1376   {
1377     /* Signalling NaN.  */
1378     static union { unsigned int word[4]; long double value; } x =
1379       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
1380     size_t length;
1381     char *result =
1382       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1383     ASSERT (result != NULL);
1384     ASSERT (strlen (result) >= 3 + 3
1385             && strisnan (result, 0, strlen (result) - 3, 0)
1386             && strcmp (result + strlen (result) - 3, " 33") == 0);
1387     ASSERT (length == strlen (result));
1388     free (result);
1389   }
1390   /* asnprintf should print something for noncanonical values.  */
1391   { /* Pseudo-NaN.  */
1392     static union { unsigned int word[4]; long double value; } x =
1393       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
1394     size_t length;
1395     char *result =
1396       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1397     ASSERT (result != NULL);
1398     ASSERT (length == strlen (result));
1399     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
1400     free (result);
1401   }
1402   { /* Pseudo-Infinity.  */
1403     static union { unsigned int word[4]; long double value; } x =
1404       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
1405     size_t length;
1406     char *result =
1407       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1408     ASSERT (result != NULL);
1409     ASSERT (length == strlen (result));
1410     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
1411     free (result);
1412   }
1413   { /* Pseudo-Zero.  */
1414     static union { unsigned int word[4]; long double value; } x =
1415       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
1416     size_t length;
1417     char *result =
1418       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1419     ASSERT (result != NULL);
1420     ASSERT (length == strlen (result));
1421     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
1422     free (result);
1423   }
1424   { /* Unnormalized number.  */
1425     static union { unsigned int word[4]; long double value; } x =
1426       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
1427     size_t length;
1428     char *result =
1429       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1430     ASSERT (result != NULL);
1431     ASSERT (length == strlen (result));
1432     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
1433     free (result);
1434   }
1435   { /* Pseudo-Denormal.  */
1436     static union { unsigned int word[4]; long double value; } x =
1437       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
1438     size_t length;
1439     char *result =
1440       my_asnprintf (NULL, &length, "%Lf %d", x.value, 33, 44, 55);
1441     ASSERT (result != NULL);
1442     ASSERT (length == strlen (result));
1443     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
1444     free (result);
1445   }
1446 #endif
1447 
1448   { /* Width.  */
1449     size_t length;
1450     char *result =
1451       my_asnprintf (NULL, &length, "%10Lf %d", 1.75L, 33, 44, 55);
1452     ASSERT (result != NULL);
1453     ASSERT (strcmp (result, "  1.750000 33") == 0);
1454     ASSERT (length == strlen (result));
1455     free (result);
1456   }
1457 
1458   { /* FLAG_LEFT.  */
1459     size_t length;
1460     char *result =
1461       my_asnprintf (NULL, &length, "%-10Lf %d", 1.75L, 33, 44, 55);
1462     ASSERT (result != NULL);
1463     ASSERT (strcmp (result, "1.750000   33") == 0);
1464     ASSERT (length == strlen (result));
1465     free (result);
1466   }
1467 
1468   { /* FLAG_SHOWSIGN.  */
1469     size_t length;
1470     char *result =
1471       my_asnprintf (NULL, &length, "%+Lf %d", 1.75L, 33, 44, 55);
1472     ASSERT (result != NULL);
1473     ASSERT (strcmp (result, "+1.750000 33") == 0);
1474     ASSERT (length == strlen (result));
1475     free (result);
1476   }
1477 
1478   { /* FLAG_SPACE.  */
1479     size_t length;
1480     char *result =
1481       my_asnprintf (NULL, &length, "% Lf %d", 1.75L, 33, 44, 55);
1482     ASSERT (result != NULL);
1483     ASSERT (strcmp (result, " 1.750000 33") == 0);
1484     ASSERT (length == strlen (result));
1485     free (result);
1486   }
1487 
1488   { /* FLAG_ALT.  */
1489     size_t length;
1490     char *result =
1491       my_asnprintf (NULL, &length, "%#Lf %d", 1.75L, 33, 44, 55);
1492     ASSERT (result != NULL);
1493     ASSERT (strcmp (result, "1.750000 33") == 0);
1494     ASSERT (length == strlen (result));
1495     free (result);
1496   }
1497 
1498   { /* FLAG_ALT.  */
1499     size_t length;
1500     char *result =
1501       my_asnprintf (NULL, &length, "%#.Lf %d", 1.75L, 33, 44, 55);
1502     ASSERT (result != NULL);
1503     ASSERT (strcmp (result, "2. 33") == 0);
1504     ASSERT (length == strlen (result));
1505     free (result);
1506   }
1507 
1508   { /* FLAG_ZERO with finite number.  */
1509     size_t length;
1510     char *result =
1511       my_asnprintf (NULL, &length, "%015Lf %d", 1234.0L, 33, 44, 55);
1512     ASSERT (result != NULL);
1513     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1514     ASSERT (length == strlen (result));
1515     free (result);
1516   }
1517 
1518   { /* FLAG_ZERO with infinite number.  */
1519     size_t length;
1520     char *result =
1521       my_asnprintf (NULL, &length, "%015Lf %d", - Infinityl (), 33, 44, 55);
1522     ASSERT (result != NULL);
1523     ASSERT (strcmp (result, "           -inf 33") == 0
1524             || strcmp (result, "      -infinity 33") == 0);
1525     ASSERT (length == strlen (result));
1526     free (result);
1527   }
1528 
1529   { /* FLAG_ZERO with NaN.  */
1530     size_t length;
1531     char *result =
1532       my_asnprintf (NULL, &length, "%050Lf %d", NaNl (), 33, 44, 55);
1533     ASSERT (result != NULL);
1534     ASSERT (strlen (result) == 50 + 3
1535             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1536             && strcmp (result + strlen (result) - 3, " 33") == 0);
1537     ASSERT (length == strlen (result));
1538     free (result);
1539   }
1540 
1541   { /* Precision.  */
1542     size_t length;
1543     char *result =
1544       my_asnprintf (NULL, &length, "%.Lf %d", 1234.0L, 33, 44, 55);
1545     ASSERT (result != NULL);
1546     ASSERT (strcmp (result, "1234 33") == 0);
1547     ASSERT (length == strlen (result));
1548     free (result);
1549   }
1550 
1551   { /* Precision with no rounding.  */
1552     size_t length;
1553     char *result =
1554       my_asnprintf (NULL, &length, "%.2Lf %d", 999.951L, 33, 44, 55);
1555     ASSERT (result != NULL);
1556     ASSERT (strcmp (result, "999.95 33") == 0);
1557     ASSERT (length == strlen (result));
1558     free (result);
1559   }
1560 
1561   { /* Precision with rounding.  */
1562     size_t length;
1563     char *result =
1564       my_asnprintf (NULL, &length, "%.2Lf %d", 999.996L, 33, 44, 55);
1565     ASSERT (result != NULL);
1566     ASSERT (strcmp (result, "1000.00 33") == 0);
1567     ASSERT (length == strlen (result));
1568     free (result);
1569   }
1570 
1571   /* Test the support of the %F format directive.  */
1572 
1573   { /* A positive number.  */
1574     size_t length;
1575     char *result =
1576       my_asnprintf (NULL, &length, "%F %d", 12.75, 33, 44, 55);
1577     ASSERT (result != NULL);
1578     ASSERT (strcmp (result, "12.750000 33") == 0);
1579     ASSERT (length == strlen (result));
1580     free (result);
1581   }
1582 
1583   { /* A larger positive number.  */
1584     size_t length;
1585     char *result =
1586       my_asnprintf (NULL, &length, "%F %d", 1234567.0, 33, 44, 55);
1587     ASSERT (result != NULL);
1588     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1589     ASSERT (length == strlen (result));
1590     free (result);
1591   }
1592 
1593   { /* A negative number.  */
1594     size_t length;
1595     char *result =
1596       my_asnprintf (NULL, &length, "%F %d", -0.03125, 33, 44, 55);
1597     ASSERT (result != NULL);
1598     ASSERT (strcmp (result, "-0.031250 33") == 0);
1599     ASSERT (length == strlen (result));
1600     free (result);
1601   }
1602 
1603   { /* Positive zero.  */
1604     size_t length;
1605     char *result =
1606       my_asnprintf (NULL, &length, "%F %d", 0.0, 33, 44, 55);
1607     ASSERT (result != NULL);
1608     ASSERT (strcmp (result, "0.000000 33") == 0);
1609     ASSERT (length == strlen (result));
1610     free (result);
1611   }
1612 
1613   { /* Negative zero.  */
1614     size_t length;
1615     char *result =
1616       my_asnprintf (NULL, &length, "%F %d", minus_zerod, 33, 44, 55);
1617     ASSERT (result != NULL);
1618     if (have_minus_zero ())
1619       ASSERT (strcmp (result, "-0.000000 33") == 0);
1620     ASSERT (length == strlen (result));
1621     free (result);
1622   }
1623 
1624   { /* Positive infinity.  */
1625     size_t length;
1626     char *result =
1627       my_asnprintf (NULL, &length, "%F %d", Infinityd (), 33, 44, 55);
1628     ASSERT (result != NULL);
1629     ASSERT (strcmp (result, "INF 33") == 0
1630             || strcmp (result, "INFINITY 33") == 0);
1631     ASSERT (length == strlen (result));
1632     free (result);
1633   }
1634 
1635   { /* Negative infinity.  */
1636     size_t length;
1637     char *result =
1638       my_asnprintf (NULL, &length, "%F %d", - Infinityd (), 33, 44, 55);
1639     ASSERT (result != NULL);
1640     ASSERT (strcmp (result, "-INF 33") == 0
1641             || strcmp (result, "-INFINITY 33") == 0);
1642     ASSERT (length == strlen (result));
1643     free (result);
1644   }
1645 
1646   { /* NaN.  */
1647     size_t length;
1648     char *result =
1649       my_asnprintf (NULL, &length, "%F %d", NaNd (), 33, 44, 55);
1650     ASSERT (result != NULL);
1651     ASSERT (strlen (result) >= 3 + 3
1652             && strisnan (result, 0, strlen (result) - 3, 1)
1653             && strcmp (result + strlen (result) - 3, " 33") == 0);
1654     ASSERT (length == strlen (result));
1655     free (result);
1656   }
1657 
1658   { /* FLAG_ZERO.  */
1659     size_t length;
1660     char *result =
1661       my_asnprintf (NULL, &length, "%015F %d", 1234.0, 33, 44, 55);
1662     ASSERT (result != NULL);
1663     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1664     ASSERT (length == strlen (result));
1665     free (result);
1666   }
1667 
1668   { /* FLAG_ZERO with infinite number.  */
1669     size_t length;
1670     char *result =
1671       my_asnprintf (NULL, &length, "%015F %d", - Infinityd (), 33, 44, 55);
1672     ASSERT (result != NULL);
1673     ASSERT (strcmp (result, "           -INF 33") == 0
1674             || strcmp (result, "      -INFINITY 33") == 0);
1675     ASSERT (length == strlen (result));
1676     free (result);
1677   }
1678 
1679   { /* Precision.  */
1680     size_t length;
1681     char *result =
1682       my_asnprintf (NULL, &length, "%.F %d", 1234.0, 33, 44, 55);
1683     ASSERT (result != NULL);
1684     ASSERT (strcmp (result, "1234 33") == 0);
1685     ASSERT (length == strlen (result));
1686     free (result);
1687   }
1688 
1689   { /* Precision with no rounding.  */
1690     size_t length;
1691     char *result =
1692       my_asnprintf (NULL, &length, "%.2F %d", 999.951, 33, 44, 55);
1693     ASSERT (result != NULL);
1694     ASSERT (strcmp (result, "999.95 33") == 0);
1695     ASSERT (length == strlen (result));
1696     free (result);
1697   }
1698 
1699   { /* Precision with rounding.  */
1700     size_t length;
1701     char *result =
1702       my_asnprintf (NULL, &length, "%.2F %d", 999.996, 33, 44, 55);
1703     ASSERT (result != NULL);
1704     ASSERT (strcmp (result, "1000.00 33") == 0);
1705     ASSERT (length == strlen (result));
1706     free (result);
1707   }
1708 
1709   { /* A positive number.  */
1710     size_t length;
1711     char *result =
1712       my_asnprintf (NULL, &length, "%LF %d", 12.75L, 33, 44, 55);
1713     ASSERT (result != NULL);
1714     ASSERT (strcmp (result, "12.750000 33") == 0);
1715     ASSERT (length == strlen (result));
1716     free (result);
1717   }
1718 
1719   { /* A larger positive number.  */
1720     size_t length;
1721     char *result =
1722       my_asnprintf (NULL, &length, "%LF %d", 1234567.0L, 33, 44, 55);
1723     ASSERT (result != NULL);
1724     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1725     ASSERT (length == strlen (result));
1726     free (result);
1727   }
1728 
1729   { /* A negative number.  */
1730     size_t length;
1731     char *result =
1732       my_asnprintf (NULL, &length, "%LF %d", -0.03125L, 33, 44, 55);
1733     ASSERT (result != NULL);
1734     ASSERT (strcmp (result, "-0.031250 33") == 0);
1735     ASSERT (length == strlen (result));
1736     free (result);
1737   }
1738 
1739   { /* Positive zero.  */
1740     size_t length;
1741     char *result =
1742       my_asnprintf (NULL, &length, "%LF %d", 0.0L, 33, 44, 55);
1743     ASSERT (result != NULL);
1744     ASSERT (strcmp (result, "0.000000 33") == 0);
1745     ASSERT (length == strlen (result));
1746     free (result);
1747   }
1748 
1749   { /* Negative zero.  */
1750     size_t length;
1751     char *result =
1752       my_asnprintf (NULL, &length, "%LF %d", minus_zerol, 33, 44, 55);
1753     ASSERT (result != NULL);
1754     if (have_minus_zero ())
1755       ASSERT (strcmp (result, "-0.000000 33") == 0);
1756     ASSERT (length == strlen (result));
1757     free (result);
1758   }
1759 
1760   { /* Positive infinity.  */
1761     size_t length;
1762     char *result =
1763       my_asnprintf (NULL, &length, "%LF %d", Infinityl (), 33, 44, 55);
1764     ASSERT (result != NULL);
1765     ASSERT (strcmp (result, "INF 33") == 0
1766             || strcmp (result, "INFINITY 33") == 0);
1767     ASSERT (length == strlen (result));
1768     free (result);
1769   }
1770 
1771   { /* Negative infinity.  */
1772     size_t length;
1773     char *result =
1774       my_asnprintf (NULL, &length, "%LF %d", - Infinityl (), 33, 44, 55);
1775     ASSERT (result != NULL);
1776     ASSERT (strcmp (result, "-INF 33") == 0
1777             || strcmp (result, "-INFINITY 33") == 0);
1778     ASSERT (length == strlen (result));
1779     free (result);
1780   }
1781 
1782   { /* NaN.  */
1783     size_t length;
1784     char *result =
1785       my_asnprintf (NULL, &length, "%LF %d", NaNl (), 33, 44, 55);
1786     ASSERT (result != NULL);
1787     ASSERT (strlen (result) >= 3 + 3
1788             && strisnan (result, 0, strlen (result) - 3, 1)
1789             && strcmp (result + strlen (result) - 3, " 33") == 0);
1790     ASSERT (length == strlen (result));
1791     free (result);
1792   }
1793 
1794   { /* FLAG_ZERO.  */
1795     size_t length;
1796     char *result =
1797       my_asnprintf (NULL, &length, "%015LF %d", 1234.0L, 33, 44, 55);
1798     ASSERT (result != NULL);
1799     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1800     ASSERT (length == strlen (result));
1801     free (result);
1802   }
1803 
1804   { /* FLAG_ZERO with infinite number.  */
1805     size_t length;
1806     char *result =
1807       my_asnprintf (NULL, &length, "%015LF %d", - Infinityl (), 33, 44, 55);
1808     ASSERT (result != NULL);
1809     ASSERT (strcmp (result, "           -INF 33") == 0
1810             || strcmp (result, "      -INFINITY 33") == 0);
1811     ASSERT (length == strlen (result));
1812     free (result);
1813   }
1814 
1815   { /* Precision.  */
1816     size_t length;
1817     char *result =
1818       my_asnprintf (NULL, &length, "%.LF %d", 1234.0L, 33, 44, 55);
1819     ASSERT (result != NULL);
1820     ASSERT (strcmp (result, "1234 33") == 0);
1821     ASSERT (length == strlen (result));
1822     free (result);
1823   }
1824 
1825   { /* Precision with no rounding.  */
1826     size_t length;
1827     char *result =
1828       my_asnprintf (NULL, &length, "%.2LF %d", 999.951L, 33, 44, 55);
1829     ASSERT (result != NULL);
1830     ASSERT (strcmp (result, "999.95 33") == 0);
1831     ASSERT (length == strlen (result));
1832     free (result);
1833   }
1834 
1835   { /* Precision with rounding.  */
1836     size_t length;
1837     char *result =
1838       my_asnprintf (NULL, &length, "%.2LF %d", 999.996L, 33, 44, 55);
1839     ASSERT (result != NULL);
1840     ASSERT (strcmp (result, "1000.00 33") == 0);
1841     ASSERT (length == strlen (result));
1842     free (result);
1843   }
1844 
1845   /* Test the support of the %e format directive.  */
1846 
1847   { /* A positive number.  */
1848     size_t length;
1849     char *result =
1850       my_asnprintf (NULL, &length, "%e %d", 12.75, 33, 44, 55);
1851     ASSERT (result != NULL);
1852     ASSERT (strcmp (result, "1.275000e+01 33") == 0
1853             || strcmp (result, "1.275000e+001 33") == 0);
1854     ASSERT (length == strlen (result));
1855     free (result);
1856   }
1857 
1858   { /* A larger positive number.  */
1859     size_t length;
1860     char *result =
1861       my_asnprintf (NULL, &length, "%e %d", 1234567.0, 33, 44, 55);
1862     ASSERT (result != NULL);
1863     ASSERT (strcmp (result, "1.234567e+06 33") == 0
1864             || strcmp (result, "1.234567e+006 33") == 0);
1865     ASSERT (length == strlen (result));
1866     free (result);
1867   }
1868 
1869   { /* Small and large positive numbers.  */
1870     static struct { double value; const char *string; } data[] =
1871       {
1872         { 1.234321234321234e-37, "1.234321e-37" },
1873         { 1.234321234321234e-36, "1.234321e-36" },
1874         { 1.234321234321234e-35, "1.234321e-35" },
1875         { 1.234321234321234e-34, "1.234321e-34" },
1876         { 1.234321234321234e-33, "1.234321e-33" },
1877         { 1.234321234321234e-32, "1.234321e-32" },
1878         { 1.234321234321234e-31, "1.234321e-31" },
1879         { 1.234321234321234e-30, "1.234321e-30" },
1880         { 1.234321234321234e-29, "1.234321e-29" },
1881         { 1.234321234321234e-28, "1.234321e-28" },
1882         { 1.234321234321234e-27, "1.234321e-27" },
1883         { 1.234321234321234e-26, "1.234321e-26" },
1884         { 1.234321234321234e-25, "1.234321e-25" },
1885         { 1.234321234321234e-24, "1.234321e-24" },
1886         { 1.234321234321234e-23, "1.234321e-23" },
1887         { 1.234321234321234e-22, "1.234321e-22" },
1888         { 1.234321234321234e-21, "1.234321e-21" },
1889         { 1.234321234321234e-20, "1.234321e-20" },
1890         { 1.234321234321234e-19, "1.234321e-19" },
1891         { 1.234321234321234e-18, "1.234321e-18" },
1892         { 1.234321234321234e-17, "1.234321e-17" },
1893         { 1.234321234321234e-16, "1.234321e-16" },
1894         { 1.234321234321234e-15, "1.234321e-15" },
1895         { 1.234321234321234e-14, "1.234321e-14" },
1896         { 1.234321234321234e-13, "1.234321e-13" },
1897         { 1.234321234321234e-12, "1.234321e-12" },
1898         { 1.234321234321234e-11, "1.234321e-11" },
1899         { 1.234321234321234e-10, "1.234321e-10" },
1900         { 1.234321234321234e-9, "1.234321e-09" },
1901         { 1.234321234321234e-8, "1.234321e-08" },
1902         { 1.234321234321234e-7, "1.234321e-07" },
1903         { 1.234321234321234e-6, "1.234321e-06" },
1904         { 1.234321234321234e-5, "1.234321e-05" },
1905         { 1.234321234321234e-4, "1.234321e-04" },
1906         { 1.234321234321234e-3, "1.234321e-03" },
1907         { 1.234321234321234e-2, "1.234321e-02" },
1908         { 1.234321234321234e-1, "1.234321e-01" },
1909         { 1.234321234321234, "1.234321e+00" },
1910         { 1.234321234321234e1, "1.234321e+01" },
1911         { 1.234321234321234e2, "1.234321e+02" },
1912         { 1.234321234321234e3, "1.234321e+03" },
1913         { 1.234321234321234e4, "1.234321e+04" },
1914         { 1.234321234321234e5, "1.234321e+05" },
1915         { 1.234321234321234e6, "1.234321e+06" },
1916         { 1.234321234321234e7, "1.234321e+07" },
1917         { 1.234321234321234e8, "1.234321e+08" },
1918         { 1.234321234321234e9, "1.234321e+09" },
1919         { 1.234321234321234e10, "1.234321e+10" },
1920         { 1.234321234321234e11, "1.234321e+11" },
1921         { 1.234321234321234e12, "1.234321e+12" },
1922         { 1.234321234321234e13, "1.234321e+13" },
1923         { 1.234321234321234e14, "1.234321e+14" },
1924         { 1.234321234321234e15, "1.234321e+15" },
1925         { 1.234321234321234e16, "1.234321e+16" },
1926         { 1.234321234321234e17, "1.234321e+17" },
1927         { 1.234321234321234e18, "1.234321e+18" },
1928         { 1.234321234321234e19, "1.234321e+19" },
1929         { 1.234321234321234e20, "1.234321e+20" },
1930         { 1.234321234321234e21, "1.234321e+21" },
1931         { 1.234321234321234e22, "1.234321e+22" },
1932         { 1.234321234321234e23, "1.234321e+23" },
1933         { 1.234321234321234e24, "1.234321e+24" },
1934         { 1.234321234321234e25, "1.234321e+25" },
1935         { 1.234321234321234e26, "1.234321e+26" },
1936         { 1.234321234321234e27, "1.234321e+27" },
1937         { 1.234321234321234e28, "1.234321e+28" },
1938         { 1.234321234321234e29, "1.234321e+29" },
1939         { 1.234321234321234e30, "1.234321e+30" },
1940         { 1.234321234321234e31, "1.234321e+31" },
1941         { 1.234321234321234e32, "1.234321e+32" },
1942         { 1.234321234321234e33, "1.234321e+33" },
1943         { 1.234321234321234e34, "1.234321e+34" },
1944         { 1.234321234321234e35, "1.234321e+35" },
1945         { 1.234321234321234e36, "1.234321e+36" }
1946       };
1947     size_t k;
1948     for (k = 0; k < SIZEOF (data); k++)
1949       {
1950         size_t length;
1951         char *result =
1952           my_asnprintf (NULL, &length, "%e", data[k].value);
1953         const char *expected = data[k].string;
1954         ASSERT (result != NULL);
1955         ASSERT (strcmp (result, expected) == 0
1956                 /* Some implementations produce exponents with 3 digits.  */
1957                 || (strlen (result) == strlen (expected) + 1
1958                     && memcmp (result, expected, strlen (expected) - 2) == 0
1959                     && result[strlen (expected) - 2] == '0'
1960                     && strcmp (result + strlen (expected) - 1,
1961                                expected + strlen (expected) - 2)
1962                        == 0));
1963         ASSERT (length == strlen (result));
1964         free (result);
1965       }
1966   }
1967 
1968   { /* A negative number.  */
1969     size_t length;
1970     char *result =
1971       my_asnprintf (NULL, &length, "%e %d", -0.03125, 33, 44, 55);
1972     ASSERT (result != NULL);
1973     ASSERT (strcmp (result, "-3.125000e-02 33") == 0
1974             || strcmp (result, "-3.125000e-002 33") == 0);
1975     ASSERT (length == strlen (result));
1976     free (result);
1977   }
1978 
1979   { /* Positive zero.  */
1980     size_t length;
1981     char *result =
1982       my_asnprintf (NULL, &length, "%e %d", 0.0, 33, 44, 55);
1983     ASSERT (result != NULL);
1984     ASSERT (strcmp (result, "0.000000e+00 33") == 0
1985             || strcmp (result, "0.000000e+000 33") == 0);
1986     ASSERT (length == strlen (result));
1987     free (result);
1988   }
1989 
1990   { /* Negative zero.  */
1991     size_t length;
1992     char *result =
1993       my_asnprintf (NULL, &length, "%e %d", minus_zerod, 33, 44, 55);
1994     ASSERT (result != NULL);
1995     if (have_minus_zero ())
1996       ASSERT (strcmp (result, "-0.000000e+00 33") == 0
1997               || strcmp (result, "-0.000000e+000 33") == 0);
1998     ASSERT (length == strlen (result));
1999     free (result);
2000   }
2001 
2002   { /* Positive infinity.  */
2003     size_t length;
2004     char *result =
2005       my_asnprintf (NULL, &length, "%e %d", Infinityd (), 33, 44, 55);
2006     ASSERT (result != NULL);
2007     ASSERT (strcmp (result, "inf 33") == 0
2008             || strcmp (result, "infinity 33") == 0);
2009     ASSERT (length == strlen (result));
2010     free (result);
2011   }
2012 
2013   { /* Negative infinity.  */
2014     size_t length;
2015     char *result =
2016       my_asnprintf (NULL, &length, "%e %d", - Infinityd (), 33, 44, 55);
2017     ASSERT (result != NULL);
2018     ASSERT (strcmp (result, "-inf 33") == 0
2019             || strcmp (result, "-infinity 33") == 0);
2020     ASSERT (length == strlen (result));
2021     free (result);
2022   }
2023 
2024   { /* NaN.  */
2025     size_t length;
2026     char *result =
2027       my_asnprintf (NULL, &length, "%e %d", NaNd (), 33, 44, 55);
2028     ASSERT (result != NULL);
2029     ASSERT (strlen (result) >= 3 + 3
2030             && strisnan (result, 0, strlen (result) - 3, 0)
2031             && strcmp (result + strlen (result) - 3, " 33") == 0);
2032     ASSERT (length == strlen (result));
2033     free (result);
2034   }
2035 
2036   { /* Width.  */
2037     size_t length;
2038     char *result =
2039       my_asnprintf (NULL, &length, "%15e %d", 1.75, 33, 44, 55);
2040     ASSERT (result != NULL);
2041     ASSERT (strcmp (result, "   1.750000e+00 33") == 0
2042             || strcmp (result, "  1.750000e+000 33") == 0);
2043     ASSERT (length == strlen (result));
2044     free (result);
2045   }
2046 
2047   { /* FLAG_LEFT.  */
2048     size_t length;
2049     char *result =
2050       my_asnprintf (NULL, &length, "%-15e %d", 1.75, 33, 44, 55);
2051     ASSERT (result != NULL);
2052     ASSERT (strcmp (result, "1.750000e+00    33") == 0
2053             || strcmp (result, "1.750000e+000   33") == 0);
2054     ASSERT (length == strlen (result));
2055     free (result);
2056   }
2057 
2058   { /* FLAG_SHOWSIGN.  */
2059     size_t length;
2060     char *result =
2061       my_asnprintf (NULL, &length, "%+e %d", 1.75, 33, 44, 55);
2062     ASSERT (result != NULL);
2063     ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2064             || strcmp (result, "+1.750000e+000 33") == 0);
2065     ASSERT (length == strlen (result));
2066     free (result);
2067   }
2068 
2069   { /* FLAG_SPACE.  */
2070     size_t length;
2071     char *result =
2072       my_asnprintf (NULL, &length, "% e %d", 1.75, 33, 44, 55);
2073     ASSERT (result != NULL);
2074     ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2075             || strcmp (result, " 1.750000e+000 33") == 0);
2076     ASSERT (length == strlen (result));
2077     free (result);
2078   }
2079 
2080   { /* FLAG_ALT.  */
2081     size_t length;
2082     char *result =
2083       my_asnprintf (NULL, &length, "%#e %d", 1.75, 33, 44, 55);
2084     ASSERT (result != NULL);
2085     ASSERT (strcmp (result, "1.750000e+00 33") == 0
2086             || strcmp (result, "1.750000e+000 33") == 0);
2087     ASSERT (length == strlen (result));
2088     free (result);
2089   }
2090 
2091   { /* FLAG_ALT.  */
2092     size_t length;
2093     char *result =
2094       my_asnprintf (NULL, &length, "%#.e %d", 1.75, 33, 44, 55);
2095     ASSERT (result != NULL);
2096     ASSERT (strcmp (result, "2.e+00 33") == 0
2097             || strcmp (result, "2.e+000 33") == 0);
2098     ASSERT (length == strlen (result));
2099     free (result);
2100   }
2101 
2102   { /* FLAG_ALT.  */
2103     size_t length;
2104     char *result =
2105       my_asnprintf (NULL, &length, "%#.e %d", 9.75, 33, 44, 55);
2106     ASSERT (result != NULL);
2107     ASSERT (strcmp (result, "1.e+01 33") == 0
2108             || strcmp (result, "1.e+001 33") == 0);
2109     ASSERT (length == strlen (result));
2110     free (result);
2111   }
2112 
2113   { /* FLAG_ZERO with finite number.  */
2114     size_t length;
2115     char *result =
2116       my_asnprintf (NULL, &length, "%015e %d", 1234.0, 33, 44, 55);
2117     ASSERT (result != NULL);
2118     ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2119             || strcmp (result, "001.234000e+003 33") == 0);
2120     ASSERT (length == strlen (result));
2121     free (result);
2122   }
2123 
2124   { /* FLAG_ZERO with infinite number.  */
2125     size_t length;
2126     char *result =
2127       my_asnprintf (NULL, &length, "%015e %d", - Infinityd (), 33, 44, 55);
2128     ASSERT (result != NULL);
2129     ASSERT (strcmp (result, "           -inf 33") == 0
2130             || strcmp (result, "      -infinity 33") == 0);
2131     ASSERT (length == strlen (result));
2132     free (result);
2133   }
2134 
2135   { /* FLAG_ZERO with NaN.  */
2136     size_t length;
2137     char *result =
2138       my_asnprintf (NULL, &length, "%050e %d", NaNd (), 33, 44, 55);
2139     ASSERT (result != NULL);
2140     ASSERT (strlen (result) == 50 + 3
2141             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2142             && strcmp (result + strlen (result) - 3, " 33") == 0);
2143     ASSERT (length == strlen (result));
2144     free (result);
2145   }
2146 
2147   { /* Precision.  */
2148     size_t length;
2149     char *result =
2150       my_asnprintf (NULL, &length, "%.e %d", 1234.0, 33, 44, 55);
2151     ASSERT (result != NULL);
2152     ASSERT (strcmp (result, "1e+03 33") == 0
2153             || strcmp (result, "1e+003 33") == 0);
2154     ASSERT (length == strlen (result));
2155     free (result);
2156   }
2157 
2158   { /* Precision with no rounding.  */
2159     size_t length;
2160     char *result =
2161       my_asnprintf (NULL, &length, "%.4e %d", 999.951, 33, 44, 55);
2162     ASSERT (result != NULL);
2163     ASSERT (strcmp (result, "9.9995e+02 33") == 0
2164             || strcmp (result, "9.9995e+002 33") == 0);
2165     ASSERT (length == strlen (result));
2166     free (result);
2167   }
2168 
2169   { /* Precision with rounding.  */
2170     size_t length;
2171     char *result =
2172       my_asnprintf (NULL, &length, "%.4e %d", 999.996, 33, 44, 55);
2173     ASSERT (result != NULL);
2174     ASSERT (strcmp (result, "1.0000e+03 33") == 0
2175             || strcmp (result, "1.0000e+003 33") == 0);
2176     ASSERT (length == strlen (result));
2177     free (result);
2178   }
2179 
2180   { /* A positive number.  */
2181     size_t length;
2182     char *result =
2183       my_asnprintf (NULL, &length, "%Le %d", 12.75L, 33, 44, 55);
2184     ASSERT (result != NULL);
2185     ASSERT (strcmp (result, "1.275000e+01 33") == 0
2186             || strcmp (result, "1.275000e+001 33") == 0);
2187     ASSERT (length == strlen (result));
2188     free (result);
2189   }
2190 
2191   { /* A larger positive number.  */
2192     size_t length;
2193     char *result =
2194       my_asnprintf (NULL, &length, "%Le %d", 1234567.0L, 33, 44, 55);
2195     ASSERT (result != NULL);
2196     ASSERT (strcmp (result, "1.234567e+06 33") == 0
2197             || strcmp (result, "1.234567e+006 33") == 0);
2198     ASSERT (length == strlen (result));
2199     free (result);
2200   }
2201 
2202   { /* Small and large positive numbers.  */
2203     static struct { long double value; const char *string; } data[] =
2204       {
2205         { 1.234321234321234e-37L, "1.234321e-37" },
2206         { 1.234321234321234e-36L, "1.234321e-36" },
2207         { 1.234321234321234e-35L, "1.234321e-35" },
2208         { 1.234321234321234e-34L, "1.234321e-34" },
2209         { 1.234321234321234e-33L, "1.234321e-33" },
2210         { 1.234321234321234e-32L, "1.234321e-32" },
2211         { 1.234321234321234e-31L, "1.234321e-31" },
2212         { 1.234321234321234e-30L, "1.234321e-30" },
2213         { 1.234321234321234e-29L, "1.234321e-29" },
2214         { 1.234321234321234e-28L, "1.234321e-28" },
2215         { 1.234321234321234e-27L, "1.234321e-27" },
2216         { 1.234321234321234e-26L, "1.234321e-26" },
2217         { 1.234321234321234e-25L, "1.234321e-25" },
2218         { 1.234321234321234e-24L, "1.234321e-24" },
2219         { 1.234321234321234e-23L, "1.234321e-23" },
2220         { 1.234321234321234e-22L, "1.234321e-22" },
2221         { 1.234321234321234e-21L, "1.234321e-21" },
2222         { 1.234321234321234e-20L, "1.234321e-20" },
2223         { 1.234321234321234e-19L, "1.234321e-19" },
2224         { 1.234321234321234e-18L, "1.234321e-18" },
2225         { 1.234321234321234e-17L, "1.234321e-17" },
2226         { 1.234321234321234e-16L, "1.234321e-16" },
2227         { 1.234321234321234e-15L, "1.234321e-15" },
2228         { 1.234321234321234e-14L, "1.234321e-14" },
2229         { 1.234321234321234e-13L, "1.234321e-13" },
2230         { 1.234321234321234e-12L, "1.234321e-12" },
2231         { 1.234321234321234e-11L, "1.234321e-11" },
2232         { 1.234321234321234e-10L, "1.234321e-10" },
2233         { 1.234321234321234e-9L, "1.234321e-09" },
2234         { 1.234321234321234e-8L, "1.234321e-08" },
2235         { 1.234321234321234e-7L, "1.234321e-07" },
2236         { 1.234321234321234e-6L, "1.234321e-06" },
2237         { 1.234321234321234e-5L, "1.234321e-05" },
2238         { 1.234321234321234e-4L, "1.234321e-04" },
2239         { 1.234321234321234e-3L, "1.234321e-03" },
2240         { 1.234321234321234e-2L, "1.234321e-02" },
2241         { 1.234321234321234e-1L, "1.234321e-01" },
2242         { 1.234321234321234L, "1.234321e+00" },
2243         { 1.234321234321234e1L, "1.234321e+01" },
2244         { 1.234321234321234e2L, "1.234321e+02" },
2245         { 1.234321234321234e3L, "1.234321e+03" },
2246         { 1.234321234321234e4L, "1.234321e+04" },
2247         { 1.234321234321234e5L, "1.234321e+05" },
2248         { 1.234321234321234e6L, "1.234321e+06" },
2249         { 1.234321234321234e7L, "1.234321e+07" },
2250         { 1.234321234321234e8L, "1.234321e+08" },
2251         { 1.234321234321234e9L, "1.234321e+09" },
2252         { 1.234321234321234e10L, "1.234321e+10" },
2253         { 1.234321234321234e11L, "1.234321e+11" },
2254         { 1.234321234321234e12L, "1.234321e+12" },
2255         { 1.234321234321234e13L, "1.234321e+13" },
2256         { 1.234321234321234e14L, "1.234321e+14" },
2257         { 1.234321234321234e15L, "1.234321e+15" },
2258         { 1.234321234321234e16L, "1.234321e+16" },
2259         { 1.234321234321234e17L, "1.234321e+17" },
2260         { 1.234321234321234e18L, "1.234321e+18" },
2261         { 1.234321234321234e19L, "1.234321e+19" },
2262         { 1.234321234321234e20L, "1.234321e+20" },
2263         { 1.234321234321234e21L, "1.234321e+21" },
2264         { 1.234321234321234e22L, "1.234321e+22" },
2265         { 1.234321234321234e23L, "1.234321e+23" },
2266         { 1.234321234321234e24L, "1.234321e+24" },
2267         { 1.234321234321234e25L, "1.234321e+25" },
2268         { 1.234321234321234e26L, "1.234321e+26" },
2269         { 1.234321234321234e27L, "1.234321e+27" },
2270         { 1.234321234321234e28L, "1.234321e+28" },
2271         { 1.234321234321234e29L, "1.234321e+29" },
2272         { 1.234321234321234e30L, "1.234321e+30" },
2273         { 1.234321234321234e31L, "1.234321e+31" },
2274         { 1.234321234321234e32L, "1.234321e+32" },
2275         { 1.234321234321234e33L, "1.234321e+33" },
2276         { 1.234321234321234e34L, "1.234321e+34" },
2277         { 1.234321234321234e35L, "1.234321e+35" },
2278         { 1.234321234321234e36L, "1.234321e+36" }
2279       };
2280     size_t k;
2281     for (k = 0; k < SIZEOF (data); k++)
2282       {
2283         size_t length;
2284         char *result =
2285           my_asnprintf (NULL, &length, "%Le", data[k].value);
2286         const char *expected = data[k].string;
2287         ASSERT (result != NULL);
2288         ASSERT (strcmp (result, expected) == 0
2289                 /* Some implementations produce exponents with 3 digits.  */
2290                 || (strlen (result) == strlen (expected) + 1
2291                     && memcmp (result, expected, strlen (expected) - 2) == 0
2292                     && result[strlen (expected) - 2] == '0'
2293                     && strcmp (result + strlen (expected) - 1,
2294                                expected + strlen (expected) - 2)
2295                        == 0));
2296         ASSERT (length == strlen (result));
2297         free (result);
2298       }
2299   }
2300 
2301   { /* A negative number.  */
2302     size_t length;
2303     char *result =
2304       my_asnprintf (NULL, &length, "%Le %d", -0.03125L, 33, 44, 55);
2305     ASSERT (result != NULL);
2306     ASSERT (strcmp (result, "-3.125000e-02 33") == 0
2307             || strcmp (result, "-3.125000e-002 33") == 0);
2308     ASSERT (length == strlen (result));
2309     free (result);
2310   }
2311 
2312   { /* Positive zero.  */
2313     size_t length;
2314     char *result =
2315       my_asnprintf (NULL, &length, "%Le %d", 0.0L, 33, 44, 55);
2316     ASSERT (result != NULL);
2317     ASSERT (strcmp (result, "0.000000e+00 33") == 0
2318             || strcmp (result, "0.000000e+000 33") == 0);
2319     ASSERT (length == strlen (result));
2320     free (result);
2321   }
2322 
2323   { /* Negative zero.  */
2324     size_t length;
2325     char *result =
2326       my_asnprintf (NULL, &length, "%Le %d", minus_zerol, 33, 44, 55);
2327     ASSERT (result != NULL);
2328     if (have_minus_zero ())
2329       ASSERT (strcmp (result, "-0.000000e+00 33") == 0
2330               || strcmp (result, "-0.000000e+000 33") == 0);
2331     ASSERT (length == strlen (result));
2332     free (result);
2333   }
2334 
2335   { /* Positive infinity.  */
2336     size_t length;
2337     char *result =
2338       my_asnprintf (NULL, &length, "%Le %d", Infinityl (), 33, 44, 55);
2339     ASSERT (result != NULL);
2340     ASSERT (strcmp (result, "inf 33") == 0
2341             || strcmp (result, "infinity 33") == 0);
2342     ASSERT (length == strlen (result));
2343     free (result);
2344   }
2345 
2346   { /* Negative infinity.  */
2347     size_t length;
2348     char *result =
2349       my_asnprintf (NULL, &length, "%Le %d", - Infinityl (), 33, 44, 55);
2350     ASSERT (result != NULL);
2351     ASSERT (strcmp (result, "-inf 33") == 0
2352             || strcmp (result, "-infinity 33") == 0);
2353     ASSERT (length == strlen (result));
2354     free (result);
2355   }
2356 
2357   { /* NaN.  */
2358     size_t length;
2359     char *result =
2360       my_asnprintf (NULL, &length, "%Le %d", NaNl (), 33, 44, 55);
2361     ASSERT (result != NULL);
2362     ASSERT (strlen (result) >= 3 + 3
2363             && strisnan (result, 0, strlen (result) - 3, 0)
2364             && strcmp (result + strlen (result) - 3, " 33") == 0);
2365     ASSERT (length == strlen (result));
2366     free (result);
2367   }
2368 #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_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
2369   { /* Quiet NaN.  */
2370     static union { unsigned int word[4]; long double value; } x =
2371       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2372     size_t length;
2373     char *result =
2374       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2375     ASSERT (result != NULL);
2376     ASSERT (length == strlen (result));
2377     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2378     free (result);
2379   }
2380   {
2381     /* Signalling NaN.  */
2382     static union { unsigned int word[4]; long double value; } x =
2383       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2384     size_t length;
2385     char *result =
2386       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2387     ASSERT (result != NULL);
2388     ASSERT (length == strlen (result));
2389     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2390     free (result);
2391   }
2392   /* asnprintf should print something even for noncanonical values.  */
2393   { /* Pseudo-NaN.  */
2394     static union { unsigned int word[4]; long double value; } x =
2395       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2396     size_t length;
2397     char *result =
2398       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2399     ASSERT (result != NULL);
2400     ASSERT (length == strlen (result));
2401     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2402     free (result);
2403   }
2404   { /* Pseudo-Infinity.  */
2405     static union { unsigned int word[4]; long double value; } x =
2406       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2407     size_t length;
2408     char *result =
2409       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2410     ASSERT (result != NULL);
2411     ASSERT (length == strlen (result));
2412     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2413     free (result);
2414   }
2415   { /* Pseudo-Zero.  */
2416     static union { unsigned int word[4]; long double value; } x =
2417       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2418     size_t length;
2419     char *result =
2420       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2421     ASSERT (result != NULL);
2422     ASSERT (length == strlen (result));
2423     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2424     free (result);
2425   }
2426   { /* Unnormalized number.  */
2427     static union { unsigned int word[4]; long double value; } x =
2428       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2429     size_t length;
2430     char *result =
2431       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2432     ASSERT (result != NULL);
2433     ASSERT (length == strlen (result));
2434     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2435     free (result);
2436   }
2437   { /* Pseudo-Denormal.  */
2438     static union { unsigned int word[4]; long double value; } x =
2439       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2440     size_t length;
2441     char *result =
2442       my_asnprintf (NULL, &length, "%Le %d", x.value, 33, 44, 55);
2443     ASSERT (result != NULL);
2444     ASSERT (length == strlen (result));
2445     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
2446     free (result);
2447   }
2448 #endif
2449 
2450   { /* Width.  */
2451     size_t length;
2452     char *result =
2453       my_asnprintf (NULL, &length, "%15Le %d", 1.75L, 33, 44, 55);
2454     ASSERT (result != NULL);
2455     ASSERT (strcmp (result, "   1.750000e+00 33") == 0
2456             || strcmp (result, "  1.750000e+000 33") == 0);
2457     ASSERT (length == strlen (result));
2458     free (result);
2459   }
2460 
2461   { /* FLAG_LEFT.  */
2462     size_t length;
2463     char *result =
2464       my_asnprintf (NULL, &length, "%-15Le %d", 1.75L, 33, 44, 55);
2465     ASSERT (result != NULL);
2466     ASSERT (strcmp (result, "1.750000e+00    33") == 0
2467             || strcmp (result, "1.750000e+000   33") == 0);
2468     ASSERT (length == strlen (result));
2469     free (result);
2470   }
2471 
2472   { /* FLAG_SHOWSIGN.  */
2473     size_t length;
2474     char *result =
2475       my_asnprintf (NULL, &length, "%+Le %d", 1.75L, 33, 44, 55);
2476     ASSERT (result != NULL);
2477     ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2478             || strcmp (result, "+1.750000e+000 33") == 0);
2479     ASSERT (length == strlen (result));
2480     free (result);
2481   }
2482 
2483   { /* FLAG_SPACE.  */
2484     size_t length;
2485     char *result =
2486       my_asnprintf (NULL, &length, "% Le %d", 1.75L, 33, 44, 55);
2487     ASSERT (result != NULL);
2488     ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2489             || strcmp (result, " 1.750000e+000 33") == 0);
2490     ASSERT (length == strlen (result));
2491     free (result);
2492   }
2493 
2494   { /* FLAG_ALT.  */
2495     size_t length;
2496     char *result =
2497       my_asnprintf (NULL, &length, "%#Le %d", 1.75L, 33, 44, 55);
2498     ASSERT (result != NULL);
2499     ASSERT (strcmp (result, "1.750000e+00 33") == 0
2500             || strcmp (result, "1.750000e+000 33") == 0);
2501     ASSERT (length == strlen (result));
2502     free (result);
2503   }
2504 
2505   { /* FLAG_ALT.  */
2506     size_t length;
2507     char *result =
2508       my_asnprintf (NULL, &length, "%#.Le %d", 1.75L, 33, 44, 55);
2509     ASSERT (result != NULL);
2510     ASSERT (strcmp (result, "2.e+00 33") == 0
2511             || strcmp (result, "2.e+000 33") == 0);
2512     ASSERT (length == strlen (result));
2513     free (result);
2514   }
2515 
2516   { /* FLAG_ALT.  */
2517     size_t length;
2518     char *result =
2519       my_asnprintf (NULL, &length, "%#.Le %d", 9.75L, 33, 44, 55);
2520     ASSERT (result != NULL);
2521     ASSERT (strcmp (result, "1.e+01 33") == 0
2522             || strcmp (result, "1.e+001 33") == 0);
2523     ASSERT (length == strlen (result));
2524     free (result);
2525   }
2526 
2527   { /* FLAG_ZERO with finite number.  */
2528     size_t length;
2529     char *result =
2530       my_asnprintf (NULL, &length, "%015Le %d", 1234.0L, 33, 44, 55);
2531     ASSERT (result != NULL);
2532     ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2533             || strcmp (result, "001.234000e+003 33") == 0);
2534     ASSERT (length == strlen (result));
2535     free (result);
2536   }
2537 
2538   { /* FLAG_ZERO with infinite number.  */
2539     size_t length;
2540     char *result =
2541       my_asnprintf (NULL, &length, "%015Le %d", - Infinityl (), 33, 44, 55);
2542     ASSERT (result != NULL);
2543     ASSERT (strcmp (result, "           -inf 33") == 0
2544             || strcmp (result, "      -infinity 33") == 0);
2545     ASSERT (length == strlen (result));
2546     free (result);
2547   }
2548 
2549   { /* FLAG_ZERO with NaN.  */
2550     size_t length;
2551     char *result =
2552       my_asnprintf (NULL, &length, "%050Le %d", NaNl (), 33, 44, 55);
2553     ASSERT (result != NULL);
2554     ASSERT (strlen (result) == 50 + 3
2555             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2556             && strcmp (result + strlen (result) - 3, " 33") == 0);
2557     ASSERT (length == strlen (result));
2558     free (result);
2559   }
2560 
2561   { /* Precision.  */
2562     size_t length;
2563     char *result =
2564       my_asnprintf (NULL, &length, "%.Le %d", 1234.0L, 33, 44, 55);
2565     ASSERT (result != NULL);
2566     ASSERT (strcmp (result, "1e+03 33") == 0
2567             || strcmp (result, "1e+003 33") == 0);
2568     ASSERT (length == strlen (result));
2569     free (result);
2570   }
2571 
2572   { /* Precision with no rounding.  */
2573     size_t length;
2574     char *result =
2575       my_asnprintf (NULL, &length, "%.4Le %d", 999.951L, 33, 44, 55);
2576     ASSERT (result != NULL);
2577     ASSERT (strcmp (result, "9.9995e+02 33") == 0
2578             || strcmp (result, "9.9995e+002 33") == 0);
2579     ASSERT (length == strlen (result));
2580     free (result);
2581   }
2582 
2583   { /* Precision with rounding.  */
2584     size_t length;
2585     char *result =
2586       my_asnprintf (NULL, &length, "%.4Le %d", 999.996L, 33, 44, 55);
2587     ASSERT (result != NULL);
2588     ASSERT (strcmp (result, "1.0000e+03 33") == 0
2589             || strcmp (result, "1.0000e+003 33") == 0);
2590     ASSERT (length == strlen (result));
2591     free (result);
2592   }
2593 
2594   /* Test the support of the %g format directive.  */
2595 
2596   { /* A positive number.  */
2597     size_t length;
2598     char *result =
2599       my_asnprintf (NULL, &length, "%g %d", 12.75, 33, 44, 55);
2600     ASSERT (result != NULL);
2601     ASSERT (strcmp (result, "12.75 33") == 0);
2602     ASSERT (length == strlen (result));
2603     free (result);
2604   }
2605 
2606   { /* A larger positive number.  */
2607     size_t length;
2608     char *result =
2609       my_asnprintf (NULL, &length, "%g %d", 1234567.0, 33, 44, 55);
2610     ASSERT (result != NULL);
2611     ASSERT (strcmp (result, "1.23457e+06 33") == 0
2612             || strcmp (result, "1.23457e+006 33") == 0);
2613     ASSERT (length == strlen (result));
2614     free (result);
2615   }
2616 
2617   { /* Small and large positive numbers.  */
2618     static struct { double value; const char *string; } data[] =
2619       {
2620         { 1.234321234321234e-37, "1.23432e-37" },
2621         { 1.234321234321234e-36, "1.23432e-36" },
2622         { 1.234321234321234e-35, "1.23432e-35" },
2623         { 1.234321234321234e-34, "1.23432e-34" },
2624         { 1.234321234321234e-33, "1.23432e-33" },
2625         { 1.234321234321234e-32, "1.23432e-32" },
2626         { 1.234321234321234e-31, "1.23432e-31" },
2627         { 1.234321234321234e-30, "1.23432e-30" },
2628         { 1.234321234321234e-29, "1.23432e-29" },
2629         { 1.234321234321234e-28, "1.23432e-28" },
2630         { 1.234321234321234e-27, "1.23432e-27" },
2631         { 1.234321234321234e-26, "1.23432e-26" },
2632         { 1.234321234321234e-25, "1.23432e-25" },
2633         { 1.234321234321234e-24, "1.23432e-24" },
2634         { 1.234321234321234e-23, "1.23432e-23" },
2635         { 1.234321234321234e-22, "1.23432e-22" },
2636         { 1.234321234321234e-21, "1.23432e-21" },
2637         { 1.234321234321234e-20, "1.23432e-20" },
2638         { 1.234321234321234e-19, "1.23432e-19" },
2639         { 1.234321234321234e-18, "1.23432e-18" },
2640         { 1.234321234321234e-17, "1.23432e-17" },
2641         { 1.234321234321234e-16, "1.23432e-16" },
2642         { 1.234321234321234e-15, "1.23432e-15" },
2643         { 1.234321234321234e-14, "1.23432e-14" },
2644         { 1.234321234321234e-13, "1.23432e-13" },
2645         { 1.234321234321234e-12, "1.23432e-12" },
2646         { 1.234321234321234e-11, "1.23432e-11" },
2647         { 1.234321234321234e-10, "1.23432e-10" },
2648         { 1.234321234321234e-9, "1.23432e-09" },
2649         { 1.234321234321234e-8, "1.23432e-08" },
2650         { 1.234321234321234e-7, "1.23432e-07" },
2651         { 1.234321234321234e-6, "1.23432e-06" },
2652         { 1.234321234321234e-5, "1.23432e-05" },
2653         { 1.234321234321234e-4, "0.000123432" },
2654         { 1.234321234321234e-3, "0.00123432" },
2655         { 1.234321234321234e-2, "0.0123432" },
2656         { 1.234321234321234e-1, "0.123432" },
2657         { 1.234321234321234, "1.23432" },
2658         { 1.234321234321234e1, "12.3432" },
2659         { 1.234321234321234e2, "123.432" },
2660         { 1.234321234321234e3, "1234.32" },
2661         { 1.234321234321234e4, "12343.2" },
2662         { 1.234321234321234e5, "123432" },
2663         { 1.234321234321234e6, "1.23432e+06" },
2664         { 1.234321234321234e7, "1.23432e+07" },
2665         { 1.234321234321234e8, "1.23432e+08" },
2666         { 1.234321234321234e9, "1.23432e+09" },
2667         { 1.234321234321234e10, "1.23432e+10" },
2668         { 1.234321234321234e11, "1.23432e+11" },
2669         { 1.234321234321234e12, "1.23432e+12" },
2670         { 1.234321234321234e13, "1.23432e+13" },
2671         { 1.234321234321234e14, "1.23432e+14" },
2672         { 1.234321234321234e15, "1.23432e+15" },
2673         { 1.234321234321234e16, "1.23432e+16" },
2674         { 1.234321234321234e17, "1.23432e+17" },
2675         { 1.234321234321234e18, "1.23432e+18" },
2676         { 1.234321234321234e19, "1.23432e+19" },
2677         { 1.234321234321234e20, "1.23432e+20" },
2678         { 1.234321234321234e21, "1.23432e+21" },
2679         { 1.234321234321234e22, "1.23432e+22" },
2680         { 1.234321234321234e23, "1.23432e+23" },
2681         { 1.234321234321234e24, "1.23432e+24" },
2682         { 1.234321234321234e25, "1.23432e+25" },
2683         { 1.234321234321234e26, "1.23432e+26" },
2684         { 1.234321234321234e27, "1.23432e+27" },
2685         { 1.234321234321234e28, "1.23432e+28" },
2686         { 1.234321234321234e29, "1.23432e+29" },
2687         { 1.234321234321234e30, "1.23432e+30" },
2688         { 1.234321234321234e31, "1.23432e+31" },
2689         { 1.234321234321234e32, "1.23432e+32" },
2690         { 1.234321234321234e33, "1.23432e+33" },
2691         { 1.234321234321234e34, "1.23432e+34" },
2692         { 1.234321234321234e35, "1.23432e+35" },
2693         { 1.234321234321234e36, "1.23432e+36" }
2694       };
2695     size_t k;
2696     for (k = 0; k < SIZEOF (data); k++)
2697       {
2698         size_t length;
2699         char *result =
2700           my_asnprintf (NULL, &length, "%g", data[k].value);
2701         const char *expected = data[k].string;
2702         ASSERT (result != NULL);
2703         ASSERT (strcmp (result, expected) == 0
2704                 /* Some implementations produce exponents with 3 digits.  */
2705                 || (expected[strlen (expected) - 4] == 'e'
2706                     && strlen (result) == strlen (expected) + 1
2707                     && memcmp (result, expected, strlen (expected) - 2) == 0
2708                     && result[strlen (expected) - 2] == '0'
2709                     && strcmp (result + strlen (expected) - 1,
2710                                expected + strlen (expected) - 2)
2711                        == 0));
2712         ASSERT (length == strlen (result));
2713         free (result);
2714       }
2715   }
2716 
2717   { /* A negative number.  */
2718     size_t length;
2719     char *result =
2720       my_asnprintf (NULL, &length, "%g %d", -0.03125, 33, 44, 55);
2721     ASSERT (result != NULL);
2722     ASSERT (strcmp (result, "-0.03125 33") == 0);
2723     ASSERT (length == strlen (result));
2724     free (result);
2725   }
2726 
2727   { /* Positive zero.  */
2728     size_t length;
2729     char *result =
2730       my_asnprintf (NULL, &length, "%g %d", 0.0, 33, 44, 55);
2731     ASSERT (result != NULL);
2732     ASSERT (strcmp (result, "0 33") == 0);
2733     ASSERT (length == strlen (result));
2734     free (result);
2735   }
2736 
2737   { /* Negative zero.  */
2738     size_t length;
2739     char *result =
2740       my_asnprintf (NULL, &length, "%g %d", minus_zerod, 33, 44, 55);
2741     ASSERT (result != NULL);
2742     if (have_minus_zero ())
2743       ASSERT (strcmp (result, "-0 33") == 0);
2744     ASSERT (length == strlen (result));
2745     free (result);
2746   }
2747 
2748   { /* Positive infinity.  */
2749     size_t length;
2750     char *result =
2751       my_asnprintf (NULL, &length, "%g %d", Infinityd (), 33, 44, 55);
2752     ASSERT (result != NULL);
2753     ASSERT (strcmp (result, "inf 33") == 0
2754             || strcmp (result, "infinity 33") == 0);
2755     ASSERT (length == strlen (result));
2756     free (result);
2757   }
2758 
2759   { /* Negative infinity.  */
2760     size_t length;
2761     char *result =
2762       my_asnprintf (NULL, &length, "%g %d", - Infinityd (), 33, 44, 55);
2763     ASSERT (result != NULL);
2764     ASSERT (strcmp (result, "-inf 33") == 0
2765             || strcmp (result, "-infinity 33") == 0);
2766     ASSERT (length == strlen (result));
2767     free (result);
2768   }
2769 
2770   { /* NaN.  */
2771     size_t length;
2772     char *result =
2773       my_asnprintf (NULL, &length, "%g %d", NaNd (), 33, 44, 55);
2774     ASSERT (result != NULL);
2775     ASSERT (strlen (result) >= 3 + 3
2776             && strisnan (result, 0, strlen (result) - 3, 0)
2777             && strcmp (result + strlen (result) - 3, " 33") == 0);
2778     ASSERT (length == strlen (result));
2779     free (result);
2780   }
2781 
2782   { /* Width.  */
2783     size_t length;
2784     char *result =
2785       my_asnprintf (NULL, &length, "%10g %d", 1.75, 33, 44, 55);
2786     ASSERT (result != NULL);
2787     ASSERT (strcmp (result, "      1.75 33") == 0);
2788     ASSERT (length == strlen (result));
2789     free (result);
2790   }
2791 
2792   { /* FLAG_LEFT.  */
2793     size_t length;
2794     char *result =
2795       my_asnprintf (NULL, &length, "%-10g %d", 1.75, 33, 44, 55);
2796     ASSERT (result != NULL);
2797     ASSERT (strcmp (result, "1.75       33") == 0);
2798     ASSERT (length == strlen (result));
2799     free (result);
2800   }
2801 
2802   { /* FLAG_SHOWSIGN.  */
2803     size_t length;
2804     char *result =
2805       my_asnprintf (NULL, &length, "%+g %d", 1.75, 33, 44, 55);
2806     ASSERT (result != NULL);
2807     ASSERT (strcmp (result, "+1.75 33") == 0);
2808     ASSERT (length == strlen (result));
2809     free (result);
2810   }
2811 
2812   { /* FLAG_SPACE.  */
2813     size_t length;
2814     char *result =
2815       my_asnprintf (NULL, &length, "% g %d", 1.75, 33, 44, 55);
2816     ASSERT (result != NULL);
2817     ASSERT (strcmp (result, " 1.75 33") == 0);
2818     ASSERT (length == strlen (result));
2819     free (result);
2820   }
2821 
2822   { /* FLAG_ALT.  */
2823     size_t length;
2824     char *result =
2825       my_asnprintf (NULL, &length, "%#g %d", 1.75, 33, 44, 55);
2826     ASSERT (result != NULL);
2827     ASSERT (strcmp (result, "1.75000 33") == 0);
2828     ASSERT (length == strlen (result));
2829     free (result);
2830   }
2831 
2832   { /* FLAG_ALT.  */
2833     size_t length;
2834     char *result =
2835       my_asnprintf (NULL, &length, "%#.g %d", 1.75, 33, 44, 55);
2836     ASSERT (result != NULL);
2837     ASSERT (strcmp (result, "2. 33") == 0);
2838     ASSERT (length == strlen (result));
2839     free (result);
2840   }
2841 
2842   { /* FLAG_ALT.  */
2843     size_t length;
2844     char *result =
2845       my_asnprintf (NULL, &length, "%#.g %d", 9.75, 33, 44, 55);
2846     ASSERT (result != NULL);
2847     ASSERT (strcmp (result, "1.e+01 33") == 0
2848             || strcmp (result, "1.e+001 33") == 0);
2849     ASSERT (length == strlen (result));
2850     free (result);
2851   }
2852 
2853   { /* FLAG_ZERO with finite number.  */
2854     size_t length;
2855     char *result =
2856       my_asnprintf (NULL, &length, "%010g %d", 1234.0, 33, 44, 55);
2857     ASSERT (result != NULL);
2858     ASSERT (strcmp (result, "0000001234 33") == 0);
2859     ASSERT (length == strlen (result));
2860     free (result);
2861   }
2862 
2863   { /* FLAG_ZERO with infinite number.  */
2864     size_t length;
2865     char *result =
2866       my_asnprintf (NULL, &length, "%015g %d", - Infinityd (), 33, 44, 55);
2867     ASSERT (result != NULL);
2868     ASSERT (strcmp (result, "           -inf 33") == 0
2869             || strcmp (result, "      -infinity 33") == 0);
2870     ASSERT (length == strlen (result));
2871     free (result);
2872   }
2873 
2874   { /* FLAG_ZERO with NaN.  */
2875     size_t length;
2876     char *result =
2877       my_asnprintf (NULL, &length, "%050g %d", NaNd (), 33, 44, 55);
2878     ASSERT (result != NULL);
2879     ASSERT (strlen (result) == 50 + 3
2880             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2881             && strcmp (result + strlen (result) - 3, " 33") == 0);
2882     ASSERT (length == strlen (result));
2883     free (result);
2884   }
2885 
2886   { /* Precision.  */
2887     size_t length;
2888     char *result =
2889       my_asnprintf (NULL, &length, "%.g %d", 1234.0, 33, 44, 55);
2890     ASSERT (result != NULL);
2891     ASSERT (strcmp (result, "1e+03 33") == 0
2892             || strcmp (result, "1e+003 33") == 0);
2893     ASSERT (length == strlen (result));
2894     free (result);
2895   }
2896 
2897   { /* Precision with no rounding.  */
2898     size_t length;
2899     char *result =
2900       my_asnprintf (NULL, &length, "%.5g %d", 999.951, 33, 44, 55);
2901     ASSERT (result != NULL);
2902     ASSERT (strcmp (result, "999.95 33") == 0);
2903     ASSERT (length == strlen (result));
2904     free (result);
2905   }
2906 
2907   { /* Precision with rounding.  */
2908     size_t length;
2909     char *result =
2910       my_asnprintf (NULL, &length, "%.5g %d", 999.996, 33, 44, 55);
2911     ASSERT (result != NULL);
2912     ASSERT (strcmp (result, "1000 33") == 0);
2913     ASSERT (length == strlen (result));
2914     free (result);
2915   }
2916 
2917   { /* A positive number.  */
2918     size_t length;
2919     char *result =
2920       my_asnprintf (NULL, &length, "%Lg %d", 12.75L, 33, 44, 55);
2921     ASSERT (result != NULL);
2922     ASSERT (strcmp (result, "12.75 33") == 0);
2923     ASSERT (length == strlen (result));
2924     free (result);
2925   }
2926 
2927   { /* A larger positive number.  */
2928     size_t length;
2929     char *result =
2930       my_asnprintf (NULL, &length, "%Lg %d", 1234567.0L, 33, 44, 55);
2931     ASSERT (result != NULL);
2932     ASSERT (strcmp (result, "1.23457e+06 33") == 0
2933             || strcmp (result, "1.23457e+006 33") == 0);
2934     ASSERT (length == strlen (result));
2935     free (result);
2936   }
2937 
2938   { /* Small and large positive numbers.  */
2939     static struct { long double value; const char *string; } data[] =
2940       {
2941         { 1.234321234321234e-37L, "1.23432e-37" },
2942         { 1.234321234321234e-36L, "1.23432e-36" },
2943         { 1.234321234321234e-35L, "1.23432e-35" },
2944         { 1.234321234321234e-34L, "1.23432e-34" },
2945         { 1.234321234321234e-33L, "1.23432e-33" },
2946         { 1.234321234321234e-32L, "1.23432e-32" },
2947         { 1.234321234321234e-31L, "1.23432e-31" },
2948         { 1.234321234321234e-30L, "1.23432e-30" },
2949         { 1.234321234321234e-29L, "1.23432e-29" },
2950         { 1.234321234321234e-28L, "1.23432e-28" },
2951         { 1.234321234321234e-27L, "1.23432e-27" },
2952         { 1.234321234321234e-26L, "1.23432e-26" },
2953         { 1.234321234321234e-25L, "1.23432e-25" },
2954         { 1.234321234321234e-24L, "1.23432e-24" },
2955         { 1.234321234321234e-23L, "1.23432e-23" },
2956         { 1.234321234321234e-22L, "1.23432e-22" },
2957         { 1.234321234321234e-21L, "1.23432e-21" },
2958         { 1.234321234321234e-20L, "1.23432e-20" },
2959         { 1.234321234321234e-19L, "1.23432e-19" },
2960         { 1.234321234321234e-18L, "1.23432e-18" },
2961         { 1.234321234321234e-17L, "1.23432e-17" },
2962         { 1.234321234321234e-16L, "1.23432e-16" },
2963         { 1.234321234321234e-15L, "1.23432e-15" },
2964         { 1.234321234321234e-14L, "1.23432e-14" },
2965         { 1.234321234321234e-13L, "1.23432e-13" },
2966         { 1.234321234321234e-12L, "1.23432e-12" },
2967         { 1.234321234321234e-11L, "1.23432e-11" },
2968         { 1.234321234321234e-10L, "1.23432e-10" },
2969         { 1.234321234321234e-9L, "1.23432e-09" },
2970         { 1.234321234321234e-8L, "1.23432e-08" },
2971         { 1.234321234321234e-7L, "1.23432e-07" },
2972         { 1.234321234321234e-6L, "1.23432e-06" },
2973         { 1.234321234321234e-5L, "1.23432e-05" },
2974         { 1.234321234321234e-4L, "0.000123432" },
2975         { 1.234321234321234e-3L, "0.00123432" },
2976         { 1.234321234321234e-2L, "0.0123432" },
2977         { 1.234321234321234e-1L, "0.123432" },
2978         { 1.234321234321234L, "1.23432" },
2979         { 1.234321234321234e1L, "12.3432" },
2980         { 1.234321234321234e2L, "123.432" },
2981         { 1.234321234321234e3L, "1234.32" },
2982         { 1.234321234321234e4L, "12343.2" },
2983         { 1.234321234321234e5L, "123432" },
2984         { 1.234321234321234e6L, "1.23432e+06" },
2985         { 1.234321234321234e7L, "1.23432e+07" },
2986         { 1.234321234321234e8L, "1.23432e+08" },
2987         { 1.234321234321234e9L, "1.23432e+09" },
2988         { 1.234321234321234e10L, "1.23432e+10" },
2989         { 1.234321234321234e11L, "1.23432e+11" },
2990         { 1.234321234321234e12L, "1.23432e+12" },
2991         { 1.234321234321234e13L, "1.23432e+13" },
2992         { 1.234321234321234e14L, "1.23432e+14" },
2993         { 1.234321234321234e15L, "1.23432e+15" },
2994         { 1.234321234321234e16L, "1.23432e+16" },
2995         { 1.234321234321234e17L, "1.23432e+17" },
2996         { 1.234321234321234e18L, "1.23432e+18" },
2997         { 1.234321234321234e19L, "1.23432e+19" },
2998         { 1.234321234321234e20L, "1.23432e+20" },
2999         { 1.234321234321234e21L, "1.23432e+21" },
3000         { 1.234321234321234e22L, "1.23432e+22" },
3001         { 1.234321234321234e23L, "1.23432e+23" },
3002         { 1.234321234321234e24L, "1.23432e+24" },
3003         { 1.234321234321234e25L, "1.23432e+25" },
3004         { 1.234321234321234e26L, "1.23432e+26" },
3005         { 1.234321234321234e27L, "1.23432e+27" },
3006         { 1.234321234321234e28L, "1.23432e+28" },
3007         { 1.234321234321234e29L, "1.23432e+29" },
3008         { 1.234321234321234e30L, "1.23432e+30" },
3009         { 1.234321234321234e31L, "1.23432e+31" },
3010         { 1.234321234321234e32L, "1.23432e+32" },
3011         { 1.234321234321234e33L, "1.23432e+33" },
3012         { 1.234321234321234e34L, "1.23432e+34" },
3013         { 1.234321234321234e35L, "1.23432e+35" },
3014         { 1.234321234321234e36L, "1.23432e+36" }
3015       };
3016     size_t k;
3017     for (k = 0; k < SIZEOF (data); k++)
3018       {
3019         size_t length;
3020         char *result =
3021           my_asnprintf (NULL, &length, "%Lg", data[k].value);
3022         const char *expected = data[k].string;
3023         ASSERT (result != NULL);
3024         ASSERT (strcmp (result, expected) == 0
3025                 /* Some implementations produce exponents with 3 digits.  */
3026                 || (expected[strlen (expected) - 4] == 'e'
3027                     && strlen (result) == strlen (expected) + 1
3028                     && memcmp (result, expected, strlen (expected) - 2) == 0
3029                     && result[strlen (expected) - 2] == '0'
3030                     && strcmp (result + strlen (expected) - 1,
3031                                expected + strlen (expected) - 2)
3032                        == 0));
3033         ASSERT (length == strlen (result));
3034         free (result);
3035       }
3036   }
3037 
3038   { /* A negative number.  */
3039     size_t length;
3040     char *result =
3041       my_asnprintf (NULL, &length, "%Lg %d", -0.03125L, 33, 44, 55);
3042     ASSERT (result != NULL);
3043     ASSERT (strcmp (result, "-0.03125 33") == 0);
3044     ASSERT (length == strlen (result));
3045     free (result);
3046   }
3047 
3048   { /* Positive zero.  */
3049     size_t length;
3050     char *result =
3051       my_asnprintf (NULL, &length, "%Lg %d", 0.0L, 33, 44, 55);
3052     ASSERT (result != NULL);
3053     ASSERT (strcmp (result, "0 33") == 0);
3054     ASSERT (length == strlen (result));
3055     free (result);
3056   }
3057 
3058   { /* Negative zero.  */
3059     size_t length;
3060     char *result =
3061       my_asnprintf (NULL, &length, "%Lg %d", minus_zerol, 33, 44, 55);
3062     ASSERT (result != NULL);
3063     if (have_minus_zero ())
3064       ASSERT (strcmp (result, "-0 33") == 0);
3065     ASSERT (length == strlen (result));
3066     free (result);
3067   }
3068 
3069   { /* Positive infinity.  */
3070     size_t length;
3071     char *result =
3072       my_asnprintf (NULL, &length, "%Lg %d", Infinityl (), 33, 44, 55);
3073     ASSERT (result != NULL);
3074     ASSERT (strcmp (result, "inf 33") == 0
3075             || strcmp (result, "infinity 33") == 0);
3076     ASSERT (length == strlen (result));
3077     free (result);
3078   }
3079 
3080   { /* Negative infinity.  */
3081     size_t length;
3082     char *result =
3083       my_asnprintf (NULL, &length, "%Lg %d", - Infinityl (), 33, 44, 55);
3084     ASSERT (result != NULL);
3085     ASSERT (strcmp (result, "-inf 33") == 0
3086             || strcmp (result, "-infinity 33") == 0);
3087     ASSERT (length == strlen (result));
3088     free (result);
3089   }
3090 
3091   { /* NaN.  */
3092     size_t length;
3093     char *result =
3094       my_asnprintf (NULL, &length, "%Lg %d", NaNl (), 33, 44, 55);
3095     ASSERT (result != NULL);
3096     ASSERT (strlen (result) >= 3 + 3
3097             && strisnan (result, 0, strlen (result) - 3, 0)
3098             && strcmp (result + strlen (result) - 3, " 33") == 0);
3099     ASSERT (length == strlen (result));
3100     free (result);
3101   }
3102 #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_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
3103   { /* Quiet NaN.  */
3104     static union { unsigned int word[4]; long double value; } x =
3105       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
3106     size_t length;
3107     char *result =
3108       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3109     ASSERT (result != NULL);
3110     ASSERT (strlen (result) >= 3 + 3
3111             && strisnan (result, 0, strlen (result) - 3, 0)
3112             && strcmp (result + strlen (result) - 3, " 33") == 0);
3113     ASSERT (length == strlen (result));
3114     free (result);
3115   }
3116   {
3117     /* Signalling NaN.  */
3118     static union { unsigned int word[4]; long double value; } x =
3119       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
3120     size_t length;
3121     char *result =
3122       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3123     ASSERT (result != NULL);
3124     ASSERT (strlen (result) >= 3 + 3
3125             && strisnan (result, 0, strlen (result) - 3, 0)
3126             && strcmp (result + strlen (result) - 3, " 33") == 0);
3127     ASSERT (length == strlen (result));
3128     free (result);
3129   }
3130   /* asnprintf should print something for noncanonical values.  */
3131   { /* Pseudo-NaN.  */
3132     static union { unsigned int word[4]; long double value; } x =
3133       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
3134     size_t length;
3135     char *result =
3136       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3137     ASSERT (result != NULL);
3138     ASSERT (length == strlen (result));
3139     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
3140     free (result);
3141   }
3142   { /* Pseudo-Infinity.  */
3143     static union { unsigned int word[4]; long double value; } x =
3144       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
3145     size_t length;
3146     char *result =
3147       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3148     ASSERT (result != NULL);
3149     ASSERT (length == strlen (result));
3150     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
3151     free (result);
3152   }
3153   { /* Pseudo-Zero.  */
3154     static union { unsigned int word[4]; long double value; } x =
3155       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
3156     size_t length;
3157     char *result =
3158       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3159     ASSERT (result != NULL);
3160     ASSERT (length == strlen (result));
3161     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
3162     free (result);
3163   }
3164   { /* Unnormalized number.  */
3165     static union { unsigned int word[4]; long double value; } x =
3166       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
3167     size_t length;
3168     char *result =
3169       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3170     ASSERT (result != NULL);
3171     ASSERT (length == strlen (result));
3172     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
3173     free (result);
3174   }
3175   { /* Pseudo-Denormal.  */
3176     static union { unsigned int word[4]; long double value; } x =
3177       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
3178     size_t length;
3179     char *result =
3180       my_asnprintf (NULL, &length, "%Lg %d", x.value, 33, 44, 55);
3181     ASSERT (result != NULL);
3182     ASSERT (length == strlen (result));
3183     ASSERT (3 < length && strcmp (result + length - 3, " 33") == 0);
3184     free (result);
3185   }
3186 #endif
3187 
3188   { /* Width.  */
3189     size_t length;
3190     char *result =
3191       my_asnprintf (NULL, &length, "%10Lg %d", 1.75L, 33, 44, 55);
3192     ASSERT (result != NULL);
3193     ASSERT (strcmp (result, "      1.75 33") == 0);
3194     ASSERT (length == strlen (result));
3195     free (result);
3196   }
3197 
3198   { /* FLAG_LEFT.  */
3199     size_t length;
3200     char *result =
3201       my_asnprintf (NULL, &length, "%-10Lg %d", 1.75L, 33, 44, 55);
3202     ASSERT (result != NULL);
3203     ASSERT (strcmp (result, "1.75       33") == 0);
3204     ASSERT (length == strlen (result));
3205     free (result);
3206   }
3207 
3208   { /* FLAG_SHOWSIGN.  */
3209     size_t length;
3210     char *result =
3211       my_asnprintf (NULL, &length, "%+Lg %d", 1.75L, 33, 44, 55);
3212     ASSERT (result != NULL);
3213     ASSERT (strcmp (result, "+1.75 33") == 0);
3214     ASSERT (length == strlen (result));
3215     free (result);
3216   }
3217 
3218   { /* FLAG_SPACE.  */
3219     size_t length;
3220     char *result =
3221       my_asnprintf (NULL, &length, "% Lg %d", 1.75L, 33, 44, 55);
3222     ASSERT (result != NULL);
3223     ASSERT (strcmp (result, " 1.75 33") == 0);
3224     ASSERT (length == strlen (result));
3225     free (result);
3226   }
3227 
3228   { /* FLAG_ALT.  */
3229     size_t length;
3230     char *result =
3231       my_asnprintf (NULL, &length, "%#Lg %d", 1.75L, 33, 44, 55);
3232     ASSERT (result != NULL);
3233     ASSERT (strcmp (result, "1.75000 33") == 0);
3234     ASSERT (length == strlen (result));
3235     free (result);
3236   }
3237 
3238   { /* FLAG_ALT.  */
3239     size_t length;
3240     char *result =
3241       my_asnprintf (NULL, &length, "%#.Lg %d", 1.75L, 33, 44, 55);
3242     ASSERT (result != NULL);
3243     ASSERT (strcmp (result, "2. 33") == 0);
3244     ASSERT (length == strlen (result));
3245     free (result);
3246   }
3247 
3248   { /* FLAG_ALT.  */
3249     size_t length;
3250     char *result =
3251       my_asnprintf (NULL, &length, "%#.Lg %d", 9.75L, 33, 44, 55);
3252     ASSERT (result != NULL);
3253     ASSERT (strcmp (result, "1.e+01 33") == 0
3254             || strcmp (result, "1.e+001 33") == 0);
3255     ASSERT (length == strlen (result));
3256     free (result);
3257   }
3258 
3259   { /* FLAG_ZERO with finite number.  */
3260     size_t length;
3261     char *result =
3262       my_asnprintf (NULL, &length, "%010Lg %d", 1234.0L, 33, 44, 55);
3263     ASSERT (result != NULL);
3264     ASSERT (strcmp (result, "0000001234 33") == 0);
3265     ASSERT (length == strlen (result));
3266     free (result);
3267   }
3268 
3269   { /* FLAG_ZERO with infinite number.  */
3270     size_t length;
3271     char *result =
3272       my_asnprintf (NULL, &length, "%015Lg %d", - Infinityl (), 33, 44, 55);
3273     ASSERT (result != NULL);
3274     ASSERT (strcmp (result, "           -inf 33") == 0
3275             || strcmp (result, "      -infinity 33") == 0);
3276     ASSERT (length == strlen (result));
3277     free (result);
3278   }
3279 
3280   { /* FLAG_ZERO with NaN.  */
3281     size_t length;
3282     char *result =
3283       my_asnprintf (NULL, &length, "%050Lg %d", NaNl (), 33, 44, 55);
3284     ASSERT (result != NULL);
3285     ASSERT (strlen (result) == 50 + 3
3286             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
3287             && strcmp (result + strlen (result) - 3, " 33") == 0);
3288     ASSERT (length == strlen (result));
3289     free (result);
3290   }
3291 
3292   { /* Precision.  */
3293     size_t length;
3294     char *result =
3295       my_asnprintf (NULL, &length, "%.Lg %d", 1234.0L, 33, 44, 55);
3296     ASSERT (result != NULL);
3297     ASSERT (strcmp (result, "1e+03 33") == 0
3298             || strcmp (result, "1e+003 33") == 0);
3299     ASSERT (length == strlen (result));
3300     free (result);
3301   }
3302 
3303   { /* Precision with no rounding.  */
3304     size_t length;
3305     char *result =
3306       my_asnprintf (NULL, &length, "%.5Lg %d", 999.951L, 33, 44, 55);
3307     ASSERT (result != NULL);
3308     ASSERT (strcmp (result, "999.95 33") == 0);
3309     ASSERT (length == strlen (result));
3310     free (result);
3311   }
3312 
3313   { /* Precision with rounding.  */
3314     size_t length;
3315     char *result =
3316       my_asnprintf (NULL, &length, "%.5Lg %d", 999.996L, 33, 44, 55);
3317     ASSERT (result != NULL);
3318     ASSERT (strcmp (result, "1000 33") == 0);
3319     ASSERT (length == strlen (result));
3320     free (result);
3321   }
3322 
3323   /* Test the support of the %n format directive.  */
3324 
3325   {
3326     int count = -1;
3327     size_t length;
3328     char *result =
3329       my_asnprintf (NULL, &length, "%d %n", 123, &count, 33, 44, 55);
3330     ASSERT (result != NULL);
3331     ASSERT (strcmp (result, "123 ") == 0);
3332     ASSERT (length == strlen (result));
3333     ASSERT (count == 4);
3334     free (result);
3335   }
3336 
3337   /* Test the support of the POSIX/XSI format strings with positions.  */
3338 
3339   {
3340     size_t length;
3341     char *result =
3342       my_asnprintf (NULL, &length, "%2$d %1$d", 33, 55);
3343     ASSERT (result != NULL);
3344     ASSERT (strcmp (result, "55 33") == 0);
3345     ASSERT (length == strlen (result));
3346     free (result);
3347   }
3348 
3349   /* Test the support of the grouping flag.  */
3350 
3351   {
3352     size_t length;
3353     char *result =
3354       my_asnprintf (NULL, &length, "%'d %d", 1234567, 99);
3355     ASSERT (result != NULL);
3356     ASSERT (result[strlen (result) - 1] == '9');
3357     ASSERT (length == strlen (result));
3358     free (result);
3359   }
3360 
3361   /* Test the support of the left-adjust flag.  */
3362 
3363   {
3364     size_t length;
3365     char *result =
3366       my_asnprintf (NULL, &length, "a%*sc", -3, "b");
3367     ASSERT (result != NULL);
3368     ASSERT (strcmp (result, "ab  c") == 0);
3369     ASSERT (length == strlen (result));
3370     free (result);
3371   }
3372 
3373   {
3374     size_t length;
3375     char *result =
3376       my_asnprintf (NULL, &length, "a%-*sc", 3, "b");
3377     ASSERT (result != NULL);
3378     ASSERT (strcmp (result, "ab  c") == 0);
3379     ASSERT (length == strlen (result));
3380     free (result);
3381   }
3382 
3383   {
3384     size_t length;
3385     char *result =
3386       my_asnprintf (NULL, &length, "a%-*sc", -3, "b");
3387     ASSERT (result != NULL);
3388     ASSERT (strcmp (result, "ab  c") == 0);
3389     ASSERT (length == strlen (result));
3390     free (result);
3391   }
3392 
3393   /* Test the support of large precision.  */
3394 
3395   {
3396     size_t length;
3397     char *result =
3398       my_asnprintf (NULL, &length, "%.4000d %d", 1234567, 99);
3399     size_t i;
3400     ASSERT (result != NULL);
3401     for (i = 0; i < 4000 - 7; i++)
3402       ASSERT (result[i] == '0');
3403     ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3404     ASSERT (length == strlen (result));
3405     free (result);
3406   }
3407 
3408   {
3409     size_t length;
3410     char *result =
3411       my_asnprintf (NULL, &length, "%.*d %d", 4000, 1234567, 99);
3412     size_t i;
3413     ASSERT (result != NULL);
3414     for (i = 0; i < 4000 - 7; i++)
3415       ASSERT (result[i] == '0');
3416     ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3417     ASSERT (length == strlen (result));
3418     free (result);
3419   }
3420 
3421   {
3422     size_t length;
3423     char *result =
3424       my_asnprintf (NULL, &length, "%.4000d %d", -1234567, 99);
3425     size_t i;
3426     ASSERT (result != NULL);
3427     ASSERT (result[0] == '-');
3428     for (i = 0; i < 4000 - 7; i++)
3429       ASSERT (result[1 + i] == '0');
3430     ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
3431     ASSERT (length == strlen (result));
3432     free (result);
3433   }
3434 
3435   {
3436     size_t length;
3437     char *result =
3438       my_asnprintf (NULL, &length, "%.4000u %d", 1234567, 99);
3439     size_t i;
3440     ASSERT (result != NULL);
3441     for (i = 0; i < 4000 - 7; i++)
3442       ASSERT (result[i] == '0');
3443     ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3444     ASSERT (length == strlen (result));
3445     free (result);
3446   }
3447 
3448   {
3449     size_t length;
3450     char *result =
3451       my_asnprintf (NULL, &length, "%.4000o %d", 1234567, 99);
3452     size_t i;
3453     ASSERT (result != NULL);
3454     for (i = 0; i < 4000 - 7; i++)
3455       ASSERT (result[i] == '0');
3456     ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
3457     ASSERT (length == strlen (result));
3458     free (result);
3459   }
3460 
3461   {
3462     size_t length;
3463     char *result =
3464       my_asnprintf (NULL, &length, "%.4000x %d", 1234567, 99);
3465     size_t i;
3466     ASSERT (result != NULL);
3467     for (i = 0; i < 4000 - 6; i++)
3468       ASSERT (result[i] == '0');
3469     ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
3470     ASSERT (length == strlen (result));
3471     free (result);
3472   }
3473 
3474   {
3475     size_t length;
3476     char *result =
3477       my_asnprintf (NULL, &length, "%#.4000x %d", 1234567, 99);
3478     size_t i;
3479     ASSERT (result != NULL);
3480     ASSERT (result[0] == '0');
3481     ASSERT (result[1] == 'x');
3482     for (i = 0; i < 4000 - 6; i++)
3483       ASSERT (result[2 + i] == '0');
3484     ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
3485     ASSERT (length == strlen (result));
3486     free (result);
3487   }
3488 
3489   {
3490     size_t length;
3491     char *result =
3492       my_asnprintf (NULL, &length, "%.4000f %d", 1.0, 99);
3493     size_t i;
3494     ASSERT (result != NULL);
3495     ASSERT (result[0] == '1');
3496     ASSERT (result[1] == '.');
3497     for (i = 0; i < 4000; i++)
3498       ASSERT (result[2 + i] == '0');
3499     ASSERT (strcmp (result + 2 + 4000, " 99") == 0);
3500     ASSERT (length == strlen (result));
3501     free (result);
3502   }
3503 
3504   {
3505     size_t length;
3506     char *result =
3507       my_asnprintf (NULL, &length, "%.511f %d", 1.0, 99);
3508     size_t i;
3509     ASSERT (result != NULL);
3510     ASSERT (result[0] == '1');
3511     ASSERT (result[1] == '.');
3512     for (i = 0; i < 511; i++)
3513       ASSERT (result[2 + i] == '0');
3514     ASSERT (strcmp (result + 2 + 511, " 99") == 0);
3515     ASSERT (length == strlen (result));
3516     free (result);
3517   }
3518 
3519   {
3520     char input[5000];
3521     size_t length;
3522     char *result;
3523     size_t i;
3524 
3525     for (i = 0; i < sizeof (input) - 1; i++)
3526       input[i] = 'a' + ((1000000 / (i + 1)) % 26);
3527     input[i] = '\0';
3528     result = my_asnprintf (NULL, &length, "%.4000s %d", input, 99);
3529     ASSERT (result != NULL);
3530     ASSERT (memcmp (result, input, 4000) == 0);
3531     ASSERT (strcmp (result + 4000, " 99") == 0);
3532     ASSERT (length == strlen (result));
3533     free (result);
3534   }
3535 
3536   /* Test the support of the %s format directive.  */
3537 
3538   /* To verify that these tests succeed, it is necessary to run them under
3539      a tool that checks against invalid memory accesses, such as ElectricFence
3540      or "valgrind --tool=memcheck".  */
3541   {
3542     size_t i;
3543 
3544     for (i = 1; i <= 8; i++)
3545       {
3546         char *block;
3547         size_t length;
3548         char *result;
3549 
3550         block = (char *) malloc (i);
3551         memcpy (block, "abcdefgh", i);
3552         result = my_asnprintf (NULL, &length, "%.*s", (int) i, block);
3553         ASSERT (result != NULL);
3554         ASSERT (memcmp (result, block, i) == 0);
3555         ASSERT (result[i] == '\0');
3556         ASSERT (length == strlen (result));
3557         free (result);
3558         free (block);
3559       }
3560   }
3561 #if HAVE_WCHAR_T
3562   {
3563     size_t i;
3564 
3565     for (i = 1; i <= 8; i++)
3566       {
3567         wchar_t *block;
3568         size_t j;
3569         size_t length;
3570         char *result;
3571 
3572         block = (wchar_t *) malloc (i * sizeof (wchar_t));
3573         for (j = 0; j < i; j++)
3574           block[j] = "abcdefgh"[j];
3575         result = my_asnprintf (NULL, &length, "%.*ls", (int) i, block);
3576         ASSERT (result != NULL);
3577         ASSERT (memcmp (result, "abcdefgh", i) == 0);
3578         ASSERT (result[i] == '\0');
3579         ASSERT (length == strlen (result));
3580         free (result);
3581         free (block);
3582       }
3583   }
3584 #endif
3585 
3586 #if HAVE_WCHAR_T
3587   /* Test that converting an invalid wchar_t[] to char[] fails with EILSEQ.  */
3588   {
3589     static const wchar_t input[] = { (wchar_t) 1702057263, 114, 0 };
3590     size_t length;
3591     char *result = my_asnprintf (NULL, &length, "%ls %d", input, 99);
3592     if (result == NULL)
3593       ASSERT (errno == EILSEQ);
3594     else
3595       free (result);
3596   }
3597   {
3598     static const wchar_t input[] = { (wchar_t) 1702057263, 114, 0 };
3599     size_t length;
3600     char *result = my_asnprintf (NULL, &length, "%3ls %d", input, 99);
3601     if (result == NULL)
3602       ASSERT (errno == EILSEQ);
3603     else
3604       free (result);
3605   }
3606   {
3607     static const wchar_t input[] = { (wchar_t) 1702057263, 114, 0 };
3608     size_t length;
3609     char *result = my_asnprintf (NULL, &length, "%.1ls %d", input, 99);
3610     if (result == NULL)
3611       ASSERT (errno == EILSEQ);
3612     else
3613       free (result);
3614   }
3615   {
3616     static const wchar_t input[] = { (wchar_t) 1702057263, 114, 0 };
3617     size_t length;
3618     char *result = my_asnprintf (NULL, &length, "%3.1ls %d", input, 99);
3619     if (result == NULL)
3620       ASSERT (errno == EILSEQ);
3621     else
3622       free (result);
3623   }
3624 #endif
3625 
3626 #if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
3627   /* Test that the 'I' flag is supported.  */
3628   {
3629     size_t length;
3630     char *result =
3631       my_asnprintf (NULL, &length, "%Id %d", 1234567, 99);
3632     ASSERT (result != NULL);
3633     ASSERT (strcmp (result, "1234567 99") == 0);
3634     ASSERT (length == strlen (result));
3635     free (result);
3636   }
3637 #endif
3638 }
3639 
3640 static char *
3641 my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
3642 {
3643   va_list args;
3644   char *ret;
3645 
3646   va_start (args, format);
3647   ret = vasnprintf (resultbuf, lengthp, format, args);
3648   va_end (args);
3649   return ret;
3650 }
3651 
3652 static void
3653 test_vasnprintf ()
     /* [previous][next][first][last][top][bottom][index][help] */
3654 {
3655   test_function (my_asnprintf);
3656 }
3657 
3658 static void
3659 test_asnprintf ()
     /* [previous][next][first][last][top][bottom][index][help] */
3660 {
3661   test_function (asnprintf);
3662 }
3663 
3664 int
3665 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
3666 {
3667   test_vasnprintf ();
3668   test_asnprintf ();
3669   return 0;
3670 }

/* [previous][next][first][last][top][bottom][index][help] */