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