1 /* Test of POSIX compatible vasprintf() and asprintf() functions.
2 Copyright (C) 2007 Free Software Foundation, Inc.
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)
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.
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. */
18 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */
24 #include "vasprintf.h"
32 #define ASSERT(expr) if (!(expr)) abort ();
35 test_function (int (*my_asprintf) (char **, const char *, ...))
39 /* Test return value convention. */
41 for (repeat = 0; repeat <= 8; repeat++)
44 int retval = asprintf (&result, "%d", 12345);
46 ASSERT (result != NULL);
47 ASSERT (strcmp (result, "12345") == 0);
51 /* Test support of size specifiers as in C99. */
56 my_asprintf (&result, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
57 ASSERT (result != NULL);
58 ASSERT (strcmp (result, "12345671 33") == 0);
59 ASSERT (retval == strlen (result));
66 my_asprintf (&result, "%zu %d", (size_t) 12345672, 33, 44, 55);
67 ASSERT (result != NULL);
68 ASSERT (strcmp (result, "12345672 33") == 0);
69 ASSERT (retval == strlen (result));
76 my_asprintf (&result, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
77 ASSERT (result != NULL);
78 ASSERT (strcmp (result, "12345673 33") == 0);
79 ASSERT (retval == strlen (result));
87 my_asprintf (&result, "%Lg %d", (long double) 1.5, 33, 44, 55);
88 ASSERT (result != NULL);
89 ASSERT (strcmp (result, "1.5 33") == 0);
90 ASSERT (retval == strlen (result));
95 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
96 output of floating-point numbers. */
98 { /* A positive number. */
101 my_asprintf (&result, "%a %d", 3.1416015625, 33, 44, 55);
102 ASSERT (result != NULL);
103 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
104 || strcmp (result, "0x3.244p+0 33") == 0
105 || strcmp (result, "0x6.488p-1 33") == 0
106 || strcmp (result, "0xc.91p-2 33") == 0);
107 ASSERT (retval == strlen (result));
111 { /* A negative number. */
114 my_asprintf (&result, "%A %d", -3.1416015625, 33, 44, 55);
115 ASSERT (result != NULL);
116 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
117 || strcmp (result, "-0X3.244P+0 33") == 0
118 || strcmp (result, "-0X6.488P-1 33") == 0
119 || strcmp (result, "-0XC.91P-2 33") == 0);
120 ASSERT (retval == strlen (result));
124 { /* Positive zero. */
127 my_asprintf (&result, "%a %d", 0.0, 33, 44, 55);
128 ASSERT (result != NULL);
129 ASSERT (strcmp (result, "0x0p+0 33") == 0);
130 ASSERT (retval == strlen (result));
134 { /* Negative zero. */
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));
144 { /* Positive infinity. */
147 my_asprintf (&result, "%a %d", 1.0 / 0.0, 33, 44, 55);
148 ASSERT (result != NULL);
149 ASSERT (strcmp (result, "inf 33") == 0);
150 ASSERT (retval == strlen (result));
154 { /* Negative infinity. */
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));
167 my_asprintf (&result, "%a %d", 0.0 / 0.0, 33, 44, 55);
168 ASSERT (result != NULL);
169 ASSERT (strcmp (result, "nan 33") == 0);
170 ASSERT (retval == strlen (result));
174 { /* Rounding near the decimal point. */
177 my_asprintf (&result, "%.0a %d", 1.5, 33, 44, 55);
178 ASSERT (result != NULL);
179 ASSERT (strcmp (result, "0x2p+0 33") == 0
180 || strcmp (result, "0x3p-1 33") == 0
181 || strcmp (result, "0x6p-2 33") == 0
182 || strcmp (result, "0xcp-3 33") == 0);
183 ASSERT (retval == strlen (result));
187 { /* Rounding with precision 0. */
190 my_asprintf (&result, "%.0a %d", 1.51, 33, 44, 55);
191 ASSERT (result != NULL);
192 ASSERT (strcmp (result, "0x2p+0 33") == 0
193 || strcmp (result, "0x3p-1 33") == 0
194 || strcmp (result, "0x6p-2 33") == 0
195 || strcmp (result, "0xcp-3 33") == 0);
196 ASSERT (retval == strlen (result));
200 { /* Rounding with precision 1. */
203 my_asprintf (&result, "%.1a %d", 1.51, 33, 44, 55);
204 ASSERT (result != NULL);
205 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
206 || strcmp (result, "0x3.0p-1 33") == 0
207 || strcmp (result, "0x6.1p-2 33") == 0
208 || strcmp (result, "0xc.1p-3 33") == 0);
209 ASSERT (retval == strlen (result));
213 { /* Rounding with precision 2. */
216 my_asprintf (&result, "%.2a %d", 1.51, 33, 44, 55);
217 ASSERT (result != NULL);
218 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
219 || strcmp (result, "0x3.05p-1 33") == 0
220 || strcmp (result, "0x6.0ap-2 33") == 0
221 || strcmp (result, "0xc.14p-3 33") == 0);
222 ASSERT (retval == strlen (result));
226 { /* Rounding with precision 3. */
229 my_asprintf (&result, "%.3a %d", 1.51, 33, 44, 55);
230 ASSERT (result != NULL);
231 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
232 || strcmp (result, "0x3.052p-1 33") == 0
233 || strcmp (result, "0x6.0a4p-2 33") == 0
234 || strcmp (result, "0xc.148p-3 33") == 0);
235 ASSERT (retval == strlen (result));
239 { /* Rounding can turn a ...FFF into a ...000. */
242 my_asprintf (&result, "%.3a %d", 1.49999, 33, 44, 55);
243 ASSERT (result != NULL);
244 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
245 || strcmp (result, "0x3.000p-1 33") == 0
246 || strcmp (result, "0x6.000p-2 33") == 0
247 || strcmp (result, "0xc.000p-3 33") == 0);
248 ASSERT (retval == strlen (result));
252 { /* Rounding can turn a ...FFF into a ...000.
253 This shows a MacOS X 10.3.9 (Darwin 7.9) bug. */
256 my_asprintf (&result, "%.1a %d", 1.999, 33, 44, 55);
257 ASSERT (result != NULL);
258 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
259 || strcmp (result, "0x2.0p+0 33") == 0
260 || strcmp (result, "0x4.0p-1 33") == 0
261 || strcmp (result, "0x8.0p-2 33") == 0);
262 ASSERT (retval == strlen (result));
269 my_asprintf (&result, "%10a %d", 1.75, 33, 44, 55);
270 ASSERT (result != NULL);
271 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
272 || strcmp (result, " 0x3.8p-1 33") == 0
273 || strcmp (result, " 0x7p-2 33") == 0
274 || strcmp (result, " 0xep-3 33") == 0);
275 ASSERT (retval == strlen (result));
279 { /* Small precision. */
282 my_asprintf (&result, "%.10a %d", 1.75, 33, 44, 55);
283 ASSERT (result != NULL);
284 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
285 || strcmp (result, "0x3.8000000000p-1 33") == 0
286 || strcmp (result, "0x7.0000000000p-2 33") == 0
287 || strcmp (result, "0xe.0000000000p-3 33") == 0);
288 ASSERT (retval == strlen (result));
292 { /* Large precision. */
295 my_asprintf (&result, "%.50a %d", 1.75, 33, 44, 55);
296 ASSERT (result != NULL);
297 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
298 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
299 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
300 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
301 ASSERT (retval == strlen (result));
308 my_asprintf (&result, "%-10a %d", 1.75, 33, 44, 55);
309 ASSERT (result != NULL);
310 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
311 || strcmp (result, "0x3.8p-1 33") == 0
312 || strcmp (result, "0x7p-2 33") == 0
313 || strcmp (result, "0xep-3 33") == 0);
314 ASSERT (retval == strlen (result));
318 { /* FLAG_SHOWSIGN. */
321 my_asprintf (&result, "%+a %d", 1.75, 33, 44, 55);
322 ASSERT (result != NULL);
323 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
324 || strcmp (result, "+0x3.8p-1 33") == 0
325 || strcmp (result, "+0x7p-2 33") == 0
326 || strcmp (result, "+0xep-3 33") == 0);
327 ASSERT (retval == strlen (result));
334 my_asprintf (&result, "% a %d", 1.75, 33, 44, 55);
335 ASSERT (result != NULL);
336 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
337 || strcmp (result, " 0x3.8p-1 33") == 0
338 || strcmp (result, " 0x7p-2 33") == 0
339 || strcmp (result, " 0xep-3 33") == 0);
340 ASSERT (retval == strlen (result));
347 my_asprintf (&result, "%#a %d", 1.75, 33, 44, 55);
348 ASSERT (result != NULL);
349 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
350 || strcmp (result, "0x3.8p-1 33") == 0
351 || strcmp (result, "0x7.p-2 33") == 0
352 || strcmp (result, "0xe.p-3 33") == 0);
353 ASSERT (retval == strlen (result));
360 my_asprintf (&result, "%#a %d", 1.0, 33, 44, 55);
361 ASSERT (result != NULL);
362 ASSERT (strcmp (result, "0x1.p+0 33") == 0
363 || strcmp (result, "0x2.p-1 33") == 0
364 || strcmp (result, "0x4.p-2 33") == 0
365 || strcmp (result, "0x8.p-3 33") == 0);
366 ASSERT (retval == strlen (result));
370 { /* FLAG_ZERO with finite number. */
373 my_asprintf (&result, "%010a %d", 1.75, 33, 44, 55);
374 ASSERT (result != NULL);
375 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
376 || strcmp (result, "0x003.8p-1 33") == 0
377 || strcmp (result, "0x00007p-2 33") == 0
378 || strcmp (result, "0x0000ep-3 33") == 0);
379 ASSERT (retval == strlen (result));
383 { /* FLAG_ZERO with infinite number. */
386 my_asprintf (&result, "%010a %d", 1.0 / 0.0, 33, 44, 55);
387 ASSERT (result != NULL);
388 ASSERT (strcmp (result, " inf 33") == 0);
389 ASSERT (retval == strlen (result));
393 { /* FLAG_ZERO with NaN. */
396 my_asprintf (&result, "%010a %d", 0.0 / 0.0, 33, 44, 55);
397 ASSERT (result != NULL);
398 ASSERT (strcmp (result, " nan 33") == 0);
399 ASSERT (retval == strlen (result));
405 { /* A positive number. */
408 my_asprintf (&result, "%La %d", 3.1416015625L, 33, 44, 55);
409 ASSERT (result != NULL);
410 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
411 || strcmp (result, "0x3.244p+0 33") == 0
412 || strcmp (result, "0x6.488p-1 33") == 0
413 || strcmp (result, "0xc.91p-2 33") == 0);
414 ASSERT (retval == strlen (result));
418 { /* A negative number. */
421 my_asprintf (&result, "%LA %d", -3.1416015625L, 33, 44, 55);
422 ASSERT (result != NULL);
423 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
424 || strcmp (result, "-0X3.244P+0 33") == 0
425 || strcmp (result, "-0X6.488P-1 33") == 0
426 || strcmp (result, "-0XC.91P-2 33") == 0);
427 ASSERT (retval == strlen (result));
431 { /* Positive zero. */
434 my_asprintf (&result, "%La %d", 0.0L, 33, 44, 55);
435 ASSERT (result != NULL);
436 ASSERT (strcmp (result, "0x0p+0 33") == 0);
437 ASSERT (retval == strlen (result));
441 { /* Negative zero. */
444 my_asprintf (&result, "%La %d", -0.0L, 33, 44, 55);
445 ASSERT (result != NULL);
446 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
447 ASSERT (retval == strlen (result));
451 { /* Positive infinity. */
454 my_asprintf (&result, "%La %d", 1.0L / 0.0L, 33, 44, 55);
455 ASSERT (result != NULL);
456 ASSERT (strcmp (result, "inf 33") == 0);
457 ASSERT (retval == strlen (result));
461 { /* Negative infinity. */
464 my_asprintf (&result, "%La %d", -1.0L / 0.0L, 33, 44, 55);
465 ASSERT (result != NULL);
466 ASSERT (strcmp (result, "-inf 33") == 0);
467 ASSERT (retval == strlen (result));
474 my_asprintf (&result, "%La %d", 0.0L / 0.0L, 33, 44, 55);
475 ASSERT (result != NULL);
476 ASSERT (strcmp (result, "nan 33") == 0);
477 ASSERT (retval == strlen (result));
481 { /* Rounding near the decimal point. */
484 my_asprintf (&result, "%.0La %d", 1.5L, 33, 44, 55);
485 ASSERT (result != NULL);
486 ASSERT (strcmp (result, "0x2p+0 33") == 0
487 || strcmp (result, "0x3p-1 33") == 0
488 || strcmp (result, "0x6p-2 33") == 0
489 || strcmp (result, "0xcp-3 33") == 0);
490 ASSERT (retval == strlen (result));
494 { /* Rounding with precision 0. */
497 my_asprintf (&result, "%.0La %d", 1.51L, 33, 44, 55);
498 ASSERT (result != NULL);
499 ASSERT (strcmp (result, "0x2p+0 33") == 0
500 || strcmp (result, "0x3p-1 33") == 0
501 || strcmp (result, "0x6p-2 33") == 0
502 || strcmp (result, "0xcp-3 33") == 0);
503 ASSERT (retval == strlen (result));
507 { /* Rounding with precision 1. */
510 my_asprintf (&result, "%.1La %d", 1.51L, 33, 44, 55);
511 ASSERT (result != NULL);
512 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
513 || strcmp (result, "0x3.0p-1 33") == 0
514 || strcmp (result, "0x6.1p-2 33") == 0
515 || strcmp (result, "0xc.1p-3 33") == 0);
516 ASSERT (retval == strlen (result));
520 { /* Rounding with precision 2. */
523 my_asprintf (&result, "%.2La %d", 1.51L, 33, 44, 55);
524 ASSERT (result != NULL);
525 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
526 || strcmp (result, "0x3.05p-1 33") == 0
527 || strcmp (result, "0x6.0ap-2 33") == 0
528 || strcmp (result, "0xc.14p-3 33") == 0);
529 ASSERT (retval == strlen (result));
533 { /* Rounding with precision 3. */
536 my_asprintf (&result, "%.3La %d", 1.51L, 33, 44, 55);
537 ASSERT (result != NULL);
538 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
539 || strcmp (result, "0x3.052p-1 33") == 0
540 || strcmp (result, "0x6.0a4p-2 33") == 0
541 || strcmp (result, "0xc.148p-3 33") == 0);
542 ASSERT (retval == strlen (result));
546 { /* Rounding can turn a ...FFF into a ...000. */
549 my_asprintf (&result, "%.3La %d", 1.49999L, 33, 44, 55);
550 ASSERT (result != NULL);
551 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
552 || strcmp (result, "0x3.000p-1 33") == 0
553 || strcmp (result, "0x6.000p-2 33") == 0
554 || strcmp (result, "0xc.000p-3 33") == 0);
555 ASSERT (retval == strlen (result));
559 { /* Rounding can turn a ...FFF into a ...000.
560 This shows a MacOS X 10.3.9 (Darwin 7.9) bug and a
561 glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
564 my_asprintf (&result, "%.1La %d", 1.999L, 33, 44, 55);
565 ASSERT (result != NULL);
566 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
567 || strcmp (result, "0x2.0p+0 33") == 0
568 || strcmp (result, "0x4.0p-1 33") == 0
569 || strcmp (result, "0x8.0p-2 33") == 0);
570 ASSERT (retval == strlen (result));
577 my_asprintf (&result, "%10La %d", 1.75L, 33, 44, 55);
578 ASSERT (result != NULL);
579 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
580 || strcmp (result, " 0x3.8p-1 33") == 0
581 || strcmp (result, " 0x7p-2 33") == 0
582 || strcmp (result, " 0xep-3 33") == 0);
583 ASSERT (retval == strlen (result));
587 { /* Small precision. */
590 my_asprintf (&result, "%.10La %d", 1.75L, 33, 44, 55);
591 ASSERT (result != NULL);
592 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
593 || strcmp (result, "0x3.8000000000p-1 33") == 0
594 || strcmp (result, "0x7.0000000000p-2 33") == 0
595 || strcmp (result, "0xe.0000000000p-3 33") == 0);
596 ASSERT (retval == strlen (result));
600 { /* Large precision. */
603 my_asprintf (&result, "%.50La %d", 1.75L, 33, 44, 55);
604 ASSERT (result != NULL);
605 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
606 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
607 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
608 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
609 ASSERT (retval == strlen (result));
616 my_asprintf (&result, "%-10La %d", 1.75L, 33, 44, 55);
617 ASSERT (result != NULL);
618 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
619 || strcmp (result, "0x3.8p-1 33") == 0
620 || strcmp (result, "0x7p-2 33") == 0
621 || strcmp (result, "0xep-3 33") == 0);
622 ASSERT (retval == strlen (result));
626 { /* FLAG_SHOWSIGN. */
629 my_asprintf (&result, "%+La %d", 1.75L, 33, 44, 55);
630 ASSERT (result != NULL);
631 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
632 || strcmp (result, "+0x3.8p-1 33") == 0
633 || strcmp (result, "+0x7p-2 33") == 0
634 || strcmp (result, "+0xep-3 33") == 0);
635 ASSERT (retval == strlen (result));
642 my_asprintf (&result, "% La %d", 1.75L, 33, 44, 55);
643 ASSERT (result != NULL);
644 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
645 || strcmp (result, " 0x3.8p-1 33") == 0
646 || strcmp (result, " 0x7p-2 33") == 0
647 || strcmp (result, " 0xep-3 33") == 0);
648 ASSERT (retval == strlen (result));
655 my_asprintf (&result, "%#La %d", 1.75L, 33, 44, 55);
656 ASSERT (result != NULL);
657 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
658 || strcmp (result, "0x3.8p-1 33") == 0
659 || strcmp (result, "0x7.p-2 33") == 0
660 || strcmp (result, "0xe.p-3 33") == 0);
661 ASSERT (retval == strlen (result));
668 my_asprintf (&result, "%#La %d", 1.0L, 33, 44, 55);
669 ASSERT (result != NULL);
670 ASSERT (strcmp (result, "0x1.p+0 33") == 0
671 || strcmp (result, "0x2.p-1 33") == 0
672 || strcmp (result, "0x4.p-2 33") == 0
673 || strcmp (result, "0x8.p-3 33") == 0);
674 ASSERT (retval == strlen (result));
678 { /* FLAG_ZERO with finite number. */
681 my_asprintf (&result, "%010La %d", 1.75L, 33, 44, 55);
682 ASSERT (result != NULL);
683 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
684 || strcmp (result, "0x003.8p-1 33") == 0
685 || strcmp (result, "0x00007p-2 33") == 0
686 || strcmp (result, "0x0000ep-3 33") == 0);
687 ASSERT (retval == strlen (result));
691 { /* FLAG_ZERO with infinite number. */
694 my_asprintf (&result, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
695 ASSERT (result != NULL);
696 ASSERT (strcmp (result, " inf 33") == 0);
697 ASSERT (retval == strlen (result));
701 { /* FLAG_ZERO with NaN. */
704 my_asprintf (&result, "%010La %d", 0.0L / 0.0L, 33, 44, 55);
705 ASSERT (result != NULL);
706 ASSERT (strcmp (result, " nan 33") == 0);
707 ASSERT (retval == strlen (result));
713 /* Test the support of the %n format directive. */
719 my_asprintf (&result, "%d %n", 123, &count, 33, 44, 55);
720 ASSERT (result != NULL);
721 ASSERT (strcmp (result, "123 ") == 0);
722 ASSERT (retval == strlen (result));
727 /* Test the support of the POSIX/XSI format strings with positions. */
732 my_asprintf (&result, "%2$d %1$d", 33, 55);
733 ASSERT (result != NULL);
734 ASSERT (strcmp (result, "55 33") == 0);
735 ASSERT (retval == strlen (result));
741 my_asprintf (char **result, const char *format, ...)
746 va_start (args, format);
747 ret = vasprintf (result, format, args);
755 test_function (my_asprintf);
761 test_function (asprintf);
765 main (int argc, char *argv[])