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