More tests of printf %f.
[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 static int
58 strmatch (const char *pattern, const char *string)
59 {
60   if (strlen (pattern) != strlen (string))
61     return 0;
62   for (; *pattern != '\0'; pattern++, string++)
63     if (*pattern != '*' && *string != *pattern)
64       return 0;
65   return 1;
66 }
67
68 static void
69 test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
70 {
71   char buf[8];
72   int size;
73
74   /* Test return value convention.  */
75
76   for (size = 0; size <= 8; size++)
77     {
78       size_t length = size;
79       char *result = my_asnprintf (NULL, &length, "%d", 12345);
80       ASSERT (result != NULL);
81       ASSERT (strcmp (result, "12345") == 0);
82       ASSERT (length == 5);
83       free (result);
84     }
85
86   for (size = 0; size <= 8; size++)
87     {
88       size_t length;
89       char *result;
90
91       memcpy (buf, "DEADBEEF", 8);
92       length = size;
93       result = my_asnprintf (buf, &length, "%d", 12345);
94       ASSERT (result != NULL);
95       ASSERT (strcmp (result, "12345") == 0);
96       ASSERT (length == 5);
97       if (size < 6)
98         ASSERT (result != buf);
99       ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
100       if (result != buf)
101         free (result);
102     }
103
104   /* Test support of size specifiers as in C99.  */
105
106   {
107     size_t length;
108     char *result =
109       my_asnprintf (NULL, &length, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
110     ASSERT (result != NULL);
111     ASSERT (strcmp (result, "12345671 33") == 0);
112     ASSERT (length == strlen (result));
113     free (result);
114   }
115
116   {
117     size_t length;
118     char *result =
119       my_asnprintf (NULL, &length, "%zu %d", (size_t) 12345672, 33, 44, 55);
120     ASSERT (result != NULL);
121     ASSERT (strcmp (result, "12345672 33") == 0);
122     ASSERT (length == strlen (result));
123     free (result);
124   }
125
126   {
127     size_t length;
128     char *result =
129       my_asnprintf (NULL, &length, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
130     ASSERT (result != NULL);
131     ASSERT (strcmp (result, "12345673 33") == 0);
132     ASSERT (length == strlen (result));
133     free (result);
134   }
135
136   {
137     size_t length;
138     char *result =
139       my_asnprintf (NULL, &length, "%Lg %d", (long double) 1.5, 33, 44, 55);
140     ASSERT (result != NULL);
141     ASSERT (strcmp (result, "1.5 33") == 0);
142     ASSERT (length == strlen (result));
143     free (result);
144   }
145
146   /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
147      output of floating-point numbers.  */
148
149   { /* A positive number.  */
150     size_t length;
151     char *result =
152       my_asnprintf (NULL, &length, "%a %d", 3.1416015625, 33, 44, 55);
153     ASSERT (result != NULL);
154     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
155             || strcmp (result, "0x3.244p+0 33") == 0
156             || strcmp (result, "0x6.488p-1 33") == 0
157             || strcmp (result, "0xc.91p-2 33") == 0);
158     ASSERT (length == strlen (result));
159     free (result);
160   }
161
162   { /* A negative number.  */
163     size_t length;
164     char *result =
165       my_asnprintf (NULL, &length, "%A %d", -3.1416015625, 33, 44, 55);
166     ASSERT (result != NULL);
167     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
168             || strcmp (result, "-0X3.244P+0 33") == 0
169             || strcmp (result, "-0X6.488P-1 33") == 0
170             || strcmp (result, "-0XC.91P-2 33") == 0);
171     ASSERT (length == strlen (result));
172     free (result);
173   }
174
175   { /* Positive zero.  */
176     size_t length;
177     char *result =
178       my_asnprintf (NULL, &length, "%a %d", 0.0, 33, 44, 55);
179     ASSERT (result != NULL);
180     ASSERT (strcmp (result, "0x0p+0 33") == 0);
181     ASSERT (length == strlen (result));
182     free (result);
183   }
184
185   { /* Negative zero.  */
186     size_t length;
187     char *result =
188       my_asnprintf (NULL, &length, "%a %d", -0.0, 33, 44, 55);
189     ASSERT (result != NULL);
190     ASSERT (strcmp (result, "-0x0p+0 33") == 0);
191     ASSERT (length == strlen (result));
192     free (result);
193   }
194
195   { /* Positive infinity.  */
196     size_t length;
197     char *result =
198       my_asnprintf (NULL, &length, "%a %d", 1.0 / 0.0, 33, 44, 55);
199     ASSERT (result != NULL);
200     ASSERT (strcmp (result, "inf 33") == 0);
201     ASSERT (length == strlen (result));
202     free (result);
203   }
204
205   { /* Negative infinity.  */
206     size_t length;
207     char *result =
208       my_asnprintf (NULL, &length, "%a %d", -1.0 / 0.0, 33, 44, 55);
209     ASSERT (result != NULL);
210     ASSERT (strcmp (result, "-inf 33") == 0);
211     ASSERT (length == strlen (result));
212     free (result);
213   }
214
215   { /* NaN.  */
216     size_t length;
217     char *result =
218       my_asnprintf (NULL, &length, "%a %d", NaN (), 33, 44, 55);
219     ASSERT (result != NULL);
220     ASSERT (strcmp (result, "nan 33") == 0);
221     ASSERT (length == strlen (result));
222     free (result);
223   }
224
225   { /* Rounding near the decimal point.  */
226     size_t length;
227     char *result =
228       my_asnprintf (NULL, &length, "%.0a %d", 1.5, 33, 44, 55);
229     ASSERT (result != NULL);
230     ASSERT (strcmp (result, "0x2p+0 33") == 0
231             || strcmp (result, "0x3p-1 33") == 0
232             || strcmp (result, "0x6p-2 33") == 0
233             || strcmp (result, "0xcp-3 33") == 0);
234     ASSERT (length == strlen (result));
235     free (result);
236   }
237
238   { /* Rounding with precision 0.  */
239     size_t length;
240     char *result =
241       my_asnprintf (NULL, &length, "%.0a %d", 1.51, 33, 44, 55);
242     ASSERT (result != NULL);
243     ASSERT (strcmp (result, "0x2p+0 33") == 0
244             || strcmp (result, "0x3p-1 33") == 0
245             || strcmp (result, "0x6p-2 33") == 0
246             || strcmp (result, "0xcp-3 33") == 0);
247     ASSERT (length == strlen (result));
248     free (result);
249   }
250
251   { /* Rounding with precision 1.  */
252     size_t length;
253     char *result =
254       my_asnprintf (NULL, &length, "%.1a %d", 1.51, 33, 44, 55);
255     ASSERT (result != NULL);
256     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
257             || strcmp (result, "0x3.0p-1 33") == 0
258             || strcmp (result, "0x6.1p-2 33") == 0
259             || strcmp (result, "0xc.1p-3 33") == 0);
260     ASSERT (length == strlen (result));
261     free (result);
262   }
263
264   { /* Rounding with precision 2.  */
265     size_t length;
266     char *result =
267       my_asnprintf (NULL, &length, "%.2a %d", 1.51, 33, 44, 55);
268     ASSERT (result != NULL);
269     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
270             || strcmp (result, "0x3.05p-1 33") == 0
271             || strcmp (result, "0x6.0ap-2 33") == 0
272             || strcmp (result, "0xc.14p-3 33") == 0);
273     ASSERT (length == strlen (result));
274     free (result);
275   }
276
277   { /* Rounding with precision 3.  */
278     size_t length;
279     char *result =
280       my_asnprintf (NULL, &length, "%.3a %d", 1.51, 33, 44, 55);
281     ASSERT (result != NULL);
282     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
283             || strcmp (result, "0x3.052p-1 33") == 0
284             || strcmp (result, "0x6.0a4p-2 33") == 0
285             || strcmp (result, "0xc.148p-3 33") == 0);
286     ASSERT (length == strlen (result));
287     free (result);
288   }
289
290   { /* Rounding can turn a ...FFF into a ...000.  */
291     size_t length;
292     char *result =
293       my_asnprintf (NULL, &length, "%.3a %d", 1.49999, 33, 44, 55);
294     ASSERT (result != NULL);
295     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
296             || strcmp (result, "0x3.000p-1 33") == 0
297             || strcmp (result, "0x6.000p-2 33") == 0
298             || strcmp (result, "0xc.000p-3 33") == 0);
299     ASSERT (length == strlen (result));
300     free (result);
301   }
302
303   { /* Rounding can turn a ...FFF into a ...000.
304        This shows a MacOS X 10.3.9 (Darwin 7.9) bug.  */
305     size_t length;
306     char *result =
307       my_asnprintf (NULL, &length, "%.1a %d", 1.999, 33, 44, 55);
308     ASSERT (result != NULL);
309     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
310             || strcmp (result, "0x2.0p+0 33") == 0
311             || strcmp (result, "0x4.0p-1 33") == 0
312             || strcmp (result, "0x8.0p-2 33") == 0);
313     ASSERT (length == strlen (result));
314     free (result);
315   }
316
317   { /* Width.  */
318     size_t length;
319     char *result =
320       my_asnprintf (NULL, &length, "%10a %d", 1.75, 33, 44, 55);
321     ASSERT (result != NULL);
322     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
323             || strcmp (result, "  0x3.8p-1 33") == 0
324             || strcmp (result, "    0x7p-2 33") == 0
325             || strcmp (result, "    0xep-3 33") == 0);
326     ASSERT (length == strlen (result));
327     free (result);
328   }
329
330   { /* Small precision.  */
331     size_t length;
332     char *result =
333       my_asnprintf (NULL, &length, "%.10a %d", 1.75, 33, 44, 55);
334     ASSERT (result != NULL);
335     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
336             || strcmp (result, "0x3.8000000000p-1 33") == 0
337             || strcmp (result, "0x7.0000000000p-2 33") == 0
338             || strcmp (result, "0xe.0000000000p-3 33") == 0);
339     ASSERT (length == strlen (result));
340     free (result);
341   }
342
343   { /* Large precision.  */
344     size_t length;
345     char *result =
346       my_asnprintf (NULL, &length, "%.50a %d", 1.75, 33, 44, 55);
347     ASSERT (result != NULL);
348     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
349             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
350             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
351             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
352     ASSERT (length == strlen (result));
353     free (result);
354   }
355
356   { /* FLAG_LEFT.  */
357     size_t length;
358     char *result =
359       my_asnprintf (NULL, &length, "%-10a %d", 1.75, 33, 44, 55);
360     ASSERT (result != NULL);
361     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
362             || strcmp (result, "0x3.8p-1   33") == 0
363             || strcmp (result, "0x7p-2     33") == 0
364             || strcmp (result, "0xep-3     33") == 0);
365     ASSERT (length == strlen (result));
366     free (result);
367   }
368
369   { /* FLAG_SHOWSIGN.  */
370     size_t length;
371     char *result =
372       my_asnprintf (NULL, &length, "%+a %d", 1.75, 33, 44, 55);
373     ASSERT (result != NULL);
374     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
375             || strcmp (result, "+0x3.8p-1 33") == 0
376             || strcmp (result, "+0x7p-2 33") == 0
377             || strcmp (result, "+0xep-3 33") == 0);
378     ASSERT (length == strlen (result));
379     free (result);
380   }
381
382   { /* FLAG_SPACE.  */
383     size_t length;
384     char *result =
385       my_asnprintf (NULL, &length, "% a %d", 1.75, 33, 44, 55);
386     ASSERT (result != NULL);
387     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
388             || strcmp (result, " 0x3.8p-1 33") == 0
389             || strcmp (result, " 0x7p-2 33") == 0
390             || strcmp (result, " 0xep-3 33") == 0);
391     ASSERT (length == strlen (result));
392     free (result);
393   }
394
395   { /* FLAG_ALT.  */
396     size_t length;
397     char *result =
398       my_asnprintf (NULL, &length, "%#a %d", 1.75, 33, 44, 55);
399     ASSERT (result != NULL);
400     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
401             || strcmp (result, "0x3.8p-1 33") == 0
402             || strcmp (result, "0x7.p-2 33") == 0
403             || strcmp (result, "0xe.p-3 33") == 0);
404     ASSERT (length == strlen (result));
405     free (result);
406   }
407
408   { /* FLAG_ALT.  */
409     size_t length;
410     char *result =
411       my_asnprintf (NULL, &length, "%#a %d", 1.0, 33, 44, 55);
412     ASSERT (result != NULL);
413     ASSERT (strcmp (result, "0x1.p+0 33") == 0
414             || strcmp (result, "0x2.p-1 33") == 0
415             || strcmp (result, "0x4.p-2 33") == 0
416             || strcmp (result, "0x8.p-3 33") == 0);
417     ASSERT (length == strlen (result));
418     free (result);
419   }
420
421   { /* FLAG_ZERO with finite number.  */
422     size_t length;
423     char *result =
424       my_asnprintf (NULL, &length, "%010a %d", 1.75, 33, 44, 55);
425     ASSERT (result != NULL);
426     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
427             || strcmp (result, "0x003.8p-1 33") == 0
428             || strcmp (result, "0x00007p-2 33") == 0
429             || strcmp (result, "0x0000ep-3 33") == 0);
430     ASSERT (length == strlen (result));
431     free (result);
432   }
433
434   { /* FLAG_ZERO with infinite number.  */
435     size_t length;
436     char *result =
437       my_asnprintf (NULL, &length, "%010a %d", 1.0 / 0.0, 33, 44, 55);
438     ASSERT (result != NULL);
439     /* "0000000inf 33" is not a valid result; see
440        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
441     ASSERT (strcmp (result, "       inf 33") == 0);
442     ASSERT (length == strlen (result));
443     free (result);
444   }
445
446   { /* FLAG_ZERO with NaN.  */
447     size_t length;
448     char *result =
449       my_asnprintf (NULL, &length, "%010a %d", NaN (), 33, 44, 55);
450     ASSERT (result != NULL);
451     /* "0000000nan 33" is not a valid result; see
452        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
453     ASSERT (strcmp (result, "       nan 33") == 0);
454     ASSERT (length == strlen (result));
455     free (result);
456   }
457
458   { /* A positive number.  */
459     size_t length;
460     char *result =
461       my_asnprintf (NULL, &length, "%La %d", 3.1416015625L, 33, 44, 55);
462     ASSERT (result != NULL);
463     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
464             || strcmp (result, "0x3.244p+0 33") == 0
465             || strcmp (result, "0x6.488p-1 33") == 0
466             || strcmp (result, "0xc.91p-2 33") == 0);
467     ASSERT (length == strlen (result));
468     free (result);
469   }
470
471   { /* A negative number.  */
472     size_t length;
473     char *result =
474       my_asnprintf (NULL, &length, "%LA %d", -3.1416015625L, 33, 44, 55);
475     ASSERT (result != NULL);
476     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
477             || strcmp (result, "-0X3.244P+0 33") == 0
478             || strcmp (result, "-0X6.488P-1 33") == 0
479             || strcmp (result, "-0XC.91P-2 33") == 0);
480     ASSERT (length == strlen (result));
481     free (result);
482   }
483
484   { /* Positive zero.  */
485     size_t length;
486     char *result =
487       my_asnprintf (NULL, &length, "%La %d", 0.0L, 33, 44, 55);
488     ASSERT (result != NULL);
489     ASSERT (strcmp (result, "0x0p+0 33") == 0);
490     ASSERT (length == strlen (result));
491     free (result);
492   }
493
494   { /* Negative zero.  */
495     size_t length;
496     char *result =
497       my_asnprintf (NULL, &length, "%La %d", -0.0L, 33, 44, 55);
498     ASSERT (result != NULL);
499     ASSERT (strcmp (result, "-0x0p+0 33") == 0);
500     ASSERT (length == strlen (result));
501     free (result);
502   }
503
504   { /* Positive infinity.  */
505     size_t length;
506     char *result =
507       my_asnprintf (NULL, &length, "%La %d", 1.0L / 0.0L, 33, 44, 55);
508     ASSERT (result != NULL);
509     ASSERT (strcmp (result, "inf 33") == 0);
510     ASSERT (length == strlen (result));
511     free (result);
512   }
513
514   { /* Negative infinity.  */
515     size_t length;
516     char *result =
517       my_asnprintf (NULL, &length, "%La %d", -1.0L / 0.0L, 33, 44, 55);
518     ASSERT (result != NULL);
519     ASSERT (strcmp (result, "-inf 33") == 0);
520     ASSERT (length == strlen (result));
521     free (result);
522   }
523
524   { /* NaN.  */
525     size_t length;
526     char *result =
527       my_asnprintf (NULL, &length, "%La %d", 0.0L / 0.0L, 33, 44, 55);
528     ASSERT (result != NULL);
529     ASSERT (strcmp (result, "nan 33") == 0);
530     ASSERT (length == strlen (result));
531     free (result);
532   }
533
534   { /* Rounding near the decimal point.  */
535     size_t length;
536     char *result =
537       my_asnprintf (NULL, &length, "%.0La %d", 1.5L, 33, 44, 55);
538     ASSERT (result != NULL);
539     ASSERT (strcmp (result, "0x2p+0 33") == 0
540             || strcmp (result, "0x3p-1 33") == 0
541             || strcmp (result, "0x6p-2 33") == 0
542             || strcmp (result, "0xcp-3 33") == 0);
543     ASSERT (length == strlen (result));
544     free (result);
545   }
546
547   { /* Rounding with precision 0.  */
548     size_t length;
549     char *result =
550       my_asnprintf (NULL, &length, "%.0La %d", 1.51L, 33, 44, 55);
551     ASSERT (result != NULL);
552     ASSERT (strcmp (result, "0x2p+0 33") == 0
553             || strcmp (result, "0x3p-1 33") == 0
554             || strcmp (result, "0x6p-2 33") == 0
555             || strcmp (result, "0xcp-3 33") == 0);
556     ASSERT (length == strlen (result));
557     free (result);
558   }
559
560   { /* Rounding with precision 1.  */
561     size_t length;
562     char *result =
563       my_asnprintf (NULL, &length, "%.1La %d", 1.51L, 33, 44, 55);
564     ASSERT (result != NULL);
565     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
566             || strcmp (result, "0x3.0p-1 33") == 0
567             || strcmp (result, "0x6.1p-2 33") == 0
568             || strcmp (result, "0xc.1p-3 33") == 0);
569     ASSERT (length == strlen (result));
570     free (result);
571   }
572
573   { /* Rounding with precision 2.  */
574     size_t length;
575     char *result =
576       my_asnprintf (NULL, &length, "%.2La %d", 1.51L, 33, 44, 55);
577     ASSERT (result != NULL);
578     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
579             || strcmp (result, "0x3.05p-1 33") == 0
580             || strcmp (result, "0x6.0ap-2 33") == 0
581             || strcmp (result, "0xc.14p-3 33") == 0);
582     ASSERT (length == strlen (result));
583     free (result);
584   }
585
586   { /* Rounding with precision 3.  */
587     size_t length;
588     char *result =
589       my_asnprintf (NULL, &length, "%.3La %d", 1.51L, 33, 44, 55);
590     ASSERT (result != NULL);
591     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
592             || strcmp (result, "0x3.052p-1 33") == 0
593             || strcmp (result, "0x6.0a4p-2 33") == 0
594             || strcmp (result, "0xc.148p-3 33") == 0);
595     ASSERT (length == strlen (result));
596     free (result);
597   }
598
599   { /* Rounding can turn a ...FFF into a ...000.  */
600     size_t length;
601     char *result =
602       my_asnprintf (NULL, &length, "%.3La %d", 1.49999L, 33, 44, 55);
603     ASSERT (result != NULL);
604     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
605             || strcmp (result, "0x3.000p-1 33") == 0
606             || strcmp (result, "0x6.000p-2 33") == 0
607             || strcmp (result, "0xc.000p-3 33") == 0);
608     ASSERT (length == strlen (result));
609     free (result);
610   }
611
612   { /* Rounding can turn a ...FFF into a ...000.
613        This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
614        glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
615     size_t length;
616     char *result =
617       my_asnprintf (NULL, &length, "%.1La %d", 1.999L, 33, 44, 55);
618     ASSERT (result != NULL);
619     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
620             || strcmp (result, "0x2.0p+0 33") == 0
621             || strcmp (result, "0x4.0p-1 33") == 0
622             || strcmp (result, "0x8.0p-2 33") == 0);
623     ASSERT (length == strlen (result));
624     free (result);
625   }
626
627   { /* Width.  */
628     size_t length;
629     char *result =
630       my_asnprintf (NULL, &length, "%10La %d", 1.75L, 33, 44, 55);
631     ASSERT (result != NULL);
632     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
633             || strcmp (result, "  0x3.8p-1 33") == 0
634             || strcmp (result, "    0x7p-2 33") == 0
635             || strcmp (result, "    0xep-3 33") == 0);
636     ASSERT (length == strlen (result));
637     free (result);
638   }
639
640   { /* Small precision.  */
641     size_t length;
642     char *result =
643       my_asnprintf (NULL, &length, "%.10La %d", 1.75L, 33, 44, 55);
644     ASSERT (result != NULL);
645     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
646             || strcmp (result, "0x3.8000000000p-1 33") == 0
647             || strcmp (result, "0x7.0000000000p-2 33") == 0
648             || strcmp (result, "0xe.0000000000p-3 33") == 0);
649     ASSERT (length == strlen (result));
650     free (result);
651   }
652
653   { /* Large precision.  */
654     size_t length;
655     char *result =
656       my_asnprintf (NULL, &length, "%.50La %d", 1.75L, 33, 44, 55);
657     ASSERT (result != NULL);
658     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
659             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
660             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
661             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
662     ASSERT (length == strlen (result));
663     free (result);
664   }
665
666   { /* FLAG_LEFT.  */
667     size_t length;
668     char *result =
669       my_asnprintf (NULL, &length, "%-10La %d", 1.75L, 33, 44, 55);
670     ASSERT (result != NULL);
671     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
672             || strcmp (result, "0x3.8p-1   33") == 0
673             || strcmp (result, "0x7p-2     33") == 0
674             || strcmp (result, "0xep-3     33") == 0);
675     ASSERT (length == strlen (result));
676     free (result);
677   }
678
679   { /* FLAG_SHOWSIGN.  */
680     size_t length;
681     char *result =
682       my_asnprintf (NULL, &length, "%+La %d", 1.75L, 33, 44, 55);
683     ASSERT (result != NULL);
684     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
685             || strcmp (result, "+0x3.8p-1 33") == 0
686             || strcmp (result, "+0x7p-2 33") == 0
687             || strcmp (result, "+0xep-3 33") == 0);
688     ASSERT (length == strlen (result));
689     free (result);
690   }
691
692   { /* FLAG_SPACE.  */
693     size_t length;
694     char *result =
695       my_asnprintf (NULL, &length, "% La %d", 1.75L, 33, 44, 55);
696     ASSERT (result != NULL);
697     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
698             || strcmp (result, " 0x3.8p-1 33") == 0
699             || strcmp (result, " 0x7p-2 33") == 0
700             || strcmp (result, " 0xep-3 33") == 0);
701     ASSERT (length == strlen (result));
702     free (result);
703   }
704
705   { /* FLAG_ALT.  */
706     size_t length;
707     char *result =
708       my_asnprintf (NULL, &length, "%#La %d", 1.75L, 33, 44, 55);
709     ASSERT (result != NULL);
710     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
711             || strcmp (result, "0x3.8p-1 33") == 0
712             || strcmp (result, "0x7.p-2 33") == 0
713             || strcmp (result, "0xe.p-3 33") == 0);
714     ASSERT (length == strlen (result));
715     free (result);
716   }
717
718   { /* FLAG_ALT.  */
719     size_t length;
720     char *result =
721       my_asnprintf (NULL, &length, "%#La %d", 1.0L, 33, 44, 55);
722     ASSERT (result != NULL);
723     ASSERT (strcmp (result, "0x1.p+0 33") == 0
724             || strcmp (result, "0x2.p-1 33") == 0
725             || strcmp (result, "0x4.p-2 33") == 0
726             || strcmp (result, "0x8.p-3 33") == 0);
727     ASSERT (length == strlen (result));
728     free (result);
729   }
730
731   { /* FLAG_ZERO with finite number.  */
732     size_t length;
733     char *result =
734       my_asnprintf (NULL, &length, "%010La %d", 1.75L, 33, 44, 55);
735     ASSERT (result != NULL);
736     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
737             || strcmp (result, "0x003.8p-1 33") == 0
738             || strcmp (result, "0x00007p-2 33") == 0
739             || strcmp (result, "0x0000ep-3 33") == 0);
740     ASSERT (length == strlen (result));
741     free (result);
742   }
743
744   { /* FLAG_ZERO with infinite number.  */
745     size_t length;
746     char *result =
747       my_asnprintf (NULL, &length, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
748     ASSERT (result != NULL);
749     /* "0000000inf 33" is not a valid result; see
750        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
751     ASSERT (strcmp (result, "       inf 33") == 0);
752     ASSERT (length == strlen (result));
753     free (result);
754   }
755
756   { /* FLAG_ZERO with NaN.  */
757     size_t length;
758     char *result =
759       my_asnprintf (NULL, &length, "%010La %d", 0.0L / 0.0L, 33, 44, 55);
760     ASSERT (result != NULL);
761     /* "0000000nan 33" is not a valid result; see
762        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
763     ASSERT (strcmp (result, "       nan 33") == 0);
764     ASSERT (length == strlen (result));
765     free (result);
766   }
767
768   /* Test the support of the %f format directive.  */
769
770   { /* A positive number.  */
771     size_t length;
772     char *result =
773       my_asnprintf (NULL, &length, "%f %d", 12.75, 33, 44, 55);
774     ASSERT (result != NULL);
775     ASSERT (strcmp (result, "12.750000 33") == 0);
776     ASSERT (length == strlen (result));
777     free (result);
778   }
779
780   { /* A larger positive number.  */
781     size_t length;
782     char *result =
783       my_asnprintf (NULL, &length, "%f %d", 1234567.0, 33, 44, 55);
784     ASSERT (result != NULL);
785     ASSERT (strcmp (result, "1234567.000000 33") == 0);
786     ASSERT (length == strlen (result));
787     free (result);
788   }
789
790   { /* Small and large positive numbers.  */
791     static struct { double value; const char *string; } data[] =
792       {
793         { 1.234321234321234e-37, "0.000000" },
794         { 1.234321234321234e-36, "0.000000" },
795         { 1.234321234321234e-35, "0.000000" },
796         { 1.234321234321234e-34, "0.000000" },
797         { 1.234321234321234e-33, "0.000000" },
798         { 1.234321234321234e-32, "0.000000" },
799         { 1.234321234321234e-31, "0.000000" },
800         { 1.234321234321234e-30, "0.000000" },
801         { 1.234321234321234e-29, "0.000000" },
802         { 1.234321234321234e-28, "0.000000" },
803         { 1.234321234321234e-27, "0.000000" },
804         { 1.234321234321234e-26, "0.000000" },
805         { 1.234321234321234e-25, "0.000000" },
806         { 1.234321234321234e-24, "0.000000" },
807         { 1.234321234321234e-23, "0.000000" },
808         { 1.234321234321234e-22, "0.000000" },
809         { 1.234321234321234e-21, "0.000000" },
810         { 1.234321234321234e-20, "0.000000" },
811         { 1.234321234321234e-19, "0.000000" },
812         { 1.234321234321234e-18, "0.000000" },
813         { 1.234321234321234e-17, "0.000000" },
814         { 1.234321234321234e-16, "0.000000" },
815         { 1.234321234321234e-15, "0.000000" },
816         { 1.234321234321234e-14, "0.000000" },
817         { 1.234321234321234e-13, "0.000000" },
818         { 1.234321234321234e-12, "0.000000" },
819         { 1.234321234321234e-11, "0.000000" },
820         { 1.234321234321234e-10, "0.000000" },
821         { 1.234321234321234e-9, "0.000000" },
822         { 1.234321234321234e-8, "0.000000" },
823         { 1.234321234321234e-7, "0.000000" },
824         { 1.234321234321234e-6, "0.000001" },
825         { 1.234321234321234e-5, "0.000012" },
826         { 1.234321234321234e-4, "0.000123" },
827         { 1.234321234321234e-3, "0.001234" },
828         { 1.234321234321234e-2, "0.012343" },
829         { 1.234321234321234e-1, "0.123432" },
830         { 1.234321234321234, "1.234321" },
831         { 1.234321234321234e1, "12.343212" },
832         { 1.234321234321234e2, "123.432123" },
833         { 1.234321234321234e3, "1234.321234" },
834         { 1.234321234321234e4, "12343.212343" },
835         { 1.234321234321234e5, "123432.123432" },
836         { 1.234321234321234e6, "1234321.234321" },
837         { 1.234321234321234e7, "12343212.343212" },
838         { 1.234321234321234e8, "123432123.432123" },
839         { 1.234321234321234e9, "1234321234.321234" },
840         { 1.234321234321234e10, "12343212343.2123**" },
841         { 1.234321234321234e11, "123432123432.123***" },
842         { 1.234321234321234e12, "1234321234321.23****" },
843         { 1.234321234321234e13, "12343212343212.3*****" },
844         { 1.234321234321234e14, "123432123432123.******" },
845         { 1.234321234321234e15, "1234321234321234.000000" },
846         { 1.234321234321234e16, "123432123432123**.000000" },
847         { 1.234321234321234e17, "123432123432123***.000000" },
848         { 1.234321234321234e18, "123432123432123****.000000" },
849         { 1.234321234321234e19, "123432123432123*****.000000" },
850         { 1.234321234321234e20, "123432123432123******.000000" },
851         { 1.234321234321234e21, "123432123432123*******.000000" },
852         { 1.234321234321234e22, "123432123432123********.000000" },
853         { 1.234321234321234e23, "123432123432123*********.000000" },
854         { 1.234321234321234e24, "123432123432123**********.000000" },
855         { 1.234321234321234e25, "123432123432123***********.000000" },
856         { 1.234321234321234e26, "123432123432123************.000000" },
857         { 1.234321234321234e27, "123432123432123*************.000000" },
858         { 1.234321234321234e28, "123432123432123**************.000000" },
859         { 1.234321234321234e29, "123432123432123***************.000000" },
860         { 1.234321234321234e30, "123432123432123****************.000000" },
861         { 1.234321234321234e31, "123432123432123*****************.000000" },
862         { 1.234321234321234e32, "123432123432123******************.000000" },
863         { 1.234321234321234e33, "123432123432123*******************.000000" },
864         { 1.234321234321234e34, "123432123432123********************.000000" },
865         { 1.234321234321234e35, "123432123432123*********************.000000" },
866         { 1.234321234321234e36, "123432123432123**********************.000000" }
867       };
868     size_t k;
869     for (k = 0; k < SIZEOF (data); k++)
870       {
871         size_t length;
872         char *result =
873           my_asnprintf (NULL, &length, "%f", data[k].value);
874         ASSERT (result != NULL);
875         ASSERT (strmatch (data[k].string, result));
876         ASSERT (length == strlen (result));
877         free (result);
878       }
879   }
880
881   { /* A negative number.  */
882     size_t length;
883     char *result =
884       my_asnprintf (NULL, &length, "%f %d", -0.03125, 33, 44, 55);
885     ASSERT (result != NULL);
886     ASSERT (strcmp (result, "-0.031250 33") == 0);
887     ASSERT (length == strlen (result));
888     free (result);
889   }
890
891   { /* Positive zero.  */
892     size_t length;
893     char *result =
894       my_asnprintf (NULL, &length, "%f %d", 0.0, 33, 44, 55);
895     ASSERT (result != NULL);
896     ASSERT (strcmp (result, "0.000000 33") == 0);
897     ASSERT (length == strlen (result));
898     free (result);
899   }
900
901   { /* Negative zero.  */
902     size_t length;
903     char *result =
904       my_asnprintf (NULL, &length, "%f %d", -0.0, 33, 44, 55);
905     ASSERT (result != NULL);
906     ASSERT (strcmp (result, "-0.000000 33") == 0);
907     ASSERT (length == strlen (result));
908     free (result);
909   }
910
911   { /* Positive infinity.  */
912     size_t length;
913     char *result =
914       my_asnprintf (NULL, &length, "%f %d", 1.0 / 0.0, 33, 44, 55);
915     ASSERT (result != NULL);
916     ASSERT (strcmp (result, "inf 33") == 0
917             || strcmp (result, "infinity 33") == 0);
918     ASSERT (length == strlen (result));
919     free (result);
920   }
921
922   { /* Negative infinity.  */
923     size_t length;
924     char *result =
925       my_asnprintf (NULL, &length, "%f %d", -1.0 / 0.0, 33, 44, 55);
926     ASSERT (result != NULL);
927     ASSERT (strcmp (result, "-inf 33") == 0
928             || strcmp (result, "-infinity 33") == 0);
929     ASSERT (length == strlen (result));
930     free (result);
931   }
932
933   { /* NaN.  */
934     size_t length;
935     char *result =
936       my_asnprintf (NULL, &length, "%f %d", NaN (), 33, 44, 55);
937     ASSERT (result != NULL);
938     ASSERT (strcmp (result, "nan 33") == 0);
939     ASSERT (length == strlen (result));
940     free (result);
941   }
942
943   { /* Width.  */
944     size_t length;
945     char *result =
946       my_asnprintf (NULL, &length, "%10f %d", 1.75, 33, 44, 55);
947     ASSERT (result != NULL);
948     ASSERT (strcmp (result, "  1.750000 33") == 0);
949     ASSERT (length == strlen (result));
950     free (result);
951   }
952
953   { /* FLAG_LEFT.  */
954     size_t length;
955     char *result =
956       my_asnprintf (NULL, &length, "%-10f %d", 1.75, 33, 44, 55);
957     ASSERT (result != NULL);
958     ASSERT (strcmp (result, "1.750000   33") == 0);
959     ASSERT (length == strlen (result));
960     free (result);
961   }
962
963   { /* FLAG_SHOWSIGN.  */
964     size_t length;
965     char *result =
966       my_asnprintf (NULL, &length, "%+f %d", 1.75, 33, 44, 55);
967     ASSERT (result != NULL);
968     ASSERT (strcmp (result, "+1.750000 33") == 0);
969     ASSERT (length == strlen (result));
970     free (result);
971   }
972
973   { /* FLAG_SPACE.  */
974     size_t length;
975     char *result =
976       my_asnprintf (NULL, &length, "% f %d", 1.75, 33, 44, 55);
977     ASSERT (result != NULL);
978     ASSERT (strcmp (result, " 1.750000 33") == 0);
979     ASSERT (length == strlen (result));
980     free (result);
981   }
982
983   { /* FLAG_ALT.  */
984     size_t length;
985     char *result =
986       my_asnprintf (NULL, &length, "%#f %d", 1.75, 33, 44, 55);
987     ASSERT (result != NULL);
988     ASSERT (strcmp (result, "1.750000 33") == 0);
989     ASSERT (length == strlen (result));
990     free (result);
991   }
992
993   { /* FLAG_ALT.  */
994     size_t length;
995     char *result =
996       my_asnprintf (NULL, &length, "%#.f %d", 1.75, 33, 44, 55);
997     ASSERT (result != NULL);
998     ASSERT (strcmp (result, "2. 33") == 0);
999     ASSERT (length == strlen (result));
1000     free (result);
1001   }
1002
1003   { /* FLAG_ZERO with finite number.  */
1004     size_t length;
1005     char *result =
1006       my_asnprintf (NULL, &length, "%015f %d", 1234.0, 33, 44, 55);
1007     ASSERT (result != NULL);
1008     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1009     ASSERT (length == strlen (result));
1010     free (result);
1011   }
1012
1013   { /* FLAG_ZERO with infinite number.  */
1014     size_t length;
1015     char *result =
1016       my_asnprintf (NULL, &length, "%015f %d", -1.0 / 0.0, 33, 44, 55);
1017     ASSERT (result != NULL);
1018     ASSERT (strcmp (result, "           -inf 33") == 0
1019             || strcmp (result, "      -infinity 33") == 0);
1020     ASSERT (length == strlen (result));
1021     free (result);
1022   }
1023
1024   { /* FLAG_ZERO with NaN.  */
1025     size_t length;
1026     char *result =
1027       my_asnprintf (NULL, &length, "%015f %d", NaN (), 33, 44, 55);
1028     ASSERT (result != NULL);
1029     ASSERT (strcmp (result, "            nan 33") == 0);
1030     ASSERT (length == strlen (result));
1031     free (result);
1032   }
1033
1034   { /* Precision.  */
1035     size_t length;
1036     char *result =
1037       my_asnprintf (NULL, &length, "%.f %d", 1234.0, 33, 44, 55);
1038     ASSERT (result != NULL);
1039     ASSERT (strcmp (result, "1234 33") == 0);
1040     ASSERT (length == strlen (result));
1041     free (result);
1042   }
1043
1044   { /* A positive number.  */
1045     size_t length;
1046     char *result =
1047       my_asnprintf (NULL, &length, "%Lf %d", 12.75L, 33, 44, 55);
1048     ASSERT (result != NULL);
1049     ASSERT (strcmp (result, "12.750000 33") == 0);
1050     ASSERT (length == strlen (result));
1051     free (result);
1052   }
1053
1054   { /* A larger positive number.  */
1055     size_t length;
1056     char *result =
1057       my_asnprintf (NULL, &length, "%Lf %d", 1234567.0L, 33, 44, 55);
1058     ASSERT (result != NULL);
1059     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1060     ASSERT (length == strlen (result));
1061     free (result);
1062   }
1063
1064   { /* Small and large positive numbers.  */
1065     static struct { long double value; const char *string; } data[] =
1066       {
1067         { 1.234321234321234e-37L, "0.000000" },
1068         { 1.234321234321234e-36L, "0.000000" },
1069         { 1.234321234321234e-35L, "0.000000" },
1070         { 1.234321234321234e-34L, "0.000000" },
1071         { 1.234321234321234e-33L, "0.000000" },
1072         { 1.234321234321234e-32L, "0.000000" },
1073         { 1.234321234321234e-31L, "0.000000" },
1074         { 1.234321234321234e-30L, "0.000000" },
1075         { 1.234321234321234e-29L, "0.000000" },
1076         { 1.234321234321234e-28L, "0.000000" },
1077         { 1.234321234321234e-27L, "0.000000" },
1078         { 1.234321234321234e-26L, "0.000000" },
1079         { 1.234321234321234e-25L, "0.000000" },
1080         { 1.234321234321234e-24L, "0.000000" },
1081         { 1.234321234321234e-23L, "0.000000" },
1082         { 1.234321234321234e-22L, "0.000000" },
1083         { 1.234321234321234e-21L, "0.000000" },
1084         { 1.234321234321234e-20L, "0.000000" },
1085         { 1.234321234321234e-19L, "0.000000" },
1086         { 1.234321234321234e-18L, "0.000000" },
1087         { 1.234321234321234e-17L, "0.000000" },
1088         { 1.234321234321234e-16L, "0.000000" },
1089         { 1.234321234321234e-15L, "0.000000" },
1090         { 1.234321234321234e-14L, "0.000000" },
1091         { 1.234321234321234e-13L, "0.000000" },
1092         { 1.234321234321234e-12L, "0.000000" },
1093         { 1.234321234321234e-11L, "0.000000" },
1094         { 1.234321234321234e-10L, "0.000000" },
1095         { 1.234321234321234e-9L, "0.000000" },
1096         { 1.234321234321234e-8L, "0.000000" },
1097         { 1.234321234321234e-7L, "0.000000" },
1098         { 1.234321234321234e-6L, "0.000001" },
1099         { 1.234321234321234e-5L, "0.000012" },
1100         { 1.234321234321234e-4L, "0.000123" },
1101         { 1.234321234321234e-3L, "0.001234" },
1102         { 1.234321234321234e-2L, "0.012343" },
1103         { 1.234321234321234e-1L, "0.123432" },
1104         { 1.234321234321234L, "1.234321" },
1105         { 1.234321234321234e1L, "12.343212" },
1106         { 1.234321234321234e2L, "123.432123" },
1107         { 1.234321234321234e3L, "1234.321234" },
1108         { 1.234321234321234e4L, "12343.212343" },
1109         { 1.234321234321234e5L, "123432.123432" },
1110         { 1.234321234321234e6L, "1234321.234321" },
1111         { 1.234321234321234e7L, "12343212.343212" },
1112         { 1.234321234321234e8L, "123432123.432123" },
1113         { 1.234321234321234e9L, "1234321234.321234" },
1114         { 1.234321234321234e10L, "12343212343.2123**" },
1115         { 1.234321234321234e11L, "123432123432.123***" },
1116         { 1.234321234321234e12L, "1234321234321.23****" },
1117         { 1.234321234321234e13L, "12343212343212.3*****" },
1118         { 1.234321234321234e14L, "123432123432123.******" },
1119         { 1.234321234321234e15L, "1234321234321234.000000" },
1120         { 1.234321234321234e16L, "123432123432123**.000000" },
1121         { 1.234321234321234e17L, "123432123432123***.000000" },
1122         { 1.234321234321234e18L, "123432123432123****.000000" },
1123         { 1.234321234321234e19L, "123432123432123*****.000000" },
1124         { 1.234321234321234e20L, "123432123432123******.000000" },
1125         { 1.234321234321234e21L, "123432123432123*******.000000" },
1126         { 1.234321234321234e22L, "123432123432123********.000000" },
1127         { 1.234321234321234e23L, "123432123432123*********.000000" },
1128         { 1.234321234321234e24L, "123432123432123**********.000000" },
1129         { 1.234321234321234e25L, "123432123432123***********.000000" },
1130         { 1.234321234321234e26L, "123432123432123************.000000" },
1131         { 1.234321234321234e27L, "123432123432123*************.000000" },
1132         { 1.234321234321234e28L, "123432123432123**************.000000" },
1133         { 1.234321234321234e29L, "123432123432123***************.000000" },
1134         { 1.234321234321234e30L, "123432123432123****************.000000" },
1135         { 1.234321234321234e31L, "123432123432123*****************.000000" },
1136         { 1.234321234321234e32L, "123432123432123******************.000000" },
1137         { 1.234321234321234e33L, "123432123432123*******************.000000" },
1138         { 1.234321234321234e34L, "123432123432123********************.000000" },
1139         { 1.234321234321234e35L, "123432123432123*********************.000000" },
1140         { 1.234321234321234e36L, "123432123432123**********************.000000" }
1141       };
1142     size_t k;
1143     for (k = 0; k < SIZEOF (data); k++)
1144       {
1145         size_t length;
1146         char *result =
1147           my_asnprintf (NULL, &length, "%Lf", data[k].value);
1148         ASSERT (result != NULL);
1149         ASSERT (strmatch (data[k].string, result));
1150         ASSERT (length == strlen (result));
1151         free (result);
1152       }
1153   }
1154
1155   { /* A negative number.  */
1156     size_t length;
1157     char *result =
1158       my_asnprintf (NULL, &length, "%Lf %d", -0.03125L, 33, 44, 55);
1159     ASSERT (result != NULL);
1160     ASSERT (strcmp (result, "-0.031250 33") == 0);
1161     ASSERT (length == strlen (result));
1162     free (result);
1163   }
1164
1165   { /* Positive zero.  */
1166     size_t length;
1167     char *result =
1168       my_asnprintf (NULL, &length, "%Lf %d", 0.0L, 33, 44, 55);
1169     ASSERT (result != NULL);
1170     ASSERT (strcmp (result, "0.000000 33") == 0);
1171     ASSERT (length == strlen (result));
1172     free (result);
1173   }
1174
1175   { /* Negative zero.  */
1176     size_t length;
1177     char *result =
1178       my_asnprintf (NULL, &length, "%Lf %d", -0.0L, 33, 44, 55);
1179     ASSERT (result != NULL);
1180     ASSERT (strcmp (result, "-0.000000 33") == 0);
1181     ASSERT (length == strlen (result));
1182     free (result);
1183   }
1184
1185   { /* Positive infinity.  */
1186     size_t length;
1187     char *result =
1188       my_asnprintf (NULL, &length, "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
1189     ASSERT (result != NULL);
1190     ASSERT (strcmp (result, "inf 33") == 0
1191             || strcmp (result, "infinity 33") == 0);
1192     ASSERT (length == strlen (result));
1193     free (result);
1194   }
1195
1196   { /* Negative infinity.  */
1197     size_t length;
1198     char *result =
1199       my_asnprintf (NULL, &length, "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
1200     ASSERT (result != NULL);
1201     ASSERT (strcmp (result, "-inf 33") == 0
1202             || strcmp (result, "-infinity 33") == 0);
1203     ASSERT (length == strlen (result));
1204     free (result);
1205   }
1206
1207   { /* NaN.  */
1208     static long double zero = 0.0L;
1209     size_t length;
1210     char *result =
1211       my_asnprintf (NULL, &length, "%Lf %d", zero / zero, 33, 44, 55);
1212     ASSERT (result != NULL);
1213     ASSERT (strcmp (result, "nan 33") == 0);
1214     ASSERT (length == strlen (result));
1215     free (result);
1216   }
1217
1218   { /* Width.  */
1219     size_t length;
1220     char *result =
1221       my_asnprintf (NULL, &length, "%10Lf %d", 1.75L, 33, 44, 55);
1222     ASSERT (result != NULL);
1223     ASSERT (strcmp (result, "  1.750000 33") == 0);
1224     ASSERT (length == strlen (result));
1225     free (result);
1226   }
1227
1228   { /* FLAG_LEFT.  */
1229     size_t length;
1230     char *result =
1231       my_asnprintf (NULL, &length, "%-10Lf %d", 1.75L, 33, 44, 55);
1232     ASSERT (result != NULL);
1233     ASSERT (strcmp (result, "1.750000   33") == 0);
1234     ASSERT (length == strlen (result));
1235     free (result);
1236   }
1237
1238   { /* FLAG_SHOWSIGN.  */
1239     size_t length;
1240     char *result =
1241       my_asnprintf (NULL, &length, "%+Lf %d", 1.75L, 33, 44, 55);
1242     ASSERT (result != NULL);
1243     ASSERT (strcmp (result, "+1.750000 33") == 0);
1244     ASSERT (length == strlen (result));
1245     free (result);
1246   }
1247
1248   { /* FLAG_SPACE.  */
1249     size_t length;
1250     char *result =
1251       my_asnprintf (NULL, &length, "% Lf %d", 1.75L, 33, 44, 55);
1252     ASSERT (result != NULL);
1253     ASSERT (strcmp (result, " 1.750000 33") == 0);
1254     ASSERT (length == strlen (result));
1255     free (result);
1256   }
1257
1258   { /* FLAG_ALT.  */
1259     size_t length;
1260     char *result =
1261       my_asnprintf (NULL, &length, "%#Lf %d", 1.75L, 33, 44, 55);
1262     ASSERT (result != NULL);
1263     ASSERT (strcmp (result, "1.750000 33") == 0);
1264     ASSERT (length == strlen (result));
1265     free (result);
1266   }
1267
1268   { /* FLAG_ALT.  */
1269     size_t length;
1270     char *result =
1271       my_asnprintf (NULL, &length, "%#.Lf %d", 1.75L, 33, 44, 55);
1272     ASSERT (result != NULL);
1273     ASSERT (strcmp (result, "2. 33") == 0);
1274     ASSERT (length == strlen (result));
1275     free (result);
1276   }
1277
1278   { /* FLAG_ZERO with finite number.  */
1279     size_t length;
1280     char *result =
1281       my_asnprintf (NULL, &length, "%015Lf %d", 1234.0L, 33, 44, 55);
1282     ASSERT (result != NULL);
1283     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1284     ASSERT (length == strlen (result));
1285     free (result);
1286   }
1287
1288   { /* FLAG_ZERO with infinite number.  */
1289     size_t length;
1290     char *result =
1291       my_asnprintf (NULL, &length, "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
1292     ASSERT (result != NULL);
1293     ASSERT (strcmp (result, "           -inf 33") == 0
1294             || strcmp (result, "      -infinity 33") == 0);
1295     ASSERT (length == strlen (result));
1296     free (result);
1297   }
1298
1299   { /* FLAG_ZERO with NaN.  */
1300     static long double zero = 0.0L;
1301     size_t length;
1302     char *result =
1303       my_asnprintf (NULL, &length, "%015Lf %d", zero / zero, 33, 44, 55);
1304     ASSERT (result != NULL);
1305     ASSERT (strcmp (result, "            nan 33") == 0);
1306     ASSERT (length == strlen (result));
1307     free (result);
1308   }
1309
1310   { /* Precision.  */
1311     size_t length;
1312     char *result =
1313       my_asnprintf (NULL, &length, "%.Lf %d", 1234.0L, 33, 44, 55);
1314     ASSERT (result != NULL);
1315     ASSERT (strcmp (result, "1234 33") == 0);
1316     ASSERT (length == strlen (result));
1317     free (result);
1318   }
1319
1320   /* Test the support of the %F format directive.  */
1321
1322   { /* A positive number.  */
1323     size_t length;
1324     char *result =
1325       my_asnprintf (NULL, &length, "%F %d", 12.75, 33, 44, 55);
1326     ASSERT (result != NULL);
1327     ASSERT (strcmp (result, "12.750000 33") == 0);
1328     ASSERT (length == strlen (result));
1329     free (result);
1330   }
1331
1332   { /* A larger positive number.  */
1333     size_t length;
1334     char *result =
1335       my_asnprintf (NULL, &length, "%F %d", 1234567.0, 33, 44, 55);
1336     ASSERT (result != NULL);
1337     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1338     ASSERT (length == strlen (result));
1339     free (result);
1340   }
1341
1342   { /* A negative number.  */
1343     size_t length;
1344     char *result =
1345       my_asnprintf (NULL, &length, "%F %d", -0.03125, 33, 44, 55);
1346     ASSERT (result != NULL);
1347     ASSERT (strcmp (result, "-0.031250 33") == 0);
1348     ASSERT (length == strlen (result));
1349     free (result);
1350   }
1351
1352   { /* Positive zero.  */
1353     size_t length;
1354     char *result =
1355       my_asnprintf (NULL, &length, "%F %d", 0.0, 33, 44, 55);
1356     ASSERT (result != NULL);
1357     ASSERT (strcmp (result, "0.000000 33") == 0);
1358     ASSERT (length == strlen (result));
1359     free (result);
1360   }
1361
1362   { /* Negative zero.  */
1363     size_t length;
1364     char *result =
1365       my_asnprintf (NULL, &length, "%F %d", -0.0, 33, 44, 55);
1366     ASSERT (result != NULL);
1367     ASSERT (strcmp (result, "-0.000000 33") == 0);
1368     ASSERT (length == strlen (result));
1369     free (result);
1370   }
1371
1372   { /* Positive infinity.  */
1373     size_t length;
1374     char *result =
1375       my_asnprintf (NULL, &length, "%F %d", 1.0 / 0.0, 33, 44, 55);
1376     ASSERT (result != NULL);
1377     ASSERT (strcmp (result, "INF 33") == 0
1378             || strcmp (result, "INFINITY 33") == 0);
1379     ASSERT (length == strlen (result));
1380     free (result);
1381   }
1382
1383   { /* Negative infinity.  */
1384     size_t length;
1385     char *result =
1386       my_asnprintf (NULL, &length, "%F %d", -1.0 / 0.0, 33, 44, 55);
1387     ASSERT (result != NULL);
1388     ASSERT (strcmp (result, "-INF 33") == 0
1389             || strcmp (result, "-INFINITY 33") == 0);
1390     ASSERT (length == strlen (result));
1391     free (result);
1392   }
1393
1394   { /* NaN.  */
1395     size_t length;
1396     char *result =
1397       my_asnprintf (NULL, &length, "%F %d", NaN (), 33, 44, 55);
1398     ASSERT (result != NULL);
1399     ASSERT (strcmp (result, "NAN 33") == 0);
1400     ASSERT (length == strlen (result));
1401     free (result);
1402   }
1403
1404   { /* FLAG_ZERO.  */
1405     size_t length;
1406     char *result =
1407       my_asnprintf (NULL, &length, "%015F %d", 1234.0, 33, 44, 55);
1408     ASSERT (result != NULL);
1409     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1410     ASSERT (length == strlen (result));
1411     free (result);
1412   }
1413
1414   { /* FLAG_ZERO with infinite number.  */
1415     size_t length;
1416     char *result =
1417       my_asnprintf (NULL, &length, "%015F %d", -1.0 / 0.0, 33, 44, 55);
1418     ASSERT (result != NULL);
1419     ASSERT (strcmp (result, "           -INF 33") == 0
1420             || strcmp (result, "      -INFINITY 33") == 0);
1421     ASSERT (length == strlen (result));
1422     free (result);
1423   }
1424
1425   { /* Precision.  */
1426     size_t length;
1427     char *result =
1428       my_asnprintf (NULL, &length, "%.F %d", 1234.0, 33, 44, 55);
1429     ASSERT (result != NULL);
1430     ASSERT (strcmp (result, "1234 33") == 0);
1431     ASSERT (length == strlen (result));
1432     free (result);
1433   }
1434
1435   { /* A positive number.  */
1436     size_t length;
1437     char *result =
1438       my_asnprintf (NULL, &length, "%LF %d", 12.75L, 33, 44, 55);
1439     ASSERT (result != NULL);
1440     ASSERT (strcmp (result, "12.750000 33") == 0);
1441     ASSERT (length == strlen (result));
1442     free (result);
1443   }
1444
1445   { /* A larger positive number.  */
1446     size_t length;
1447     char *result =
1448       my_asnprintf (NULL, &length, "%LF %d", 1234567.0L, 33, 44, 55);
1449     ASSERT (result != NULL);
1450     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1451     ASSERT (length == strlen (result));
1452     free (result);
1453   }
1454
1455   { /* A negative number.  */
1456     size_t length;
1457     char *result =
1458       my_asnprintf (NULL, &length, "%LF %d", -0.03125L, 33, 44, 55);
1459     ASSERT (result != NULL);
1460     ASSERT (strcmp (result, "-0.031250 33") == 0);
1461     ASSERT (length == strlen (result));
1462     free (result);
1463   }
1464
1465   { /* Positive zero.  */
1466     size_t length;
1467     char *result =
1468       my_asnprintf (NULL, &length, "%LF %d", 0.0L, 33, 44, 55);
1469     ASSERT (result != NULL);
1470     ASSERT (strcmp (result, "0.000000 33") == 0);
1471     ASSERT (length == strlen (result));
1472     free (result);
1473   }
1474
1475   { /* Negative zero.  */
1476     size_t length;
1477     char *result =
1478       my_asnprintf (NULL, &length, "%LF %d", -0.0L, 33, 44, 55);
1479     ASSERT (result != NULL);
1480     ASSERT (strcmp (result, "-0.000000 33") == 0);
1481     ASSERT (length == strlen (result));
1482     free (result);
1483   }
1484
1485   { /* Positive infinity.  */
1486     size_t length;
1487     char *result =
1488       my_asnprintf (NULL, &length, "%LF %d", 1.0L / 0.0L, 33, 44, 55);
1489     ASSERT (result != NULL);
1490     ASSERT (strcmp (result, "INF 33") == 0
1491             || strcmp (result, "INFINITY 33") == 0);
1492     ASSERT (length == strlen (result));
1493     free (result);
1494   }
1495
1496   { /* Negative infinity.  */
1497     size_t length;
1498     char *result =
1499       my_asnprintf (NULL, &length, "%LF %d", -1.0L / 0.0L, 33, 44, 55);
1500     ASSERT (result != NULL);
1501     ASSERT (strcmp (result, "-INF 33") == 0
1502             || strcmp (result, "-INFINITY 33") == 0);
1503     ASSERT (length == strlen (result));
1504     free (result);
1505   }
1506
1507   { /* NaN.  */
1508     static long double zero = 0.0L;
1509     size_t length;
1510     char *result =
1511       my_asnprintf (NULL, &length, "%LF %d", zero / zero, 33, 44, 55);
1512     ASSERT (result != NULL);
1513     ASSERT (strcmp (result, "NAN 33") == 0);
1514     ASSERT (length == strlen (result));
1515     free (result);
1516   }
1517
1518   { /* FLAG_ZERO.  */
1519     size_t length;
1520     char *result =
1521       my_asnprintf (NULL, &length, "%015LF %d", 1234.0L, 33, 44, 55);
1522     ASSERT (result != NULL);
1523     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1524     ASSERT (length == strlen (result));
1525     free (result);
1526   }
1527
1528   { /* FLAG_ZERO with infinite number.  */
1529     size_t length;
1530     char *result =
1531       my_asnprintf (NULL, &length, "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
1532     ASSERT (result != NULL);
1533     ASSERT (strcmp (result, "           -INF 33") == 0
1534             || strcmp (result, "      -INFINITY 33") == 0);
1535     ASSERT (length == strlen (result));
1536     free (result);
1537   }
1538
1539   { /* Precision.  */
1540     size_t length;
1541     char *result =
1542       my_asnprintf (NULL, &length, "%.LF %d", 1234.0L, 33, 44, 55);
1543     ASSERT (result != NULL);
1544     ASSERT (strcmp (result, "1234 33") == 0);
1545     ASSERT (length == strlen (result));
1546     free (result);
1547   }
1548
1549   /* Test the support of the %n format directive.  */
1550
1551   {
1552     int count = -1;
1553     size_t length;
1554     char *result =
1555       my_asnprintf (NULL, &length, "%d %n", 123, &count, 33, 44, 55);
1556     ASSERT (result != NULL);
1557     ASSERT (strcmp (result, "123 ") == 0);
1558     ASSERT (length == strlen (result));
1559     ASSERT (count == 4);
1560     free (result);
1561   }
1562
1563   /* Test the support of the POSIX/XSI format strings with positions.  */
1564
1565   {
1566     size_t length;
1567     char *result =
1568       my_asnprintf (NULL, &length, "%2$d %1$d", 33, 55);
1569     ASSERT (result != NULL);
1570     ASSERT (strcmp (result, "55 33") == 0);
1571     ASSERT (length == strlen (result));
1572     free (result);
1573   }
1574
1575   /* Test the support of the grouping flag.  */
1576
1577   {
1578     size_t length;
1579     char *result =
1580       my_asnprintf (NULL, &length, "%'d %d", 1234567, 99);
1581     ASSERT (result != NULL);
1582     ASSERT (result[strlen (result) - 1] == '9');
1583     ASSERT (length == strlen (result));
1584     free (result);
1585   }
1586 }
1587
1588 static char *
1589 my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
1590 {
1591   va_list args;
1592   char *ret;
1593
1594   va_start (args, format);
1595   ret = vasnprintf (resultbuf, lengthp, format, args);
1596   va_end (args);
1597   return ret;
1598 }
1599
1600 static void
1601 test_vasnprintf ()
1602 {
1603   test_function (my_asnprintf);
1604 }
1605
1606 static void
1607 test_asnprintf ()
1608 {
1609   test_function (asnprintf);
1610 }
1611
1612 int
1613 main (int argc, char *argv[])
1614 {
1615   test_vasnprintf ();
1616   test_asnprintf ();
1617   return 0;
1618 }