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