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