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