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