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