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