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