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