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