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