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