1 /* Test gmp_printf and related functions.
3 Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 /* Usage: t-printf [-s]
23 -s Check the data against the system printf, where possible. This is
24 only an option since we don't want to fail if the system printf is
36 #include <stddef.h> /* for ptrdiff_t */
41 #if HAVE_OBSTACK_VPRINTF
42 #define obstack_chunk_alloc tests_allocate
43 #define obstack_chunk_free tests_free_nosize
48 # include <inttypes.h> /* for intmax_t */
56 #include <unistd.h> /* for unlink */
64 int option_check_printf = 0;
67 #define CHECK_VFPRINTF_FILENAME "t-printf.tmp"
68 FILE *check_vfprintf_fp;
71 /* From any of the tests run here. */
72 #define MAX_OUTPUT 1024
77 check_plain (const char *want, const char *fmt_orig, ...)
79 check_plain (va_alist)
84 int got_len, want_len;
90 va_start (ap, fmt_orig);
95 want = va_arg (ap, const char *);
96 fmt_orig = va_arg (ap, const char *);
99 if (! option_check_printf)
102 fmtsize = strlen (fmt_orig) + 1;
103 fmt = (*__gmp_allocate_func) (fmtsize);
105 for (p = fmt_orig, q = fmt; *p != '\0'; p++)
110 /* The exact value of the exponent isn't guaranteed in glibc, and it
111 and gmp_printf do slightly different things, so don't compare
115 if (p > fmt_orig && *(p-1) == '.')
116 goto done; /* don't test the "all digits" cases */
117 /* discard 'F' type */
130 want_len = strlen (want);
131 ASSERT_ALWAYS (want_len < sizeof(got));
133 got_len = vsprintf (got, fmt, ap);
135 if (got_len != want_len || strcmp (got, want) != 0)
137 printf ("wanted data doesn't match plain vsprintf\n");
138 printf (" fmt |%s|\n", fmt);
139 printf (" got |%s|\n", got);
140 printf (" want |%s|\n", want);
141 printf (" got_len %d\n", got_len);
142 printf (" want_len %d\n", want_len);
147 (*__gmp_free_func) (fmt, fmtsize);
151 check_vsprintf (const char *want, const char *fmt, va_list ap)
153 char got[MAX_OUTPUT];
154 int got_len, want_len;
156 want_len = strlen (want);
157 got_len = gmp_vsprintf (got, fmt, ap);
159 if (got_len != want_len || strcmp (got, want) != 0)
161 printf ("gmp_vsprintf wrong\n");
162 printf (" fmt |%s|\n", fmt);
163 printf (" got |%s|\n", got);
164 printf (" want |%s|\n", want);
165 printf (" got_len %d\n", got_len);
166 printf (" want_len %d\n", want_len);
172 check_vfprintf (const char *want, const char *fmt, va_list ap)
174 char got[MAX_OUTPUT];
175 int got_len, want_len, fread_len;
178 want_len = strlen (want);
180 rewind (check_vfprintf_fp);
181 got_len = gmp_vfprintf (check_vfprintf_fp, fmt, ap);
182 ASSERT_ALWAYS (got_len != -1);
183 ASSERT_ALWAYS (fflush (check_vfprintf_fp) == 0);
185 ftell_len = ftell (check_vfprintf_fp);
186 ASSERT_ALWAYS (ftell_len != -1);
188 rewind (check_vfprintf_fp);
189 ASSERT_ALWAYS (ftell_len <= sizeof(got));
190 fread_len = fread (got, 1, ftell_len, check_vfprintf_fp);
192 if (got_len != want_len
193 || ftell_len != want_len
194 || fread_len != want_len
195 || memcmp (got, want, want_len) != 0)
197 printf ("gmp_vfprintf wrong\n");
198 printf (" fmt |%s|\n", fmt);
199 printf (" got |%.*s|\n", fread_len, got);
200 printf (" want |%s|\n", want);
201 printf (" got_len %d\n", got_len);
202 printf (" ftell_len %ld\n", ftell_len);
203 printf (" fread_len %d\n", fread_len);
204 printf (" want_len %d\n", want_len);
210 check_vsnprintf (const char *want, const char *fmt, va_list ap)
212 char got[MAX_OUTPUT+1];
213 int ret, got_len, want_len;
216 want_len = strlen (want);
221 /* do 0 to 5, then want-5 to want+5 */
223 if (bufsize > 5 && bufsize < want_len-5)
224 bufsize = want_len-5;
225 if (bufsize > want_len + 5)
227 ASSERT_ALWAYS (bufsize+1 <= sizeof (got));
230 ret = gmp_vsnprintf (got, bufsize, fmt, ap);
232 got_len = MIN (MAX(1,bufsize)-1, want_len);
234 if (got[bufsize] != '!')
236 printf ("gmp_vsnprintf overwrote bufsize sentinel\n");
242 printf ("gmp_vsnprintf return value wrong\n");
248 if (memcmp (got, want, got_len) != 0 || got[got_len] != '\0')
250 printf ("gmp_vsnprintf wrong result string\n");
252 printf (" fmt |%s|\n", fmt);
253 printf (" bufsize %lu\n", (unsigned long) bufsize);
254 printf (" got |%s|\n", got);
255 printf (" want |%.*s|\n", got_len, want);
256 printf (" want full |%s|\n", want);
257 printf (" ret %d\n", ret);
258 printf (" want_len %d\n", want_len);
266 check_vasprintf (const char *want, const char *fmt, va_list ap)
269 int got_len, want_len;
271 want_len = strlen (want);
272 got_len = gmp_vasprintf (&got, fmt, ap);
274 if (got_len != want_len || strcmp (got, want) != 0)
276 printf ("gmp_vasprintf wrong\n");
277 printf (" fmt |%s|\n", fmt);
278 printf (" got |%s|\n", got);
279 printf (" want |%s|\n", want);
280 printf (" got_len %d\n", got_len);
281 printf (" want_len %d\n", want_len);
284 (*__gmp_free_func) (got, strlen(got)+1);
288 check_obstack_vprintf (const char *want, const char *fmt, va_list ap)
290 #if HAVE_OBSTACK_VPRINTF
292 int got_len, want_len, ob_len;
295 want_len = strlen (want);
298 got_len = gmp_obstack_vprintf (&ob, fmt, ap);
299 got = obstack_base (&ob);
300 ob_len = obstack_object_size (&ob);
302 if (got_len != want_len
303 || ob_len != want_len
304 || memcmp (got, want, want_len) != 0)
306 printf ("gmp_obstack_vprintf wrong\n");
307 printf (" fmt |%s|\n", fmt);
308 printf (" got |%s|\n", got);
309 printf (" want |%s|\n", want);
310 printf (" got_len %d\n", got_len);
311 printf (" ob_len %d\n", ob_len);
312 printf (" want_len %d\n", want_len);
315 obstack_free (&ob, NULL);
322 check_one (const char *want, const char *fmt, ...)
335 want = va_arg (ap, const char *);
336 fmt = va_arg (ap, const char *);
340 check_vsprintf (want, fmt, ap);
341 check_vfprintf (want, fmt, ap);
342 check_vsnprintf (want, fmt, ap);
343 check_vasprintf (want, fmt, ap);
344 check_obstack_vprintf (want, fmt, ap);
348 #define hex_or_octal_p(fmt) \
349 (strchr (fmt, 'x') != NULL \
350 || strchr (fmt, 'X') != NULL \
351 || strchr (fmt, 'o') != NULL)
356 static const struct {
363 { "%Zd", "123", "123" },
364 { "%Zd", "-1", "-1" },
365 { "%Zd", "-123", "-123" },
367 { "%+Zd", "0", "+0" },
368 { "%+Zd", "123", "+123" },
369 { "%+Zd", "-123", "-123" },
371 { "%Zx", "123", "7b" },
372 { "%ZX", "123", "7B" },
373 { "%Zx", "-123", "-7b" },
374 { "%ZX", "-123", "-7B" },
375 { "%Zo", "123", "173" },
376 { "%Zo", "-123", "-173" },
378 { "%#Zx", "0", "0" },
379 { "%#ZX", "0", "0" },
380 { "%#Zx", "123", "0x7b" },
381 { "%#ZX", "123", "0X7B" },
382 { "%#Zx", "-123", "-0x7b" },
383 { "%#ZX", "-123", "-0X7B" },
385 { "%#Zo", "0", "0" },
386 { "%#Zo", "123", "0173" },
387 { "%#Zo", "-123", "-0173" },
389 { "%10Zd", "0", " 0" },
390 { "%10Zd", "123", " 123" },
391 { "%10Zd", "-123", " -123" },
393 { "%-10Zd", "0", "0 " },
394 { "%-10Zd", "123", "123 " },
395 { "%-10Zd", "-123", "-123 " },
397 { "%+10Zd", "123", " +123" },
398 { "%+-10Zd", "123", "+123 " },
399 { "%+10Zd", "-123", " -123" },
400 { "%+-10Zd", "-123", "-123 " },
402 { "%08Zd", "0", "00000000" },
403 { "%08Zd", "123", "00000123" },
404 { "%08Zd", "-123", "-0000123" },
406 { "%+08Zd", "0", "+0000000" },
407 { "%+08Zd", "123", "+0000123" },
408 { "%+08Zd", "-123", "-0000123" },
410 { "%#08Zx", "0", "00000000" },
411 { "%#08Zx", "123", "0x00007b" },
412 { "%#08Zx", "-123", "-0x0007b" },
414 { "%+#08Zx", "0", "+0000000" },
415 { "%+#08Zx", "123", "+0x0007b" },
416 { "%+#08Zx", "-123", "-0x0007b" },
418 { "%.0Zd", "0", "" },
419 { "%.1Zd", "0", "0" },
420 { "%.2Zd", "0", "00" },
421 { "%.3Zd", "0", "000" },
427 mp_size_t nsize, zeros;
431 for (i = 0; i < numberof (data); i++)
433 mpz_set_str_or_abort (z, data[i].z, 0);
435 /* don't try negatives or forced sign in hex or octal */
436 if (mpz_fits_slong_p (z)
437 && ! (hex_or_octal_p (data[i].fmt)
438 && (strchr (data[i].fmt, '+') != NULL || mpz_sgn(z) < 0)))
440 check_plain (data[i].want, data[i].fmt, mpz_get_si (z));
443 check_one (data[i].want, data[i].fmt, z);
445 /* Same again, with %N and possibly some high zero limbs */
446 nfmt = __gmp_allocate_strdup (data[i].fmt);
447 for (j = 0; nfmt[j] != '\0'; j++)
450 for (zeros = 0; zeros <= 3; zeros++)
452 nsize = ABSIZ(z)+zeros;
453 MPZ_REALLOC (z, nsize);
454 nsize = (SIZ(z) >= 0 ? nsize : -nsize);
455 refmpn_zero (PTR(z)+ABSIZ(z), zeros);
456 check_one (data[i].want, nfmt, PTR(z), nsize);
458 __gmp_free_func (nfmt, strlen(nfmt)+1);
467 static const struct {
474 { "%Qd", "123", "123" },
475 { "%Qd", "-1", "-1" },
476 { "%Qd", "-123", "-123" },
477 { "%Qd", "3/2", "3/2" },
478 { "%Qd", "-3/2", "-3/2" },
480 { "%+Qd", "0", "+0" },
481 { "%+Qd", "123", "+123" },
482 { "%+Qd", "-123", "-123" },
483 { "%+Qd", "5/8", "+5/8" },
484 { "%+Qd", "-5/8", "-5/8" },
486 { "%Qx", "123", "7b" },
487 { "%QX", "123", "7B" },
488 { "%Qx", "15/16", "f/10" },
489 { "%QX", "15/16", "F/10" },
490 { "%Qx", "-123", "-7b" },
491 { "%QX", "-123", "-7B" },
492 { "%Qx", "-15/16", "-f/10" },
493 { "%QX", "-15/16", "-F/10" },
494 { "%Qo", "123", "173" },
495 { "%Qo", "-123", "-173" },
496 { "%Qo", "16/17", "20/21" },
497 { "%Qo", "-16/17", "-20/21" },
499 { "%#Qx", "0", "0" },
500 { "%#QX", "0", "0" },
501 { "%#Qx", "123", "0x7b" },
502 { "%#QX", "123", "0X7B" },
503 { "%#Qx", "5/8", "0x5/0x8" },
504 { "%#QX", "5/8", "0X5/0X8" },
505 { "%#Qx", "-123", "-0x7b" },
506 { "%#QX", "-123", "-0X7B" },
507 { "%#Qx", "-5/8", "-0x5/0x8" },
508 { "%#QX", "-5/8", "-0X5/0X8" },
509 { "%#Qo", "0", "0" },
510 { "%#Qo", "123", "0173" },
511 { "%#Qo", "-123", "-0173" },
512 { "%#Qo", "5/7", "05/07" },
513 { "%#Qo", "-5/7", "-05/07" },
515 /* zero denominator and showbase */
516 { "%#10Qo", "0/0", " 0/0" },
517 { "%#10Qd", "0/0", " 0/0" },
518 { "%#10Qx", "0/0", " 0/0" },
519 { "%#10Qo", "123/0", " 0173/0" },
520 { "%#10Qd", "123/0", " 123/0" },
521 { "%#10Qx", "123/0", " 0x7b/0" },
522 { "%#10QX", "123/0", " 0X7B/0" },
523 { "%#10Qo", "-123/0", " -0173/0" },
524 { "%#10Qd", "-123/0", " -123/0" },
525 { "%#10Qx", "-123/0", " -0x7b/0" },
526 { "%#10QX", "-123/0", " -0X7B/0" },
528 { "%10Qd", "0", " 0" },
529 { "%-10Qd", "0", "0 " },
530 { "%10Qd", "123", " 123" },
531 { "%-10Qd", "123", "123 " },
532 { "%10Qd", "-123", " -123" },
533 { "%-10Qd", "-123", "-123 " },
535 { "%+10Qd", "123", " +123" },
536 { "%+-10Qd", "123", "+123 " },
537 { "%+10Qd", "-123", " -123" },
538 { "%+-10Qd", "-123", "-123 " },
540 { "%08Qd", "0", "00000000" },
541 { "%08Qd", "123", "00000123" },
542 { "%08Qd", "-123", "-0000123" },
544 { "%+08Qd", "0", "+0000000" },
545 { "%+08Qd", "123", "+0000123" },
546 { "%+08Qd", "-123", "-0000123" },
548 { "%#08Qx", "0", "00000000" },
549 { "%#08Qx", "123", "0x00007b" },
550 { "%#08Qx", "-123", "-0x0007b" },
552 { "%+#08Qx", "0", "+0000000" },
553 { "%+#08Qx", "123", "+0x0007b" },
554 { "%+#08Qx", "-123", "-0x0007b" },
562 for (i = 0; i < numberof (data); i++)
564 mpq_set_str_or_abort (q, data[i].q, 0);
565 check_one (data[i].want, data[i].fmt, q);
574 static const struct {
581 { "%Ff", "0", "0.000000" },
582 { "%Ff", "123", "123.000000" },
583 { "%Ff", "-123", "-123.000000" },
585 { "%+Ff", "0", "+0.000000" },
586 { "%+Ff", "123", "+123.000000" },
587 { "%+Ff", "-123", "-123.000000" },
589 { "%.0Ff", "0", "0" },
590 { "%.0Ff", "123", "123" },
591 { "%.0Ff", "-123", "-123" },
593 { "%8.0Ff", "0", " 0" },
594 { "%8.0Ff", "123", " 123" },
595 { "%8.0Ff", "-123", " -123" },
597 { "%08.0Ff", "0", "00000000" },
598 { "%08.0Ff", "123", "00000123" },
599 { "%08.0Ff", "-123", "-0000123" },
601 { "%10.2Ff", "0", " 0.00" },
602 { "%10.2Ff", "0.25", " 0.25" },
603 { "%10.2Ff", "123.25", " 123.25" },
604 { "%10.2Ff", "-123.25", " -123.25" },
606 { "%-10.2Ff", "0", "0.00 " },
607 { "%-10.2Ff", "0.25", "0.25 " },
608 { "%-10.2Ff", "123.25", "123.25 " },
609 { "%-10.2Ff", "-123.25", "-123.25 " },
611 { "%.2Ff", "0.00000000000001", "0.00" },
612 { "%.2Ff", "0.002", "0.00" },
613 { "%.2Ff", "0.008", "0.01" },
615 { "%.0Ff", "123.00000000000001", "123" },
616 { "%.0Ff", "123.2", "123" },
617 { "%.0Ff", "123.8", "124" },
619 { "%.0Ff", "999999.9", "1000000" },
620 { "%.0Ff", "3999999.9", "4000000" },
622 { "%Fe", "0", "0.000000e+00" },
623 { "%Fe", "1", "1.000000e+00" },
624 { "%Fe", "123", "1.230000e+02" },
626 { "%FE", "0", "0.000000E+00" },
627 { "%FE", "1", "1.000000E+00" },
628 { "%FE", "123", "1.230000E+02" },
630 { "%Fe", "0", "0.000000e+00" },
631 { "%Fe", "1", "1.000000e+00" },
633 { "%.0Fe", "10000000000", "1e+10" },
634 { "%.0Fe", "-10000000000", "-1e+10" },
636 { "%.2Fe", "10000000000", "1.00e+10" },
637 { "%.2Fe", "-10000000000", "-1.00e+10" },
639 { "%8.0Fe", "10000000000", " 1e+10" },
640 { "%8.0Fe", "-10000000000", " -1e+10" },
642 { "%-8.0Fe", "10000000000", "1e+10 " },
643 { "%-8.0Fe", "-10000000000", "-1e+10 " },
645 { "%12.2Fe", "10000000000", " 1.00e+10" },
646 { "%12.2Fe", "-10000000000", " -1.00e+10" },
648 { "%012.2Fe", "10000000000", "00001.00e+10" },
649 { "%012.2Fe", "-10000000000", "-0001.00e+10" },
653 { "%Fg", "-1", "-1" },
655 { "%.0Fg", "0", "0" },
656 { "%.0Fg", "1", "1" },
657 { "%.0Fg", "-1", "-1" },
659 { "%.1Fg", "100", "1e+02" },
660 { "%.2Fg", "100", "1e+02" },
661 { "%.3Fg", "100", "100" },
662 { "%.4Fg", "100", "100" },
664 { "%Fg", "0.001", "0.001" },
665 { "%Fg", "0.0001", "0.0001" },
666 { "%Fg", "0.00001", "1e-05" },
667 { "%Fg", "0.000001", "1e-06" },
669 { "%.4Fg", "1.00000000000001", "1" },
670 { "%.4Fg", "100000000000001", "1e+14" },
672 { "%.4Fg", "12345678", "1.235e+07" },
674 { "%Fa", "0","0x0p+0" },
675 { "%FA", "0","0X0P+0" },
677 { "%Fa", "1","0x1p+0" },
678 { "%Fa", "65535","0xf.fffp+12" },
679 { "%Fa", "65536","0x1p+16" },
680 { "%F.10a", "65536","0x1.0000000000p+16" },
681 { "%F.1a", "65535","0x1.0p+16" },
682 { "%F.0a", "65535","0x1p+16" },
684 { "%.2Ff", "0.99609375", "1.00" },
685 { "%.Ff", "0.99609375", "0.99609375" },
686 { "%.Fe", "0.99609375", "9.9609375e-01" },
687 { "%.Fg", "0.99609375", "0.99609375" },
688 { "%.20Fg", "1000000", "1000000" },
689 { "%.Fg", "1000000", "1000000" },
691 { "%#.0Ff", "1", "1." },
692 { "%#.0Fe", "1", "1.e+00" },
693 { "%#.0Fg", "1", "1." },
695 { "%#.1Ff", "1", "1.0" },
696 { "%#.1Fe", "1", "1.0e+00" },
697 { "%#.1Fg", "1", "1." },
699 { "%#.4Ff", "1234", "1234.0000" },
700 { "%#.4Fe", "1234", "1.2340e+03" },
701 { "%#.4Fg", "1234", "1234." },
703 { "%#.8Ff", "1234", "1234.00000000" },
704 { "%#.8Fe", "1234", "1.23400000e+03" },
705 { "%#.8Fg", "1234", "1234.0000" },
715 for (i = 0; i < numberof (data); i++)
717 if (data[i].f[0] == '0' && data[i].f[1] == 'x')
718 mpf_set_str_or_abort (f, data[i].f, 16);
720 mpf_set_str_or_abort (f, data[i].f, 10);
722 /* if mpf->double doesn't truncate, then expect same result */
724 if (mpf_cmp_d (f, d) == 0)
725 check_plain (data[i].want, data[i].fmt, d);
727 check_one (data[i].want, data[i].fmt, f);
742 check_one ("0", "%Md", CNST_LIMB(0));
743 check_one ("1", "%Md", CNST_LIMB(1));
745 /* "i" many 1 bits, tested against mpz_get_str in decimal and hex */
747 mpz_init_set_ui (z, 1L);
748 for (i = 1; i <= GMP_LIMB_BITS; i++)
750 s = mpz_get_str (NULL, 10, z);
751 check_one (s, "%Mu", limb);
752 (*__gmp_free_func) (s, strlen (s) + 1);
754 s = mpz_get_str (NULL, 16, z);
755 check_one (s, "%Mx", limb);
756 (*__gmp_free_func) (s, strlen (s) + 1);
758 s = mpz_get_str (NULL, -16, z);
759 check_one (s, "%MX", limb);
760 (*__gmp_free_func) (s, strlen (s) + 1);
763 mpz_mul_2exp (z, z, 1L);
764 mpz_add_ui (z, z, 1L);
776 check_one ("blah", "%nblah", &n);
777 ASSERT_ALWAYS (n == 0);
782 check_one ("hello ", "hello %n", &n);
783 ASSERT_ALWAYS (n == 6);
788 check_one ("hello world", "hello %n world", &n);
789 ASSERT_ALWAYS (n == 6);
792 #define CHECK_N(type, string) \
799 sprintf (fmt, "%%d%%%sn%%d", string); \
800 check_one ("123456", fmt, 123, &x[0], 456); \
802 /* should write whole of x[0] and none of x[1] */ \
803 ASSERT_ALWAYS (x[0] == 3); \
804 ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \
808 CHECK_N (mp_limb_t, "M");
809 CHECK_N (char, "hh");
812 CHECK_N (long long, "L");
815 CHECK_N (intmax_t, "j");
818 CHECK_N (ptrdiff_t, "t");
820 CHECK_N (short, "h");
821 CHECK_N (size_t, "z");
825 mpz_init_set_si (x[0], -987L);
826 mpz_init_set_si (x[1], 654L);
827 check_one ("123456", "%d%Zn%d", 123, x[0], 456);
828 MPZ_CHECK_FORMAT (x[0]);
829 MPZ_CHECK_FORMAT (x[1]);
830 ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0);
831 ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0);
840 mpq_set_ui (x[0], 987L, 654L);
841 mpq_set_ui (x[1], 4115L, 226L);
842 check_one ("123456", "%d%Qn%d", 123, x[0], 456);
843 MPQ_CHECK_FORMAT (x[0]);
844 MPQ_CHECK_FORMAT (x[1]);
845 ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0);
846 ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0);
855 mpf_set_ui (x[0], 987L);
856 mpf_set_ui (x[1], 654L);
857 check_one ("123456", "%d%Fn%d", 123, x[0], 456);
858 MPF_CHECK_FORMAT (x[0]);
859 MPF_CHECK_FORMAT (x[1]);
860 ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0);
861 ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0);
868 mp_limb_t a_want[numberof(a)];
872 check_one ("blah", "bl%Nnah", a, (mp_size_t) 0);
873 ASSERT_ALWAYS (a[0] == 123);
875 MPN_ZERO (a_want, numberof (a_want));
876 for (i = 1; i < numberof (a); i++)
878 check_one ("blah", "bl%Nnah", a, i);
880 ASSERT_ALWAYS (mpn_cmp (a, a_want, i) == 0);
895 check_one ("!", "%c", '!');
897 check_one ("hello world", "hello %s", "world");
898 check_one ("hello:", "%s:", "hello");
900 check_one ("hello0", "%s%Zd", "hello", z, z);
904 memset (xs, 'x', sizeof(xs)-1);
905 check_one (xs, "%s", xs);
908 mpz_set_ui (z, 12345L);
909 check_one (" 12345", "%*Zd", 10, z);
910 check_one ("0000012345", "%0*Zd", 10, z);
911 check_one ("12345 ", "%*Zd", -10, z);
912 check_one ("12345 and 678", "%Zd and %d", z, 678);
913 check_one ("12345,1,12345,2,12345", "%Zd,%d,%Zd,%d,%Zd", z, 1, z, 2, z);
915 /* from the glibc info docs */
917 check_one ("| 0|0 | +0|+0 | 0|00000| | 00|0|",
918 "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
919 /**/ z, z, z, z, z, z, z, z, z);
921 check_one ("| 1|1 | +1|+1 | 1|00001| 1| 01|1|",
922 "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
923 /**/ z, z, z, z, z, z, z, z, z);
925 check_one ("| -1|-1 | -1|-1 | -1|-0001| -1| -01|-1|",
926 "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
927 /**/ z, z, z, z, z, z, z, z, z);
928 mpz_set_si (z, 100000L);
929 check_one ("|100000|100000|+100000|+100000| 100000|100000|100000|100000|100000|",
930 "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
931 /**/ z, z, z, z, z, z, z, z, z);
933 check_one ("| 0| 0| 0| 0| 0| 0| 00000000|",
934 "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
935 /**/ z, z, z, z, z, z, z);
937 check_one ("| 1| 1| 1| 01| 0x1| 0X1|0x00000001|",
938 "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
939 /**/ z, z, z, z, z, z, z);
940 mpz_set_si (z, 100000L);
941 check_one ("|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0|",
942 "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
943 /**/ z, z, z, z, z, z, z);
945 /* %zd for size_t won't be available on old systems, and running something
946 to see if it works might be bad, so only try it on glibc, and only on a
947 new enough version (glibc 2.0 doesn't have %zd) */
948 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)
949 mpz_set_ui (z, 789L);
950 check_one ("456 789 blah", "%zd %Zd blah", (size_t) 456, z);
959 main (int argc, char *argv[])
961 if (argc > 1 && strcmp (argv[1], "-s") == 0)
962 option_check_printf = 1;
965 check_vfprintf_fp = fopen (CHECK_VFPRINTF_FILENAME, "w+");
966 ASSERT_ALWAYS (check_vfprintf_fp != NULL);
975 ASSERT_ALWAYS (fclose (check_vfprintf_fp) == 0);
976 unlink (CHECK_VFPRINTF_FILENAME);