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