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