Add tests for %f and %F directives.
[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   {
115     size_t length;
116     char *result =
117       my_asnprintf (NULL, &length, "%Lg %d", (long double) 1.5, 33, 44, 55);
118     ASSERT (result != NULL);
119     ASSERT (strcmp (result, "1.5 33") == 0);
120     ASSERT (length == strlen (result));
121     free (result);
122   }
123
124   /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
125      output of floating-point numbers.  */
126
127   { /* A positive number.  */
128     size_t length;
129     char *result =
130       my_asnprintf (NULL, &length, "%a %d", 3.1416015625, 33, 44, 55);
131     ASSERT (result != NULL);
132     ASSERT (strcmp (result, "0x1.922p+1 33") == 0
133             || strcmp (result, "0x3.244p+0 33") == 0
134             || strcmp (result, "0x6.488p-1 33") == 0
135             || strcmp (result, "0xc.91p-2 33") == 0);
136     ASSERT (length == strlen (result));
137     free (result);
138   }
139
140   { /* A negative number.  */
141     size_t length;
142     char *result =
143       my_asnprintf (NULL, &length, "%A %d", -3.1416015625, 33, 44, 55);
144     ASSERT (result != NULL);
145     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
146             || strcmp (result, "-0X3.244P+0 33") == 0
147             || strcmp (result, "-0X6.488P-1 33") == 0
148             || strcmp (result, "-0XC.91P-2 33") == 0);
149     ASSERT (length == strlen (result));
150     free (result);
151   }
152
153   { /* Positive 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   { /* Negative zero.  */
164     size_t length;
165     char *result =
166       my_asnprintf (NULL, &length, "%a %d", -0.0, 33, 44, 55);
167     ASSERT (result != NULL);
168     ASSERT (strcmp (result, "-0x0p+0 33") == 0);
169     ASSERT (length == strlen (result));
170     free (result);
171   }
172
173   { /* Positive 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   { /* Negative infinity.  */
184     size_t length;
185     char *result =
186       my_asnprintf (NULL, &length, "%a %d", -1.0 / 0.0, 33, 44, 55);
187     ASSERT (result != NULL);
188     ASSERT (strcmp (result, "-inf 33") == 0);
189     ASSERT (length == strlen (result));
190     free (result);
191   }
192
193   { /* NaN.  */
194     size_t length;
195     char *result =
196       my_asnprintf (NULL, &length, "%a %d", NaN (), 33, 44, 55);
197     ASSERT (result != NULL);
198     ASSERT (strcmp (result, "nan 33") == 0);
199     ASSERT (length == strlen (result));
200     free (result);
201   }
202
203   { /* Rounding near the decimal point.  */
204     size_t length;
205     char *result =
206       my_asnprintf (NULL, &length, "%.0a %d", 1.5, 33, 44, 55);
207     ASSERT (result != NULL);
208     ASSERT (strcmp (result, "0x2p+0 33") == 0
209             || strcmp (result, "0x3p-1 33") == 0
210             || strcmp (result, "0x6p-2 33") == 0
211             || strcmp (result, "0xcp-3 33") == 0);
212     ASSERT (length == strlen (result));
213     free (result);
214   }
215
216   { /* Rounding with precision 0.  */
217     size_t length;
218     char *result =
219       my_asnprintf (NULL, &length, "%.0a %d", 1.51, 33, 44, 55);
220     ASSERT (result != NULL);
221     ASSERT (strcmp (result, "0x2p+0 33") == 0
222             || strcmp (result, "0x3p-1 33") == 0
223             || strcmp (result, "0x6p-2 33") == 0
224             || strcmp (result, "0xcp-3 33") == 0);
225     ASSERT (length == strlen (result));
226     free (result);
227   }
228
229   { /* Rounding with precision 1.  */
230     size_t length;
231     char *result =
232       my_asnprintf (NULL, &length, "%.1a %d", 1.51, 33, 44, 55);
233     ASSERT (result != NULL);
234     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
235             || strcmp (result, "0x3.0p-1 33") == 0
236             || strcmp (result, "0x6.1p-2 33") == 0
237             || strcmp (result, "0xc.1p-3 33") == 0);
238     ASSERT (length == strlen (result));
239     free (result);
240   }
241
242   { /* Rounding with precision 2.  */
243     size_t length;
244     char *result =
245       my_asnprintf (NULL, &length, "%.2a %d", 1.51, 33, 44, 55);
246     ASSERT (result != NULL);
247     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
248             || strcmp (result, "0x3.05p-1 33") == 0
249             || strcmp (result, "0x6.0ap-2 33") == 0
250             || strcmp (result, "0xc.14p-3 33") == 0);
251     ASSERT (length == strlen (result));
252     free (result);
253   }
254
255   { /* Rounding with precision 3.  */
256     size_t length;
257     char *result =
258       my_asnprintf (NULL, &length, "%.3a %d", 1.51, 33, 44, 55);
259     ASSERT (result != NULL);
260     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
261             || strcmp (result, "0x3.052p-1 33") == 0
262             || strcmp (result, "0x6.0a4p-2 33") == 0
263             || strcmp (result, "0xc.148p-3 33") == 0);
264     ASSERT (length == strlen (result));
265     free (result);
266   }
267
268   { /* Rounding can turn a ...FFF into a ...000.  */
269     size_t length;
270     char *result =
271       my_asnprintf (NULL, &length, "%.3a %d", 1.49999, 33, 44, 55);
272     ASSERT (result != NULL);
273     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
274             || strcmp (result, "0x3.000p-1 33") == 0
275             || strcmp (result, "0x6.000p-2 33") == 0
276             || strcmp (result, "0xc.000p-3 33") == 0);
277     ASSERT (length == strlen (result));
278     free (result);
279   }
280
281   { /* Rounding can turn a ...FFF into a ...000.
282        This shows a MacOS X 10.3.9 (Darwin 7.9) bug.  */
283     size_t length;
284     char *result =
285       my_asnprintf (NULL, &length, "%.1a %d", 1.999, 33, 44, 55);
286     ASSERT (result != NULL);
287     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
288             || strcmp (result, "0x2.0p+0 33") == 0
289             || strcmp (result, "0x4.0p-1 33") == 0
290             || strcmp (result, "0x8.0p-2 33") == 0);
291     ASSERT (length == strlen (result));
292     free (result);
293   }
294
295   { /* Width.  */
296     size_t length;
297     char *result =
298       my_asnprintf (NULL, &length, "%10a %d", 1.75, 33, 44, 55);
299     ASSERT (result != NULL);
300     ASSERT (strcmp (result, "  0x1.cp+0 33") == 0
301             || strcmp (result, "  0x3.8p-1 33") == 0
302             || strcmp (result, "    0x7p-2 33") == 0
303             || strcmp (result, "    0xep-3 33") == 0);
304     ASSERT (length == strlen (result));
305     free (result);
306   }
307
308   { /* Small precision.  */
309     size_t length;
310     char *result =
311       my_asnprintf (NULL, &length, "%.10a %d", 1.75, 33, 44, 55);
312     ASSERT (result != NULL);
313     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
314             || strcmp (result, "0x3.8000000000p-1 33") == 0
315             || strcmp (result, "0x7.0000000000p-2 33") == 0
316             || strcmp (result, "0xe.0000000000p-3 33") == 0);
317     ASSERT (length == strlen (result));
318     free (result);
319   }
320
321   { /* Large precision.  */
322     size_t length;
323     char *result =
324       my_asnprintf (NULL, &length, "%.50a %d", 1.75, 33, 44, 55);
325     ASSERT (result != NULL);
326     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
327             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
328             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
329             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
330     ASSERT (length == strlen (result));
331     free (result);
332   }
333
334   { /* FLAG_LEFT.  */
335     size_t length;
336     char *result =
337       my_asnprintf (NULL, &length, "%-10a %d", 1.75, 33, 44, 55);
338     ASSERT (result != NULL);
339     ASSERT (strcmp (result, "0x1.cp+0   33") == 0
340             || strcmp (result, "0x3.8p-1   33") == 0
341             || strcmp (result, "0x7p-2     33") == 0
342             || strcmp (result, "0xep-3     33") == 0);
343     ASSERT (length == strlen (result));
344     free (result);
345   }
346
347   { /* FLAG_SHOWSIGN.  */
348     size_t length;
349     char *result =
350       my_asnprintf (NULL, &length, "%+a %d", 1.75, 33, 44, 55);
351     ASSERT (result != NULL);
352     ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
353             || strcmp (result, "+0x3.8p-1 33") == 0
354             || strcmp (result, "+0x7p-2 33") == 0
355             || strcmp (result, "+0xep-3 33") == 0);
356     ASSERT (length == strlen (result));
357     free (result);
358   }
359
360   { /* FLAG_SPACE.  */
361     size_t length;
362     char *result =
363       my_asnprintf (NULL, &length, "% a %d", 1.75, 33, 44, 55);
364     ASSERT (result != NULL);
365     ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
366             || strcmp (result, " 0x3.8p-1 33") == 0
367             || strcmp (result, " 0x7p-2 33") == 0
368             || strcmp (result, " 0xep-3 33") == 0);
369     ASSERT (length == strlen (result));
370     free (result);
371   }
372
373   { /* FLAG_ALT.  */
374     size_t length;
375     char *result =
376       my_asnprintf (NULL, &length, "%#a %d", 1.75, 33, 44, 55);
377     ASSERT (result != NULL);
378     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
379             || strcmp (result, "0x3.8p-1 33") == 0
380             || strcmp (result, "0x7.p-2 33") == 0
381             || strcmp (result, "0xe.p-3 33") == 0);
382     ASSERT (length == strlen (result));
383     free (result);
384   }
385
386   { /* FLAG_ALT.  */
387     size_t length;
388     char *result =
389       my_asnprintf (NULL, &length, "%#a %d", 1.0, 33, 44, 55);
390     ASSERT (result != NULL);
391     ASSERT (strcmp (result, "0x1.p+0 33") == 0
392             || strcmp (result, "0x2.p-1 33") == 0
393             || strcmp (result, "0x4.p-2 33") == 0
394             || strcmp (result, "0x8.p-3 33") == 0);
395     ASSERT (length == strlen (result));
396     free (result);
397   }
398
399   { /* FLAG_ZERO with finite number.  */
400     size_t length;
401     char *result =
402       my_asnprintf (NULL, &length, "%010a %d", 1.75, 33, 44, 55);
403     ASSERT (result != NULL);
404     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
405             || strcmp (result, "0x003.8p-1 33") == 0
406             || strcmp (result, "0x00007p-2 33") == 0
407             || strcmp (result, "0x0000ep-3 33") == 0);
408     ASSERT (length == strlen (result));
409     free (result);
410   }
411
412   { /* FLAG_ZERO with infinite number.  */
413     size_t length;
414     char *result =
415       my_asnprintf (NULL, &length, "%010a %d", 1.0 / 0.0, 33, 44, 55);
416     ASSERT (result != NULL);
417     /* "0000000inf 33" is not a valid result; see
418        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
419     ASSERT (strcmp (result, "       inf 33") == 0);
420     ASSERT (length == strlen (result));
421     free (result);
422   }
423
424   { /* FLAG_ZERO with NaN.  */
425     size_t length;
426     char *result =
427       my_asnprintf (NULL, &length, "%010a %d", NaN (), 33, 44, 55);
428     ASSERT (result != NULL);
429     /* "0000000nan 33" is not a valid result; see
430        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
431     ASSERT (strcmp (result, "       nan 33") == 0);
432     ASSERT (length == strlen (result));
433     free (result);
434   }
435
436   { /* A positive 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   { /* A negative number.  */
450     size_t length;
451     char *result =
452       my_asnprintf (NULL, &length, "%LA %d", -3.1416015625L, 33, 44, 55);
453     ASSERT (result != NULL);
454     ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
455             || strcmp (result, "-0X3.244P+0 33") == 0
456             || strcmp (result, "-0X6.488P-1 33") == 0
457             || strcmp (result, "-0XC.91P-2 33") == 0);
458     ASSERT (length == strlen (result));
459     free (result);
460   }
461
462   { /* Positive zero.  */
463     size_t length;
464     char *result =
465       my_asnprintf (NULL, &length, "%La %d", 0.0L, 33, 44, 55);
466     ASSERT (result != NULL);
467     ASSERT (strcmp (result, "0x0p+0 33") == 0);
468     ASSERT (length == strlen (result));
469     free (result);
470   }
471
472   { /* Negative zero.  */
473     size_t length;
474     char *result =
475       my_asnprintf (NULL, &length, "%La %d", -0.0L, 33, 44, 55);
476     ASSERT (result != NULL);
477     ASSERT (strcmp (result, "-0x0p+0 33") == 0);
478     ASSERT (length == strlen (result));
479     free (result);
480   }
481
482   { /* Positive infinity.  */
483     size_t length;
484     char *result =
485       my_asnprintf (NULL, &length, "%La %d", 1.0L / 0.0L, 33, 44, 55);
486     ASSERT (result != NULL);
487     ASSERT (strcmp (result, "inf 33") == 0);
488     ASSERT (length == strlen (result));
489     free (result);
490   }
491
492   { /* Negative infinity.  */
493     size_t length;
494     char *result =
495       my_asnprintf (NULL, &length, "%La %d", -1.0L / 0.0L, 33, 44, 55);
496     ASSERT (result != NULL);
497     ASSERT (strcmp (result, "-inf 33") == 0);
498     ASSERT (length == strlen (result));
499     free (result);
500   }
501
502   { /* NaN.  */
503     size_t length;
504     char *result =
505       my_asnprintf (NULL, &length, "%La %d", 0.0L / 0.0L, 33, 44, 55);
506     ASSERT (result != NULL);
507     ASSERT (strcmp (result, "nan 33") == 0);
508     ASSERT (length == strlen (result));
509     free (result);
510   }
511
512   { /* Rounding near the decimal point.  */
513     size_t length;
514     char *result =
515       my_asnprintf (NULL, &length, "%.0La %d", 1.5L, 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 0.  */
526     size_t length;
527     char *result =
528       my_asnprintf (NULL, &length, "%.0La %d", 1.51L, 33, 44, 55);
529     ASSERT (result != NULL);
530     ASSERT (strcmp (result, "0x2p+0 33") == 0
531             || strcmp (result, "0x3p-1 33") == 0
532             || strcmp (result, "0x6p-2 33") == 0
533             || strcmp (result, "0xcp-3 33") == 0);
534     ASSERT (length == strlen (result));
535     free (result);
536   }
537
538   { /* Rounding with precision 1.  */
539     size_t length;
540     char *result =
541       my_asnprintf (NULL, &length, "%.1La %d", 1.51L, 33, 44, 55);
542     ASSERT (result != NULL);
543     ASSERT (strcmp (result, "0x1.8p+0 33") == 0
544             || strcmp (result, "0x3.0p-1 33") == 0
545             || strcmp (result, "0x6.1p-2 33") == 0
546             || strcmp (result, "0xc.1p-3 33") == 0);
547     ASSERT (length == strlen (result));
548     free (result);
549   }
550
551   { /* Rounding with precision 2.  */
552     size_t length;
553     char *result =
554       my_asnprintf (NULL, &length, "%.2La %d", 1.51L, 33, 44, 55);
555     ASSERT (result != NULL);
556     ASSERT (strcmp (result, "0x1.83p+0 33") == 0
557             || strcmp (result, "0x3.05p-1 33") == 0
558             || strcmp (result, "0x6.0ap-2 33") == 0
559             || strcmp (result, "0xc.14p-3 33") == 0);
560     ASSERT (length == strlen (result));
561     free (result);
562   }
563
564   { /* Rounding with precision 3.  */
565     size_t length;
566     char *result =
567       my_asnprintf (NULL, &length, "%.3La %d", 1.51L, 33, 44, 55);
568     ASSERT (result != NULL);
569     ASSERT (strcmp (result, "0x1.829p+0 33") == 0
570             || strcmp (result, "0x3.052p-1 33") == 0
571             || strcmp (result, "0x6.0a4p-2 33") == 0
572             || strcmp (result, "0xc.148p-3 33") == 0);
573     ASSERT (length == strlen (result));
574     free (result);
575   }
576
577   { /* Rounding can turn a ...FFF into a ...000.  */
578     size_t length;
579     char *result =
580       my_asnprintf (NULL, &length, "%.3La %d", 1.49999L, 33, 44, 55);
581     ASSERT (result != NULL);
582     ASSERT (strcmp (result, "0x1.800p+0 33") == 0
583             || strcmp (result, "0x3.000p-1 33") == 0
584             || strcmp (result, "0x6.000p-2 33") == 0
585             || strcmp (result, "0xc.000p-3 33") == 0);
586     ASSERT (length == strlen (result));
587     free (result);
588   }
589
590   { /* Rounding can turn a ...FFF into a ...000.
591        This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
592        glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>.  */
593     size_t length;
594     char *result =
595       my_asnprintf (NULL, &length, "%.1La %d", 1.999L, 33, 44, 55);
596     ASSERT (result != NULL);
597     ASSERT (strcmp (result, "0x1.0p+1 33") == 0
598             || strcmp (result, "0x2.0p+0 33") == 0
599             || strcmp (result, "0x4.0p-1 33") == 0
600             || strcmp (result, "0x8.0p-2 33") == 0);
601     ASSERT (length == strlen (result));
602     free (result);
603   }
604
605   { /* Width.  */
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.cp+0 33") == 0
611             || strcmp (result, "  0x3.8p-1 33") == 0
612             || strcmp (result, "    0x7p-2 33") == 0
613             || strcmp (result, "    0xep-3 33") == 0);
614     ASSERT (length == strlen (result));
615     free (result);
616   }
617
618   { /* Small precision.  */
619     size_t length;
620     char *result =
621       my_asnprintf (NULL, &length, "%.10La %d", 1.75L, 33, 44, 55);
622     ASSERT (result != NULL);
623     ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
624             || strcmp (result, "0x3.8000000000p-1 33") == 0
625             || strcmp (result, "0x7.0000000000p-2 33") == 0
626             || strcmp (result, "0xe.0000000000p-3 33") == 0);
627     ASSERT (length == strlen (result));
628     free (result);
629   }
630
631   { /* Large precision.  */
632     size_t length;
633     char *result =
634       my_asnprintf (NULL, &length, "%.50La %d", 1.75L, 33, 44, 55);
635     ASSERT (result != NULL);
636     ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
637             || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
638             || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
639             || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
640     ASSERT (length == strlen (result));
641     free (result);
642   }
643
644   { /* FLAG_LEFT.  */
645     size_t length;
646     char *result =
647       my_asnprintf (NULL, &length, "%-10La %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_SHOWSIGN.  */
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_SPACE.  */
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, " 0x7p-2 33") == 0
678             || strcmp (result, " 0xep-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.75L, 33, 44, 55);
687     ASSERT (result != NULL);
688     ASSERT (strcmp (result, "0x1.cp+0 33") == 0
689             || strcmp (result, "0x3.8p-1 33") == 0
690             || strcmp (result, "0x7.p-2 33") == 0
691             || strcmp (result, "0xe.p-3 33") == 0);
692     ASSERT (length == strlen (result));
693     free (result);
694   }
695
696   { /* FLAG_ALT.  */
697     size_t length;
698     char *result =
699       my_asnprintf (NULL, &length, "%#La %d", 1.0L, 33, 44, 55);
700     ASSERT (result != NULL);
701     ASSERT (strcmp (result, "0x1.p+0 33") == 0
702             || strcmp (result, "0x2.p-1 33") == 0
703             || strcmp (result, "0x4.p-2 33") == 0
704             || strcmp (result, "0x8.p-3 33") == 0);
705     ASSERT (length == strlen (result));
706     free (result);
707   }
708
709   { /* FLAG_ZERO with finite number.  */
710     size_t length;
711     char *result =
712       my_asnprintf (NULL, &length, "%010La %d", 1.75L, 33, 44, 55);
713     ASSERT (result != NULL);
714     ASSERT (strcmp (result, "0x001.cp+0 33") == 0
715             || strcmp (result, "0x003.8p-1 33") == 0
716             || strcmp (result, "0x00007p-2 33") == 0
717             || strcmp (result, "0x0000ep-3 33") == 0);
718     ASSERT (length == strlen (result));
719     free (result);
720   }
721
722   { /* FLAG_ZERO with infinite number.  */
723     size_t length;
724     char *result =
725       my_asnprintf (NULL, &length, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
726     ASSERT (result != NULL);
727     /* "0000000inf 33" is not a valid result; see
728        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
729     ASSERT (strcmp (result, "       inf 33") == 0);
730     ASSERT (length == strlen (result));
731     free (result);
732   }
733
734   { /* FLAG_ZERO with NaN.  */
735     size_t length;
736     char *result =
737       my_asnprintf (NULL, &length, "%010La %d", 0.0L / 0.0L, 33, 44, 55);
738     ASSERT (result != NULL);
739     /* "0000000nan 33" is not a valid result; see
740        <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
741     ASSERT (strcmp (result, "       nan 33") == 0);
742     ASSERT (length == strlen (result));
743     free (result);
744   }
745
746   /* Test the support of the %f format directive.  */
747
748   { /* A positive number.  */
749     size_t length;
750     char *result =
751       my_asnprintf (NULL, &length, "%f %d", 12.75, 33, 44, 55);
752     ASSERT (result != NULL);
753     ASSERT (strcmp (result, "12.750000 33") == 0);
754     ASSERT (length == strlen (result));
755     free (result);
756   }
757
758   { /* A larger positive number.  */
759     size_t length;
760     char *result =
761       my_asnprintf (NULL, &length, "%f %d", 1234567.0, 33, 44, 55);
762     ASSERT (result != NULL);
763     ASSERT (strcmp (result, "1234567.000000 33") == 0);
764     ASSERT (length == strlen (result));
765     free (result);
766   }
767
768   { /* A negative number.  */
769     size_t length;
770     char *result =
771       my_asnprintf (NULL, &length, "%f %d", -0.03125, 33, 44, 55);
772     ASSERT (result != NULL);
773     ASSERT (strcmp (result, "-0.031250 33") == 0);
774     ASSERT (length == strlen (result));
775     free (result);
776   }
777
778   { /* Positive zero.  */
779     size_t length;
780     char *result =
781       my_asnprintf (NULL, &length, "%f %d", 0.0, 33, 44, 55);
782     ASSERT (result != NULL);
783     ASSERT (strcmp (result, "0.000000 33") == 0);
784     ASSERT (length == strlen (result));
785     free (result);
786   }
787
788   { /* Negative zero.  */
789     size_t length;
790     char *result =
791       my_asnprintf (NULL, &length, "%f %d", -0.0, 33, 44, 55);
792     ASSERT (result != NULL);
793     ASSERT (strcmp (result, "-0.000000 33") == 0);
794     ASSERT (length == strlen (result));
795     free (result);
796   }
797
798   { /* Positive infinity.  */
799     size_t length;
800     char *result =
801       my_asnprintf (NULL, &length, "%f %d", 1.0 / 0.0, 33, 44, 55);
802     ASSERT (result != NULL);
803     ASSERT (strcmp (result, "inf 33") == 0
804             || strcmp (result, "infinity 33") == 0);
805     ASSERT (length == strlen (result));
806     free (result);
807   }
808
809   { /* Negative infinity.  */
810     size_t length;
811     char *result =
812       my_asnprintf (NULL, &length, "%f %d", -1.0 / 0.0, 33, 44, 55);
813     ASSERT (result != NULL);
814     ASSERT (strcmp (result, "-inf 33") == 0
815             || strcmp (result, "-infinity 33") == 0);
816     ASSERT (length == strlen (result));
817     free (result);
818   }
819
820   { /* NaN.  */
821     size_t length;
822     char *result =
823       my_asnprintf (NULL, &length, "%f %d", NaN (), 33, 44, 55);
824     ASSERT (result != NULL);
825     ASSERT (strcmp (result, "nan 33") == 0);
826     ASSERT (length == strlen (result));
827     free (result);
828   }
829
830   { /* FLAG_ZERO.  */
831     size_t length;
832     char *result =
833       my_asnprintf (NULL, &length, "%015f %d", 1234.0, 33, 44, 55);
834     ASSERT (result != NULL);
835     ASSERT (strcmp (result, "00001234.000000 33") == 0);
836     ASSERT (length == strlen (result));
837     free (result);
838   }
839
840   { /* FLAG_ZERO with infinite number.  */
841     size_t length;
842     char *result =
843       my_asnprintf (NULL, &length, "%015f %d", -1.0 / 0.0, 33, 44, 55);
844     ASSERT (result != NULL);
845     ASSERT (strcmp (result, "           -inf 33") == 0
846             || strcmp (result, "      -infinity 33") == 0);
847     ASSERT (length == strlen (result));
848     free (result);
849   }
850
851   { /* Precision.  */
852     size_t length;
853     char *result =
854       my_asnprintf (NULL, &length, "%.f %d", 1234.0, 33, 44, 55);
855     ASSERT (result != NULL);
856     ASSERT (strcmp (result, "1234 33") == 0);
857     ASSERT (length == strlen (result));
858     free (result);
859   }
860
861   { /* A positive number.  */
862     size_t length;
863     char *result =
864       my_asnprintf (NULL, &length, "%Lf %d", 12.75L, 33, 44, 55);
865     ASSERT (result != NULL);
866     ASSERT (strcmp (result, "12.750000 33") == 0);
867     ASSERT (length == strlen (result));
868     free (result);
869   }
870
871   { /* A larger positive number.  */
872     size_t length;
873     char *result =
874       my_asnprintf (NULL, &length, "%Lf %d", 1234567.0L, 33, 44, 55);
875     ASSERT (result != NULL);
876     ASSERT (strcmp (result, "1234567.000000 33") == 0);
877     ASSERT (length == strlen (result));
878     free (result);
879   }
880
881   { /* A negative number.  */
882     size_t length;
883     char *result =
884       my_asnprintf (NULL, &length, "%Lf %d", -0.03125L, 33, 44, 55);
885     ASSERT (result != NULL);
886     ASSERT (strcmp (result, "-0.031250 33") == 0);
887     ASSERT (length == strlen (result));
888     free (result);
889   }
890
891   { /* Positive zero.  */
892     size_t length;
893     char *result =
894       my_asnprintf (NULL, &length, "%Lf %d", 0.0L, 33, 44, 55);
895     ASSERT (result != NULL);
896     ASSERT (strcmp (result, "0.000000 33") == 0);
897     ASSERT (length == strlen (result));
898     free (result);
899   }
900
901   { /* Negative zero.  */
902     size_t length;
903     char *result =
904       my_asnprintf (NULL, &length, "%Lf %d", -0.0L, 33, 44, 55);
905     ASSERT (result != NULL);
906     ASSERT (strcmp (result, "-0.000000 33") == 0);
907     ASSERT (length == strlen (result));
908     free (result);
909   }
910
911   { /* Positive infinity.  */
912     size_t length;
913     char *result =
914       my_asnprintf (NULL, &length, "%Lf %d", 1.0L / 0.0L, 33, 44, 55);
915     ASSERT (result != NULL);
916     ASSERT (strcmp (result, "inf 33") == 0
917             || strcmp (result, "infinity 33") == 0);
918     ASSERT (length == strlen (result));
919     free (result);
920   }
921
922   { /* Negative infinity.  */
923     size_t length;
924     char *result =
925       my_asnprintf (NULL, &length, "%Lf %d", -1.0L / 0.0L, 33, 44, 55);
926     ASSERT (result != NULL);
927     ASSERT (strcmp (result, "-inf 33") == 0
928             || strcmp (result, "-infinity 33") == 0);
929     ASSERT (length == strlen (result));
930     free (result);
931   }
932
933   { /* NaN.  */
934     static long double zero = 0.0L;
935     size_t length;
936     char *result =
937       my_asnprintf (NULL, &length, "%Lf %d", zero / zero, 33, 44, 55);
938     ASSERT (result != NULL);
939     ASSERT (strcmp (result, "nan 33") == 0);
940     ASSERT (length == strlen (result));
941     free (result);
942   }
943
944   { /* FLAG_ZERO.  */
945     size_t length;
946     char *result =
947       my_asnprintf (NULL, &length, "%015Lf %d", 1234.0L, 33, 44, 55);
948     ASSERT (result != NULL);
949     ASSERT (strcmp (result, "00001234.000000 33") == 0);
950     ASSERT (length == strlen (result));
951     free (result);
952   }
953
954   { /* FLAG_ZERO with infinite number.  */
955     size_t length;
956     char *result =
957       my_asnprintf (NULL, &length, "%015Lf %d", -1.0L / 0.0L, 33, 44, 55);
958     ASSERT (result != NULL);
959     ASSERT (strcmp (result, "           -inf 33") == 0
960             || strcmp (result, "      -infinity 33") == 0);
961     ASSERT (length == strlen (result));
962     free (result);
963   }
964
965   { /* Precision.  */
966     size_t length;
967     char *result =
968       my_asnprintf (NULL, &length, "%.Lf %d", 1234.0L, 33, 44, 55);
969     ASSERT (result != NULL);
970     ASSERT (strcmp (result, "1234 33") == 0);
971     ASSERT (length == strlen (result));
972     free (result);
973   }
974
975   /* Test the support of the %F format directive.  */
976
977   { /* A positive number.  */
978     size_t length;
979     char *result =
980       my_asnprintf (NULL, &length, "%F %d", 12.75, 33, 44, 55);
981     ASSERT (result != NULL);
982     ASSERT (strcmp (result, "12.750000 33") == 0);
983     ASSERT (length == strlen (result));
984     free (result);
985   }
986
987   { /* A larger positive number.  */
988     size_t length;
989     char *result =
990       my_asnprintf (NULL, &length, "%F %d", 1234567.0, 33, 44, 55);
991     ASSERT (result != NULL);
992     ASSERT (strcmp (result, "1234567.000000 33") == 0);
993     ASSERT (length == strlen (result));
994     free (result);
995   }
996
997   { /* A negative number.  */
998     size_t length;
999     char *result =
1000       my_asnprintf (NULL, &length, "%F %d", -0.03125, 33, 44, 55);
1001     ASSERT (result != NULL);
1002     ASSERT (strcmp (result, "-0.031250 33") == 0);
1003     ASSERT (length == strlen (result));
1004     free (result);
1005   }
1006
1007   { /* Positive zero.  */
1008     size_t length;
1009     char *result =
1010       my_asnprintf (NULL, &length, "%F %d", 0.0, 33, 44, 55);
1011     ASSERT (result != NULL);
1012     ASSERT (strcmp (result, "0.000000 33") == 0);
1013     ASSERT (length == strlen (result));
1014     free (result);
1015   }
1016
1017   { /* Negative zero.  */
1018     size_t length;
1019     char *result =
1020       my_asnprintf (NULL, &length, "%F %d", -0.0, 33, 44, 55);
1021     ASSERT (result != NULL);
1022     ASSERT (strcmp (result, "-0.000000 33") == 0);
1023     ASSERT (length == strlen (result));
1024     free (result);
1025   }
1026
1027   { /* Positive infinity.  */
1028     size_t length;
1029     char *result =
1030       my_asnprintf (NULL, &length, "%F %d", 1.0 / 0.0, 33, 44, 55);
1031     ASSERT (result != NULL);
1032     ASSERT (strcmp (result, "INF 33") == 0
1033             || strcmp (result, "INFINITY 33") == 0);
1034     ASSERT (length == strlen (result));
1035     free (result);
1036   }
1037
1038   { /* Negative infinity.  */
1039     size_t length;
1040     char *result =
1041       my_asnprintf (NULL, &length, "%F %d", -1.0 / 0.0, 33, 44, 55);
1042     ASSERT (result != NULL);
1043     ASSERT (strcmp (result, "-INF 33") == 0
1044             || strcmp (result, "-INFINITY 33") == 0);
1045     ASSERT (length == strlen (result));
1046     free (result);
1047   }
1048
1049   { /* NaN.  */
1050     size_t length;
1051     char *result =
1052       my_asnprintf (NULL, &length, "%F %d", NaN (), 33, 44, 55);
1053     ASSERT (result != NULL);
1054     ASSERT (strcmp (result, "NAN 33") == 0);
1055     ASSERT (length == strlen (result));
1056     free (result);
1057   }
1058
1059   { /* FLAG_ZERO.  */
1060     size_t length;
1061     char *result =
1062       my_asnprintf (NULL, &length, "%015F %d", 1234.0, 33, 44, 55);
1063     ASSERT (result != NULL);
1064     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1065     ASSERT (length == strlen (result));
1066     free (result);
1067   }
1068
1069   { /* FLAG_ZERO with infinite number.  */
1070     size_t length;
1071     char *result =
1072       my_asnprintf (NULL, &length, "%015F %d", -1.0 / 0.0, 33, 44, 55);
1073     ASSERT (result != NULL);
1074     ASSERT (strcmp (result, "           -INF 33") == 0
1075             || strcmp (result, "      -INFINITY 33") == 0);
1076     ASSERT (length == strlen (result));
1077     free (result);
1078   }
1079
1080   { /* Precision.  */
1081     size_t length;
1082     char *result =
1083       my_asnprintf (NULL, &length, "%.F %d", 1234.0, 33, 44, 55);
1084     ASSERT (result != NULL);
1085     ASSERT (strcmp (result, "1234 33") == 0);
1086     ASSERT (length == strlen (result));
1087     free (result);
1088   }
1089
1090   { /* A positive number.  */
1091     size_t length;
1092     char *result =
1093       my_asnprintf (NULL, &length, "%LF %d", 12.75L, 33, 44, 55);
1094     ASSERT (result != NULL);
1095     ASSERT (strcmp (result, "12.750000 33") == 0);
1096     ASSERT (length == strlen (result));
1097     free (result);
1098   }
1099
1100   { /* A larger positive number.  */
1101     size_t length;
1102     char *result =
1103       my_asnprintf (NULL, &length, "%LF %d", 1234567.0L, 33, 44, 55);
1104     ASSERT (result != NULL);
1105     ASSERT (strcmp (result, "1234567.000000 33") == 0);
1106     ASSERT (length == strlen (result));
1107     free (result);
1108   }
1109
1110   { /* A negative number.  */
1111     size_t length;
1112     char *result =
1113       my_asnprintf (NULL, &length, "%LF %d", -0.03125L, 33, 44, 55);
1114     ASSERT (result != NULL);
1115     ASSERT (strcmp (result, "-0.031250 33") == 0);
1116     ASSERT (length == strlen (result));
1117     free (result);
1118   }
1119
1120   { /* Positive zero.  */
1121     size_t length;
1122     char *result =
1123       my_asnprintf (NULL, &length, "%LF %d", 0.0L, 33, 44, 55);
1124     ASSERT (result != NULL);
1125     ASSERT (strcmp (result, "0.000000 33") == 0);
1126     ASSERT (length == strlen (result));
1127     free (result);
1128   }
1129
1130   { /* Negative zero.  */
1131     size_t length;
1132     char *result =
1133       my_asnprintf (NULL, &length, "%LF %d", -0.0L, 33, 44, 55);
1134     ASSERT (result != NULL);
1135     ASSERT (strcmp (result, "-0.000000 33") == 0);
1136     ASSERT (length == strlen (result));
1137     free (result);
1138   }
1139
1140   { /* Positive infinity.  */
1141     size_t length;
1142     char *result =
1143       my_asnprintf (NULL, &length, "%LF %d", 1.0L / 0.0L, 33, 44, 55);
1144     ASSERT (result != NULL);
1145     ASSERT (strcmp (result, "INF 33") == 0
1146             || strcmp (result, "INFINITY 33") == 0);
1147     ASSERT (length == strlen (result));
1148     free (result);
1149   }
1150
1151   { /* Negative infinity.  */
1152     size_t length;
1153     char *result =
1154       my_asnprintf (NULL, &length, "%LF %d", -1.0L / 0.0L, 33, 44, 55);
1155     ASSERT (result != NULL);
1156     ASSERT (strcmp (result, "-INF 33") == 0
1157             || strcmp (result, "-INFINITY 33") == 0);
1158     ASSERT (length == strlen (result));
1159     free (result);
1160   }
1161
1162   { /* NaN.  */
1163     static long double zero = 0.0L;
1164     size_t length;
1165     char *result =
1166       my_asnprintf (NULL, &length, "%LF %d", zero / zero, 33, 44, 55);
1167     ASSERT (result != NULL);
1168     ASSERT (strcmp (result, "NAN 33") == 0);
1169     ASSERT (length == strlen (result));
1170     free (result);
1171   }
1172
1173   { /* FLAG_ZERO.  */
1174     size_t length;
1175     char *result =
1176       my_asnprintf (NULL, &length, "%015LF %d", 1234.0L, 33, 44, 55);
1177     ASSERT (result != NULL);
1178     ASSERT (strcmp (result, "00001234.000000 33") == 0);
1179     ASSERT (length == strlen (result));
1180     free (result);
1181   }
1182
1183   { /* FLAG_ZERO with infinite number.  */
1184     size_t length;
1185     char *result =
1186       my_asnprintf (NULL, &length, "%015LF %d", -1.0L / 0.0L, 33, 44, 55);
1187     ASSERT (result != NULL);
1188     ASSERT (strcmp (result, "           -INF 33") == 0
1189             || strcmp (result, "      -INFINITY 33") == 0);
1190     ASSERT (length == strlen (result));
1191     free (result);
1192   }
1193
1194   { /* Precision.  */
1195     size_t length;
1196     char *result =
1197       my_asnprintf (NULL, &length, "%.LF %d", 1234.0L, 33, 44, 55);
1198     ASSERT (result != NULL);
1199     ASSERT (strcmp (result, "1234 33") == 0);
1200     ASSERT (length == strlen (result));
1201     free (result);
1202   }
1203
1204   /* Test the support of the %n format directive.  */
1205
1206   {
1207     int count = -1;
1208     size_t length;
1209     char *result =
1210       my_asnprintf (NULL, &length, "%d %n", 123, &count, 33, 44, 55);
1211     ASSERT (result != NULL);
1212     ASSERT (strcmp (result, "123 ") == 0);
1213     ASSERT (length == strlen (result));
1214     ASSERT (count == 4);
1215     free (result);
1216   }
1217
1218   /* Test the support of the POSIX/XSI format strings with positions.  */
1219
1220   {
1221     size_t length;
1222     char *result =
1223       my_asnprintf (NULL, &length, "%2$d %1$d", 33, 55);
1224     ASSERT (result != NULL);
1225     ASSERT (strcmp (result, "55 33") == 0);
1226     ASSERT (length == strlen (result));
1227     free (result);
1228   }
1229 }
1230
1231 static char *
1232 my_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
1233 {
1234   va_list args;
1235   char *ret;
1236
1237   va_start (args, format);
1238   ret = vasnprintf (resultbuf, lengthp, format, args);
1239   va_end (args);
1240   return ret;
1241 }
1242
1243 static void
1244 test_vasnprintf ()
1245 {
1246   test_function (my_asnprintf);
1247 }
1248
1249 static void
1250 test_asnprintf ()
1251 {
1252   test_function (asnprintf);
1253 }
1254
1255 int
1256 main (int argc, char *argv[])
1257 {
1258   test_vasnprintf ();
1259   test_asnprintf ();
1260   return 0;
1261 }