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