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