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