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