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