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