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