Annotation of OpenXM_contrib/gmp/tests/misc/t-printf.c, Revision 1.1
1.1 ! ohara 1: /* Test gmp_printf and related functions.
! 2:
! 3: Copyright 2001, 2002 Free Software Foundation, Inc.
! 4:
! 5: This file is part of the GNU MP Library.
! 6:
! 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 2.1 of the License, or (at your
! 10: option) any later version.
! 11:
! 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.
! 16:
! 17: You should have received a copy of the GNU Lesser General Public License
! 18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 20: MA 02111-1307, USA. */
! 21:
! 22:
! 23: /* Usage: t-printf [-s]
! 24:
! 25: -s Check the data against the system printf, where possible. This is
! 26: only an option since we don't want to fail if the system printf is
! 27: faulty or strange. */
! 28:
! 29:
! 30: #include "config.h"
! 31:
! 32: #if HAVE_STDARG
! 33: #include <stdarg.h>
! 34: #else
! 35: #include <varargs.h>
! 36: #endif
! 37:
! 38: #include <stddef.h> /* for ptrdiff_t */
! 39: #include <stdio.h>
! 40: #include <stdlib.h>
! 41: #include <string.h>
! 42:
! 43: #if HAVE_OBSTACK_VPRINTF
! 44: #define obstack_chunk_alloc tests_allocate
! 45: #define obstack_chunk_free tests_free_nosize
! 46: #include <obstack.h>
! 47: #endif
! 48:
! 49: #if HAVE_INTTYPES_H
! 50: # include <inttypes.h> /* for intmax_t */
! 51: #else
! 52: # if HAVE_STDINT_H
! 53: # include <stdint.h>
! 54: # endif
! 55: #endif
! 56:
! 57: #if HAVE_UNISTD_H
! 58: #include <unistd.h> /* for unlink */
! 59: #endif
! 60:
! 61: #include "gmp.h"
! 62: #include "gmp-impl.h"
! 63: #include "tests.h"
! 64:
! 65:
! 66: int option_check_printf = 0;
! 67:
! 68:
! 69: #define CHECK_VFPRINTF_FILENAME "t-printf.tmp"
! 70: FILE *check_vfprintf_fp;
! 71:
! 72:
! 73: /* From any of the tests run here. */
! 74: #define MAX_OUTPUT 1024
! 75:
! 76:
! 77: void
! 78: #if HAVE_STDARG
! 79: check_plain (const char *want, const char *fmt_orig, ...)
! 80: #else
! 81: check_plain (va_alist)
! 82: va_dcl
! 83: #endif
! 84: {
! 85: char got[MAX_OUTPUT];
! 86: int got_len, want_len;
! 87: size_t fmtsize;
! 88: char *fmt, *q;
! 89: const char *p;
! 90: va_list ap;
! 91: #if HAVE_STDARG
! 92: va_start (ap, fmt_orig);
! 93: #else
! 94: const char *want;
! 95: const char *fmt_orig;
! 96: va_start (ap);
! 97: want = va_arg (ap, const char *);
! 98: fmt_orig = va_arg (ap, const char *);
! 99: #endif
! 100:
! 101: if (! option_check_printf)
! 102: return;
! 103:
! 104: fmtsize = strlen (fmt_orig) + 1;
! 105: fmt = (*__gmp_allocate_func) (fmtsize);
! 106:
! 107: for (p = fmt_orig, q = fmt; *p != '\0'; p++)
! 108: {
! 109: switch (*p) {
! 110: case 'a':
! 111: case 'A':
! 112: /* The exact value of the exponent isn't guaranteed in glibc, and it
! 113: and gmp_printf do slightly different things, so don't compare
! 114: directly. */
! 115: goto done;
! 116: case 'F':
! 117: if (p > fmt_orig && *(p-1) == '.')
! 118: goto done; /* don't test the "all digits" cases */
! 119: /* discard 'F' type */
! 120: break;
! 121: case 'Z':
! 122: /* transmute */
! 123: *q++ = 'l';
! 124: break;
! 125: default:
! 126: *q++ = *p;
! 127: break;
! 128: }
! 129: }
! 130: *q = '\0';
! 131:
! 132: want_len = strlen (want);
! 133: ASSERT_ALWAYS (want_len < sizeof(got));
! 134:
! 135: got_len = vsprintf (got, fmt, ap);
! 136:
! 137: if (got_len != want_len || strcmp (got, want) != 0)
! 138: {
! 139: printf ("wanted data doesn't match plain vsprintf\n");
! 140: printf (" fmt |%s|\n", fmt);
! 141: printf (" got |%s|\n", got);
! 142: printf (" want |%s|\n", want);
! 143: printf (" got_len %d\n", got_len);
! 144: printf (" want_len %d\n", want_len);
! 145: abort ();
! 146: }
! 147:
! 148: done:
! 149: (*__gmp_free_func) (fmt, fmtsize);
! 150: }
! 151:
! 152: void
! 153: check_vsprintf (const char *want, const char *fmt, va_list ap)
! 154: {
! 155: char got[MAX_OUTPUT];
! 156: int got_len, want_len;
! 157:
! 158: want_len = strlen (want);
! 159: got_len = gmp_vsprintf (got, fmt, ap);
! 160:
! 161: if (got_len != want_len || strcmp (got, want) != 0)
! 162: {
! 163: printf ("gmp_vsprintf wrong\n");
! 164: printf (" fmt |%s|\n", fmt);
! 165: printf (" got |%s|\n", got);
! 166: printf (" want |%s|\n", want);
! 167: printf (" got_len %d\n", got_len);
! 168: printf (" want_len %d\n", want_len);
! 169: abort ();
! 170: }
! 171: }
! 172:
! 173: void
! 174: check_vfprintf (const char *want, const char *fmt, va_list ap)
! 175: {
! 176: char got[MAX_OUTPUT];
! 177: int got_len, want_len, fread_len;
! 178: long ftell_len;
! 179:
! 180: want_len = strlen (want);
! 181:
! 182: rewind (check_vfprintf_fp);
! 183: got_len = gmp_vfprintf (check_vfprintf_fp, fmt, ap);
! 184: ASSERT_ALWAYS (got_len != -1);
! 185: ASSERT_ALWAYS (fflush (check_vfprintf_fp) == 0);
! 186:
! 187: ftell_len = ftell (check_vfprintf_fp);
! 188: ASSERT_ALWAYS (ftell_len != -1);
! 189:
! 190: rewind (check_vfprintf_fp);
! 191: ASSERT_ALWAYS (ftell_len <= sizeof(got));
! 192: fread_len = fread (got, 1, ftell_len, check_vfprintf_fp);
! 193:
! 194: if (got_len != want_len
! 195: || ftell_len != want_len
! 196: || fread_len != want_len
! 197: || memcmp (got, want, want_len) != 0)
! 198: {
! 199: printf ("gmp_vfprintf wrong\n");
! 200: printf (" fmt |%s|\n", fmt);
! 201: printf (" got |%.*s|\n", fread_len, got);
! 202: printf (" want |%s|\n", want);
! 203: printf (" got_len %d\n", got_len);
! 204: printf (" ftell_len %ld\n", ftell_len);
! 205: printf (" fread_len %d\n", fread_len);
! 206: printf (" want_len %d\n", want_len);
! 207: abort ();
! 208: }
! 209: }
! 210:
! 211: void
! 212: check_vsnprintf (const char *want, const char *fmt, va_list ap)
! 213: {
! 214: char got[MAX_OUTPUT+1];
! 215: int ret, got_len, want_len;
! 216: size_t bufsize;
! 217:
! 218: want_len = strlen (want);
! 219:
! 220: bufsize = -1;
! 221: for (;;)
! 222: {
! 223: /* do 0 to 5, then want-5 to want+5 */
! 224: bufsize++;
! 225: if (bufsize > 5 && bufsize < want_len-5)
! 226: bufsize = want_len-5;
! 227: if (bufsize > want_len + 5)
! 228: break;
! 229: ASSERT_ALWAYS (bufsize+1 <= sizeof (got));
! 230:
! 231: got[bufsize] = '!';
! 232: ret = gmp_vsnprintf (got, bufsize, fmt, ap);
! 233:
! 234: got_len = MIN (MAX(1,bufsize)-1, want_len);
! 235:
! 236: if (got[bufsize] != '!')
! 237: {
! 238: printf ("gmp_vsnprintf overwrote bufsize sentinel\n");
! 239: goto error;
! 240: }
! 241:
! 242: if (ret != want_len)
! 243: {
! 244: printf ("gmp_vsnprintf return value wrong\n");
! 245: goto error;
! 246: }
! 247:
! 248: if (bufsize > 0)
! 249: {
! 250: if (memcmp (got, want, got_len) != 0 || got[got_len] != '\0')
! 251: {
! 252: printf ("gmp_vsnprintf wrong result string\n");
! 253: error:
! 254: printf (" fmt |%s|\n", fmt);
! 255: printf (" bufsize %u\n", bufsize);
! 256: printf (" got |%s|\n", got);
! 257: printf (" want |%.*s|\n", got_len, want);
! 258: printf (" want full |%s|\n", want);
! 259: printf (" ret %d\n", ret);
! 260: printf (" want_len %d\n", want_len);
! 261: abort ();
! 262: }
! 263: }
! 264: }
! 265: }
! 266:
! 267: void
! 268: check_vasprintf (const char *want, const char *fmt, va_list ap)
! 269: {
! 270: char *got;
! 271: int got_len, want_len;
! 272:
! 273: want_len = strlen (want);
! 274: got_len = gmp_vasprintf (&got, fmt, ap);
! 275:
! 276: if (got_len != want_len || strcmp (got, want) != 0)
! 277: {
! 278: printf ("gmp_vasprintf wrong\n");
! 279: printf (" fmt |%s|\n", fmt);
! 280: printf (" got |%s|\n", got);
! 281: printf (" want |%s|\n", want);
! 282: printf (" got_len %d\n", got_len);
! 283: printf (" want_len %d\n", want_len);
! 284: abort ();
! 285: }
! 286: (*__gmp_free_func) (got, strlen(got)+1);
! 287: }
! 288:
! 289: void
! 290: check_obstack_vprintf (const char *want, const char *fmt, va_list ap)
! 291: {
! 292: #if HAVE_OBSTACK_VPRINTF
! 293: struct obstack ob;
! 294: int got_len, want_len, ob_len;
! 295: char *got;
! 296:
! 297: want_len = strlen (want);
! 298:
! 299: obstack_init (&ob);
! 300: got_len = gmp_obstack_vprintf (&ob, fmt, ap);
! 301: got = obstack_base (&ob);
! 302: ob_len = obstack_object_size (&ob);
! 303:
! 304: if (got_len != want_len
! 305: || ob_len != want_len
! 306: || memcmp (got, want, want_len) != 0)
! 307: {
! 308: printf ("gmp_obstack_vprintf wrong\n");
! 309: printf (" fmt |%s|\n", fmt);
! 310: printf (" got |%s|\n", got);
! 311: printf (" want |%s|\n", want);
! 312: printf (" got_len %d\n", got_len);
! 313: printf (" ob_len %d\n", ob_len);
! 314: printf (" want_len %d\n", want_len);
! 315: abort ();
! 316: }
! 317: obstack_free (&ob, NULL);
! 318: #endif
! 319: }
! 320:
! 321:
! 322: void
! 323: #if HAVE_STDARG
! 324: check_one (const char *want, const char *fmt, ...)
! 325: #else
! 326: check_one (va_alist)
! 327: va_dcl
! 328: #endif
! 329: {
! 330: va_list ap;
! 331: #if HAVE_STDARG
! 332: va_start (ap, fmt);
! 333: #else
! 334: const char *want;
! 335: const char *fmt;
! 336: va_start (ap);
! 337: want = va_arg (ap, const char *);
! 338: fmt = va_arg (ap, const char *);
! 339: #endif
! 340:
! 341: /* simplest first */
! 342: check_vsprintf (want, fmt, ap);
! 343: check_vfprintf (want, fmt, ap);
! 344: check_vsnprintf (want, fmt, ap);
! 345: check_vasprintf (want, fmt, ap);
! 346: check_obstack_vprintf (want, fmt, ap);
! 347: }
! 348:
! 349:
! 350: #define hex_or_octal_p(fmt) \
! 351: (strchr (fmt, 'x') != NULL \
! 352: || strchr (fmt, 'X') != NULL \
! 353: || strchr (fmt, 'o') != NULL)
! 354:
! 355: void
! 356: check_z (void)
! 357: {
! 358: static const struct {
! 359: const char *fmt;
! 360: const char *z;
! 361: const char *want;
! 362: } data[] = {
! 363: { "%Zd", "0", "0" },
! 364: { "%Zd", "1", "1" },
! 365: { "%Zd", "123", "123" },
! 366: { "%Zd", "-1", "-1" },
! 367: { "%Zd", "-123", "-123" },
! 368:
! 369: { "%+Zd", "0", "+0" },
! 370: { "%+Zd", "123", "+123" },
! 371: { "%+Zd", "-123", "-123" },
! 372:
! 373: { "%Zx", "123", "7b" },
! 374: { "%ZX", "123", "7B" },
! 375: { "%Zx", "-123", "-7b" },
! 376: { "%ZX", "-123", "-7B" },
! 377: { "%Zo", "123", "173" },
! 378: { "%Zo", "-123", "-173" },
! 379:
! 380: { "%#Zx", "0", "0" },
! 381: { "%#ZX", "0", "0" },
! 382: { "%#Zx", "123", "0x7b" },
! 383: { "%#ZX", "123", "0X7B" },
! 384: { "%#Zx", "-123", "-0x7b" },
! 385: { "%#ZX", "-123", "-0X7B" },
! 386:
! 387: { "%#Zo", "0", "0" },
! 388: { "%#Zo", "123", "0173" },
! 389: { "%#Zo", "-123", "-0173" },
! 390:
! 391: { "%10Zd", "0", " 0" },
! 392: { "%10Zd", "123", " 123" },
! 393: { "%10Zd", "-123", " -123" },
! 394:
! 395: { "%-10Zd", "0", "0 " },
! 396: { "%-10Zd", "123", "123 " },
! 397: { "%-10Zd", "-123", "-123 " },
! 398:
! 399: { "%+10Zd", "123", " +123" },
! 400: { "%+-10Zd", "123", "+123 " },
! 401: { "%+10Zd", "-123", " -123" },
! 402: { "%+-10Zd", "-123", "-123 " },
! 403:
! 404: { "%08Zd", "0", "00000000" },
! 405: { "%08Zd", "123", "00000123" },
! 406: { "%08Zd", "-123", "-0000123" },
! 407:
! 408: { "%+08Zd", "0", "+0000000" },
! 409: { "%+08Zd", "123", "+0000123" },
! 410: { "%+08Zd", "-123", "-0000123" },
! 411:
! 412: { "%#08Zx", "0", "00000000" },
! 413: { "%#08Zx", "123", "0x00007b" },
! 414: { "%#08Zx", "-123", "-0x0007b" },
! 415:
! 416: { "%+#08Zx", "0", "+0000000" },
! 417: { "%+#08Zx", "123", "+0x0007b" },
! 418: { "%+#08Zx", "-123", "-0x0007b" },
! 419:
! 420: { "%.0Zd", "0", "" },
! 421: { "%.1Zd", "0", "0" },
! 422: { "%.2Zd", "0", "00" },
! 423: { "%.3Zd", "0", "000" },
! 424: };
! 425:
! 426: int i, j, zeros;
! 427: mpz_t z;
! 428: char *nfmt;
! 429: mp_size_t nsize;
! 430:
! 431: mpz_init (z);
! 432:
! 433: for (i = 0; i < numberof (data); i++)
! 434: {
! 435: mpz_set_str_or_abort (z, data[i].z, 0);
! 436:
! 437: /* don't try negatives or forced sign in hex or octal */
! 438: if (mpz_fits_slong_p (z)
! 439: && ! (hex_or_octal_p (data[i].fmt)
! 440: && (strchr (data[i].fmt, '+') != NULL || mpz_sgn(z) < 0)))
! 441: {
! 442: check_plain (data[i].want, data[i].fmt, mpz_get_si (z));
! 443: }
! 444:
! 445: check_one (data[i].want, data[i].fmt, z);
! 446:
! 447: /* Same again, with %N and possibly some high zero limbs */
! 448: nfmt = __gmp_allocate_strdup (data[i].fmt);
! 449: for (j = 0; nfmt[j] != '\0'; j++)
! 450: if (nfmt[j] == 'Z')
! 451: nfmt[j] = 'N';
! 452: for (zeros = 0; zeros <= 3; zeros++)
! 453: {
! 454: nsize = ABSIZ(z)+zeros;
! 455: MPZ_REALLOC (z, nsize);
! 456: nsize = (SIZ(z) >= 0 ? nsize : -nsize);
! 457: refmpn_zero (PTR(z)+ABSIZ(z), zeros);
! 458: check_one (data[i].want, nfmt, PTR(z), nsize);
! 459: }
! 460: __gmp_free_func (nfmt, strlen(nfmt)+1);
! 461: }
! 462:
! 463: mpz_clear (z);
! 464: }
! 465:
! 466: void
! 467: check_q (void)
! 468: {
! 469: static const struct {
! 470: const char *fmt;
! 471: const char *q;
! 472: const char *want;
! 473: } data[] = {
! 474: { "%Qd", "0", "0" },
! 475: { "%Qd", "1", "1" },
! 476: { "%Qd", "123", "123" },
! 477: { "%Qd", "-1", "-1" },
! 478: { "%Qd", "-123", "-123" },
! 479: { "%Qd", "3/2", "3/2" },
! 480: { "%Qd", "-3/2", "-3/2" },
! 481:
! 482: { "%+Qd", "0", "+0" },
! 483: { "%+Qd", "123", "+123" },
! 484: { "%+Qd", "-123", "-123" },
! 485: { "%+Qd", "5/8", "+5/8" },
! 486: { "%+Qd", "-5/8", "-5/8" },
! 487:
! 488: { "%Qx", "123", "7b" },
! 489: { "%QX", "123", "7B" },
! 490: { "%Qx", "15/16", "f/10" },
! 491: { "%QX", "15/16", "F/10" },
! 492: { "%Qx", "-123", "-7b" },
! 493: { "%QX", "-123", "-7B" },
! 494: { "%Qx", "-15/16", "-f/10" },
! 495: { "%QX", "-15/16", "-F/10" },
! 496: { "%Qo", "123", "173" },
! 497: { "%Qo", "-123", "-173" },
! 498: { "%Qo", "16/17", "20/21" },
! 499: { "%Qo", "-16/17", "-20/21" },
! 500:
! 501: { "%#Qx", "0", "0" },
! 502: { "%#QX", "0", "0" },
! 503: { "%#Qx", "123", "0x7b" },
! 504: { "%#QX", "123", "0X7B" },
! 505: { "%#Qx", "5/8", "0x5/0x8" },
! 506: { "%#QX", "5/8", "0X5/0X8" },
! 507: { "%#Qx", "-123", "-0x7b" },
! 508: { "%#QX", "-123", "-0X7B" },
! 509: { "%#Qx", "-5/8", "-0x5/0x8" },
! 510: { "%#QX", "-5/8", "-0X5/0X8" },
! 511: { "%#Qo", "0", "0" },
! 512: { "%#Qo", "123", "0173" },
! 513: { "%#Qo", "-123", "-0173" },
! 514: { "%#Qo", "5/7", "05/07" },
! 515: { "%#Qo", "-5/7", "-05/07" },
! 516:
! 517: /* zero denominator and showbase */
! 518: { "%#10Qo", "0/0", " 0/0" },
! 519: { "%#10Qd", "0/0", " 0/0" },
! 520: { "%#10Qx", "0/0", " 0/0" },
! 521: { "%#10Qo", "123/0", " 0173/0" },
! 522: { "%#10Qd", "123/0", " 123/0" },
! 523: { "%#10Qx", "123/0", " 0x7b/0" },
! 524: { "%#10QX", "123/0", " 0X7B/0" },
! 525: { "%#10Qo", "-123/0", " -0173/0" },
! 526: { "%#10Qd", "-123/0", " -123/0" },
! 527: { "%#10Qx", "-123/0", " -0x7b/0" },
! 528: { "%#10QX", "-123/0", " -0X7B/0" },
! 529:
! 530: { "%10Qd", "0", " 0" },
! 531: { "%-10Qd", "0", "0 " },
! 532: { "%10Qd", "123", " 123" },
! 533: { "%-10Qd", "123", "123 " },
! 534: { "%10Qd", "-123", " -123" },
! 535: { "%-10Qd", "-123", "-123 " },
! 536:
! 537: { "%+10Qd", "123", " +123" },
! 538: { "%+-10Qd", "123", "+123 " },
! 539: { "%+10Qd", "-123", " -123" },
! 540: { "%+-10Qd", "-123", "-123 " },
! 541:
! 542: { "%08Qd", "0", "00000000" },
! 543: { "%08Qd", "123", "00000123" },
! 544: { "%08Qd", "-123", "-0000123" },
! 545:
! 546: { "%+08Qd", "0", "+0000000" },
! 547: { "%+08Qd", "123", "+0000123" },
! 548: { "%+08Qd", "-123", "-0000123" },
! 549:
! 550: { "%#08Qx", "0", "00000000" },
! 551: { "%#08Qx", "123", "0x00007b" },
! 552: { "%#08Qx", "-123", "-0x0007b" },
! 553:
! 554: { "%+#08Qx", "0", "+0000000" },
! 555: { "%+#08Qx", "123", "+0x0007b" },
! 556: { "%+#08Qx", "-123", "-0x0007b" },
! 557: };
! 558:
! 559: int i;
! 560: mpq_t q;
! 561:
! 562: mpq_init (q);
! 563:
! 564: for (i = 0; i < numberof (data); i++)
! 565: {
! 566: mpq_set_str_or_abort (q, data[i].q, 0);
! 567: check_one (data[i].want, data[i].fmt, q);
! 568: }
! 569:
! 570: mpq_clear (q);
! 571: }
! 572:
! 573: void
! 574: check_f (void)
! 575: {
! 576: static const struct {
! 577: const char *fmt;
! 578: const char *f;
! 579: const char *want;
! 580:
! 581: } data[] = {
! 582:
! 583: { "%Ff", "0", "0.000000" },
! 584: { "%Ff", "123", "123.000000" },
! 585: { "%Ff", "-123", "-123.000000" },
! 586:
! 587: { "%+Ff", "0", "+0.000000" },
! 588: { "%+Ff", "123", "+123.000000" },
! 589: { "%+Ff", "-123", "-123.000000" },
! 590:
! 591: { "%.0Ff", "0", "0" },
! 592: { "%.0Ff", "123", "123" },
! 593: { "%.0Ff", "-123", "-123" },
! 594:
! 595: { "%8.0Ff", "0", " 0" },
! 596: { "%8.0Ff", "123", " 123" },
! 597: { "%8.0Ff", "-123", " -123" },
! 598:
! 599: { "%08.0Ff", "0", "00000000" },
! 600: { "%08.0Ff", "123", "00000123" },
! 601: { "%08.0Ff", "-123", "-0000123" },
! 602:
! 603: { "%10.2Ff", "0", " 0.00" },
! 604: { "%10.2Ff", "0.25", " 0.25" },
! 605: { "%10.2Ff", "123.25", " 123.25" },
! 606: { "%10.2Ff", "-123.25", " -123.25" },
! 607:
! 608: { "%-10.2Ff", "0", "0.00 " },
! 609: { "%-10.2Ff", "0.25", "0.25 " },
! 610: { "%-10.2Ff", "123.25", "123.25 " },
! 611: { "%-10.2Ff", "-123.25", "-123.25 " },
! 612:
! 613: { "%.2Ff", "0.00000000000001", "0.00" },
! 614: { "%.2Ff", "0.002", "0.00" },
! 615: { "%.2Ff", "0.008", "0.01" },
! 616:
! 617: { "%.0Ff", "123.00000000000001", "123" },
! 618: { "%.0Ff", "123.2", "123" },
! 619: { "%.0Ff", "123.8", "124" },
! 620:
! 621: { "%.0Ff", "999999.9", "1000000" },
! 622: { "%.0Ff", "3999999.9", "4000000" },
! 623:
! 624: { "%Fe", "0", "0.000000e+00" },
! 625: { "%Fe", "1", "1.000000e+00" },
! 626: { "%Fe", "123", "1.230000e+02" },
! 627:
! 628: { "%FE", "0", "0.000000E+00" },
! 629: { "%FE", "1", "1.000000E+00" },
! 630: { "%FE", "123", "1.230000E+02" },
! 631:
! 632: { "%Fe", "0", "0.000000e+00" },
! 633: { "%Fe", "1", "1.000000e+00" },
! 634:
! 635: { "%.0Fe", "10000000000", "1e+10" },
! 636: { "%.0Fe", "-10000000000", "-1e+10" },
! 637:
! 638: { "%.2Fe", "10000000000", "1.00e+10" },
! 639: { "%.2Fe", "-10000000000", "-1.00e+10" },
! 640:
! 641: { "%8.0Fe", "10000000000", " 1e+10" },
! 642: { "%8.0Fe", "-10000000000", " -1e+10" },
! 643:
! 644: { "%-8.0Fe", "10000000000", "1e+10 " },
! 645: { "%-8.0Fe", "-10000000000", "-1e+10 " },
! 646:
! 647: { "%12.2Fe", "10000000000", " 1.00e+10" },
! 648: { "%12.2Fe", "-10000000000", " -1.00e+10" },
! 649:
! 650: { "%012.2Fe", "10000000000", "00001.00e+10" },
! 651: { "%012.2Fe", "-10000000000", "-0001.00e+10" },
! 652:
! 653: { "%Fg", "0", "0" },
! 654: { "%Fg", "1", "1" },
! 655: { "%Fg", "-1", "-1" },
! 656:
! 657: { "%.0Fg", "0", "0" },
! 658: { "%.0Fg", "1", "1" },
! 659: { "%.0Fg", "-1", "-1" },
! 660:
! 661: { "%.1Fg", "100", "1e+02" },
! 662: { "%.2Fg", "100", "1e+02" },
! 663: { "%.3Fg", "100", "100" },
! 664: { "%.4Fg", "100", "100" },
! 665:
! 666: { "%Fg", "0.001", "0.001" },
! 667: { "%Fg", "0.0001", "0.0001" },
! 668: { "%Fg", "0.00001", "1e-05" },
! 669: { "%Fg", "0.000001", "1e-06" },
! 670:
! 671: { "%.4Fg", "1.00000000000001", "1" },
! 672: { "%.4Fg", "100000000000001", "1e+14" },
! 673:
! 674: { "%.4Fg", "12345678", "1.235e+07" },
! 675:
! 676: { "%Fa", "0","0x0p+0" },
! 677: { "%FA", "0","0X0P+0" },
! 678:
! 679: { "%Fa", "1","0x1p+0" },
! 680: { "%Fa", "65535","0xf.fffp+12" },
! 681: { "%Fa", "65536","0x1p+16" },
! 682: { "%F.10a", "65536","0x1.0000000000p+16" },
! 683: { "%F.1a", "65535","0x1.0p+16" },
! 684: { "%F.0a", "65535","0x1p+16" },
! 685:
! 686: { "%.2Ff", "0.99609375", "1.00" },
! 687: { "%.Ff", "0.99609375", "0.99609375" },
! 688: { "%.Fe", "0.99609375", "9.9609375e-01" },
! 689: { "%.Fg", "0.99609375", "0.99609375" },
! 690: { "%.20Fg", "1000000", "1000000" },
! 691: { "%.Fg", "1000000", "1000000" },
! 692:
! 693: { "%#.0Ff", "1", "1." },
! 694: { "%#.0Fe", "1", "1.e+00" },
! 695: { "%#.0Fg", "1", "1." },
! 696:
! 697: { "%#.1Ff", "1", "1.0" },
! 698: { "%#.1Fe", "1", "1.0e+00" },
! 699: { "%#.1Fg", "1", "1." },
! 700:
! 701: { "%#.4Ff", "1234", "1234.0000" },
! 702: { "%#.4Fe", "1234", "1.2340e+03" },
! 703: { "%#.4Fg", "1234", "1234." },
! 704:
! 705: { "%#.8Ff", "1234", "1234.00000000" },
! 706: { "%#.8Fe", "1234", "1.23400000e+03" },
! 707: { "%#.8Fg", "1234", "1234.0000" },
! 708:
! 709: };
! 710:
! 711: int i;
! 712: mpf_t f;
! 713: double d;
! 714:
! 715: mpf_init2 (f, 256L);
! 716:
! 717: for (i = 0; i < numberof (data); i++)
! 718: {
! 719: if (data[i].f[0] == '0' && data[i].f[1] == 'x')
! 720: mpf_set_str_or_abort (f, data[i].f, 16);
! 721: else
! 722: mpf_set_str_or_abort (f, data[i].f, 10);
! 723:
! 724: /* if mpf->double doesn't truncate, then expect same result */
! 725: d = mpf_get_d (f);
! 726: if (mpf_cmp_d (f, d) == 0)
! 727: check_plain (data[i].want, data[i].fmt, d);
! 728:
! 729: check_one (data[i].want, data[i].fmt, f);
! 730: }
! 731:
! 732: mpf_clear (f);
! 733: }
! 734:
! 735:
! 736: void
! 737: check_n (void)
! 738: {
! 739: {
! 740: int n = -1;
! 741: check_one ("blah", "%nblah", &n);
! 742: ASSERT_ALWAYS (n == 0);
! 743: }
! 744:
! 745: {
! 746: int n = -1;
! 747: check_one ("hello ", "hello %n", &n);
! 748: ASSERT_ALWAYS (n == 6);
! 749: }
! 750:
! 751: {
! 752: int n = -1;
! 753: check_one ("hello world", "hello %n world", &n);
! 754: ASSERT_ALWAYS (n == 6);
! 755: }
! 756:
! 757: #define CHECK_N(type, string) \
! 758: do { \
! 759: type x[2]; \
! 760: char fmt[128]; \
! 761: \
! 762: x[0] = ~ (type) 0; \
! 763: x[1] = ~ (type) 0; \
! 764: sprintf (fmt, "%%d%%%sn%%d", string); \
! 765: check_one ("123456", fmt, 123, &x[0], 456); \
! 766: \
! 767: /* should write whole of x[0] and none of x[1] */ \
! 768: ASSERT_ALWAYS (x[0] == 3); \
! 769: ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \
! 770: \
! 771: } while (0)
! 772:
! 773: CHECK_N (char, "hh");
! 774: CHECK_N (long, "l");
! 775: #if HAVE_LONG_LONG
! 776: CHECK_N (long long, "L");
! 777: #endif
! 778: #if HAVE_INTMAX_T
! 779: CHECK_N (intmax_t, "j");
! 780: #endif
! 781: #if HAVE_PTRDIFF_T
! 782: CHECK_N (ptrdiff_t, "t");
! 783: #endif
! 784: CHECK_N (short, "h");
! 785: CHECK_N (size_t, "z");
! 786:
! 787: {
! 788: mpz_t x[2];
! 789: mpz_init_set_si (x[0], -987L);
! 790: mpz_init_set_si (x[1], 654L);
! 791: check_one ("123456", "%d%Zn%d", 123, x[0], 456);
! 792: MPZ_CHECK_FORMAT (x[0]);
! 793: MPZ_CHECK_FORMAT (x[1]);
! 794: ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0);
! 795: ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0);
! 796: mpz_clear (x[0]);
! 797: mpz_clear (x[1]);
! 798: }
! 799:
! 800: {
! 801: mpq_t x[2];
! 802: mpq_init (x[0]);
! 803: mpq_init (x[1]);
! 804: mpq_set_ui (x[0], -987L, 654L);
! 805: mpq_set_ui (x[1], 4115L, 226L);
! 806: check_one ("123456", "%d%Qn%d", 123, x[0], 456);
! 807: MPQ_CHECK_FORMAT (x[0]);
! 808: MPQ_CHECK_FORMAT (x[1]);
! 809: ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0);
! 810: ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0);
! 811: mpq_clear (x[0]);
! 812: mpq_clear (x[1]);
! 813: }
! 814:
! 815: {
! 816: mpf_t x[2];
! 817: mpf_init (x[0]);
! 818: mpf_init (x[1]);
! 819: mpf_set_ui (x[0], -987L);
! 820: mpf_set_ui (x[1], 654L);
! 821: check_one ("123456", "%d%Fn%d", 123, x[0], 456);
! 822: MPF_CHECK_FORMAT (x[0]);
! 823: MPF_CHECK_FORMAT (x[1]);
! 824: ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0);
! 825: ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0);
! 826: mpf_clear (x[0]);
! 827: mpf_clear (x[1]);
! 828: }
! 829:
! 830: {
! 831: mp_limb_t a[5];
! 832: mp_limb_t a_want[numberof(a)];
! 833: mp_size_t i;
! 834:
! 835: a[0] = 123;
! 836: check_one ("blah", "bl%Nnah", a, (mp_size_t) 0);
! 837: ASSERT_ALWAYS (a[0] == 123);
! 838:
! 839: MPN_ZERO (a_want, numberof (a_want));
! 840: for (i = 1; i < numberof (a); i++)
! 841: {
! 842: check_one ("blah", "bl%Nnah", a, i);
! 843: a_want[0] = 2;
! 844: ASSERT_ALWAYS (mpn_cmp (a, a_want, i) == 0);
! 845: }
! 846: }
! 847: }
! 848:
! 849:
! 850: void
! 851: check_misc (void)
! 852: {
! 853: mpz_t z;
! 854: mpf_t f;
! 855:
! 856: mpz_init (z);
! 857: mpf_init2 (f, 128L);
! 858:
! 859: check_one ("!", "%c", '!');
! 860:
! 861: check_one ("hello world", "hello %s", "world");
! 862: check_one ("hello:", "%s:", "hello");
! 863: mpz_set_ui (z, 0L);
! 864: check_one ("hello0", "%s%Zd", "hello", z, z);
! 865:
! 866: {
! 867: static char xs[801];
! 868: memset (xs, 'x', sizeof(xs)-1);
! 869: check_one (xs, "%s", xs);
! 870: }
! 871:
! 872: mpz_set_ui (z, 12345L);
! 873: check_one (" 12345", "%*Zd", 10, z);
! 874: check_one ("0000012345", "%0*Zd", 10, z);
! 875: check_one ("12345 ", "%*Zd", -10, z);
! 876: check_one ("12345 and 678", "%Zd and %d", z, 678);
! 877: check_one ("12345,1,12345,2,12345", "%Zd,%d,%Zd,%d,%Zd", z, 1, z, 2, z);
! 878:
! 879: /* from the glibc info docs */
! 880: mpz_set_si (z, 0L);
! 881: check_one ("| 0|0 | +0|+0 | 0|00000| | 00|0|",
! 882: "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
! 883: /**/ z, z, z, z, z, z, z, z, z);
! 884: mpz_set_si (z, 1L);
! 885: check_one ("| 1|1 | +1|+1 | 1|00001| 1| 01|1|",
! 886: "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
! 887: /**/ z, z, z, z, z, z, z, z, z);
! 888: mpz_set_si (z, -1L);
! 889: check_one ("| -1|-1 | -1|-1 | -1|-0001| -1| -01|-1|",
! 890: "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
! 891: /**/ z, z, z, z, z, z, z, z, z);
! 892: mpz_set_si (z, 100000L);
! 893: check_one ("|100000|100000|+100000|+100000| 100000|100000|100000|100000|100000|",
! 894: "|%5Zd|%-5Zd|%+5Zd|%+-5Zd|% 5Zd|%05Zd|%5.0Zd|%5.2Zd|%Zd|",
! 895: /**/ z, z, z, z, z, z, z, z, z);
! 896: mpz_set_si (z, 0L);
! 897: check_one ("| 0| 0| 0| 0| 0| 0| 00000000|",
! 898: "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
! 899: /**/ z, z, z, z, z, z, z);
! 900: mpz_set_si (z, 1L);
! 901: check_one ("| 1| 1| 1| 01| 0x1| 0X1|0x00000001|",
! 902: "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
! 903: /**/ z, z, z, z, z, z, z);
! 904: mpz_set_si (z, 100000L);
! 905: check_one ("|303240|186a0|186A0|0303240|0x186a0|0X186A0|0x000186a0|",
! 906: "|%5Zo|%5Zx|%5ZX|%#5Zo|%#5Zx|%#5ZX|%#10.8Zx|",
! 907: /**/ z, z, z, z, z, z, z);
! 908:
! 909: /* %zd for size_t won't be available on old systems, and running something
! 910: to see if it works might be bad, so only try it on glibc, and only on a
! 911: new enough version (glibc 2.0 doesn't have %zd) */
! 912: #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)
! 913: mpz_set_ui (z, 789L);
! 914: check_one ("456 789 blah", "%zd %Zd blah", (size_t) 456, z);
! 915: #endif
! 916:
! 917: mpz_clear (z);
! 918: mpf_clear (f);
! 919: }
! 920:
! 921:
! 922: int
! 923: main (int argc, char *argv[])
! 924: {
! 925: if (argc > 1 && strcmp (argv[1], "-s") == 0)
! 926: option_check_printf = 1;
! 927:
! 928: tests_start ();
! 929: check_vfprintf_fp = fopen (CHECK_VFPRINTF_FILENAME, "w+");
! 930: ASSERT_ALWAYS (check_vfprintf_fp != NULL);
! 931:
! 932: check_z ();
! 933: check_q ();
! 934: check_f ();
! 935: check_n ();
! 936: check_misc ();
! 937:
! 938: ASSERT_ALWAYS (fclose (check_vfprintf_fp) == 0);
! 939: unlink (CHECK_VFPRINTF_FILENAME);
! 940: tests_end ();
! 941: exit (0);
! 942: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>