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