Test a corner case. Exclude two buggy implementations.
[gnulib.git] / tests / test-vasnprintf-posix.c
1 /* Test of POSIX compatible vasnprintf() and asnprintf() functions.
2    Copyright (C) 2007 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 2, or (at your option)
7    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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include "vasnprintf.h"
25
26 #include <stdarg.h>
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #define ASSERT(expr) if (!(expr)) abort ();
32
33 static void
34 test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...))
35 {
36   char buf[8];
37   int size;
38
39   /* Test return value convention.  */
40
41   for (size = 0; size <= 8; size++)
42     {
43       size_t length = size;
44       char *result = my_asnprintf (NULL, &length, "%d", 12345);
45       ASSERT (result != NULL);
46       ASSERT (strcmp (result, "12345") == 0);
47       ASSERT (length == 5);
48       free (result);
49     }
50
51   for (size = 0; size <= 8; size++)
52     {
53       size_t length;
54       char *result;
55
56       memcpy (buf, "DEADBEEF", 8);
57       length = size;
58       result = my_asnprintf (buf, &length, "%d", 12345);
59       ASSERT (result != NULL);
60       ASSERT (strcmp (result, "12345") == 0);
61       ASSERT (length == 5);
62       if (size < 6)
63         ASSERT (result != buf);
64       ASSERT (memcmp (buf + size, "DEADBEEF" + size, 8 - size) == 0);
65       if (result != buf)
66         free (result);
67     }
68
69   /* Test support of size specifiers as in C99.  */
70
71   {
72     size_t length;
73     char *result =
74       my_asnprintf (NULL, &length, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
75     ASSERT (result != NULL);
76     ASSERT (strcmp (result, "12345671 33") == 0);
77     ASSERT (length == strlen (result));
78     free (result);
79   }
80
81   {
82     size_t length;
83     char *result =
84       my_asnprintf (NULL, &length, "%zu %d", (size_t) 12345672, 33, 44, 55);
85     ASSERT (result != NULL);
86     ASSERT (strcmp (result, "12345672 33") == 0);
87     ASSERT (length == strlen (result));
88     free (result);
89   }
90
91   {
92     size_t length;
93     char *result =
94       my_asnprintf (NULL, &length, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
95     ASSERT (result != NULL);
96     ASSERT (strcmp (result, "12345673 33") == 0);
97     ASSERT (length == strlen (result));
98     free (result);
99   }
100
101 #if HAVE_LONG_DOUBLE
102   {
103     size_t length;
104     char *result =
105       my_asnprintf (NULL, &length, "%Lg %d", (long double) 1.5, 33, 44, 55);
106     ASSERT (result != NULL);
107     ASSERT (strcmp (result, "1.5 33") == 0);
108     ASSERT (length == strlen (result));
109     free (result);
110   }
111 #endif
112
113   /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
114      output of floating-point numbers.  */
115
116   { /* A positive number.  */
117     size_t length;
118     char *result =
119       my_asnprintf (NULL, &length, "%a %d", 3.1416015625, 33, 44, 55);
120     ASSERT (result != NULL);
121     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
122             || strcmp (result, "0x3.244p+0 33") == 0
123             || strcmp (result, "0x6.488p-1 33") == 0
124             || strcmp (result, "0xc.91p-2 33") == 0);
125     ASSERT (length == strlen (result));
126     free (result);
127   }
128
129   { /* A negative number.  */
130     size_t length;
131     char *result =
132       my_asnprintf (NULL, &length, "%A %d", -3.1416015625, 33, 44, 55);
133     ASSERT (result != NULL);
134     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
135             || strcmp (result, "-0X3.244P+0 33") == 0
136             || strcmp (result, "-0X6.488P-1 33") == 0
137             || strcmp (result, "-0XC.91P-2 33") == 0);
138     ASSERT (length == strlen (result));
139     free (result);
140   }
141
142   { /* Positive zero.  */
143     size_t length;
144     char *result =
145       my_asnprintf (NULL, &length, "%a %d", 0.0, 33, 44, 55);
146     ASSERT (result != NULL);
147     ASSERT (strcmp (result, "0x0p+0 33") == 0);
148     ASSERT (length == strlen (result));
149     free (result);
150   }
151
152   { /* Negative zero.  */
153     size_t length;
154     char *result =
155       my_asnprintf (NULL, &length, "%a %d", -0.0, 33, 44, 55);
156     ASSERT (result != NULL);
157     ASSERT (strcmp (result, "-0x0p+0 33") == 0);
158     ASSERT (length == strlen (result));
159     free (result);
160   }
161
162   { /* Positive infinity.  */
163     size_t length;
164     char *result =
165       my_asnprintf (NULL, &length, "%a %d", 1.0 / 0.0, 33, 44, 55);
166     ASSERT (result != NULL);
167     ASSERT (strcmp (result, "inf 33") == 0);
168     ASSERT (length == strlen (result));
169     free (result);
170   }
171
172   { /* Negative infinity.  */
173     size_t length;
174     char *result =
175       my_asnprintf (NULL, &length, "%a %d", -1.0 / 0.0, 33, 44, 55);
176     ASSERT (result != NULL);
177     ASSERT (strcmp (result, "-inf 33") == 0);
178     ASSERT (length == strlen (result));
179     free (result);
180   }
181
182   { /* NaN.  */
183     size_t length;
184     char *result =
185       my_asnprintf (NULL, &length, "%a %d", 0.0 / 0.0, 33, 44, 55);
186     ASSERT (result != NULL);
187     ASSERT (strcmp (result, "nan 33") == 0);
188     ASSERT (length == strlen (result));
189     free (result);
190   }
191
192   { /* Rounding near the decimal point.  */
193     size_t length;
194     char *result =
195       my_asnprintf (NULL, &length, "%.0a %d", 1.5, 33, 44, 55);
196     ASSERT (result != NULL);
197     ASSERT (strcmp (result, "0x2p+0 33") == 0
198             || strcmp (result, "0x3p-1 33") == 0
199             || strcmp (result, "0x6p-2 33") == 0
200             || strcmp (result, "0xcp-3 33") == 0);
201     ASSERT (length == strlen (result));
202     free (result);
203   }
204
205   { /* Rounding with precision 0.  */
206     size_t length;
207     char *result =
208       my_asnprintf (NULL, &length, "%.0a %d", 1.51, 33, 44, 55);
209     ASSERT (result != NULL);
210     ASSERT (strcmp (result, "0x2p+0 33") == 0
211             || strcmp (result, "0x3p-1 33") == 0
212             || strcmp (result, "0x6p-2 33") == 0
213             || strcmp (result, "0xcp-3 33") == 0);
214     ASSERT (length == strlen (result));
215     free (result);
216   }
217
218   { /* Rounding with precision 1.  */
219     size_t length;
220     char *result =
221       my_asnprintf (NULL, &length, "%.1a %d", 1.51, 33, 44, 55);
222     ASSERT (result != NULL);
223     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
224             || strcmp (result, "0x3.0p-1 33") == 0
225             || strcmp (result, "0x6.1p-2 33") == 0
226             || strcmp (result, "0xc.1p-3 33") == 0);
227     ASSERT (length == strlen (result));
228     free (result);
229   }
230
231   { /* Rounding with precision 2.  */
232     size_t length;
233     char *result =
234       my_asnprintf (NULL, &length, "%.2a %d", 1.51, 33, 44, 55);
235     ASSERT (result != NULL);
236     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
237             || strcmp (result, "0x3.05p-1 33") == 0
238             || strcmp (result, "0x6.0ap-2 33") == 0
239             || strcmp (result, "0xc.14p-3 33") == 0);
240     ASSERT (length == strlen (result));
241     free (result);
242   }
243
244   { /* Rounding with precision 3.  */
245     size_t length;
246     char *result =
247       my_asnprintf (NULL, &length, "%.3a %d", 1.51, 33, 44, 55);
248     ASSERT (result != NULL);
249     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
250             || strcmp (result, "0x3.052p-1 33") == 0
251             || strcmp (result, "0x6.0a4p-2 33") == 0
252             || strcmp (result, "0xc.148p-3 33") == 0);
253     ASSERT (length == strlen (result));
254     free (result);
255   }
256
257   { /* Rounding can turn a ...FFF into a ...000.  */
258     size_t length;
259     char *result =
260       my_asnprintf (NULL, &length, "%.3a %d", 1.49999, 33, 44, 55);
261     ASSERT (result != NULL);
262     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
263             || strcmp (result, "0x3.000p-1 33") == 0
264             || strcmp (result, "0x6.000p-2 33") == 0
265             || strcmp (result, "0xc.000p-3 33") == 0);
266     ASSERT (length == strlen (result));
267     free (result);
268   }
269
270   { /* Rounding can turn a ...FFF into a ...000.
271        This shows a MacOS X 10.3.9 (Darwin 7.9) bug.  */
272     size_t length;
273     char *result =
274       my_asnprintf (NULL, &length, "%.1a %d", 1.999, 33, 44, 55);
275     ASSERT (result != NULL);
276     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
277             || strcmp (result, "0x2.0p+0 33") == 0
278             || strcmp (result, "0x4.0p-1 33") == 0
279             || strcmp (result, "0x8.0p-2 33") == 0);
280     ASSERT (length == strlen (result));
281     free (result);
282   }
283
284   { /* Width.  */
285     size_t length;
286     char *result =
287       my_asnprintf (NULL, &length, "%10a %d", 1.75, 33, 44, 55);
288     ASSERT (result != NULL);
289     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
290             || strcmp (result, "  0x3.8p-1 33") == 0
291             || strcmp (result, "    0x7p-2 33") == 0
292             || strcmp (result, "    0xep-3 33") == 0);
293     ASSERT (length == strlen (result));
294     free (result);
295   }
296
297   { /* Small precision.  */
298     size_t length;
299     char *result =
300       my_asnprintf (NULL, &length, "%.10a %d", 1.75, 33, 44, 55);
301     ASSERT (result != NULL);
302     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
303             || strcmp (result, "0x3.8000000000p-1 33") == 0
304             || strcmp (result, "0x7.0000000000p-2 33") == 0
305             || strcmp (result, "0xe.0000000000p-3 33") == 0);
306     ASSERT (length == strlen (result));
307     free (result);
308   }
309
310   { /* Large precision.  */
311     size_t length;
312     char *result =
313       my_asnprintf (NULL, &length, "%.50a %d", 1.75, 33, 44, 55);
314     ASSERT (result != NULL);
315     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
316             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
317             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
318             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
319     ASSERT (length == strlen (result));
320     free (result);
321   }
322
323   { /* FLAG_LEFT.  */
324     size_t length;
325     char *result =
326       my_asnprintf (NULL, &length, "%-10a %d", 1.75, 33, 44, 55);
327     ASSERT (result != NULL);
328     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
329             || strcmp (result, "0x3.8p-1   33") == 0
330             || strcmp (result, "0x7p-2     33") == 0
331             || strcmp (result, "0xep-3     33") == 0);
332     ASSERT (length == strlen (result));
333     free (result);
334   }
335
336   { /* FLAG_SHOWSIGN.  */
337     size_t length;
338     char *result =
339       my_asnprintf (NULL, &length, "%+a %d", 1.75, 33, 44, 55);
340     ASSERT (result != NULL);
341     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
342             || strcmp (result, "+0x3.8p-1 33") == 0
343             || strcmp (result, "+0x7p-2 33") == 0
344             || strcmp (result, "+0xep-3 33") == 0);
345     ASSERT (length == strlen (result));
346     free (result);
347   }
348
349   { /* FLAG_SPACE.  */
350     size_t length;
351     char *result =
352       my_asnprintf (NULL, &length, "% a %d", 1.75, 33, 44, 55);
353     ASSERT (result != NULL);
354     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
355             || strcmp (result, " 0x3.8p-1 33") == 0
356             || strcmp (result, " 0x7p-2 33") == 0
357             || strcmp (result, " 0xep-3 33") == 0);
358     ASSERT (length == strlen (result));
359     free (result);
360   }
361
362   { /* FLAG_ALT.  */
363     size_t length;
364     char *result =
365       my_asnprintf (NULL, &length, "%#a %d", 1.75, 33, 44, 55);
366     ASSERT (result != NULL);
367     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
368             || strcmp (result, "0x3.8p-1 33") == 0
369             || strcmp (result, "0x7.p-2 33") == 0
370             || strcmp (result, "0xe.p-3 33") == 0);
371     ASSERT (length == strlen (result));
372     free (result);
373   }
374
375   { /* FLAG_ALT.  */
376     size_t length;
377     char *result =
378       my_asnprintf (NULL, &length, "%#a %d", 1.0, 33, 44, 55);
379     ASSERT (result != NULL);
380     ASSERT (strcmp (result, "0x1.p+0 33") == 0
381             || strcmp (result, "0x2.p-1 33") == 0
382             || strcmp (result, "0x4.p-2 33") == 0
383             || strcmp (result, "0x8.p-3 33") == 0);
384     ASSERT (length == strlen (result));
385     free (result);
386   }
387
388   { /* FLAG_ZERO with finite number.  */
389     size_t length;
390     char *result =
391       my_asnprintf (NULL, &length, "%010a %d", 1.75, 33, 44, 55);
392     ASSERT (result != NULL);
393     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
394             || strcmp (result, "0x003.8p-1 33") == 0
395             || strcmp (result, "0x00007p-2 33") == 0
396             || strcmp (result, "0x0000ep-3 33") == 0);
397     ASSERT (length == strlen (result));
398     free (result);
399   }
400
401   { /* FLAG_ZERO with infinite number.  */
402     size_t length;
403     char *result =
404       my_asnprintf (NULL, &length, "%010a %d", 1.0 / 0.0, 33, 44, 55);
405     ASSERT (result != NULL);
406     ASSERT (strcmp (result, "       inf 33") == 0);
407     ASSERT (length == strlen (result));
408     free (result);
409   }
410
411   { /* FLAG_ZERO with NaN.  */
412     size_t length;
413     char *result =
414       my_asnprintf (NULL, &length, "%010a %d", 0.0 / 0.0, 33, 44, 55);
415     ASSERT (result != NULL);
416     ASSERT (strcmp (result, "       nan 33") == 0);
417     ASSERT (length == strlen (result));
418     free (result);
419   }
420
421 #if HAVE_LONG_DOUBLE
422
423   { /* A positive number.  */
424     size_t length;
425     char *result =
426       my_asnprintf (NULL, &length, "%La %d", 3.1416015625L, 33, 44, 55);
427     ASSERT (result != NULL);
428     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
429             || strcmp (result, "0x3.244p+0 33") == 0
430             || strcmp (result, "0x6.488p-1 33") == 0
431             || strcmp (result, "0xc.91p-2 33") == 0);
432     ASSERT (length == strlen (result));
433     free (result);
434   }
435
436   { /* A negative number.  */
437     size_t length;
438     char *result =
439       my_asnprintf (NULL, &length, "%LA %d", -3.1416015625L, 33, 44, 55);
440     ASSERT (result != NULL);
441     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
442             || strcmp (result, "-0X3.244P+0 33") == 0
443             || strcmp (result, "-0X6.488P-1 33") == 0
444             || strcmp (result, "-0XC.91P-2 33") == 0);
445     ASSERT (length == strlen (result));
446     free (result);
447   }
448
449   { /* Positive zero.  */
450     size_t length;
451     char *result =
452       my_asnprintf (NULL, &length, "%La %d", 0.0L, 33, 44, 55);
453     ASSERT (result != NULL);
454     ASSERT (strcmp (result, "0x0p+0 33") == 0);
455     ASSERT (length == strlen (result));
456     free (result);
457   }
458
459   { /* Negative zero.  */
460     size_t length;
461     char *result =
462       my_asnprintf (NULL, &length, "%La %d", -0.0L, 33, 44, 55);
463     ASSERT (result != NULL);
464     ASSERT (strcmp (result, "-0x0p+0 33") == 0);
465     ASSERT (length == strlen (result));
466     free (result);
467   }
468
469   { /* Positive infinity.  */
470     size_t length;
471     char *result =
472       my_asnprintf (NULL, &length, "%La %d", 1.0L / 0.0L, 33, 44, 55);
473     ASSERT (result != NULL);
474     ASSERT (strcmp (result, "inf 33") == 0);
475     ASSERT (length == strlen (result));
476     free (result);
477   }
478
479   { /* Negative infinity.  */
480     size_t length;
481     char *result =
482       my_asnprintf (NULL, &length, "%La %d", -1.0L / 0.0L, 33, 44, 55);
483     ASSERT (result != NULL);
484     ASSERT (strcmp (result, "-inf 33") == 0);
485     ASSERT (length == strlen (result));
486     free (result);
487   }
488
489   { /* NaN.  */
490     size_t length;
491     char *result =
492       my_asnprintf (NULL, &length, "%La %d", 0.0L / 0.0L, 33, 44, 55);
493     ASSERT (result != NULL);
494     ASSERT (strcmp (result, "nan 33") == 0);
495     ASSERT (length == strlen (result));
496     free (result);
497   }
498
499   { /* Rounding near the decimal point.  */
500     size_t length;
501     char *result =
502       my_asnprintf (NULL, &length, "%.0La %d", 1.5L, 33, 44, 55);
503     ASSERT (result != NULL);
504     ASSERT (strcmp (result, "0x2p+0 33") == 0
505             || strcmp (result, "0x3p-1 33") == 0
506             || strcmp (result, "0x6p-2 33") == 0
507             || strcmp (result, "0xcp-3 33") == 0);
508     ASSERT (length == strlen (result));
509     free (result);
510   }
511
512   { /* Rounding with precision 0.  */
513     size_t length;
514     char *result =
515       my_asnprintf (NULL, &length, "%.0La %d", 1.51L, 33, 44, 55);
516     ASSERT (result != NULL);
517     ASSERT (strcmp (result, "0x2p+0 33") == 0
518             || strcmp (result, "0x3p-1 33") == 0
519             || strcmp (result, "0x6p-2 33") == 0
520             || strcmp (result, "0xcp-3 33") == 0);
521     ASSERT (length == strlen (result));
522     free (result);
523   }
524
525   { /* Rounding with precision 1.  */
526     size_t length;
527     char *result =
528       my_asnprintf (NULL, &length, "%.1La %d", 1.51L, 33, 44, 55);
529     ASSERT (result != NULL);
530     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
531             || strcmp (result, "0x3.0p-1 33") == 0
532             || strcmp (result, "0x6.1p-2 33") == 0
533             || strcmp (result, "0xc.1p-3 33") == 0);
534     ASSERT (length == strlen (result));
535     free (result);
536   }
537
538   { /* Rounding with precision 2.  */
539     size_t length;
540     char *result =
541       my_asnprintf (NULL, &length, "%.2La %d", 1.51L, 33, 44, 55);
542     ASSERT (result != NULL);
543     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
544             || strcmp (result, "0x3.05p-1 33") == 0
545             || strcmp (result, "0x6.0ap-2 33") == 0
546             || strcmp (result, "0xc.14p-3 33") == 0);
547     ASSERT (length == strlen (result));
548     free (result);
549   }
550
551   { /* Rounding with precision 3.  */
552     size_t length;
553     char *result =
554       my_asnprintf (NULL, &length, "%.3La %d", 1.51L, 33, 44, 55);
555     ASSERT (result != NULL);
556     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
557             || strcmp (result, "0x3.052p-1 33") == 0
558             || strcmp (result, "0x6.0a4p-2 33") == 0
559             || strcmp (result, "0xc.148p-3 33") == 0);
560     ASSERT (length == strlen (result));
561     free (result);
562   }
563
564   { /* Rounding can turn a ...FFF into a ...000.  */
565     size_t length;
566     char *result =
567       my_asnprintf (NULL, &length, "%.3La %d", 1.49999L, 33, 44, 55);
568     ASSERT (result != NULL);
569     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
570             || strcmp (result, "0x3.000p-1 33") == 0
571             || strcmp (result, "0x6.000p-2 33") == 0
572             || strcmp (result, "0xc.000p-3 33") == 0);
573     ASSERT (length == strlen (result));
574     free (result);
575   }
576
577   { /* Rounding can turn a ...FFF into a ...000.
578        This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
579        glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
580     size_t length;
581     char *result =
582       my_asnprintf (NULL, &length, "%.1La %d", 1.999L, 33, 44, 55);
583     ASSERT (result != NULL);
584     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
585             || strcmp (result, "0x2.0p+0 33") == 0
586             || strcmp (result, "0x4.0p-1 33") == 0
587             || strcmp (result, "0x8.0p-2 33") == 0);
588     ASSERT (length == strlen (result));
589     free (result);
590   }
591
592   { /* Width.  */
593     size_t length;
594     char *result =
595       my_asnprintf (NULL, &length, "%10La %d", 1.75L, 33, 44, 55);
596     ASSERT (result != NULL);
597     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
598             || strcmp (result, "  0x3.8p-1 33") == 0
599             || strcmp (result, "    0x7p-2 33") == 0
600             || strcmp (result, "    0xep-3 33") == 0);
601     ASSERT (length == strlen (result));
602     free (result);
603   }
604
605   { /* Small precision.  */
606     size_t length;
607     char *result =
608       my_asnprintf (NULL, &length, "%.10La %d", 1.75L, 33, 44, 55);
609     ASSERT (result != NULL);
610     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
611             || strcmp (result, "0x3.8000000000p-1 33") == 0
612             || strcmp (result, "0x7.0000000000p-2 33") == 0
613             || strcmp (result, "0xe.0000000000p-3 33") == 0);
614     ASSERT (length == strlen (result));
615     free (result);
616   }
617
618   { /* Large precision.  */
619     size_t length;
620     char *result =
621       my_asnprintf (NULL, &length, "%.50La %d", 1.75L, 33, 44, 55);
622     ASSERT (result != NULL);
623     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
624             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
625             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
626             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
627     ASSERT (length == strlen (result));
628     free (result);
629   }
630
631   { /* FLAG_LEFT.  */
632     size_t length;
633     char *result =
634       my_asnprintf (NULL, &length, "%-10La %d", 1.75L, 33, 44, 55);
635     ASSERT (result != NULL);
636     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
637             || strcmp (result, "0x3.8p-1   33") == 0
638             || strcmp (result, "0x7p-2     33") == 0
639             || strcmp (result, "0xep-3     33") == 0);
640     ASSERT (length == strlen (result));
641     free (result);
642   }
643
644   { /* FLAG_SHOWSIGN.  */
645     size_t length;
646     char *result =
647       my_asnprintf (NULL, &length, "%+La %d", 1.75L, 33, 44, 55);
648     ASSERT (result != NULL);
649     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
650             || strcmp (result, "+0x3.8p-1 33") == 0
651             || strcmp (result, "+0x7p-2 33") == 0
652             || strcmp (result, "+0xep-3 33") == 0);
653     ASSERT (length == strlen (result));
654     free (result);
655   }
656
657   { /* FLAG_SPACE.  */
658     size_t length;
659     char *result =
660       my_asnprintf (NULL, &length, "% La %d", 1.75L, 33, 44, 55);
661     ASSERT (result != NULL);
662     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
663             || strcmp (result, " 0x3.8p-1 33") == 0
664             || strcmp (result, " 0x7p-2 33") == 0
665             || strcmp (result, " 0xep-3 33") == 0);
666     ASSERT (length == strlen (result));
667     free (result);
668   }
669
670   { /* FLAG_ALT.  */
671     size_t length;
672     char *result =
673       my_asnprintf (NULL, &length, "%#La %d", 1.75L, 33, 44, 55);
674     ASSERT (result != NULL);
675     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
676             || strcmp (result, "0x3.8p-1 33") == 0
677             || strcmp (result, "0x7.p-2 33") == 0
678             || strcmp (result, "0xe.p-3 33") == 0);
679     ASSERT (length == strlen (result));
680     free (result);
681   }
682
683   { /* FLAG_ALT.  */
684     size_t length;
685     char *result =
686       my_asnprintf (NULL, &length, "%#La %d", 1.0L, 33, 44, 55);
687     ASSERT (result != NULL);
688     ASSERT (strcmp (result, "0x1.p+0 33") == 0
689             || strcmp (result, "0x2.p-1 33") == 0
690             || strcmp (result, "0x4.p-2 33") == 0
691             || strcmp (result, "0x8.p-3 33") == 0);
692     ASSERT (length == strlen (result));
693     free (result);
694   }
695
696   { /* FLAG_ZERO with finite number.  */
697     size_t length;
698     char *result =
699       my_asnprintf (NULL, &length, "%010La %d", 1.75L, 33, 44, 55);
700     ASSERT (result != NULL);
701     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
702             || strcmp (result, "0x003.8p-1 33") == 0
703             || strcmp (result, "0x00007p-2 33") == 0
704             || strcmp (result, "0x0000ep-3 33") == 0);
705     ASSERT (length == strlen (result));
706     free (result);
707   }
708
709   { /* FLAG_ZERO with infinite number.  */
710     size_t length;
711     char *result =
712       my_asnprintf (NULL, &length, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
713     ASSERT (result != NULL);
714     ASSERT (strcmp (result, "       inf 33") == 0);
715     ASSERT (length == strlen (result));
716     free (result);
717   }
718
719   { /* FLAG_ZERO with NaN.  */
720     size_t length;
721     char *result =
722       my_asnprintf (NULL, &length, "%010La %d", 0.0L / 0.0L, 33, 44, 55);
723     ASSERT (result != NULL);
724     ASSERT (strcmp (result, "       nan 33") == 0);
725     ASSERT (length == strlen (result));
726     free (result);
727   }
728
729 #endif
730
731   /* Test the support of the %n format directive.  */
732
733   {
734     int count = -1;
735     size_t length;
736     char *result =
737       my_asnprintf (NULL, &length, "%d %n", 123, &count, 33, 44, 55);
738     ASSERT (result != NULL);
739     ASSERT (strcmp (result, "123 ") == 0);
740     ASSERT (length == strlen (result));
741     ASSERT (count == 4);
742     free (result);
743   }
744
745   /* Test the support of the POSIX/XSI format strings with positions.  */
746
747   {
748     size_t length;
749     char *result =
750       my_asnprintf (NULL, &length, "%2$d %1$d", 33, 55);
751     ASSERT (result != NULL);
752     ASSERT (strcmp (result, "55 33") == 0);
753     ASSERT (length == strlen (result));
754     free (result);
755   }
756 }
757
758 static char *
759 my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
760 {
761   va_list args;
762   char *ret;
763
764   va_start (args, format);
765   ret = vasnprintf (resultbuf, lengthp, format, args);
766   va_end (args);
767   return ret;
768 }
769
770 static void
771 test_vasnprintf ()
772 {
773   test_function (my_asnprintf);
774 }
775
776 static void
777 test_asnprintf ()
778 {
779   test_function (asnprintf);
780 }
781
782 int
783 main (int argc, char *argv[])
784 {
785   test_vasnprintf ();
786   test_asnprintf ();
787   return 0;
788 }