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