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