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