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