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 *, ...))
40 /* Test return value convention. */
42 for (repeat = 0; repeat <= 8; repeat++)
45 int retval = asprintf (&result, "%d", 12345);
47 ASSERT (result != NULL);
48 ASSERT (strcmp (result, "12345") == 0);
52 /* Test support of size specifiers as in C99. */
57 my_asprintf (&result, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
58 ASSERT (result != NULL);
59 ASSERT (strcmp (result, "12345671 33") == 0);
60 ASSERT (retval == strlen (result));
67 my_asprintf (&result, "%zu %d", (size_t) 12345672, 33, 44, 55);
68 ASSERT (result != NULL);
69 ASSERT (strcmp (result, "12345672 33") == 0);
70 ASSERT (retval == strlen (result));
77 my_asprintf (&result, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
78 ASSERT (result != NULL);
79 ASSERT (strcmp (result, "12345673 33") == 0);
80 ASSERT (retval == strlen (result));
88 my_asprintf (&result, "%Lg %d", (long double) 1.5, 33, 44, 55);
89 ASSERT (result != NULL);
90 ASSERT (strcmp (result, "1.5 33") == 0);
91 ASSERT (retval == strlen (result));
96 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
97 output of floating-point numbers. */
99 { /* A positive number. */
102 my_asprintf (&result, "%a %d", 3.1416015625, 33, 44, 55);
103 ASSERT (result != NULL);
104 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
105 || strcmp (result, "0x3.244p+0 33") == 0
106 || strcmp (result, "0x6.488p-1 33") == 0
107 || strcmp (result, "0xc.91p-2 33") == 0);
108 ASSERT (retval == strlen (result));
112 { /* A negative number. */
115 my_asprintf (&result, "%A %d", -3.1416015625, 33, 44, 55);
116 ASSERT (result != NULL);
117 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
118 || strcmp (result, "-0X3.244P+0 33") == 0
119 || strcmp (result, "-0X6.488P-1 33") == 0
120 || strcmp (result, "-0XC.91P-2 33") == 0);
121 ASSERT (retval == strlen (result));
125 { /* Positive zero. */
128 my_asprintf (&result, "%a %d", 0.0, 33, 44, 55);
129 ASSERT (result != NULL);
130 ASSERT (strcmp (result, "0x0p+0 33") == 0);
131 ASSERT (retval == strlen (result));
135 { /* Negative zero. */
138 my_asprintf (&result, "%a %d", -0.0, 33, 44, 55);
139 ASSERT (result != NULL);
140 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
141 ASSERT (retval == strlen (result));
145 { /* Positive infinity. */
148 my_asprintf (&result, "%a %d", 1.0 / 0.0, 33, 44, 55);
149 ASSERT (result != NULL);
150 ASSERT (strcmp (result, "inf 33") == 0);
151 ASSERT (retval == strlen (result));
155 { /* Negative infinity. */
158 my_asprintf (&result, "%a %d", -1.0 / 0.0, 33, 44, 55);
159 ASSERT (result != NULL);
160 ASSERT (strcmp (result, "-inf 33") == 0);
161 ASSERT (retval == strlen (result));
168 my_asprintf (&result, "%a %d", 0.0 / 0.0, 33, 44, 55);
169 ASSERT (result != NULL);
170 ASSERT (strcmp (result, "nan 33") == 0);
171 ASSERT (retval == strlen (result));
175 { /* Rounding near the decimal point. */
178 my_asprintf (&result, "%.0a %d", 1.5, 33, 44, 55);
179 ASSERT (result != NULL);
180 ASSERT (strcmp (result, "0x2p+0 33") == 0
181 || strcmp (result, "0x3p-1 33") == 0
182 || strcmp (result, "0x6p-2 33") == 0
183 || strcmp (result, "0xcp-3 33") == 0);
184 ASSERT (retval == strlen (result));
188 { /* Rounding with precision 0. */
191 my_asprintf (&result, "%.0a %d", 1.51, 33, 44, 55);
192 ASSERT (result != NULL);
193 ASSERT (strcmp (result, "0x2p+0 33") == 0
194 || strcmp (result, "0x3p-1 33") == 0
195 || strcmp (result, "0x6p-2 33") == 0
196 || strcmp (result, "0xcp-3 33") == 0);
197 ASSERT (retval == strlen (result));
201 { /* Rounding with precision 1. */
204 my_asprintf (&result, "%.1a %d", 1.51, 33, 44, 55);
205 ASSERT (result != NULL);
206 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
207 || strcmp (result, "0x3.0p-1 33") == 0
208 || strcmp (result, "0x6.1p-2 33") == 0
209 || strcmp (result, "0xc.1p-3 33") == 0);
210 ASSERT (retval == strlen (result));
214 { /* Rounding with precision 2. */
217 my_asprintf (&result, "%.2a %d", 1.51, 33, 44, 55);
218 ASSERT (result != NULL);
219 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
220 || strcmp (result, "0x3.05p-1 33") == 0
221 || strcmp (result, "0x6.0ap-2 33") == 0
222 || strcmp (result, "0xc.14p-3 33") == 0);
223 ASSERT (retval == strlen (result));
227 { /* Rounding with precision 3. */
230 my_asprintf (&result, "%.3a %d", 1.51, 33, 44, 55);
231 ASSERT (result != NULL);
232 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
233 || strcmp (result, "0x3.052p-1 33") == 0
234 || strcmp (result, "0x6.0a4p-2 33") == 0
235 || strcmp (result, "0xc.148p-3 33") == 0);
236 ASSERT (retval == strlen (result));
240 { /* Rounding can turn a ...FFF into a ...000. */
243 my_asprintf (&result, "%.3a %d", 1.49999, 33, 44, 55);
244 ASSERT (result != NULL);
245 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
246 || strcmp (result, "0x3.000p-1 33") == 0
247 || strcmp (result, "0x6.000p-2 33") == 0
248 || strcmp (result, "0xc.000p-3 33") == 0);
249 ASSERT (retval == strlen (result));
256 my_asprintf (&result, "%10a %d", 1.75, 33, 44, 55);
257 ASSERT (result != NULL);
258 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
259 || strcmp (result, " 0x3.8p-1 33") == 0
260 || strcmp (result, " 0x7p-2 33") == 0
261 || strcmp (result, " 0xep-3 33") == 0);
262 ASSERT (retval == strlen (result));
266 { /* Small precision. */
269 my_asprintf (&result, "%.10a %d", 1.75, 33, 44, 55);
270 ASSERT (result != NULL);
271 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
272 || strcmp (result, "0x3.8000000000p-1 33") == 0
273 || strcmp (result, "0x7.0000000000p-2 33") == 0
274 || strcmp (result, "0xe.0000000000p-3 33") == 0);
275 ASSERT (retval == strlen (result));
279 { /* Large precision. */
282 my_asprintf (&result, "%.50a %d", 1.75, 33, 44, 55);
283 ASSERT (result != NULL);
284 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
285 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
286 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
287 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
288 ASSERT (retval == strlen (result));
295 my_asprintf (&result, "%-10a %d", 1.75, 33, 44, 55);
296 ASSERT (result != NULL);
297 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
298 || strcmp (result, "0x3.8p-1 33") == 0
299 || strcmp (result, "0x7p-2 33") == 0
300 || strcmp (result, "0xep-3 33") == 0);
301 ASSERT (retval == strlen (result));
305 { /* FLAG_SHOWSIGN. */
308 my_asprintf (&result, "%+a %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));
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, "0x7.p-2 33") == 0
339 || strcmp (result, "0xe.p-3 33") == 0);
340 ASSERT (retval == strlen (result));
347 my_asprintf (&result, "%#a %d", 1.0, 33, 44, 55);
348 ASSERT (result != NULL);
349 ASSERT (strcmp (result, "0x1.p+0 33") == 0
350 || strcmp (result, "0x2.p-1 33") == 0
351 || strcmp (result, "0x4.p-2 33") == 0
352 || strcmp (result, "0x8.p-3 33") == 0);
353 ASSERT (retval == strlen (result));
357 { /* FLAG_ZERO with finite number. */
360 my_asprintf (&result, "%010a %d", 1.75, 33, 44, 55);
361 ASSERT (result != NULL);
362 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
363 || strcmp (result, "0x003.8p-1 33") == 0
364 || strcmp (result, "0x00007p-2 33") == 0
365 || strcmp (result, "0x0000ep-3 33") == 0);
366 ASSERT (retval == strlen (result));
370 { /* FLAG_ZERO with infinite number. */
373 my_asprintf (&result, "%010a %d", 1.0 / 0.0, 33, 44, 55);
374 ASSERT (result != NULL);
375 ASSERT (strcmp (result, " inf 33") == 0);
376 ASSERT (retval == strlen (result));
380 { /* FLAG_ZERO with NaN. */
383 my_asprintf (&result, "%010a %d", 0.0 / 0.0, 33, 44, 55);
384 ASSERT (result != NULL);
385 ASSERT (strcmp (result, " nan 33") == 0);
386 ASSERT (retval == strlen (result));
392 { /* A positive number. */
395 my_asprintf (&result, "%La %d", 3.1416015625L, 33, 44, 55);
396 ASSERT (result != NULL);
397 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
398 || strcmp (result, "0x3.244p+0 33") == 0
399 || strcmp (result, "0x6.488p-1 33") == 0
400 || strcmp (result, "0xc.91p-2 33") == 0);
401 ASSERT (retval == strlen (result));
405 { /* A negative 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 { /* Positive zero. */
421 my_asprintf (&result, "%La %d", 0.0L, 33, 44, 55);
422 ASSERT (result != NULL);
423 ASSERT (strcmp (result, "0x0p+0 33") == 0);
424 ASSERT (retval == strlen (result));
428 { /* Negative zero. */
431 my_asprintf (&result, "%La %d", -0.0L, 33, 44, 55);
432 ASSERT (result != NULL);
433 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
434 ASSERT (retval == strlen (result));
438 { /* Positive infinity. */
441 my_asprintf (&result, "%La %d", 1.0L / 0.0L, 33, 44, 55);
442 ASSERT (result != NULL);
443 ASSERT (strcmp (result, "inf 33") == 0);
444 ASSERT (retval == strlen (result));
448 { /* Negative infinity. */
451 my_asprintf (&result, "%La %d", -1.0L / 0.0L, 33, 44, 55);
452 ASSERT (result != NULL);
453 ASSERT (strcmp (result, "-inf 33") == 0);
454 ASSERT (retval == strlen (result));
461 my_asprintf (&result, "%La %d", 0.0L / 0.0L, 33, 44, 55);
462 ASSERT (result != NULL);
463 ASSERT (strcmp (result, "nan 33") == 0);
464 ASSERT (retval == strlen (result));
468 { /* Rounding near the decimal point. */
471 my_asprintf (&result, "%.0La %d", 1.5L, 33, 44, 55);
472 ASSERT (result != NULL);
473 ASSERT (strcmp (result, "0x2p+0 33") == 0
474 || strcmp (result, "0x3p-1 33") == 0
475 || strcmp (result, "0x6p-2 33") == 0
476 || strcmp (result, "0xcp-3 33") == 0);
477 ASSERT (retval == strlen (result));
481 { /* Rounding with precision 0. */
484 my_asprintf (&result, "%.0La %d", 1.51L, 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 1. */
497 my_asprintf (&result, "%.1La %d", 1.51L, 33, 44, 55);
498 ASSERT (result != NULL);
499 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
500 || strcmp (result, "0x3.0p-1 33") == 0
501 || strcmp (result, "0x6.1p-2 33") == 0
502 || strcmp (result, "0xc.1p-3 33") == 0);
503 ASSERT (retval == strlen (result));
507 { /* Rounding with precision 2. */
510 my_asprintf (&result, "%.2La %d", 1.51L, 33, 44, 55);
511 ASSERT (result != NULL);
512 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
513 || strcmp (result, "0x3.05p-1 33") == 0
514 || strcmp (result, "0x6.0ap-2 33") == 0
515 || strcmp (result, "0xc.14p-3 33") == 0);
516 ASSERT (retval == strlen (result));
520 { /* Rounding with precision 3. */
523 my_asprintf (&result, "%.3La %d", 1.51L, 33, 44, 55);
524 ASSERT (result != NULL);
525 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
526 || strcmp (result, "0x3.052p-1 33") == 0
527 || strcmp (result, "0x6.0a4p-2 33") == 0
528 || strcmp (result, "0xc.148p-3 33") == 0);
529 ASSERT (retval == strlen (result));
533 { /* Rounding can turn a ...FFF into a ...000. */
536 my_asprintf (&result, "%.3La %d", 1.49999L, 33, 44, 55);
537 ASSERT (result != NULL);
538 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
539 || strcmp (result, "0x3.000p-1 33") == 0
540 || strcmp (result, "0x6.000p-2 33") == 0
541 || strcmp (result, "0xc.000p-3 33") == 0);
542 ASSERT (retval == strlen (result));
549 my_asprintf (&result, "%10La %d", 1.75L, 33, 44, 55);
550 ASSERT (result != NULL);
551 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
552 || strcmp (result, " 0x3.8p-1 33") == 0
553 || strcmp (result, " 0x7p-2 33") == 0
554 || strcmp (result, " 0xep-3 33") == 0);
555 ASSERT (retval == strlen (result));
559 { /* Small precision. */
562 my_asprintf (&result, "%.10La %d", 1.75L, 33, 44, 55);
563 ASSERT (result != NULL);
564 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
565 || strcmp (result, "0x3.8000000000p-1 33") == 0
566 || strcmp (result, "0x7.0000000000p-2 33") == 0
567 || strcmp (result, "0xe.0000000000p-3 33") == 0);
568 ASSERT (retval == strlen (result));
572 { /* Large precision. */
575 my_asprintf (&result, "%.50La %d", 1.75L, 33, 44, 55);
576 ASSERT (result != NULL);
577 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
578 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
579 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
580 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
581 ASSERT (retval == strlen (result));
588 my_asprintf (&result, "%-10La %d", 1.75L, 33, 44, 55);
589 ASSERT (result != NULL);
590 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
591 || strcmp (result, "0x3.8p-1 33") == 0
592 || strcmp (result, "0x7p-2 33") == 0
593 || strcmp (result, "0xep-3 33") == 0);
594 ASSERT (retval == strlen (result));
598 { /* FLAG_SHOWSIGN. */
601 my_asprintf (&result, "%+La %d", 1.75L, 33, 44, 55);
602 ASSERT (result != NULL);
603 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
604 || strcmp (result, "+0x3.8p-1 33") == 0
605 || strcmp (result, "+0x7p-2 33") == 0
606 || strcmp (result, "+0xep-3 33") == 0);
607 ASSERT (retval == strlen (result));
614 my_asprintf (&result, "% La %d", 1.75L, 33, 44, 55);
615 ASSERT (result != NULL);
616 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
617 || strcmp (result, " 0x3.8p-1 33") == 0
618 || strcmp (result, " 0x7p-2 33") == 0
619 || strcmp (result, " 0xep-3 33") == 0);
620 ASSERT (retval == strlen (result));
627 my_asprintf (&result, "%#La %d", 1.75L, 33, 44, 55);
628 ASSERT (result != NULL);
629 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
630 || strcmp (result, "0x3.8p-1 33") == 0
631 || strcmp (result, "0x7.p-2 33") == 0
632 || strcmp (result, "0xe.p-3 33") == 0);
633 ASSERT (retval == strlen (result));
640 my_asprintf (&result, "%#La %d", 1.0L, 33, 44, 55);
641 ASSERT (result != NULL);
642 ASSERT (strcmp (result, "0x1.p+0 33") == 0
643 || strcmp (result, "0x2.p-1 33") == 0
644 || strcmp (result, "0x4.p-2 33") == 0
645 || strcmp (result, "0x8.p-3 33") == 0);
646 ASSERT (retval == strlen (result));
650 { /* FLAG_ZERO with finite number. */
653 my_asprintf (&result, "%010La %d", 1.75L, 33, 44, 55);
654 ASSERT (result != NULL);
655 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
656 || strcmp (result, "0x003.8p-1 33") == 0
657 || strcmp (result, "0x00007p-2 33") == 0
658 || strcmp (result, "0x0000ep-3 33") == 0);
659 ASSERT (retval == strlen (result));
663 { /* FLAG_ZERO with infinite number. */
666 my_asprintf (&result, "%010La %d", 1.0L / 0.0L, 33, 44, 55);
667 ASSERT (result != NULL);
668 ASSERT (strcmp (result, " inf 33") == 0);
669 ASSERT (retval == strlen (result));
673 { /* FLAG_ZERO with NaN. */
676 my_asprintf (&result, "%010La %d", 0.0L / 0.0L, 33, 44, 55);
677 ASSERT (result != NULL);
678 ASSERT (strcmp (result, " nan 33") == 0);
679 ASSERT (retval == strlen (result));
685 /* Test the support of the %n format directive. */
691 my_asprintf (&result, "%d %n", 123, &count, 33, 44, 55);
692 ASSERT (result != NULL);
693 ASSERT (strcmp (result, "123 ") == 0);
694 ASSERT (retval == strlen (result));
699 /* Test the support of the POSIX/XSI format strings with positions. */
704 my_asprintf (&result, "%2$d %1$d", 33, 55);
705 ASSERT (result != NULL);
706 ASSERT (strcmp (result, "55 33") == 0);
707 ASSERT (retval == strlen (result));
713 my_asprintf (char **result, const char *format, ...)
718 va_start (args, format);
719 ret = vasprintf (result, format, args);
727 test_function (my_asprintf);
733 test_function (asprintf);
737 main (int argc, char *argv[])