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