root/maint/gnulib/tests/test-vasprintf-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_asprintf
  6. test_vasprintf
  7. test_asprintf
  8. main

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

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