aboutsummaryrefslogtreecommitdiff
path: root/gmp-6.3.0/tests/mpz/t-io_raw.c
diff options
context:
space:
mode:
authorDuncan Wilkie <antigravityd@gmail.com>2023-11-18 06:11:09 -0600
committerDuncan Wilkie <antigravityd@gmail.com>2023-11-18 06:11:09 -0600
commit11da511c784eca003deb90c23570f0873954e0de (patch)
treee14fdd3d5d6345956d67e79ae771d0633d28362b /gmp-6.3.0/tests/mpz/t-io_raw.c
Initial commit.
Diffstat (limited to 'gmp-6.3.0/tests/mpz/t-io_raw.c')
-rw-r--r--gmp-6.3.0/tests/mpz/t-io_raw.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/gmp-6.3.0/tests/mpz/t-io_raw.c b/gmp-6.3.0/tests/mpz/t-io_raw.c
new file mode 100644
index 0000000..e299b5a
--- /dev/null
+++ b/gmp-6.3.0/tests/mpz/t-io_raw.c
@@ -0,0 +1,286 @@
+/* Test mpz_inp_raw and mpz_out_raw.
+
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gmp-impl.h"
+#include "tests.h"
+
+#define FILENAME "t-io_raw.tmp"
+
+
+/* In the fopen, "b" selects binary mode on DOS systems, meaning no
+ conversion of '\n' to and from CRLF. It's believed systems without such
+ nonsense will simply ignore the "b", but in case that's not so a plain
+ "w+" is attempted if "w+b" fails. */
+
+FILE *
+fopen_wplusb_or_die (const char *filename)
+{
+ FILE *fp;
+ fp = fopen (filename, "w+b");
+ if (fp == NULL)
+ fp = fopen (filename, "w+");
+
+ if (fp == NULL)
+ {
+ printf ("Cannot create file %s\n", filename);
+ abort ();
+ }
+ return fp;
+}
+
+/* use 0x80 to check nothing bad happens with sign extension etc */
+#define BYTEVAL(i) (((i) + 1) | 0x80)
+
+void
+check_in (void)
+{
+ int i, j, zeros, neg, error = 0;
+ mpz_t want, got;
+ size_t want_ret, got_ret;
+ mp_size_t size;
+ FILE *fp;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ for (i = 0; i < 32; i++)
+ {
+ for (zeros = 0; zeros < 8; zeros++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ want_ret = i + zeros + 4;
+
+ /* need this to get the twos complement right */
+ ASSERT_ALWAYS (sizeof (size) >= 4);
+
+ size = i + zeros;
+ if (neg)
+ size = -size;
+
+ fp = fopen_wplusb_or_die (FILENAME);
+ for (j = 3; j >= 0; j--)
+ ASSERT_ALWAYS (putc ((size >> (j*8)) & 0xFF, fp) != EOF);
+ for (j = 0; j < zeros; j++)
+ ASSERT_ALWAYS (putc ('\0', fp) != EOF);
+ for (j = 0; j < i; j++)
+ ASSERT_ALWAYS (putc (BYTEVAL (j), fp) != EOF);
+ /* and some trailing garbage */
+ ASSERT_ALWAYS (putc ('x', fp) != EOF);
+ ASSERT_ALWAYS (putc ('y', fp) != EOF);
+ ASSERT_ALWAYS (putc ('z', fp) != EOF);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+
+ got_ret = mpz_inp_raw (got, fp);
+ ASSERT_ALWAYS (! ferror(fp));
+ ASSERT_ALWAYS (fclose (fp) == 0);
+
+ MPZ_CHECK_FORMAT (got);
+
+ if (got_ret != want_ret)
+ {
+ printf ("check_in: return value wrong\n");
+ error = 1;
+ }
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("check_in: result wrong\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" i=%d zeros=%d neg=%d\n", i, zeros, neg);
+ printf (" got_ret %lu\n", (unsigned long) got_ret);
+ printf (" want_ret %lu\n", (unsigned long) want_ret);
+ mpz_trace (" got ", got);
+ mpz_trace (" want ", want);
+ abort ();
+ }
+
+ mpz_neg (want, want);
+ }
+ }
+ mpz_mul_2exp (want, want, 8);
+ mpz_add_ui (want, want, (unsigned long) BYTEVAL (i));
+ }
+
+ mpz_clear (want);
+ mpz_clear (got);
+}
+
+
+void
+check_out (void)
+{
+ int i, j, neg, error = 0;
+ mpz_t z;
+ char want[256], got[256], *p;
+ size_t want_len, got_ret, got_read;
+ mp_size_t size;
+ FILE *fp;
+
+ mpz_init (z);
+
+ for (i = 0; i < 32; i++)
+ {
+ for (neg = 0; neg <= 1; neg++)
+ {
+ want_len = i + 4;
+
+ /* need this to get the twos complement right */
+ ASSERT_ALWAYS (sizeof (size) >= 4);
+
+ size = i;
+ if (neg)
+ size = -size;
+
+ p = want;
+ for (j = 3; j >= 0; j--)
+ *p++ = size >> (j*8);
+ for (j = 0; j < i; j++)
+ *p++ = BYTEVAL (j);
+ ASSERT_ALWAYS (p <= want + sizeof (want));
+
+ fp = fopen_wplusb_or_die (FILENAME);
+ got_ret = mpz_out_raw (fp, z);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+ got_read = fread (got, 1, sizeof(got), fp);
+ ASSERT_ALWAYS (! ferror(fp));
+ ASSERT_ALWAYS (fclose (fp) == 0);
+
+ if (got_ret != want_len)
+ {
+ printf ("check_out: wrong return value\n");
+ error = 1;
+ }
+ if (got_read != want_len)
+ {
+ printf ("check_out: wrong number of bytes read back\n");
+ error = 1;
+ }
+ if (memcmp (want, got, want_len) != 0)
+ {
+ printf ("check_out: wrong data\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" i=%d neg=%d\n", i, neg);
+ mpz_trace (" z", z);
+ printf (" got_ret %lu\n", (unsigned long) got_ret);
+ printf (" got_read %lu\n", (unsigned long) got_read);
+ printf (" want_len %lu\n", (unsigned long) want_len);
+ printf (" want");
+ for (j = 0; j < want_len; j++)
+ printf (" %02X", (unsigned) (unsigned char) want[j]);
+ printf ("\n");
+ printf (" got ");
+ for (j = 0; j < want_len; j++)
+ printf (" %02X", (unsigned) (unsigned char) got[j]);
+ printf ("\n");
+ abort ();
+ }
+
+ mpz_neg (z, z);
+ }
+ mpz_mul_2exp (z, z, 8);
+ mpz_add_ui (z, z, (unsigned long) BYTEVAL (i));
+ }
+
+ mpz_clear (z);
+}
+
+
+void
+check_rand (void)
+{
+ gmp_randstate_ptr rands = RANDS;
+ int i, error = 0;
+ mpz_t got, want;
+ size_t inp_ret, out_ret;
+ FILE *fp;
+
+ mpz_init (want);
+ mpz_init (got);
+
+ for (i = 0; i < 500; i++)
+ {
+ mpz_erandomb (want, rands, 10*GMP_LIMB_BITS);
+ mpz_negrandom (want, rands);
+
+ fp = fopen_wplusb_or_die (FILENAME);
+ out_ret = mpz_out_raw (fp, want);
+ ASSERT_ALWAYS (fflush (fp) == 0);
+ rewind (fp);
+ inp_ret = mpz_inp_raw (got, fp);
+ ASSERT_ALWAYS (fclose (fp) == 0);
+
+ MPZ_CHECK_FORMAT (got);
+
+ if (inp_ret != out_ret)
+ {
+ printf ("check_rand: different inp/out return values\n");
+ error = 1;
+ }
+ if (mpz_cmp (got, want) != 0)
+ {
+ printf ("check_rand: wrong result\n");
+ error = 1;
+ }
+ if (error)
+ {
+ printf (" out_ret %lu\n", (unsigned long) out_ret);
+ printf (" inp_ret %lu\n", (unsigned long) inp_ret);
+ mpz_trace (" want", want);
+ mpz_trace (" got ", got);
+ abort ();
+ }
+ }
+
+ mpz_clear (got);
+ mpz_clear (want);
+}
+
+
+int
+main (void)
+{
+ tests_start ();
+ mp_trace_base = -16;
+
+ check_in ();
+ check_out ();
+ check_rand ();
+
+ unlink (FILENAME);
+ tests_end ();
+
+ exit (0);
+}