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