Guarantee a definition of NAN.
[gnulib.git] / tests / test-vasprintf-posix.c
1 /* Test of POSIX compatible vasprintf() and asprintf() functions.
2    Copyright (C) 2007-2008 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 3 of the License, or
7    (at your option) 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, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22
23 #include <float.h>
24 #include <math.h>
25 #include <stdarg.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
33 #define ASSERT(expr) \
34   do                                                                         \
35     {                                                                        \
36       if (!(expr))                                                           \
37         {                                                                    \
38           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
39           abort ();                                                          \
40         }                                                                    \
41     }                                                                        \
42   while (0)
43
44 /* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0.  */
45 static int
46 have_minus_zero ()
47 {
48   static double plus_zero = 0.0;
49   static double minus_zero = -0.0;
50   return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
51 }
52
53 /* Representation of an 80-bit 'long double' as an initializer for a sequence
54    of 'unsigned int' words.  */
55 #ifdef WORDS_BIGENDIAN
56 # define LDBL80_WORDS(exponent,manthi,mantlo) \
57     { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
58       ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
59       (unsigned int) (mantlo) << 16                                        \
60     }
61 #else
62 # define LDBL80_WORDS(exponent,manthi,mantlo) \
63     { mantlo, manthi, exponent }
64 #endif
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, "%050a %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) == 50 + 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 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
553   { /* Quiet NaN.  */
554     static union { unsigned int word[4]; long double value; } x =
555       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
556     char *result;
557     int retval =
558       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
559     ASSERT (result != NULL);
560     ASSERT (strlen (result) >= 3 + 3
561             && strisnan (result, 0, strlen (result) - 3, 0)
562             && strcmp (result + strlen (result) - 3, " 33") == 0);
563     ASSERT (retval == strlen (result));
564     free (result);
565   }
566   {
567     /* Signalling NaN.  */
568     static union { unsigned int word[4]; long double value; } x =
569       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
570     char *result;
571     int retval =
572       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
573     ASSERT (result != NULL);
574     ASSERT (strlen (result) >= 3 + 3
575             && strisnan (result, 0, strlen (result) - 3, 0)
576             && strcmp (result + strlen (result) - 3, " 33") == 0);
577     ASSERT (retval == strlen (result));
578     free (result);
579   }
580   /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
581      Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
582        Intel IA-64 Architecture Software Developer's Manual, Volume 1:
583        Application Architecture.
584        Table 5-2 "Floating-Point Register Encodings"
585        Figure 5-6 "Memory to Floating-Point Register Data Translation"
586    */
587   { /* Pseudo-NaN.  */
588     static union { unsigned int word[4]; long double value; } x =
589       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
590     char *result;
591     int retval =
592       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
593     ASSERT (result != NULL);
594     ASSERT (strlen (result) >= 3 + 3
595             && strisnan (result, 0, strlen (result) - 3, 0)
596             && strcmp (result + strlen (result) - 3, " 33") == 0);
597     ASSERT (retval == strlen (result));
598     free (result);
599   }
600   { /* Pseudo-Infinity.  */
601     static union { unsigned int word[4]; long double value; } x =
602       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
603     char *result;
604     int retval =
605       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
606     ASSERT (result != NULL);
607     ASSERT (strlen (result) >= 3 + 3
608             && strisnan (result, 0, strlen (result) - 3, 0)
609             && strcmp (result + strlen (result) - 3, " 33") == 0);
610     ASSERT (retval == strlen (result));
611     free (result);
612   }
613   { /* Pseudo-Zero.  */
614     static union { unsigned int word[4]; long double value; } x =
615       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
616     char *result;
617     int retval =
618       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
619     ASSERT (result != NULL);
620     ASSERT (strlen (result) >= 3 + 3
621             && strisnan (result, 0, strlen (result) - 3, 0)
622             && strcmp (result + strlen (result) - 3, " 33") == 0);
623     ASSERT (retval == strlen (result));
624     free (result);
625   }
626   { /* Unnormalized number.  */
627     static union { unsigned int word[4]; long double value; } x =
628       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
629     char *result;
630     int retval =
631       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
632     ASSERT (result != NULL);
633     ASSERT (strlen (result) >= 3 + 3
634             && strisnan (result, 0, strlen (result) - 3, 0)
635             && strcmp (result + strlen (result) - 3, " 33") == 0);
636     ASSERT (retval == strlen (result));
637     free (result);
638   }
639   { /* Pseudo-Denormal.  */
640     static union { unsigned int word[4]; long double value; } x =
641       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
642     char *result;
643     int retval =
644       my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
645     ASSERT (result != NULL);
646     ASSERT (strlen (result) >= 3 + 3
647             && strisnan (result, 0, strlen (result) - 3, 0)
648             && strcmp (result + strlen (result) - 3, " 33") == 0);
649     ASSERT (retval == strlen (result));
650     free (result);
651   }
652 #endif
653
654   { /* Rounding near the decimal point.  */
655     char *result;
656     int retval =
657       my_asprintf (&result, "%.0La %d", 1.5L, 33, 44, 55);
658     ASSERT (result != NULL);
659     ASSERT (strcmp (result, "0x2p+0 33") == 0
660             || strcmp (result, "0x3p-1 33") == 0
661             || strcmp (result, "0x6p-2 33") == 0
662             || strcmp (result, "0xcp-3 33") == 0);
663     ASSERT (retval == strlen (result));
664     free (result);
665   }
666
667   { /* Rounding with precision 0.  */
668     char *result;
669     int retval =
670       my_asprintf (&result, "%.0La %d", 1.51L, 33, 44, 55);
671     ASSERT (result != NULL);
672     ASSERT (strcmp (result, "0x2p+0 33") == 0
673             || strcmp (result, "0x3p-1 33") == 0
674             || strcmp (result, "0x6p-2 33") == 0
675             || strcmp (result, "0xcp-3 33") == 0);
676     ASSERT (retval == strlen (result));
677     free (result);
678   }
679
680   { /* Rounding with precision 1.  */
681     char *result;
682     int retval =
683       my_asprintf (&result, "%.1La %d", 1.51L, 33, 44, 55);
684     ASSERT (result != NULL);
685     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
686             || strcmp (result, "0x3.0p-1 33") == 0
687             || strcmp (result, "0x6.1p-2 33") == 0
688             || strcmp (result, "0xc.1p-3 33") == 0);
689     ASSERT (retval == strlen (result));
690     free (result);
691   }
692
693   { /* Rounding with precision 2.  */
694     char *result;
695     int retval =
696       my_asprintf (&result, "%.2La %d", 1.51L, 33, 44, 55);
697     ASSERT (result != NULL);
698     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
699             || strcmp (result, "0x3.05p-1 33") == 0
700             || strcmp (result, "0x6.0ap-2 33") == 0
701             || strcmp (result, "0xc.14p-3 33") == 0);
702     ASSERT (retval == strlen (result));
703     free (result);
704   }
705
706   { /* Rounding with precision 3.  */
707     char *result;
708     int retval =
709       my_asprintf (&result, "%.3La %d", 1.51L, 33, 44, 55);
710     ASSERT (result != NULL);
711     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
712             || strcmp (result, "0x3.052p-1 33") == 0
713             || strcmp (result, "0x6.0a4p-2 33") == 0
714             || strcmp (result, "0xc.148p-3 33") == 0);
715     ASSERT (retval == strlen (result));
716     free (result);
717   }
718
719   { /* Rounding can turn a ...FFF into a ...000.  */
720     char *result;
721     int retval =
722       my_asprintf (&result, "%.3La %d", 1.49999L, 33, 44, 55);
723     ASSERT (result != NULL);
724     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
725             || strcmp (result, "0x3.000p-1 33") == 0
726             || strcmp (result, "0x6.000p-2 33") == 0
727             || strcmp (result, "0xc.000p-3 33") == 0);
728     ASSERT (retval == strlen (result));
729     free (result);
730   }
731
732   { /* Rounding can turn a ...FFF into a ...000.
733        This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
734        glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
735     char *result;
736     int retval =
737       my_asprintf (&result, "%.1La %d", 1.999L, 33, 44, 55);
738     ASSERT (result != NULL);
739     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
740             || strcmp (result, "0x2.0p+0 33") == 0
741             || strcmp (result, "0x4.0p-1 33") == 0
742             || strcmp (result, "0x8.0p-2 33") == 0);
743     ASSERT (retval == strlen (result));
744     free (result);
745   }
746
747   { /* Width.  */
748     char *result;
749     int retval =
750       my_asprintf (&result, "%10La %d", 1.75L, 33, 44, 55);
751     ASSERT (result != NULL);
752     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
753             || strcmp (result, "  0x3.8p-1 33") == 0
754             || strcmp (result, "    0x7p-2 33") == 0
755             || strcmp (result, "    0xep-3 33") == 0);
756     ASSERT (retval == strlen (result));
757     free (result);
758   }
759
760   { /* Small precision.  */
761     char *result;
762     int retval =
763       my_asprintf (&result, "%.10La %d", 1.75L, 33, 44, 55);
764     ASSERT (result != NULL);
765     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
766             || strcmp (result, "0x3.8000000000p-1 33") == 0
767             || strcmp (result, "0x7.0000000000p-2 33") == 0
768             || strcmp (result, "0xe.0000000000p-3 33") == 0);
769     ASSERT (retval == strlen (result));
770     free (result);
771   }
772
773   { /* Large precision.  */
774     char *result;
775     int retval =
776       my_asprintf (&result, "%.50La %d", 1.75L, 33, 44, 55);
777     ASSERT (result != NULL);
778     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
779             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
780             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
781             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
782     ASSERT (retval == strlen (result));
783     free (result);
784   }
785
786   { /* FLAG_LEFT.  */
787     char *result;
788     int retval =
789       my_asprintf (&result, "%-10La %d", 1.75L, 33, 44, 55);
790     ASSERT (result != NULL);
791     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
792             || strcmp (result, "0x3.8p-1   33") == 0
793             || strcmp (result, "0x7p-2     33") == 0
794             || strcmp (result, "0xep-3     33") == 0);
795     ASSERT (retval == strlen (result));
796     free (result);
797   }
798
799   { /* FLAG_SHOWSIGN.  */
800     char *result;
801     int retval =
802       my_asprintf (&result, "%+La %d", 1.75L, 33, 44, 55);
803     ASSERT (result != NULL);
804     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
805             || strcmp (result, "+0x3.8p-1 33") == 0
806             || strcmp (result, "+0x7p-2 33") == 0
807             || strcmp (result, "+0xep-3 33") == 0);
808     ASSERT (retval == strlen (result));
809     free (result);
810   }
811
812   { /* FLAG_SPACE.  */
813     char *result;
814     int retval =
815       my_asprintf (&result, "% La %d", 1.75L, 33, 44, 55);
816     ASSERT (result != NULL);
817     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
818             || strcmp (result, " 0x3.8p-1 33") == 0
819             || strcmp (result, " 0x7p-2 33") == 0
820             || strcmp (result, " 0xep-3 33") == 0);
821     ASSERT (retval == strlen (result));
822     free (result);
823   }
824
825   { /* FLAG_ALT.  */
826     char *result;
827     int retval =
828       my_asprintf (&result, "%#La %d", 1.75L, 33, 44, 55);
829     ASSERT (result != NULL);
830     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
831             || strcmp (result, "0x3.8p-1 33") == 0
832             || strcmp (result, "0x7.p-2 33") == 0
833             || strcmp (result, "0xe.p-3 33") == 0);
834     ASSERT (retval == strlen (result));
835     free (result);
836   }
837
838   { /* FLAG_ALT.  */
839     char *result;
840     int retval =
841       my_asprintf (&result, "%#La %d", 1.0L, 33, 44, 55);
842     ASSERT (result != NULL);
843     ASSERT (strcmp (result, "0x1.p+0 33") == 0
844             || strcmp (result, "0x2.p-1 33") == 0
845             || strcmp (result, "0x4.p-2 33") == 0
846             || strcmp (result, "0x8.p-3 33") == 0);
847     ASSERT (retval == strlen (result));
848     free (result);
849   }
850
851   { /* FLAG_ZERO with finite number.  */
852     char *result;
853     int retval =
854       my_asprintf (&result, "%010La %d", 1.75L, 33, 44, 55);
855     ASSERT (result != NULL);
856     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
857             || strcmp (result, "0x003.8p-1 33") == 0
858             || strcmp (result, "0x00007p-2 33") == 0
859             || strcmp (result, "0x0000ep-3 33") == 0);
860     ASSERT (retval == strlen (result));
861     free (result);
862   }
863
864   { /* FLAG_ZERO with infinite number.  */
865     char *result;
866     int retval =
867       my_asprintf (&result, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
868     ASSERT (result != NULL);
869     /* "0000000inf 33" is not a valid result; see
870        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
871     ASSERT (strcmp (result, "       inf 33") == 0);
872     ASSERT (retval == strlen (result));
873     free (result);
874   }
875
876   { /* FLAG_ZERO with NaN.  */
877     char *result;
878     int retval =
879       my_asprintf (&result, "%050La %d", 0.0L / 0.0L, 33, 44, 55);
880     ASSERT (result != NULL);
881     /* "0000000nan 33" is not a valid result; see
882        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
883     ASSERT (strlen (result) == 50 + 3
884             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
885             && strcmp (result + strlen (result) - 3, " 33") == 0);
886     ASSERT (retval == strlen (result));
887     free (result);
888   }
889
890   /* Test the support of the %f format directive.  */
891
892   { /* A positive number.  */
893     char *result;
894     int retval =
895       my_asprintf (&result, "%f %d", 12.75, 33, 44, 55);
896     ASSERT (result != NULL);
897     ASSERT (strcmp (result, "12.750000 33") == 0);
898     ASSERT (retval == strlen (result));
899     free (result);
900   }
901
902   { /* A larger positive number.  */
903     char *result;
904     int retval =
905       my_asprintf (&result, "%f %d", 1234567.0, 33, 44, 55);
906     ASSERT (result != NULL);
907     ASSERT (strcmp (result, "1234567.000000 33") == 0);
908     ASSERT (retval == strlen (result));
909     free (result);
910   }
911
912   { /* Small and large positive numbers.  */
913     static struct { double value; const char *string; } data[] =
914       {
915         { 1.234321234321234e-37, "0.000000" },
916         { 1.234321234321234e-36, "0.000000" },
917         { 1.234321234321234e-35, "0.000000" },
918         { 1.234321234321234e-34, "0.000000" },
919         { 1.234321234321234e-33, "0.000000" },
920         { 1.234321234321234e-32, "0.000000" },
921         { 1.234321234321234e-31, "0.000000" },
922         { 1.234321234321234e-30, "0.000000" },
923         { 1.234321234321234e-29, "0.000000" },
924         { 1.234321234321234e-28, "0.000000" },
925         { 1.234321234321234e-27, "0.000000" },
926         { 1.234321234321234e-26, "0.000000" },
927         { 1.234321234321234e-25, "0.000000" },
928         { 1.234321234321234e-24, "0.000000" },
929         { 1.234321234321234e-23, "0.000000" },
930         { 1.234321234321234e-22, "0.000000" },
931         { 1.234321234321234e-21, "0.000000" },
932         { 1.234321234321234e-20, "0.000000" },
933         { 1.234321234321234e-19, "0.000000" },
934         { 1.234321234321234e-18, "0.000000" },
935         { 1.234321234321234e-17, "0.000000" },
936         { 1.234321234321234e-16, "0.000000" },
937         { 1.234321234321234e-15, "0.000000" },
938         { 1.234321234321234e-14, "0.000000" },
939         { 1.234321234321234e-13, "0.000000" },
940         { 1.234321234321234e-12, "0.000000" },
941         { 1.234321234321234e-11, "0.000000" },
942         { 1.234321234321234e-10, "0.000000" },
943         { 1.234321234321234e-9, "0.000000" },
944         { 1.234321234321234e-8, "0.000000" },
945         { 1.234321234321234e-7, "0.000000" },
946         { 1.234321234321234e-6, "0.000001" },
947         { 1.234321234321234e-5, "0.000012" },
948         { 1.234321234321234e-4, "0.000123" },
949         { 1.234321234321234e-3, "0.001234" },
950         { 1.234321234321234e-2, "0.012343" },
951         { 1.234321234321234e-1, "0.123432" },
952         { 1.234321234321234, "1.234321" },
953         { 1.234321234321234e1, "12.343212" },
954         { 1.234321234321234e2, "123.432123" },
955         { 1.234321234321234e3, "1234.321234" },
956         { 1.234321234321234e4, "12343.212343" },
957         { 1.234321234321234e5, "123432.123432" },
958         { 1.234321234321234e6, "1234321.234321" },
959         { 1.234321234321234e7, "12343212.343212" },
960         { 1.234321234321234e8, "123432123.432123" },
961         { 1.234321234321234e9, "1234321234.321234" },
962         { 1.234321234321234e10, "12343212343.2123**" },
963         { 1.234321234321234e11, "123432123432.123***" },
964         { 1.234321234321234e12, "1234321234321.23****" },
965         { 1.234321234321234e13, "12343212343212.3*****" },
966         { 1.234321234321234e14, "123432123432123.******" },
967         { 1.234321234321234e15, "1234321234321234.000000" },
968         { 1.234321234321234e16, "123432123432123**.000000" },
969         { 1.234321234321234e17, "123432123432123***.000000" },
970         { 1.234321234321234e18, "123432123432123****.000000" },
971         { 1.234321234321234e19, "123432123432123*****.000000" },
972         { 1.234321234321234e20, "123432123432123******.000000" },
973         { 1.234321234321234e21, "123432123432123*******.000000" },
974         { 1.234321234321234e22, "123432123432123********.000000" },
975         { 1.234321234321234e23, "123432123432123*********.000000" },
976         { 1.234321234321234e24, "123432123432123**********.000000" },
977         { 1.234321234321234e25, "123432123432123***********.000000" },
978         { 1.234321234321234e26, "123432123432123************.000000" },
979         { 1.234321234321234e27, "123432123432123*************.000000" },
980         { 1.234321234321234e28, "123432123432123**************.000000" },
981         { 1.234321234321234e29, "123432123432123***************.000000" },
982         { 1.234321234321234e30, "123432123432123****************.000000" },
983         { 1.234321234321234e31, "123432123432123*****************.000000" },
984         { 1.234321234321234e32, "123432123432123******************.000000" },
985         { 1.234321234321234e33, "123432123432123*******************.000000" },
986         { 1.234321234321234e34, "123432123432123********************.000000" },
987         { 1.234321234321234e35, "123432123432123*********************.000000" },
988         { 1.234321234321234e36, "123432123432123**********************.000000" }
989       };
990     size_t k;
991     for (k = 0; k < SIZEOF (data); k++)
992       {
993         char *result;
994         int retval =
995           my_asprintf (&result, "%f", data[k].value);
996         ASSERT (result != NULL);
997         ASSERT (strmatch (data[k].string, result));
998         ASSERT (retval == strlen (result));
999         free (result);
1000       }
1001   }
1002
1003   { /* A negative number.  */
1004     char *result;
1005     int retval =
1006       my_asprintf (&result, "%f %d", -0.03125, 33, 44, 55);
1007     ASSERT (result != NULL);
1008     ASSERT (strcmp (result, "-0.031250 33") == 0);
1009     ASSERT (retval == strlen (result));
1010     free (result);
1011   }
1012
1013   { /* Positive zero.  */
1014     char *result;
1015     int retval =
1016       my_asprintf (&result, "%f %d", 0.0, 33, 44, 55);
1017     ASSERT (result != NULL);
1018     ASSERT (strcmp (result, "0.000000 33") == 0);
1019     ASSERT (retval == strlen (result));
1020     free (result);
1021   }
1022
1023   { /* Negative zero.  */
1024     char *result;
1025     int retval =
1026       my_asprintf (&result, "%f %d", -0.0, 33, 44, 55);
1027     ASSERT (result != NULL);
1028     if (have_minus_zero ())
1029       ASSERT (strcmp (result, "-0.000000 33") == 0);
1030     ASSERT (retval == strlen (result));
1031     free (result);
1032   }
1033
1034   { /* Positive infinity.  */
1035     char *result;
1036     int retval =
1037       my_asprintf (&result, "%f %d", 1.0 / 0.0, 33, 44, 55);
1038     ASSERT (result != NULL);
1039     ASSERT (strcmp (result, "inf 33") == 0
1040             || strcmp (result, "infinity 33") == 0);
1041     ASSERT (retval == strlen (result));
1042     free (result);
1043   }
1044
1045   { /* Negative infinity.  */
1046     char *result;
1047     int retval =
1048       my_asprintf (&result, "%f %d", -1.0 / 0.0, 33, 44, 55);
1049     ASSERT (result != NULL);
1050     ASSERT (strcmp (result, "-inf 33") == 0
1051             || strcmp (result, "-infinity 33") == 0);
1052     ASSERT (retval == strlen (result));
1053     free (result);
1054   }
1055
1056   { /* NaN.  */
1057     char *result;
1058     int retval =
1059       my_asprintf (&result, "%f %d", NAN, 33, 44, 55);
1060     ASSERT (result != NULL);
1061     ASSERT (strlen (result) >= 3 + 3
1062             && strisnan (result, 0, strlen (result) - 3, 0)
1063             && strcmp (result + strlen (result) - 3, " 33") == 0);
1064     ASSERT (retval == strlen (result));
1065     free (result);
1066   }
1067
1068   { /* Width.  */
1069     char *result;
1070     int retval =
1071       my_asprintf (&result, "%10f %d", 1.75, 33, 44, 55);
1072     ASSERT (result != NULL);
1073     ASSERT (strcmp (result, "  1.750000 33") == 0);
1074     ASSERT (retval == strlen (result));
1075     free (result);
1076   }
1077
1078   { /* FLAG_LEFT.  */
1079     char *result;
1080     int retval =
1081       my_asprintf (&result, "%-10f %d", 1.75, 33, 44, 55);
1082     ASSERT (result != NULL);
1083     ASSERT (strcmp (result, "1.750000   33") == 0);
1084     ASSERT (retval == strlen (result));
1085     free (result);
1086   }
1087
1088   { /* FLAG_SHOWSIGN.  */
1089     char *result;
1090     int retval =
1091       my_asprintf (&result, "%+f %d", 1.75, 33, 44, 55);
1092     ASSERT (result != NULL);
1093     ASSERT (strcmp (result, "+1.750000 33") == 0);
1094     ASSERT (retval == strlen (result));
1095     free (result);
1096   }
1097
1098   { /* FLAG_SPACE.  */
1099     char *result;
1100     int retval =
1101       my_asprintf (&result, "% f %d", 1.75, 33, 44, 55);
1102     ASSERT (result != NULL);
1103     ASSERT (strcmp (result, " 1.750000 33") == 0);
1104     ASSERT (retval == strlen (result));
1105     free (result);
1106   }
1107
1108   { /* FLAG_ALT.  */
1109     char *result;
1110     int retval =
1111       my_asprintf (&result, "%#f %d", 1.75, 33, 44, 55);
1112     ASSERT (result != NULL);
1113     ASSERT (strcmp (result, "1.750000 33") == 0);
1114     ASSERT (retval == strlen (result));
1115     free (result);
1116   }
1117
1118   { /* FLAG_ALT.  */
1119     char *result;
1120     int retval =
1121       my_asprintf (&result, "%#.f %d", 1.75, 33, 44, 55);
1122     ASSERT (result != NULL);
1123     ASSERT (strcmp (result, "2. 33") == 0);
1124     ASSERT (retval == strlen (result));
1125     free (result);
1126   }
1127
1128   { /* FLAG_ZERO with finite number.  */
1129     char *result;
1130     int retval =
1131       my_asprintf (&result, "%015f %d", 1234.0, 33, 44, 55);
1132     ASSERT (result != NULL);
1133     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1134     ASSERT (retval == strlen (result));
1135     free (result);
1136   }
1137
1138   { /* FLAG_ZERO with infinite number.  */
1139     char *result;
1140     int retval =
1141       my_asprintf (&result, "%015f %d", -1.0 / 0.0, 33, 44, 55);
1142     ASSERT (result != NULL);
1143     ASSERT (strcmp (result, "           -inf 33") == 0
1144             || strcmp (result, "      -infinity 33") == 0);
1145     ASSERT (retval == strlen (result));
1146     free (result);
1147   }
1148
1149   { /* FLAG_ZERO with NaN.  */
1150     char *result;
1151     int retval =
1152       my_asprintf (&result, "%050f %d", NAN, 33, 44, 55);
1153     ASSERT (result != NULL);
1154     ASSERT (strlen (result) == 50 + 3
1155             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1156             && strcmp (result + strlen (result) - 3, " 33") == 0);
1157     ASSERT (retval == strlen (result));
1158     free (result);
1159   }
1160
1161   { /* Precision.  */
1162     char *result;
1163     int retval =
1164       my_asprintf (&result, "%.f %d", 1234.0, 33, 44, 55);
1165     ASSERT (result != NULL);
1166     ASSERT (strcmp (result, "1234 33") == 0);
1167     ASSERT (retval == strlen (result));
1168     free (result);
1169   }
1170
1171   { /* A positive number.  */
1172     char *result;
1173     int retval =
1174       my_asprintf (&result, "%Lf %d", 12.75L, 33, 44, 55);
1175     ASSERT (result != NULL);
1176     ASSERT (strcmp (result, "12.750000 33") == 0);
1177     ASSERT (retval == strlen (result));
1178     free (result);
1179   }
1180
1181   { /* A larger positive number.  */
1182     char *result;
1183     int retval =
1184       my_asprintf (&result, "%Lf %d", 1234567.0L, 33, 44, 55);
1185     ASSERT (result != NULL);
1186     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1187     ASSERT (retval == strlen (result));
1188     free (result);
1189   }
1190
1191   { /* Small and large positive numbers.  */
1192     static struct { long double value; const char *string; } data[] =
1193       {
1194         { 1.234321234321234e-37L, "0.000000" },
1195         { 1.234321234321234e-36L, "0.000000" },
1196         { 1.234321234321234e-35L, "0.000000" },
1197         { 1.234321234321234e-34L, "0.000000" },
1198         { 1.234321234321234e-33L, "0.000000" },
1199         { 1.234321234321234e-32L, "0.000000" },
1200         { 1.234321234321234e-31L, "0.000000" },
1201         { 1.234321234321234e-30L, "0.000000" },
1202         { 1.234321234321234e-29L, "0.000000" },
1203         { 1.234321234321234e-28L, "0.000000" },
1204         { 1.234321234321234e-27L, "0.000000" },
1205         { 1.234321234321234e-26L, "0.000000" },
1206         { 1.234321234321234e-25L, "0.000000" },
1207         { 1.234321234321234e-24L, "0.000000" },
1208         { 1.234321234321234e-23L, "0.000000" },
1209         { 1.234321234321234e-22L, "0.000000" },
1210         { 1.234321234321234e-21L, "0.000000" },
1211         { 1.234321234321234e-20L, "0.000000" },
1212         { 1.234321234321234e-19L, "0.000000" },
1213         { 1.234321234321234e-18L, "0.000000" },
1214         { 1.234321234321234e-17L, "0.000000" },
1215         { 1.234321234321234e-16L, "0.000000" },
1216         { 1.234321234321234e-15L, "0.000000" },
1217         { 1.234321234321234e-14L, "0.000000" },
1218         { 1.234321234321234e-13L, "0.000000" },
1219         { 1.234321234321234e-12L, "0.000000" },
1220         { 1.234321234321234e-11L, "0.000000" },
1221         { 1.234321234321234e-10L, "0.000000" },
1222         { 1.234321234321234e-9L, "0.000000" },
1223         { 1.234321234321234e-8L, "0.000000" },
1224         { 1.234321234321234e-7L, "0.000000" },
1225         { 1.234321234321234e-6L, "0.000001" },
1226         { 1.234321234321234e-5L, "0.000012" },
1227         { 1.234321234321234e-4L, "0.000123" },
1228         { 1.234321234321234e-3L, "0.001234" },
1229         { 1.234321234321234e-2L, "0.012343" },
1230         { 1.234321234321234e-1L, "0.123432" },
1231         { 1.234321234321234L, "1.234321" },
1232         { 1.234321234321234e1L, "12.343212" },
1233         { 1.234321234321234e2L, "123.432123" },
1234         { 1.234321234321234e3L, "1234.321234" },
1235         { 1.234321234321234e4L, "12343.212343" },
1236         { 1.234321234321234e5L, "123432.123432" },
1237         { 1.234321234321234e6L, "1234321.234321" },
1238         { 1.234321234321234e7L, "12343212.343212" },
1239         { 1.234321234321234e8L, "123432123.432123" },
1240         { 1.234321234321234e9L, "1234321234.321234" },
1241         { 1.234321234321234e10L, "12343212343.2123**" },
1242         { 1.234321234321234e11L, "123432123432.123***" },
1243         { 1.234321234321234e12L, "1234321234321.23****" },
1244         { 1.234321234321234e13L, "12343212343212.3*****" },
1245         { 1.234321234321234e14L, "123432123432123.******" },
1246         { 1.234321234321234e15L, "1234321234321234.000000" },
1247         { 1.234321234321234e16L, "123432123432123**.000000" },
1248         { 1.234321234321234e17L, "123432123432123***.000000" },
1249         { 1.234321234321234e18L, "123432123432123****.000000" },
1250         { 1.234321234321234e19L, "123432123432123*****.000000" },
1251         { 1.234321234321234e20L, "123432123432123******.000000" },
1252         { 1.234321234321234e21L, "123432123432123*******.000000" },
1253         { 1.234321234321234e22L, "123432123432123********.000000" },
1254         { 1.234321234321234e23L, "123432123432123*********.000000" },
1255         { 1.234321234321234e24L, "123432123432123**********.000000" },
1256         { 1.234321234321234e25L, "123432123432123***********.000000" },
1257         { 1.234321234321234e26L, "123432123432123************.000000" },
1258         { 1.234321234321234e27L, "123432123432123*************.000000" },
1259         { 1.234321234321234e28L, "123432123432123**************.000000" },
1260         { 1.234321234321234e29L, "123432123432123***************.000000" },
1261         { 1.234321234321234e30L, "123432123432123****************.000000" },
1262         { 1.234321234321234e31L, "123432123432123*****************.000000" },
1263         { 1.234321234321234e32L, "123432123432123******************.000000" },
1264         { 1.234321234321234e33L, "123432123432123*******************.000000" },
1265         { 1.234321234321234e34L, "123432123432123********************.000000" },
1266         { 1.234321234321234e35L, "123432123432123*********************.000000" },
1267         { 1.234321234321234e36L, "123432123432123**********************.000000" }
1268       };
1269     size_t k;
1270     for (k = 0; k < SIZEOF (data); k++)
1271       {
1272         char *result;
1273         int retval =
1274           my_asprintf (&result, "%Lf", data[k].value);
1275         ASSERT (result != NULL);
1276         ASSERT (strmatch (data[k].string, result));
1277         ASSERT (retval == strlen (result));
1278         free (result);
1279       }
1280   }
1281
1282   { /* A negative number.  */
1283     char *result;
1284     int retval =
1285       my_asprintf (&result, "%Lf %d", -0.03125L, 33, 44, 55);
1286     ASSERT (result != NULL);
1287     ASSERT (strcmp (result, "-0.031250 33") == 0);
1288     ASSERT (retval == strlen (result));
1289     free (result);
1290   }
1291
1292   { /* Positive zero.  */
1293     char *result;
1294     int retval =
1295       my_asprintf (&result, "%Lf %d", 0.0L, 33, 44, 55);
1296     ASSERT (result != NULL);
1297     ASSERT (strcmp (result, "0.000000 33") == 0);
1298     ASSERT (retval == strlen (result));
1299     free (result);
1300   }
1301
1302   { /* Negative zero.  */
1303     char *result;
1304     int retval =
1305       my_asprintf (&result, "%Lf %d", -0.0L, 33, 44, 55);
1306     ASSERT (result != NULL);
1307     if (have_minus_zero ())
1308       ASSERT (strcmp (result, "-0.000000 33") == 0);
1309     ASSERT (retval == strlen (result));
1310     free (result);
1311   }
1312
1313   { /* Positive infinity.  */
1314     char *result;
1315     int retval =
1316       my_asprintf (&result, "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
1317     ASSERT (result != NULL);
1318     ASSERT (strcmp (result, "inf 33") == 0
1319             || strcmp (result, "infinity 33") == 0);
1320     ASSERT (retval == strlen (result));
1321     free (result);
1322   }
1323
1324   { /* Negative infinity.  */
1325     char *result;
1326     int retval =
1327       my_asprintf (&result, "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
1328     ASSERT (result != NULL);
1329     ASSERT (strcmp (result, "-inf 33") == 0
1330             || strcmp (result, "-infinity 33") == 0);
1331     ASSERT (retval == strlen (result));
1332     free (result);
1333   }
1334
1335   { /* NaN.  */
1336     static long double zero = 0.0L;
1337     char *result;
1338     int retval =
1339       my_asprintf (&result, "%Lf %d", zero / zero, 33, 44, 55);
1340     ASSERT (result != NULL);
1341     ASSERT (strlen (result) >= 3 + 3
1342             && strisnan (result, 0, strlen (result) - 3, 0)
1343             && strcmp (result + strlen (result) - 3, " 33") == 0);
1344     ASSERT (retval == strlen (result));
1345     free (result);
1346   }
1347 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
1348   { /* Quiet NaN.  */
1349     static union { unsigned int word[4]; long double value; } x =
1350       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
1351     char *result;
1352     int retval =
1353       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1354     ASSERT (result != NULL);
1355     ASSERT (strlen (result) >= 3 + 3
1356             && strisnan (result, 0, strlen (result) - 3, 0)
1357             && strcmp (result + strlen (result) - 3, " 33") == 0);
1358     ASSERT (retval == strlen (result));
1359     free (result);
1360   }
1361   {
1362     /* Signalling NaN.  */
1363     static union { unsigned int word[4]; long double value; } x =
1364       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
1365     char *result;
1366     int retval =
1367       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1368     ASSERT (result != NULL);
1369     ASSERT (strlen (result) >= 3 + 3
1370             && strisnan (result, 0, strlen (result) - 3, 0)
1371             && strcmp (result + strlen (result) - 3, " 33") == 0);
1372     ASSERT (retval == strlen (result));
1373     free (result);
1374   }
1375   /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
1376      Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
1377        Intel IA-64 Architecture Software Developer's Manual, Volume 1:
1378        Application Architecture.
1379        Table 5-2 "Floating-Point Register Encodings"
1380        Figure 5-6 "Memory to Floating-Point Register Data Translation"
1381    */
1382   { /* Pseudo-NaN.  */
1383     static union { unsigned int word[4]; long double value; } x =
1384       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
1385     char *result;
1386     int retval =
1387       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1388     ASSERT (result != NULL);
1389     ASSERT (strlen (result) >= 3 + 3
1390             && strisnan (result, 0, strlen (result) - 3, 0)
1391             && strcmp (result + strlen (result) - 3, " 33") == 0);
1392     ASSERT (retval == strlen (result));
1393     free (result);
1394   }
1395   { /* Pseudo-Infinity.  */
1396     static union { unsigned int word[4]; long double value; } x =
1397       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
1398     char *result;
1399     int retval =
1400       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1401     ASSERT (result != NULL);
1402     ASSERT (strlen (result) >= 3 + 3
1403             && strisnan (result, 0, strlen (result) - 3, 0)
1404             && strcmp (result + strlen (result) - 3, " 33") == 0);
1405     ASSERT (retval == strlen (result));
1406     free (result);
1407   }
1408   { /* Pseudo-Zero.  */
1409     static union { unsigned int word[4]; long double value; } x =
1410       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
1411     char *result;
1412     int retval =
1413       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1414     ASSERT (result != NULL);
1415     ASSERT (strlen (result) >= 3 + 3
1416             && strisnan (result, 0, strlen (result) - 3, 0)
1417             && strcmp (result + strlen (result) - 3, " 33") == 0);
1418     ASSERT (retval == strlen (result));
1419     free (result);
1420   }
1421   { /* Unnormalized number.  */
1422     static union { unsigned int word[4]; long double value; } x =
1423       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
1424     char *result;
1425     int retval =
1426       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1427     ASSERT (result != NULL);
1428     ASSERT (strlen (result) >= 3 + 3
1429             && strisnan (result, 0, strlen (result) - 3, 0)
1430             && strcmp (result + strlen (result) - 3, " 33") == 0);
1431     ASSERT (retval == strlen (result));
1432     free (result);
1433   }
1434   { /* Pseudo-Denormal.  */
1435     static union { unsigned int word[4]; long double value; } x =
1436       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
1437     char *result;
1438     int retval =
1439       my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1440     ASSERT (result != NULL);
1441     ASSERT (strlen (result) >= 3 + 3
1442             && strisnan (result, 0, strlen (result) - 3, 0)
1443             && strcmp (result + strlen (result) - 3, " 33") == 0);
1444     ASSERT (retval == strlen (result));
1445     free (result);
1446   }
1447 #endif
1448
1449   { /* Width.  */
1450     char *result;
1451     int retval =
1452       my_asprintf (&result, "%10Lf %d", 1.75L, 33, 44, 55);
1453     ASSERT (result != NULL);
1454     ASSERT (strcmp (result, "  1.750000 33") == 0);
1455     ASSERT (retval == strlen (result));
1456     free (result);
1457   }
1458
1459   { /* FLAG_LEFT.  */
1460     char *result;
1461     int retval =
1462       my_asprintf (&result, "%-10Lf %d", 1.75L, 33, 44, 55);
1463     ASSERT (result != NULL);
1464     ASSERT (strcmp (result, "1.750000   33") == 0);
1465     ASSERT (retval == strlen (result));
1466     free (result);
1467   }
1468
1469   { /* FLAG_SHOWSIGN.  */
1470     char *result;
1471     int retval =
1472       my_asprintf (&result, "%+Lf %d", 1.75L, 33, 44, 55);
1473     ASSERT (result != NULL);
1474     ASSERT (strcmp (result, "+1.750000 33") == 0);
1475     ASSERT (retval == strlen (result));
1476     free (result);
1477   }
1478
1479   { /* FLAG_SPACE.  */
1480     char *result;
1481     int retval =
1482       my_asprintf (&result, "% Lf %d", 1.75L, 33, 44, 55);
1483     ASSERT (result != NULL);
1484     ASSERT (strcmp (result, " 1.750000 33") == 0);
1485     ASSERT (retval == strlen (result));
1486     free (result);
1487   }
1488
1489   { /* FLAG_ALT.  */
1490     char *result;
1491     int retval =
1492       my_asprintf (&result, "%#Lf %d", 1.75L, 33, 44, 55);
1493     ASSERT (result != NULL);
1494     ASSERT (strcmp (result, "1.750000 33") == 0);
1495     ASSERT (retval == strlen (result));
1496     free (result);
1497   }
1498
1499   { /* FLAG_ALT.  */
1500     char *result;
1501     int retval =
1502       my_asprintf (&result, "%#.Lf %d", 1.75L, 33, 44, 55);
1503     ASSERT (result != NULL);
1504     ASSERT (strcmp (result, "2. 33") == 0);
1505     ASSERT (retval == strlen (result));
1506     free (result);
1507   }
1508
1509   { /* FLAG_ZERO with finite number.  */
1510     char *result;
1511     int retval =
1512       my_asprintf (&result, "%015Lf %d", 1234.0L, 33, 44, 55);
1513     ASSERT (result != NULL);
1514     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1515     ASSERT (retval == strlen (result));
1516     free (result);
1517   }
1518
1519   { /* FLAG_ZERO with infinite number.  */
1520     char *result;
1521     int retval =
1522       my_asprintf (&result, "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
1523     ASSERT (result != NULL);
1524     ASSERT (strcmp (result, "           -inf 33") == 0
1525             || strcmp (result, "      -infinity 33") == 0);
1526     ASSERT (retval == strlen (result));
1527     free (result);
1528   }
1529
1530   { /* FLAG_ZERO with NaN.  */
1531     static long double zero = 0.0L;
1532     char *result;
1533     int retval =
1534       my_asprintf (&result, "%050Lf %d", zero / zero, 33, 44, 55);
1535     ASSERT (result != NULL);
1536     ASSERT (strlen (result) == 50 + 3
1537             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1538             && strcmp (result + strlen (result) - 3, " 33") == 0);
1539     ASSERT (retval == strlen (result));
1540     free (result);
1541   }
1542
1543   { /* Precision.  */
1544     char *result;
1545     int retval =
1546       my_asprintf (&result, "%.Lf %d", 1234.0L, 33, 44, 55);
1547     ASSERT (result != NULL);
1548     ASSERT (strcmp (result, "1234 33") == 0);
1549     ASSERT (retval == strlen (result));
1550     free (result);
1551   }
1552
1553   /* Test the support of the %F format directive.  */
1554
1555   { /* A positive number.  */
1556     char *result;
1557     int retval =
1558       my_asprintf (&result, "%F %d", 12.75, 33, 44, 55);
1559     ASSERT (result != NULL);
1560     ASSERT (strcmp (result, "12.750000 33") == 0);
1561     ASSERT (retval == strlen (result));
1562     free (result);
1563   }
1564
1565   { /* A larger positive number.  */
1566     char *result;
1567     int retval =
1568       my_asprintf (&result, "%F %d", 1234567.0, 33, 44, 55);
1569     ASSERT (result != NULL);
1570     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1571     ASSERT (retval == strlen (result));
1572     free (result);
1573   }
1574
1575   { /* A negative number.  */
1576     char *result;
1577     int retval =
1578       my_asprintf (&result, "%F %d", -0.03125, 33, 44, 55);
1579     ASSERT (result != NULL);
1580     ASSERT (strcmp (result, "-0.031250 33") == 0);
1581     ASSERT (retval == strlen (result));
1582     free (result);
1583   }
1584
1585   { /* Positive zero.  */
1586     char *result;
1587     int retval =
1588       my_asprintf (&result, "%F %d", 0.0, 33, 44, 55);
1589     ASSERT (result != NULL);
1590     ASSERT (strcmp (result, "0.000000 33") == 0);
1591     ASSERT (retval == strlen (result));
1592     free (result);
1593   }
1594
1595   { /* Negative zero.  */
1596     char *result;
1597     int retval =
1598       my_asprintf (&result, "%F %d", -0.0, 33, 44, 55);
1599     ASSERT (result != NULL);
1600     if (have_minus_zero ())
1601       ASSERT (strcmp (result, "-0.000000 33") == 0);
1602     ASSERT (retval == strlen (result));
1603     free (result);
1604   }
1605
1606   { /* Positive infinity.  */
1607     char *result;
1608     int retval =
1609       my_asprintf (&result, "%F %d", 1.0 / 0.0, 33, 44, 55);
1610     ASSERT (result != NULL);
1611     ASSERT (strcmp (result, "INF 33") == 0
1612             || strcmp (result, "INFINITY 33") == 0);
1613     ASSERT (retval == strlen (result));
1614     free (result);
1615   }
1616
1617   { /* Negative infinity.  */
1618     char *result;
1619     int retval =
1620       my_asprintf (&result, "%F %d", -1.0 / 0.0, 33, 44, 55);
1621     ASSERT (result != NULL);
1622     ASSERT (strcmp (result, "-INF 33") == 0
1623             || strcmp (result, "-INFINITY 33") == 0);
1624     ASSERT (retval == strlen (result));
1625     free (result);
1626   }
1627
1628   { /* NaN.  */
1629     char *result;
1630     int retval =
1631       my_asprintf (&result, "%F %d", NAN, 33, 44, 55);
1632     ASSERT (result != NULL);
1633     ASSERT (strlen (result) >= 3 + 3
1634             && strisnan (result, 0, strlen (result) - 3, 1)
1635             && strcmp (result + strlen (result) - 3, " 33") == 0);
1636     ASSERT (retval == strlen (result));
1637     free (result);
1638   }
1639
1640   { /* FLAG_ZERO.  */
1641     char *result;
1642     int retval =
1643       my_asprintf (&result, "%015F %d", 1234.0, 33, 44, 55);
1644     ASSERT (result != NULL);
1645     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1646     ASSERT (retval == strlen (result));
1647     free (result);
1648   }
1649
1650   { /* FLAG_ZERO with infinite number.  */
1651     char *result;
1652     int retval =
1653       my_asprintf (&result, "%015F %d", -1.0 / 0.0, 33, 44, 55);
1654     ASSERT (result != NULL);
1655     ASSERT (strcmp (result, "           -INF 33") == 0
1656             || strcmp (result, "      -INFINITY 33") == 0);
1657     ASSERT (retval == strlen (result));
1658     free (result);
1659   }
1660
1661   { /* Precision.  */
1662     char *result;
1663     int retval =
1664       my_asprintf (&result, "%.F %d", 1234.0, 33, 44, 55);
1665     ASSERT (result != NULL);
1666     ASSERT (strcmp (result, "1234 33") == 0);
1667     ASSERT (retval == strlen (result));
1668     free (result);
1669   }
1670
1671   { /* A positive number.  */
1672     char *result;
1673     int retval =
1674       my_asprintf (&result, "%LF %d", 12.75L, 33, 44, 55);
1675     ASSERT (result != NULL);
1676     ASSERT (strcmp (result, "12.750000 33") == 0);
1677     ASSERT (retval == strlen (result));
1678     free (result);
1679   }
1680
1681   { /* A larger positive number.  */
1682     char *result;
1683     int retval =
1684       my_asprintf (&result, "%LF %d", 1234567.0L, 33, 44, 55);
1685     ASSERT (result != NULL);
1686     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1687     ASSERT (retval == strlen (result));
1688     free (result);
1689   }
1690
1691   { /* A negative number.  */
1692     char *result;
1693     int retval =
1694       my_asprintf (&result, "%LF %d", -0.03125L, 33, 44, 55);
1695     ASSERT (result != NULL);
1696     ASSERT (strcmp (result, "-0.031250 33") == 0);
1697     ASSERT (retval == strlen (result));
1698     free (result);
1699   }
1700
1701   { /* Positive zero.  */
1702     char *result;
1703     int retval =
1704       my_asprintf (&result, "%LF %d", 0.0L, 33, 44, 55);
1705     ASSERT (result != NULL);
1706     ASSERT (strcmp (result, "0.000000 33") == 0);
1707     ASSERT (retval == strlen (result));
1708     free (result);
1709   }
1710
1711   { /* Negative zero.  */
1712     char *result;
1713     int retval =
1714       my_asprintf (&result, "%LF %d", -0.0L, 33, 44, 55);
1715     ASSERT (result != NULL);
1716     if (have_minus_zero ())
1717       ASSERT (strcmp (result, "-0.000000 33") == 0);
1718     ASSERT (retval == strlen (result));
1719     free (result);
1720   }
1721
1722   { /* Positive infinity.  */
1723     char *result;
1724     int retval =
1725       my_asprintf (&result, "%LF %d", 1.0L / 0.0L, 33, 44, 55);
1726     ASSERT (result != NULL);
1727     ASSERT (strcmp (result, "INF 33") == 0
1728             || strcmp (result, "INFINITY 33") == 0);
1729     ASSERT (retval == strlen (result));
1730     free (result);
1731   }
1732
1733   { /* Negative infinity.  */
1734     char *result;
1735     int retval =
1736       my_asprintf (&result, "%LF %d", -1.0L / 0.0L, 33, 44, 55);
1737     ASSERT (result != NULL);
1738     ASSERT (strcmp (result, "-INF 33") == 0
1739             || strcmp (result, "-INFINITY 33") == 0);
1740     ASSERT (retval == strlen (result));
1741     free (result);
1742   }
1743
1744   { /* NaN.  */
1745     static long double zero = 0.0L;
1746     char *result;
1747     int retval =
1748       my_asprintf (&result, "%LF %d", zero / zero, 33, 44, 55);
1749     ASSERT (result != NULL);
1750     ASSERT (strlen (result) >= 3 + 3
1751             && strisnan (result, 0, strlen (result) - 3, 1)
1752             && strcmp (result + strlen (result) - 3, " 33") == 0);
1753     ASSERT (retval == strlen (result));
1754     free (result);
1755   }
1756
1757   { /* FLAG_ZERO.  */
1758     char *result;
1759     int retval =
1760       my_asprintf (&result, "%015LF %d", 1234.0L, 33, 44, 55);
1761     ASSERT (result != NULL);
1762     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1763     ASSERT (retval == strlen (result));
1764     free (result);
1765   }
1766
1767   { /* FLAG_ZERO with infinite number.  */
1768     char *result;
1769     int retval =
1770       my_asprintf (&result, "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
1771     ASSERT (result != NULL);
1772     ASSERT (strcmp (result, "           -INF 33") == 0
1773             || strcmp (result, "      -INFINITY 33") == 0);
1774     ASSERT (retval == strlen (result));
1775     free (result);
1776   }
1777
1778   { /* Precision.  */
1779     char *result;
1780     int retval =
1781       my_asprintf (&result, "%.LF %d", 1234.0L, 33, 44, 55);
1782     ASSERT (result != NULL);
1783     ASSERT (strcmp (result, "1234 33") == 0);
1784     ASSERT (retval == strlen (result));
1785     free (result);
1786   }
1787
1788   /* Test the support of the %e format directive.  */
1789
1790   { /* A positive number.  */
1791     char *result;
1792     int retval =
1793       my_asprintf (&result, "%e %d", 12.75, 33, 44, 55);
1794     ASSERT (result != NULL);
1795     ASSERT (strcmp (result, "1.275000e+01 33") == 0
1796             || strcmp (result, "1.275000e+001 33") == 0);
1797     ASSERT (retval == strlen (result));
1798     free (result);
1799   }
1800
1801   { /* A larger positive number.  */
1802     char *result;
1803     int retval =
1804       my_asprintf (&result, "%e %d", 1234567.0, 33, 44, 55);
1805     ASSERT (result != NULL);
1806     ASSERT (strcmp (result, "1.234567e+06 33") == 0
1807             || strcmp (result, "1.234567e+006 33") == 0);
1808     ASSERT (retval == strlen (result));
1809     free (result);
1810   }
1811
1812   { /* Small and large positive numbers.  */
1813     static struct { double value; const char *string; } data[] =
1814       {
1815         { 1.234321234321234e-37, "1.234321e-37" },
1816         { 1.234321234321234e-36, "1.234321e-36" },
1817         { 1.234321234321234e-35, "1.234321e-35" },
1818         { 1.234321234321234e-34, "1.234321e-34" },
1819         { 1.234321234321234e-33, "1.234321e-33" },
1820         { 1.234321234321234e-32, "1.234321e-32" },
1821         { 1.234321234321234e-31, "1.234321e-31" },
1822         { 1.234321234321234e-30, "1.234321e-30" },
1823         { 1.234321234321234e-29, "1.234321e-29" },
1824         { 1.234321234321234e-28, "1.234321e-28" },
1825         { 1.234321234321234e-27, "1.234321e-27" },
1826         { 1.234321234321234e-26, "1.234321e-26" },
1827         { 1.234321234321234e-25, "1.234321e-25" },
1828         { 1.234321234321234e-24, "1.234321e-24" },
1829         { 1.234321234321234e-23, "1.234321e-23" },
1830         { 1.234321234321234e-22, "1.234321e-22" },
1831         { 1.234321234321234e-21, "1.234321e-21" },
1832         { 1.234321234321234e-20, "1.234321e-20" },
1833         { 1.234321234321234e-19, "1.234321e-19" },
1834         { 1.234321234321234e-18, "1.234321e-18" },
1835         { 1.234321234321234e-17, "1.234321e-17" },
1836         { 1.234321234321234e-16, "1.234321e-16" },
1837         { 1.234321234321234e-15, "1.234321e-15" },
1838         { 1.234321234321234e-14, "1.234321e-14" },
1839         { 1.234321234321234e-13, "1.234321e-13" },
1840         { 1.234321234321234e-12, "1.234321e-12" },
1841         { 1.234321234321234e-11, "1.234321e-11" },
1842         { 1.234321234321234e-10, "1.234321e-10" },
1843         { 1.234321234321234e-9, "1.234321e-09" },
1844         { 1.234321234321234e-8, "1.234321e-08" },
1845         { 1.234321234321234e-7, "1.234321e-07" },
1846         { 1.234321234321234e-6, "1.234321e-06" },
1847         { 1.234321234321234e-5, "1.234321e-05" },
1848         { 1.234321234321234e-4, "1.234321e-04" },
1849         { 1.234321234321234e-3, "1.234321e-03" },
1850         { 1.234321234321234e-2, "1.234321e-02" },
1851         { 1.234321234321234e-1, "1.234321e-01" },
1852         { 1.234321234321234, "1.234321e+00" },
1853         { 1.234321234321234e1, "1.234321e+01" },
1854         { 1.234321234321234e2, "1.234321e+02" },
1855         { 1.234321234321234e3, "1.234321e+03" },
1856         { 1.234321234321234e4, "1.234321e+04" },
1857         { 1.234321234321234e5, "1.234321e+05" },
1858         { 1.234321234321234e6, "1.234321e+06" },
1859         { 1.234321234321234e7, "1.234321e+07" },
1860         { 1.234321234321234e8, "1.234321e+08" },
1861         { 1.234321234321234e9, "1.234321e+09" },
1862         { 1.234321234321234e10, "1.234321e+10" },
1863         { 1.234321234321234e11, "1.234321e+11" },
1864         { 1.234321234321234e12, "1.234321e+12" },
1865         { 1.234321234321234e13, "1.234321e+13" },
1866         { 1.234321234321234e14, "1.234321e+14" },
1867         { 1.234321234321234e15, "1.234321e+15" },
1868         { 1.234321234321234e16, "1.234321e+16" },
1869         { 1.234321234321234e17, "1.234321e+17" },
1870         { 1.234321234321234e18, "1.234321e+18" },
1871         { 1.234321234321234e19, "1.234321e+19" },
1872         { 1.234321234321234e20, "1.234321e+20" },
1873         { 1.234321234321234e21, "1.234321e+21" },
1874         { 1.234321234321234e22, "1.234321e+22" },
1875         { 1.234321234321234e23, "1.234321e+23" },
1876         { 1.234321234321234e24, "1.234321e+24" },
1877         { 1.234321234321234e25, "1.234321e+25" },
1878         { 1.234321234321234e26, "1.234321e+26" },
1879         { 1.234321234321234e27, "1.234321e+27" },
1880         { 1.234321234321234e28, "1.234321e+28" },
1881         { 1.234321234321234e29, "1.234321e+29" },
1882         { 1.234321234321234e30, "1.234321e+30" },
1883         { 1.234321234321234e31, "1.234321e+31" },
1884         { 1.234321234321234e32, "1.234321e+32" },
1885         { 1.234321234321234e33, "1.234321e+33" },
1886         { 1.234321234321234e34, "1.234321e+34" },
1887         { 1.234321234321234e35, "1.234321e+35" },
1888         { 1.234321234321234e36, "1.234321e+36" }
1889       };
1890     size_t k;
1891     for (k = 0; k < SIZEOF (data); k++)
1892       {
1893         char *result;
1894         int retval =
1895           my_asprintf (&result, "%e", data[k].value);
1896         const char *expected = data[k].string;
1897         ASSERT (result != NULL);
1898         ASSERT (strcmp (result, expected) == 0
1899                 /* Some implementations produce exponents with 3 digits.  */
1900                 || (strlen (result) == strlen (expected) + 1
1901                     && memcmp (result, expected, strlen (expected) - 2) == 0
1902                     && result[strlen (expected) - 2] == '0'
1903                     && strcmp (result + strlen (expected) - 1,
1904                                expected + strlen (expected) - 2)
1905                        == 0));
1906         ASSERT (retval == strlen (result));
1907         free (result);
1908       }
1909   }
1910
1911   { /* A negative number.  */
1912     char *result;
1913     int retval =
1914       my_asprintf (&result, "%e %d", -0.03125, 33, 44, 55);
1915     ASSERT (result != NULL);
1916     ASSERT (strcmp (result, "-3.125000e-02 33") == 0
1917             || strcmp (result, "-3.125000e-002 33") == 0);
1918     ASSERT (retval == strlen (result));
1919     free (result);
1920   }
1921
1922   { /* Positive zero.  */
1923     char *result;
1924     int retval =
1925       my_asprintf (&result, "%e %d", 0.0, 33, 44, 55);
1926     ASSERT (result != NULL);
1927     ASSERT (strcmp (result, "0.000000e+00 33") == 0
1928             || strcmp (result, "0.000000e+000 33") == 0);
1929     ASSERT (retval == strlen (result));
1930     free (result);
1931   }
1932
1933   { /* Negative zero.  */
1934     char *result;
1935     int retval =
1936       my_asprintf (&result, "%e %d", -0.0, 33, 44, 55);
1937     ASSERT (result != NULL);
1938     if (have_minus_zero ())
1939       ASSERT (strcmp (result, "-0.000000e+00 33") == 0
1940               || strcmp (result, "-0.000000e+000 33") == 0);
1941     ASSERT (retval == strlen (result));
1942     free (result);
1943   }
1944
1945   { /* Positive infinity.  */
1946     char *result;
1947     int retval =
1948       my_asprintf (&result, "%e %d", 1.0 / 0.0, 33, 44, 55);
1949     ASSERT (result != NULL);
1950     ASSERT (strcmp (result, "inf 33") == 0
1951             || strcmp (result, "infinity 33") == 0);
1952     ASSERT (retval == strlen (result));
1953     free (result);
1954   }
1955
1956   { /* Negative infinity.  */
1957     char *result;
1958     int retval =
1959       my_asprintf (&result, "%e %d", -1.0 / 0.0, 33, 44, 55);
1960     ASSERT (result != NULL);
1961     ASSERT (strcmp (result, "-inf 33") == 0
1962             || strcmp (result, "-infinity 33") == 0);
1963     ASSERT (retval == strlen (result));
1964     free (result);
1965   }
1966
1967   { /* NaN.  */
1968     char *result;
1969     int retval =
1970       my_asprintf (&result, "%e %d", NAN, 33, 44, 55);
1971     ASSERT (result != NULL);
1972     ASSERT (strlen (result) >= 3 + 3
1973             && strisnan (result, 0, strlen (result) - 3, 0)
1974             && strcmp (result + strlen (result) - 3, " 33") == 0);
1975     ASSERT (retval == strlen (result));
1976     free (result);
1977   }
1978
1979   { /* Width.  */
1980     char *result;
1981     int retval =
1982       my_asprintf (&result, "%15e %d", 1.75, 33, 44, 55);
1983     ASSERT (result != NULL);
1984     ASSERT (strcmp (result, "   1.750000e+00 33") == 0
1985             || strcmp (result, "  1.750000e+000 33") == 0);
1986     ASSERT (retval == strlen (result));
1987     free (result);
1988   }
1989
1990   { /* FLAG_LEFT.  */
1991     char *result;
1992     int retval =
1993       my_asprintf (&result, "%-15e %d", 1.75, 33, 44, 55);
1994     ASSERT (result != NULL);
1995     ASSERT (strcmp (result, "1.750000e+00    33") == 0
1996             || strcmp (result, "1.750000e+000   33") == 0);
1997     ASSERT (retval == strlen (result));
1998     free (result);
1999   }
2000
2001   { /* FLAG_SHOWSIGN.  */
2002     char *result;
2003     int retval =
2004       my_asprintf (&result, "%+e %d", 1.75, 33, 44, 55);
2005     ASSERT (result != NULL);
2006     ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2007             || strcmp (result, "+1.750000e+000 33") == 0);
2008     ASSERT (retval == strlen (result));
2009     free (result);
2010   }
2011
2012   { /* FLAG_SPACE.  */
2013     char *result;
2014     int retval =
2015       my_asprintf (&result, "% e %d", 1.75, 33, 44, 55);
2016     ASSERT (result != NULL);
2017     ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2018             || strcmp (result, " 1.750000e+000 33") == 0);
2019     ASSERT (retval == strlen (result));
2020     free (result);
2021   }
2022
2023   { /* FLAG_ALT.  */
2024     char *result;
2025     int retval =
2026       my_asprintf (&result, "%#e %d", 1.75, 33, 44, 55);
2027     ASSERT (result != NULL);
2028     ASSERT (strcmp (result, "1.750000e+00 33") == 0
2029             || strcmp (result, "1.750000e+000 33") == 0);
2030     ASSERT (retval == strlen (result));
2031     free (result);
2032   }
2033
2034   { /* FLAG_ALT.  */
2035     char *result;
2036     int retval =
2037       my_asprintf (&result, "%#.e %d", 1.75, 33, 44, 55);
2038     ASSERT (result != NULL);
2039     ASSERT (strcmp (result, "2.e+00 33") == 0
2040             || strcmp (result, "2.e+000 33") == 0);
2041     ASSERT (retval == strlen (result));
2042     free (result);
2043   }
2044
2045   { /* FLAG_ALT.  */
2046     char *result;
2047     int retval =
2048       my_asprintf (&result, "%#.e %d", 9.75, 33, 44, 55);
2049     ASSERT (result != NULL);
2050     ASSERT (strcmp (result, "1.e+01 33") == 0
2051             || strcmp (result, "1.e+001 33") == 0);
2052     ASSERT (retval == strlen (result));
2053     free (result);
2054   }
2055
2056   { /* FLAG_ZERO with finite number.  */
2057     char *result;
2058     int retval =
2059       my_asprintf (&result, "%015e %d", 1234.0, 33, 44, 55);
2060     ASSERT (result != NULL);
2061     ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2062             || strcmp (result, "001.234000e+003 33") == 0);
2063     ASSERT (retval == strlen (result));
2064     free (result);
2065   }
2066
2067   { /* FLAG_ZERO with infinite number.  */
2068     char *result;
2069     int retval =
2070       my_asprintf (&result, "%015e %d", -1.0 / 0.0, 33, 44, 55);
2071     ASSERT (result != NULL);
2072     ASSERT (strcmp (result, "           -inf 33") == 0
2073             || strcmp (result, "      -infinity 33") == 0);
2074     ASSERT (retval == strlen (result));
2075     free (result);
2076   }
2077
2078   { /* FLAG_ZERO with NaN.  */
2079     char *result;
2080     int retval =
2081       my_asprintf (&result, "%050e %d", NAN, 33, 44, 55);
2082     ASSERT (result != NULL);
2083     ASSERT (strlen (result) == 50 + 3
2084             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2085             && strcmp (result + strlen (result) - 3, " 33") == 0);
2086     ASSERT (retval == strlen (result));
2087     free (result);
2088   }
2089
2090   { /* Precision.  */
2091     char *result;
2092     int retval =
2093       my_asprintf (&result, "%.e %d", 1234.0, 33, 44, 55);
2094     ASSERT (result != NULL);
2095     ASSERT (strcmp (result, "1e+03 33") == 0
2096             || strcmp (result, "1e+003 33") == 0);
2097     ASSERT (retval == strlen (result));
2098     free (result);
2099   }
2100
2101   { /* A positive number.  */
2102     char *result;
2103     int retval =
2104       my_asprintf (&result, "%Le %d", 12.75L, 33, 44, 55);
2105     ASSERT (result != NULL);
2106     ASSERT (strcmp (result, "1.275000e+01 33") == 0);
2107     ASSERT (retval == strlen (result));
2108     free (result);
2109   }
2110
2111   { /* A larger positive number.  */
2112     char *result;
2113     int retval =
2114       my_asprintf (&result, "%Le %d", 1234567.0L, 33, 44, 55);
2115     ASSERT (result != NULL);
2116     ASSERT (strcmp (result, "1.234567e+06 33") == 0);
2117     ASSERT (retval == strlen (result));
2118     free (result);
2119   }
2120
2121   { /* Small and large positive numbers.  */
2122     static struct { long double value; const char *string; } data[] =
2123       {
2124         { 1.234321234321234e-37L, "1.234321e-37" },
2125         { 1.234321234321234e-36L, "1.234321e-36" },
2126         { 1.234321234321234e-35L, "1.234321e-35" },
2127         { 1.234321234321234e-34L, "1.234321e-34" },
2128         { 1.234321234321234e-33L, "1.234321e-33" },
2129         { 1.234321234321234e-32L, "1.234321e-32" },
2130         { 1.234321234321234e-31L, "1.234321e-31" },
2131         { 1.234321234321234e-30L, "1.234321e-30" },
2132         { 1.234321234321234e-29L, "1.234321e-29" },
2133         { 1.234321234321234e-28L, "1.234321e-28" },
2134         { 1.234321234321234e-27L, "1.234321e-27" },
2135         { 1.234321234321234e-26L, "1.234321e-26" },
2136         { 1.234321234321234e-25L, "1.234321e-25" },
2137         { 1.234321234321234e-24L, "1.234321e-24" },
2138         { 1.234321234321234e-23L, "1.234321e-23" },
2139         { 1.234321234321234e-22L, "1.234321e-22" },
2140         { 1.234321234321234e-21L, "1.234321e-21" },
2141         { 1.234321234321234e-20L, "1.234321e-20" },
2142         { 1.234321234321234e-19L, "1.234321e-19" },
2143         { 1.234321234321234e-18L, "1.234321e-18" },
2144         { 1.234321234321234e-17L, "1.234321e-17" },
2145         { 1.234321234321234e-16L, "1.234321e-16" },
2146         { 1.234321234321234e-15L, "1.234321e-15" },
2147         { 1.234321234321234e-14L, "1.234321e-14" },
2148         { 1.234321234321234e-13L, "1.234321e-13" },
2149         { 1.234321234321234e-12L, "1.234321e-12" },
2150         { 1.234321234321234e-11L, "1.234321e-11" },
2151         { 1.234321234321234e-10L, "1.234321e-10" },
2152         { 1.234321234321234e-9L, "1.234321e-09" },
2153         { 1.234321234321234e-8L, "1.234321e-08" },
2154         { 1.234321234321234e-7L, "1.234321e-07" },
2155         { 1.234321234321234e-6L, "1.234321e-06" },
2156         { 1.234321234321234e-5L, "1.234321e-05" },
2157         { 1.234321234321234e-4L, "1.234321e-04" },
2158         { 1.234321234321234e-3L, "1.234321e-03" },
2159         { 1.234321234321234e-2L, "1.234321e-02" },
2160         { 1.234321234321234e-1L, "1.234321e-01" },
2161         { 1.234321234321234L, "1.234321e+00" },
2162         { 1.234321234321234e1L, "1.234321e+01" },
2163         { 1.234321234321234e2L, "1.234321e+02" },
2164         { 1.234321234321234e3L, "1.234321e+03" },
2165         { 1.234321234321234e4L, "1.234321e+04" },
2166         { 1.234321234321234e5L, "1.234321e+05" },
2167         { 1.234321234321234e6L, "1.234321e+06" },
2168         { 1.234321234321234e7L, "1.234321e+07" },
2169         { 1.234321234321234e8L, "1.234321e+08" },
2170         { 1.234321234321234e9L, "1.234321e+09" },
2171         { 1.234321234321234e10L, "1.234321e+10" },
2172         { 1.234321234321234e11L, "1.234321e+11" },
2173         { 1.234321234321234e12L, "1.234321e+12" },
2174         { 1.234321234321234e13L, "1.234321e+13" },
2175         { 1.234321234321234e14L, "1.234321e+14" },
2176         { 1.234321234321234e15L, "1.234321e+15" },
2177         { 1.234321234321234e16L, "1.234321e+16" },
2178         { 1.234321234321234e17L, "1.234321e+17" },
2179         { 1.234321234321234e18L, "1.234321e+18" },
2180         { 1.234321234321234e19L, "1.234321e+19" },
2181         { 1.234321234321234e20L, "1.234321e+20" },
2182         { 1.234321234321234e21L, "1.234321e+21" },
2183         { 1.234321234321234e22L, "1.234321e+22" },
2184         { 1.234321234321234e23L, "1.234321e+23" },
2185         { 1.234321234321234e24L, "1.234321e+24" },
2186         { 1.234321234321234e25L, "1.234321e+25" },
2187         { 1.234321234321234e26L, "1.234321e+26" },
2188         { 1.234321234321234e27L, "1.234321e+27" },
2189         { 1.234321234321234e28L, "1.234321e+28" },
2190         { 1.234321234321234e29L, "1.234321e+29" },
2191         { 1.234321234321234e30L, "1.234321e+30" },
2192         { 1.234321234321234e31L, "1.234321e+31" },
2193         { 1.234321234321234e32L, "1.234321e+32" },
2194         { 1.234321234321234e33L, "1.234321e+33" },
2195         { 1.234321234321234e34L, "1.234321e+34" },
2196         { 1.234321234321234e35L, "1.234321e+35" },
2197         { 1.234321234321234e36L, "1.234321e+36" }
2198       };
2199     size_t k;
2200     for (k = 0; k < SIZEOF (data); k++)
2201       {
2202         char *result;
2203         int retval =
2204           my_asprintf (&result, "%Le", data[k].value);
2205         ASSERT (result != NULL);
2206         ASSERT (strcmp (result, data[k].string) == 0);
2207         ASSERT (retval == strlen (result));
2208         free (result);
2209       }
2210   }
2211
2212   { /* A negative number.  */
2213     char *result;
2214     int retval =
2215       my_asprintf (&result, "%Le %d", -0.03125L, 33, 44, 55);
2216     ASSERT (result != NULL);
2217     ASSERT (strcmp (result, "-3.125000e-02 33") == 0);
2218     ASSERT (retval == strlen (result));
2219     free (result);
2220   }
2221
2222   { /* Positive zero.  */
2223     char *result;
2224     int retval =
2225       my_asprintf (&result, "%Le %d", 0.0L, 33, 44, 55);
2226     ASSERT (result != NULL);
2227     ASSERT (strcmp (result, "0.000000e+00 33") == 0);
2228     ASSERT (retval == strlen (result));
2229     free (result);
2230   }
2231
2232   { /* Negative zero.  */
2233     char *result;
2234     int retval =
2235       my_asprintf (&result, "%Le %d", -0.0L, 33, 44, 55);
2236     ASSERT (result != NULL);
2237     if (have_minus_zero ())
2238       ASSERT (strcmp (result, "-0.000000e+00 33") == 0);
2239     ASSERT (retval == strlen (result));
2240     free (result);
2241   }
2242
2243   { /* Positive infinity.  */
2244     char *result;
2245     int retval =
2246       my_asprintf (&result, "%Le %d", 1.0L / 0.0L, 33, 44, 55);
2247     ASSERT (result != NULL);
2248     ASSERT (strcmp (result, "inf 33") == 0
2249             || strcmp (result, "infinity 33") == 0);
2250     ASSERT (retval == strlen (result));
2251     free (result);
2252   }
2253
2254   { /* Negative infinity.  */
2255     char *result;
2256     int retval =
2257       my_asprintf (&result, "%Le %d", -1.0L / 0.0L, 33, 44, 55);
2258     ASSERT (result != NULL);
2259     ASSERT (strcmp (result, "-inf 33") == 0
2260             || strcmp (result, "-infinity 33") == 0);
2261     ASSERT (retval == strlen (result));
2262     free (result);
2263   }
2264
2265   { /* NaN.  */
2266     static long double zero = 0.0L;
2267     char *result;
2268     int retval =
2269       my_asprintf (&result, "%Le %d", zero / zero, 33, 44, 55);
2270     ASSERT (result != NULL);
2271     ASSERT (strlen (result) >= 3 + 3
2272             && strisnan (result, 0, strlen (result) - 3, 0)
2273             && strcmp (result + strlen (result) - 3, " 33") == 0);
2274     ASSERT (retval == strlen (result));
2275     free (result);
2276   }
2277 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
2278   { /* Quiet NaN.  */
2279     static union { unsigned int word[4]; long double value; } x =
2280       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2281     char *result;
2282     int retval =
2283       my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2284     ASSERT (result != NULL);
2285     ASSERT (strlen (result) >= 3 + 3
2286             && strisnan (result, 0, strlen (result) - 3, 0)
2287             && strcmp (result + strlen (result) - 3, " 33") == 0);
2288     ASSERT (retval == strlen (result));
2289     free (result);
2290   }
2291   {
2292     /* Signalling NaN.  */
2293     static union { unsigned int word[4]; long double value; } x =
2294       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2295     char *result;
2296     int retval =
2297       my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2298     ASSERT (result != NULL);
2299     ASSERT (strlen (result) >= 3 + 3
2300             && strisnan (result, 0, strlen (result) - 3, 0)
2301             && strcmp (result + strlen (result) - 3, " 33") == 0);
2302     ASSERT (retval == strlen (result));
2303     free (result);
2304   }
2305   /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
2306      Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
2307        Intel IA-64 Architecture Software Developer's Manual, Volume 1:
2308        Application Architecture.
2309        Table 5-2 "Floating-Point Register Encodings"
2310        Figure 5-6 "Memory to Floating-Point Register Data Translation"
2311    */
2312   { /* Pseudo-NaN.  */
2313     static union { unsigned int word[4]; long double value; } x =
2314       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2315     char *result;
2316     int retval =
2317       my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2318     ASSERT (result != NULL);
2319     ASSERT (strlen (result) >= 3 + 3
2320             && strisnan (result, 0, strlen (result) - 3, 0)
2321             && strcmp (result + strlen (result) - 3, " 33") == 0);
2322     ASSERT (retval == strlen (result));
2323     free (result);
2324   }
2325   { /* Pseudo-Infinity.  */
2326     static union { unsigned int word[4]; long double value; } x =
2327       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2328     char *result;
2329     int retval =
2330       my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2331     ASSERT (result != NULL);
2332     ASSERT (strlen (result) >= 3 + 3
2333             && strisnan (result, 0, strlen (result) - 3, 0)
2334             && strcmp (result + strlen (result) - 3, " 33") == 0);
2335     ASSERT (retval == strlen (result));
2336     free (result);
2337   }
2338   { /* Pseudo-Zero.  */
2339     static union { unsigned int word[4]; long double value; } x =
2340       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2341     char *result;
2342     int retval =
2343       my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2344     ASSERT (result != NULL);
2345     ASSERT (strlen (result) >= 3 + 3
2346             && strisnan (result, 0, strlen (result) - 3, 0)
2347             && strcmp (result + strlen (result) - 3, " 33") == 0);
2348     ASSERT (retval == strlen (result));
2349     free (result);
2350   }
2351   { /* Unnormalized number.  */
2352     static union { unsigned int word[4]; long double value; } x =
2353       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2354     char *result;
2355     int retval =
2356       my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2357     ASSERT (result != NULL);
2358     ASSERT (strlen (result) >= 3 + 3
2359             && strisnan (result, 0, strlen (result) - 3, 0)
2360             && strcmp (result + strlen (result) - 3, " 33") == 0);
2361     ASSERT (retval == strlen (result));
2362     free (result);
2363   }
2364   { /* Pseudo-Denormal.  */
2365     static union { unsigned int word[4]; long double value; } x =
2366       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2367     char *result;
2368     int retval =
2369       my_asprintf (&result, "%Le %d", x.value, 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 #endif
2378
2379   { /* Width.  */
2380     char *result;
2381     int retval =
2382       my_asprintf (&result, "%15Le %d", 1.75L, 33, 44, 55);
2383     ASSERT (result != NULL);
2384     ASSERT (strcmp (result, "   1.750000e+00 33") == 0);
2385     ASSERT (retval == strlen (result));
2386     free (result);
2387   }
2388
2389   { /* FLAG_LEFT.  */
2390     char *result;
2391     int retval =
2392       my_asprintf (&result, "%-15Le %d", 1.75L, 33, 44, 55);
2393     ASSERT (result != NULL);
2394     ASSERT (strcmp (result, "1.750000e+00    33") == 0);
2395     ASSERT (retval == strlen (result));
2396     free (result);
2397   }
2398
2399   { /* FLAG_SHOWSIGN.  */
2400     char *result;
2401     int retval =
2402       my_asprintf (&result, "%+Le %d", 1.75L, 33, 44, 55);
2403     ASSERT (result != NULL);
2404     ASSERT (strcmp (result, "+1.750000e+00 33") == 0);
2405     ASSERT (retval == strlen (result));
2406     free (result);
2407   }
2408
2409   { /* FLAG_SPACE.  */
2410     char *result;
2411     int retval =
2412       my_asprintf (&result, "% Le %d", 1.75L, 33, 44, 55);
2413     ASSERT (result != NULL);
2414     ASSERT (strcmp (result, " 1.750000e+00 33") == 0);
2415     ASSERT (retval == strlen (result));
2416     free (result);
2417   }
2418
2419   { /* FLAG_ALT.  */
2420     char *result;
2421     int retval =
2422       my_asprintf (&result, "%#Le %d", 1.75L, 33, 44, 55);
2423     ASSERT (result != NULL);
2424     ASSERT (strcmp (result, "1.750000e+00 33") == 0);
2425     ASSERT (retval == strlen (result));
2426     free (result);
2427   }
2428
2429   { /* FLAG_ALT.  */
2430     char *result;
2431     int retval =
2432       my_asprintf (&result, "%#.Le %d", 1.75L, 33, 44, 55);
2433     ASSERT (result != NULL);
2434     ASSERT (strcmp (result, "2.e+00 33") == 0);
2435     ASSERT (retval == strlen (result));
2436     free (result);
2437   }
2438
2439   { /* FLAG_ALT.  */
2440     char *result;
2441     int retval =
2442       my_asprintf (&result, "%#.Le %d", 9.75L, 33, 44, 55);
2443     ASSERT (result != NULL);
2444     ASSERT (strcmp (result, "1.e+01 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, "%015Le %d", 1234.0L, 33, 44, 55);
2453     ASSERT (result != NULL);
2454     ASSERT (strcmp (result, "0001.234000e+03 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, "%015Le %d", -1.0L / 0.0L, 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     static long double zero = 0.0L;
2472     char *result;
2473     int retval =
2474       my_asprintf (&result, "%050Le %d", zero / zero, 33, 44, 55);
2475     ASSERT (result != NULL);
2476     ASSERT (strlen (result) == 50 + 3
2477             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2478             && strcmp (result + strlen (result) - 3, " 33") == 0);
2479     ASSERT (retval == strlen (result));
2480     free (result);
2481   }
2482
2483   { /* Precision.  */
2484     char *result;
2485     int retval =
2486       my_asprintf (&result, "%.Le %d", 1234.0L, 33, 44, 55);
2487     ASSERT (result != NULL);
2488     ASSERT (strcmp (result, "1e+03 33") == 0);
2489     ASSERT (retval == strlen (result));
2490     free (result);
2491   }
2492
2493   /* Test the support of the %g format directive.  */
2494
2495   { /* A positive number.  */
2496     char *result;
2497     int retval =
2498       my_asprintf (&result, "%g %d", 12.75, 33, 44, 55);
2499     ASSERT (result != NULL);
2500     ASSERT (strcmp (result, "12.75 33") == 0);
2501     ASSERT (retval == strlen (result));
2502     free (result);
2503   }
2504
2505   { /* A larger positive number.  */
2506     char *result;
2507     int retval =
2508       my_asprintf (&result, "%g %d", 1234567.0, 33, 44, 55);
2509     ASSERT (result != NULL);
2510     ASSERT (strcmp (result, "1.23457e+06 33") == 0
2511             || strcmp (result, "1.23457e+006 33") == 0);
2512     ASSERT (retval == strlen (result));
2513     free (result);
2514   }
2515
2516   { /* Small and large positive numbers.  */
2517     static struct { double value; const char *string; } data[] =
2518       {
2519         { 1.234321234321234e-37, "1.23432e-37" },
2520         { 1.234321234321234e-36, "1.23432e-36" },
2521         { 1.234321234321234e-35, "1.23432e-35" },
2522         { 1.234321234321234e-34, "1.23432e-34" },
2523         { 1.234321234321234e-33, "1.23432e-33" },
2524         { 1.234321234321234e-32, "1.23432e-32" },
2525         { 1.234321234321234e-31, "1.23432e-31" },
2526         { 1.234321234321234e-30, "1.23432e-30" },
2527         { 1.234321234321234e-29, "1.23432e-29" },
2528         { 1.234321234321234e-28, "1.23432e-28" },
2529         { 1.234321234321234e-27, "1.23432e-27" },
2530         { 1.234321234321234e-26, "1.23432e-26" },
2531         { 1.234321234321234e-25, "1.23432e-25" },
2532         { 1.234321234321234e-24, "1.23432e-24" },
2533         { 1.234321234321234e-23, "1.23432e-23" },
2534         { 1.234321234321234e-22, "1.23432e-22" },
2535         { 1.234321234321234e-21, "1.23432e-21" },
2536         { 1.234321234321234e-20, "1.23432e-20" },
2537         { 1.234321234321234e-19, "1.23432e-19" },
2538         { 1.234321234321234e-18, "1.23432e-18" },
2539         { 1.234321234321234e-17, "1.23432e-17" },
2540         { 1.234321234321234e-16, "1.23432e-16" },
2541         { 1.234321234321234e-15, "1.23432e-15" },
2542         { 1.234321234321234e-14, "1.23432e-14" },
2543         { 1.234321234321234e-13, "1.23432e-13" },
2544         { 1.234321234321234e-12, "1.23432e-12" },
2545         { 1.234321234321234e-11, "1.23432e-11" },
2546         { 1.234321234321234e-10, "1.23432e-10" },
2547         { 1.234321234321234e-9, "1.23432e-09" },
2548         { 1.234321234321234e-8, "1.23432e-08" },
2549         { 1.234321234321234e-7, "1.23432e-07" },
2550         { 1.234321234321234e-6, "1.23432e-06" },
2551         { 1.234321234321234e-5, "1.23432e-05" },
2552         { 1.234321234321234e-4, "0.000123432" },
2553         { 1.234321234321234e-3, "0.00123432" },
2554         { 1.234321234321234e-2, "0.0123432" },
2555         { 1.234321234321234e-1, "0.123432" },
2556         { 1.234321234321234, "1.23432" },
2557         { 1.234321234321234e1, "12.3432" },
2558         { 1.234321234321234e2, "123.432" },
2559         { 1.234321234321234e3, "1234.32" },
2560         { 1.234321234321234e4, "12343.2" },
2561         { 1.234321234321234e5, "123432" },
2562         { 1.234321234321234e6, "1.23432e+06" },
2563         { 1.234321234321234e7, "1.23432e+07" },
2564         { 1.234321234321234e8, "1.23432e+08" },
2565         { 1.234321234321234e9, "1.23432e+09" },
2566         { 1.234321234321234e10, "1.23432e+10" },
2567         { 1.234321234321234e11, "1.23432e+11" },
2568         { 1.234321234321234e12, "1.23432e+12" },
2569         { 1.234321234321234e13, "1.23432e+13" },
2570         { 1.234321234321234e14, "1.23432e+14" },
2571         { 1.234321234321234e15, "1.23432e+15" },
2572         { 1.234321234321234e16, "1.23432e+16" },
2573         { 1.234321234321234e17, "1.23432e+17" },
2574         { 1.234321234321234e18, "1.23432e+18" },
2575         { 1.234321234321234e19, "1.23432e+19" },
2576         { 1.234321234321234e20, "1.23432e+20" },
2577         { 1.234321234321234e21, "1.23432e+21" },
2578         { 1.234321234321234e22, "1.23432e+22" },
2579         { 1.234321234321234e23, "1.23432e+23" },
2580         { 1.234321234321234e24, "1.23432e+24" },
2581         { 1.234321234321234e25, "1.23432e+25" },
2582         { 1.234321234321234e26, "1.23432e+26" },
2583         { 1.234321234321234e27, "1.23432e+27" },
2584         { 1.234321234321234e28, "1.23432e+28" },
2585         { 1.234321234321234e29, "1.23432e+29" },
2586         { 1.234321234321234e30, "1.23432e+30" },
2587         { 1.234321234321234e31, "1.23432e+31" },
2588         { 1.234321234321234e32, "1.23432e+32" },
2589         { 1.234321234321234e33, "1.23432e+33" },
2590         { 1.234321234321234e34, "1.23432e+34" },
2591         { 1.234321234321234e35, "1.23432e+35" },
2592         { 1.234321234321234e36, "1.23432e+36" }
2593       };
2594     size_t k;
2595     for (k = 0; k < SIZEOF (data); k++)
2596       {
2597         char *result;
2598         int retval =
2599           my_asprintf (&result, "%g", data[k].value);
2600         const char *expected = data[k].string;
2601         ASSERT (result != NULL);
2602         ASSERT (strcmp (result, expected) == 0
2603                 /* Some implementations produce exponents with 3 digits.  */
2604                 || (expected[strlen (expected) - 4] == 'e'
2605                     && strlen (result) == strlen (expected) + 1
2606                     && memcmp (result, expected, strlen (expected) - 2) == 0
2607                     && result[strlen (expected) - 2] == '0'
2608                     && strcmp (result + strlen (expected) - 1,
2609                                expected + strlen (expected) - 2)
2610                        == 0));
2611         ASSERT (retval == strlen (result));
2612         free (result);
2613       }
2614   }
2615
2616   { /* A negative number.  */
2617     char *result;
2618     int retval =
2619       my_asprintf (&result, "%g %d", -0.03125, 33, 44, 55);
2620     ASSERT (result != NULL);
2621     ASSERT (strcmp (result, "-0.03125 33") == 0);
2622     ASSERT (retval == strlen (result));
2623     free (result);
2624   }
2625
2626   { /* Positive zero.  */
2627     char *result;
2628     int retval =
2629       my_asprintf (&result, "%g %d", 0.0, 33, 44, 55);
2630     ASSERT (result != NULL);
2631     ASSERT (strcmp (result, "0 33") == 0);
2632     ASSERT (retval == strlen (result));
2633     free (result);
2634   }
2635
2636   { /* Negative zero.  */
2637     char *result;
2638     int retval =
2639       my_asprintf (&result, "%g %d", -0.0, 33, 44, 55);
2640     ASSERT (result != NULL);
2641     if (have_minus_zero ())
2642       ASSERT (strcmp (result, "-0 33") == 0);
2643     ASSERT (retval == strlen (result));
2644     free (result);
2645   }
2646
2647   { /* Positive infinity.  */
2648     char *result;
2649     int retval =
2650       my_asprintf (&result, "%g %d", 1.0 / 0.0, 33, 44, 55);
2651     ASSERT (result != NULL);
2652     ASSERT (strcmp (result, "inf 33") == 0
2653             || strcmp (result, "infinity 33") == 0);
2654     ASSERT (retval == strlen (result));
2655     free (result);
2656   }
2657
2658   { /* Negative infinity.  */
2659     char *result;
2660     int retval =
2661       my_asprintf (&result, "%g %d", -1.0 / 0.0, 33, 44, 55);
2662     ASSERT (result != NULL);
2663     ASSERT (strcmp (result, "-inf 33") == 0
2664             || strcmp (result, "-infinity 33") == 0);
2665     ASSERT (retval == strlen (result));
2666     free (result);
2667   }
2668
2669   { /* NaN.  */
2670     char *result;
2671     int retval =
2672       my_asprintf (&result, "%g %d", NAN, 33, 44, 55);
2673     ASSERT (result != NULL);
2674     ASSERT (strlen (result) >= 3 + 3
2675             && strisnan (result, 0, strlen (result) - 3, 0)
2676             && strcmp (result + strlen (result) - 3, " 33") == 0);
2677     ASSERT (retval == strlen (result));
2678     free (result);
2679   }
2680
2681   { /* Width.  */
2682     char *result;
2683     int retval =
2684       my_asprintf (&result, "%10g %d", 1.75, 33, 44, 55);
2685     ASSERT (result != NULL);
2686     ASSERT (strcmp (result, "      1.75 33") == 0);
2687     ASSERT (retval == strlen (result));
2688     free (result);
2689   }
2690
2691   { /* FLAG_LEFT.  */
2692     char *result;
2693     int retval =
2694       my_asprintf (&result, "%-10g %d", 1.75, 33, 44, 55);
2695     ASSERT (result != NULL);
2696     ASSERT (strcmp (result, "1.75       33") == 0);
2697     ASSERT (retval == strlen (result));
2698     free (result);
2699   }
2700
2701   { /* FLAG_SHOWSIGN.  */
2702     char *result;
2703     int retval =
2704       my_asprintf (&result, "%+g %d", 1.75, 33, 44, 55);
2705     ASSERT (result != NULL);
2706     ASSERT (strcmp (result, "+1.75 33") == 0);
2707     ASSERT (retval == strlen (result));
2708     free (result);
2709   }
2710
2711   { /* FLAG_SPACE.  */
2712     char *result;
2713     int retval =
2714       my_asprintf (&result, "% g %d", 1.75, 33, 44, 55);
2715     ASSERT (result != NULL);
2716     ASSERT (strcmp (result, " 1.75 33") == 0);
2717     ASSERT (retval == strlen (result));
2718     free (result);
2719   }
2720
2721   { /* FLAG_ALT.  */
2722     char *result;
2723     int retval =
2724       my_asprintf (&result, "%#g %d", 1.75, 33, 44, 55);
2725     ASSERT (result != NULL);
2726     ASSERT (strcmp (result, "1.75000 33") == 0);
2727     ASSERT (retval == strlen (result));
2728     free (result);
2729   }
2730
2731   { /* FLAG_ALT.  */
2732     char *result;
2733     int retval =
2734       my_asprintf (&result, "%#.g %d", 1.75, 33, 44, 55);
2735     ASSERT (result != NULL);
2736     ASSERT (strcmp (result, "2. 33") == 0);
2737     ASSERT (retval == strlen (result));
2738     free (result);
2739   }
2740
2741   { /* FLAG_ALT.  */
2742     char *result;
2743     int retval =
2744       my_asprintf (&result, "%#.g %d", 9.75, 33, 44, 55);
2745     ASSERT (result != NULL);
2746     ASSERT (strcmp (result, "1.e+01 33") == 0
2747             || strcmp (result, "1.e+001 33") == 0);
2748     ASSERT (retval == strlen (result));
2749     free (result);
2750   }
2751
2752   { /* FLAG_ZERO with finite number.  */
2753     char *result;
2754     int retval =
2755       my_asprintf (&result, "%010g %d", 1234.0, 33, 44, 55);
2756     ASSERT (result != NULL);
2757     ASSERT (strcmp (result, "0000001234 33") == 0);
2758     ASSERT (retval == strlen (result));
2759     free (result);
2760   }
2761
2762   { /* FLAG_ZERO with infinite number.  */
2763     char *result;
2764     int retval =
2765       my_asprintf (&result, "%015g %d", -1.0 / 0.0, 33, 44, 55);
2766     ASSERT (result != NULL);
2767     ASSERT (strcmp (result, "           -inf 33") == 0
2768             || strcmp (result, "      -infinity 33") == 0);
2769     ASSERT (retval == strlen (result));
2770     free (result);
2771   }
2772
2773   { /* FLAG_ZERO with NaN.  */
2774     char *result;
2775     int retval =
2776       my_asprintf (&result, "%050g %d", NAN, 33, 44, 55);
2777     ASSERT (result != NULL);
2778     ASSERT (strlen (result) == 50 + 3
2779             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2780             && strcmp (result + strlen (result) - 3, " 33") == 0);
2781     ASSERT (retval == strlen (result));
2782     free (result);
2783   }
2784
2785   { /* Precision.  */
2786     char *result;
2787     int retval =
2788       my_asprintf (&result, "%.g %d", 1234.0, 33, 44, 55);
2789     ASSERT (result != NULL);
2790     ASSERT (strcmp (result, "1e+03 33") == 0
2791             || strcmp (result, "1e+003 33") == 0);
2792     ASSERT (retval == strlen (result));
2793     free (result);
2794   }
2795
2796   { /* A positive number.  */
2797     char *result;
2798     int retval =
2799       my_asprintf (&result, "%Lg %d", 12.75L, 33, 44, 55);
2800     ASSERT (result != NULL);
2801     ASSERT (strcmp (result, "12.75 33") == 0);
2802     ASSERT (retval == strlen (result));
2803     free (result);
2804   }
2805
2806   { /* A larger positive number.  */
2807     char *result;
2808     int retval =
2809       my_asprintf (&result, "%Lg %d", 1234567.0L, 33, 44, 55);
2810     ASSERT (result != NULL);
2811     ASSERT (strcmp (result, "1.23457e+06 33") == 0);
2812     ASSERT (retval == strlen (result));
2813     free (result);
2814   }
2815
2816   { /* Small and large positive numbers.  */
2817     static struct { long double value; const char *string; } data[] =
2818       {
2819         { 1.234321234321234e-37L, "1.23432e-37" },
2820         { 1.234321234321234e-36L, "1.23432e-36" },
2821         { 1.234321234321234e-35L, "1.23432e-35" },
2822         { 1.234321234321234e-34L, "1.23432e-34" },
2823         { 1.234321234321234e-33L, "1.23432e-33" },
2824         { 1.234321234321234e-32L, "1.23432e-32" },
2825         { 1.234321234321234e-31L, "1.23432e-31" },
2826         { 1.234321234321234e-30L, "1.23432e-30" },
2827         { 1.234321234321234e-29L, "1.23432e-29" },
2828         { 1.234321234321234e-28L, "1.23432e-28" },
2829         { 1.234321234321234e-27L, "1.23432e-27" },
2830         { 1.234321234321234e-26L, "1.23432e-26" },
2831         { 1.234321234321234e-25L, "1.23432e-25" },
2832         { 1.234321234321234e-24L, "1.23432e-24" },
2833         { 1.234321234321234e-23L, "1.23432e-23" },
2834         { 1.234321234321234e-22L, "1.23432e-22" },
2835         { 1.234321234321234e-21L, "1.23432e-21" },
2836         { 1.234321234321234e-20L, "1.23432e-20" },
2837         { 1.234321234321234e-19L, "1.23432e-19" },
2838         { 1.234321234321234e-18L, "1.23432e-18" },
2839         { 1.234321234321234e-17L, "1.23432e-17" },
2840         { 1.234321234321234e-16L, "1.23432e-16" },
2841         { 1.234321234321234e-15L, "1.23432e-15" },
2842         { 1.234321234321234e-14L, "1.23432e-14" },
2843         { 1.234321234321234e-13L, "1.23432e-13" },
2844         { 1.234321234321234e-12L, "1.23432e-12" },
2845         { 1.234321234321234e-11L, "1.23432e-11" },
2846         { 1.234321234321234e-10L, "1.23432e-10" },
2847         { 1.234321234321234e-9L, "1.23432e-09" },
2848         { 1.234321234321234e-8L, "1.23432e-08" },
2849         { 1.234321234321234e-7L, "1.23432e-07" },
2850         { 1.234321234321234e-6L, "1.23432e-06" },
2851         { 1.234321234321234e-5L, "1.23432e-05" },
2852         { 1.234321234321234e-4L, "0.000123432" },
2853         { 1.234321234321234e-3L, "0.00123432" },
2854         { 1.234321234321234e-2L, "0.0123432" },
2855         { 1.234321234321234e-1L, "0.123432" },
2856         { 1.234321234321234L, "1.23432" },
2857         { 1.234321234321234e1L, "12.3432" },
2858         { 1.234321234321234e2L, "123.432" },
2859         { 1.234321234321234e3L, "1234.32" },
2860         { 1.234321234321234e4L, "12343.2" },
2861         { 1.234321234321234e5L, "123432" },
2862         { 1.234321234321234e6L, "1.23432e+06" },
2863         { 1.234321234321234e7L, "1.23432e+07" },
2864         { 1.234321234321234e8L, "1.23432e+08" },
2865         { 1.234321234321234e9L, "1.23432e+09" },
2866         { 1.234321234321234e10L, "1.23432e+10" },
2867         { 1.234321234321234e11L, "1.23432e+11" },
2868         { 1.234321234321234e12L, "1.23432e+12" },
2869         { 1.234321234321234e13L, "1.23432e+13" },
2870         { 1.234321234321234e14L, "1.23432e+14" },
2871         { 1.234321234321234e15L, "1.23432e+15" },
2872         { 1.234321234321234e16L, "1.23432e+16" },
2873         { 1.234321234321234e17L, "1.23432e+17" },
2874         { 1.234321234321234e18L, "1.23432e+18" },
2875         { 1.234321234321234e19L, "1.23432e+19" },
2876         { 1.234321234321234e20L, "1.23432e+20" },
2877         { 1.234321234321234e21L, "1.23432e+21" },
2878         { 1.234321234321234e22L, "1.23432e+22" },
2879         { 1.234321234321234e23L, "1.23432e+23" },
2880         { 1.234321234321234e24L, "1.23432e+24" },
2881         { 1.234321234321234e25L, "1.23432e+25" },
2882         { 1.234321234321234e26L, "1.23432e+26" },
2883         { 1.234321234321234e27L, "1.23432e+27" },
2884         { 1.234321234321234e28L, "1.23432e+28" },
2885         { 1.234321234321234e29L, "1.23432e+29" },
2886         { 1.234321234321234e30L, "1.23432e+30" },
2887         { 1.234321234321234e31L, "1.23432e+31" },
2888         { 1.234321234321234e32L, "1.23432e+32" },
2889         { 1.234321234321234e33L, "1.23432e+33" },
2890         { 1.234321234321234e34L, "1.23432e+34" },
2891         { 1.234321234321234e35L, "1.23432e+35" },
2892         { 1.234321234321234e36L, "1.23432e+36" }
2893       };
2894     size_t k;
2895     for (k = 0; k < SIZEOF (data); k++)
2896       {
2897         char *result;
2898         int retval =
2899           my_asprintf (&result, "%Lg", data[k].value);
2900         ASSERT (result != NULL);
2901         ASSERT (strcmp (result, data[k].string) == 0);
2902         ASSERT (retval == strlen (result));
2903         free (result);
2904       }
2905   }
2906
2907   { /* A negative number.  */
2908     char *result;
2909     int retval =
2910       my_asprintf (&result, "%Lg %d", -0.03125L, 33, 44, 55);
2911     ASSERT (result != NULL);
2912     ASSERT (strcmp (result, "-0.03125 33") == 0);
2913     ASSERT (retval == strlen (result));
2914     free (result);
2915   }
2916
2917   { /* Positive zero.  */
2918     char *result;
2919     int retval =
2920       my_asprintf (&result, "%Lg %d", 0.0L, 33, 44, 55);
2921     ASSERT (result != NULL);
2922     ASSERT (strcmp (result, "0 33") == 0);
2923     ASSERT (retval == strlen (result));
2924     free (result);
2925   }
2926
2927   { /* Negative zero.  */
2928     char *result;
2929     int retval =
2930       my_asprintf (&result, "%Lg %d", -0.0L, 33, 44, 55);
2931     ASSERT (result != NULL);
2932     if (have_minus_zero ())
2933       ASSERT (strcmp (result, "-0 33") == 0);
2934     ASSERT (retval == strlen (result));
2935     free (result);
2936   }
2937
2938   { /* Positive infinity.  */
2939     char *result;
2940     int retval =
2941       my_asprintf (&result, "%Lg %d", 1.0L / 0.0L, 33, 44, 55);
2942     ASSERT (result != NULL);
2943     ASSERT (strcmp (result, "inf 33") == 0
2944             || strcmp (result, "infinity 33") == 0);
2945     ASSERT (retval == strlen (result));
2946     free (result);
2947   }
2948
2949   { /* Negative infinity.  */
2950     char *result;
2951     int retval =
2952       my_asprintf (&result, "%Lg %d", -1.0L / 0.0L, 33, 44, 55);
2953     ASSERT (result != NULL);
2954     ASSERT (strcmp (result, "-inf 33") == 0
2955             || strcmp (result, "-infinity 33") == 0);
2956     ASSERT (retval == strlen (result));
2957     free (result);
2958   }
2959
2960   { /* NaN.  */
2961     static long double zero = 0.0L;
2962     char *result;
2963     int retval =
2964       my_asprintf (&result, "%Lg %d", zero / zero, 33, 44, 55);
2965     ASSERT (result != NULL);
2966     ASSERT (strlen (result) >= 3 + 3
2967             && strisnan (result, 0, strlen (result) - 3, 0)
2968             && strcmp (result + strlen (result) - 3, " 33") == 0);
2969     ASSERT (retval == strlen (result));
2970     free (result);
2971   }
2972 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))
2973   { /* Quiet NaN.  */
2974     static union { unsigned int word[4]; long double value; } x =
2975       { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2976     char *result;
2977     int retval =
2978       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
2979     ASSERT (result != NULL);
2980     ASSERT (strlen (result) >= 3 + 3
2981             && strisnan (result, 0, strlen (result) - 3, 0)
2982             && strcmp (result + strlen (result) - 3, " 33") == 0);
2983     ASSERT (retval == strlen (result));
2984     free (result);
2985   }
2986   {
2987     /* Signalling NaN.  */
2988     static union { unsigned int word[4]; long double value; } x =
2989       { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2990     char *result;
2991     int retval =
2992       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
2993     ASSERT (result != NULL);
2994     ASSERT (strlen (result) >= 3 + 3
2995             && strisnan (result, 0, strlen (result) - 3, 0)
2996             && strcmp (result + strlen (result) - 3, " 33") == 0);
2997     ASSERT (retval == strlen (result));
2998     free (result);
2999   }
3000   /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
3001      Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
3002        Intel IA-64 Architecture Software Developer's Manual, Volume 1:
3003        Application Architecture.
3004        Table 5-2 "Floating-Point Register Encodings"
3005        Figure 5-6 "Memory to Floating-Point Register Data Translation"
3006    */
3007   { /* Pseudo-NaN.  */
3008     static union { unsigned int word[4]; long double value; } x =
3009       { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
3010     char *result;
3011     int retval =
3012       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3013     ASSERT (result != NULL);
3014     ASSERT (strlen (result) >= 3 + 3
3015             && strisnan (result, 0, strlen (result) - 3, 0)
3016             && strcmp (result + strlen (result) - 3, " 33") == 0);
3017     ASSERT (retval == strlen (result));
3018     free (result);
3019   }
3020   { /* Pseudo-Infinity.  */
3021     static union { unsigned int word[4]; long double value; } x =
3022       { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
3023     char *result;
3024     int retval =
3025       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3026     ASSERT (result != NULL);
3027     ASSERT (strlen (result) >= 3 + 3
3028             && strisnan (result, 0, strlen (result) - 3, 0)
3029             && strcmp (result + strlen (result) - 3, " 33") == 0);
3030     ASSERT (retval == strlen (result));
3031     free (result);
3032   }
3033   { /* Pseudo-Zero.  */
3034     static union { unsigned int word[4]; long double value; } x =
3035       { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
3036     char *result;
3037     int retval =
3038       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3039     ASSERT (result != NULL);
3040     ASSERT (strlen (result) >= 3 + 3
3041             && strisnan (result, 0, strlen (result) - 3, 0)
3042             && strcmp (result + strlen (result) - 3, " 33") == 0);
3043     ASSERT (retval == strlen (result));
3044     free (result);
3045   }
3046   { /* Unnormalized number.  */
3047     static union { unsigned int word[4]; long double value; } x =
3048       { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
3049     char *result;
3050     int retval =
3051       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3052     ASSERT (result != NULL);
3053     ASSERT (strlen (result) >= 3 + 3
3054             && strisnan (result, 0, strlen (result) - 3, 0)
3055             && strcmp (result + strlen (result) - 3, " 33") == 0);
3056     ASSERT (retval == strlen (result));
3057     free (result);
3058   }
3059   { /* Pseudo-Denormal.  */
3060     static union { unsigned int word[4]; long double value; } x =
3061       { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
3062     char *result;
3063     int retval =
3064       my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3065     ASSERT (result != NULL);
3066     ASSERT (strlen (result) >= 3 + 3
3067             && strisnan (result, 0, strlen (result) - 3, 0)
3068             && strcmp (result + strlen (result) - 3, " 33") == 0);
3069     ASSERT (retval == strlen (result));
3070     free (result);
3071   }
3072 #endif
3073
3074   { /* Width.  */
3075     char *result;
3076     int retval =
3077       my_asprintf (&result, "%10Lg %d", 1.75L, 33, 44, 55);
3078     ASSERT (result != NULL);
3079     ASSERT (strcmp (result, "      1.75 33") == 0);
3080     ASSERT (retval == strlen (result));
3081     free (result);
3082   }
3083
3084   { /* FLAG_LEFT.  */
3085     char *result;
3086     int retval =
3087       my_asprintf (&result, "%-10Lg %d", 1.75L, 33, 44, 55);
3088     ASSERT (result != NULL);
3089     ASSERT (strcmp (result, "1.75       33") == 0);
3090     ASSERT (retval == strlen (result));
3091     free (result);
3092   }
3093
3094   { /* FLAG_SHOWSIGN.  */
3095     char *result;
3096     int retval =
3097       my_asprintf (&result, "%+Lg %d", 1.75L, 33, 44, 55);
3098     ASSERT (result != NULL);
3099     ASSERT (strcmp (result, "+1.75 33") == 0);
3100     ASSERT (retval == strlen (result));
3101     free (result);
3102   }
3103
3104   { /* FLAG_SPACE.  */
3105     char *result;
3106     int retval =
3107       my_asprintf (&result, "% Lg %d", 1.75L, 33, 44, 55);
3108     ASSERT (result != NULL);
3109     ASSERT (strcmp (result, " 1.75 33") == 0);
3110     ASSERT (retval == strlen (result));
3111     free (result);
3112   }
3113
3114   { /* FLAG_ALT.  */
3115     char *result;
3116     int retval =
3117       my_asprintf (&result, "%#Lg %d", 1.75L, 33, 44, 55);
3118     ASSERT (result != NULL);
3119     ASSERT (strcmp (result, "1.75000 33") == 0);
3120     ASSERT (retval == strlen (result));
3121     free (result);
3122   }
3123
3124   { /* FLAG_ALT.  */
3125     char *result;
3126     int retval =
3127       my_asprintf (&result, "%#.Lg %d", 1.75L, 33, 44, 55);
3128     ASSERT (result != NULL);
3129     ASSERT (strcmp (result, "2. 33") == 0);
3130     ASSERT (retval == strlen (result));
3131     free (result);
3132   }
3133
3134   { /* FLAG_ALT.  */
3135     char *result;
3136     int retval =
3137       my_asprintf (&result, "%#.Lg %d", 9.75L, 33, 44, 55);
3138     ASSERT (result != NULL);
3139     ASSERT (strcmp (result, "1.e+01 33") == 0);
3140     ASSERT (retval == strlen (result));
3141     free (result);
3142   }
3143
3144   { /* FLAG_ZERO with finite number.  */
3145     char *result;
3146     int retval =
3147       my_asprintf (&result, "%010Lg %d", 1234.0L, 33, 44, 55);
3148     ASSERT (result != NULL);
3149     ASSERT (strcmp (result, "0000001234 33") == 0);
3150     ASSERT (retval == strlen (result));
3151     free (result);
3152   }
3153
3154   { /* FLAG_ZERO with infinite number.  */
3155     char *result;
3156     int retval =
3157       my_asprintf (&result, "%015Lg %d", -1.0L / 0.0L, 33, 44, 55);
3158     ASSERT (result != NULL);
3159     ASSERT (strcmp (result, "           -inf 33") == 0
3160             || strcmp (result, "      -infinity 33") == 0);
3161     ASSERT (retval == strlen (result));
3162     free (result);
3163   }
3164
3165   { /* FLAG_ZERO with NaN.  */
3166     static long double zero = 0.0L;
3167     char *result;
3168     int retval =
3169       my_asprintf (&result, "%050Lg %d", zero / zero, 33, 44, 55);
3170     ASSERT (result != NULL);
3171     ASSERT (strlen (result) == 50 + 3
3172             && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
3173             && strcmp (result + strlen (result) - 3, " 33") == 0);
3174     ASSERT (retval == strlen (result));
3175     free (result);
3176   }
3177
3178   { /* Precision.  */
3179     char *result;
3180     int retval =
3181       my_asprintf (&result, "%.Lg %d", 1234.0L, 33, 44, 55);
3182     ASSERT (result != NULL);
3183     ASSERT (strcmp (result, "1e+03 33") == 0);
3184     ASSERT (retval == strlen (result));
3185     free (result);
3186   }
3187
3188   /* Test the support of the %n format directive.  */
3189
3190   {
3191     int count = -1;
3192     char *result;
3193     int retval =
3194       my_asprintf (&result, "%d %n", 123, &count, 33, 44, 55);
3195     ASSERT (result != NULL);
3196     ASSERT (strcmp (result, "123 ") == 0);
3197     ASSERT (retval == strlen (result));
3198     ASSERT (count == 4);
3199     free (result);
3200   }
3201
3202   /* Test the support of the POSIX/XSI format strings with positions.  */
3203
3204   {
3205     char *result;
3206     int retval =
3207       my_asprintf (&result, "%2$d %1$d", 33, 55);
3208     ASSERT (result != NULL);
3209     ASSERT (strcmp (result, "55 33") == 0);
3210     ASSERT (retval == strlen (result));
3211     free (result);
3212   }
3213
3214   /* Test the support of the grouping flag.  */
3215
3216   {
3217     char *result;
3218     int retval =
3219       my_asprintf (&result, "%'d %d", 1234567, 99);
3220     ASSERT (result != NULL);
3221     ASSERT (result[strlen (result) - 1] == '9');
3222     ASSERT (retval == strlen (result));
3223     free (result);
3224   }
3225
3226   /* Test the support of the left-adjust flag.  */
3227
3228   {
3229     char *result;
3230     int retval =
3231       my_asprintf (&result, "a%*sc", -3, "b");
3232     ASSERT (result != NULL);
3233     ASSERT (strcmp (result, "ab  c") == 0);
3234     ASSERT (retval == strlen (result));
3235     free (result);
3236   }
3237
3238   {
3239     char *result;
3240     int retval =
3241       my_asprintf (&result, "a%-*sc", 3, "b");
3242     ASSERT (result != NULL);
3243     ASSERT (strcmp (result, "ab  c") == 0);
3244     ASSERT (retval == strlen (result));
3245     free (result);
3246   }
3247
3248   {
3249     char *result;
3250     int retval =
3251       my_asprintf (&result, "a%-*sc", -3, "b");
3252     ASSERT (result != NULL);
3253     ASSERT (strcmp (result, "ab  c") == 0);
3254     ASSERT (retval == strlen (result));
3255     free (result);
3256   }
3257
3258   /* Test the support of large precision.  */
3259
3260   {
3261     char *result;
3262     int retval =
3263       my_asprintf (&result, "%.4000d %d", 1234567, 99);
3264     size_t i;
3265     ASSERT (result != NULL);
3266     for (i = 0; i < 4000 - 7; i++)
3267       ASSERT (result[i] == '0');
3268     ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3269     ASSERT (retval == strlen (result));
3270     free (result);
3271   }
3272
3273   {
3274     char *result;
3275     int retval =
3276       my_asprintf (&result, "%.4000d %d", -1234567, 99);
3277     size_t i;
3278     ASSERT (result != NULL);
3279     ASSERT (result[0] == '-');
3280     for (i = 0; i < 4000 - 7; i++)
3281       ASSERT (result[1 + i] == '0');
3282     ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
3283     ASSERT (retval == strlen (result));
3284     free (result);
3285   }
3286
3287   {
3288     char *result;
3289     int retval =
3290       my_asprintf (&result, "%.4000u %d", 1234567, 99);
3291     size_t i;
3292     ASSERT (result != NULL);
3293     for (i = 0; i < 4000 - 7; i++)
3294       ASSERT (result[i] == '0');
3295     ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3296     ASSERT (retval == strlen (result));
3297     free (result);
3298   }
3299
3300   {
3301     char *result;
3302     int retval =
3303       my_asprintf (&result, "%.4000o %d", 1234567, 99);
3304     size_t i;
3305     ASSERT (result != NULL);
3306     for (i = 0; i < 4000 - 7; i++)
3307       ASSERT (result[i] == '0');
3308     ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
3309     ASSERT (retval == strlen (result));
3310     free (result);
3311   }
3312
3313   {
3314     char *result;
3315     int retval =
3316       my_asprintf (&result, "%.4000x %d", 1234567, 99);
3317     size_t i;
3318     ASSERT (result != NULL);
3319     for (i = 0; i < 4000 - 6; i++)
3320       ASSERT (result[i] == '0');
3321     ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
3322     ASSERT (retval == strlen (result));
3323     free (result);
3324   }
3325
3326   {
3327     char *result;
3328     int retval =
3329       my_asprintf (&result, "%#.4000x %d", 1234567, 99);
3330     size_t i;
3331     ASSERT (result != NULL);
3332     ASSERT (result[0] == '0');
3333     ASSERT (result[1] == 'x');
3334     for (i = 0; i < 4000 - 6; i++)
3335       ASSERT (result[2 + i] == '0');
3336     ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
3337     ASSERT (retval == strlen (result));
3338     free (result);
3339   }
3340
3341   {
3342     char input[5000];
3343     char *result;
3344     int retval;
3345     size_t i;
3346
3347     for (i = 0; i < sizeof (input) - 1; i++)
3348       input[i] = 'a' + ((1000000 / (i + 1)) % 26);
3349     input[i] = '\0';
3350     retval = my_asprintf (&result, "%.4000s %d", input, 99);
3351     ASSERT (result != NULL);
3352     ASSERT (memcmp (result, input, 4000) == 0);
3353     ASSERT (strcmp (result + 4000, " 99") == 0);
3354     ASSERT (retval == strlen (result));
3355     free (result);
3356   }
3357 }
3358
3359 static int
3360 my_asprintf (char **result, const char *format, ...)
3361 {
3362   va_list args;
3363   int ret;
3364
3365   va_start (args, format);
3366   ret = vasprintf (result, format, args);
3367   va_end (args);
3368   return ret;
3369 }
3370
3371 static void
3372 test_vasprintf ()
3373 {
3374   test_function (my_asprintf);
3375 }
3376
3377 static void
3378 test_asprintf ()
3379 {
3380   test_function (asprintf);
3381 }
3382
3383 int
3384 main (int argc, char *argv[])
3385 {
3386   test_vasprintf ();
3387   test_asprintf ();
3388   return 0;
3389 }