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