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