aboutsummaryrefslogtreecommitdiff
path: root/gmp-6.3.0/mini-gmp/tests/testutils.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/mini-gmp/tests/testutils.c
Initial commit.
Diffstat (limited to 'gmp-6.3.0/mini-gmp/tests/testutils.c')
-rw-r--r--gmp-6.3.0/mini-gmp/tests/testutils.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/gmp-6.3.0/mini-gmp/tests/testutils.c b/gmp-6.3.0/mini-gmp/tests/testutils.c
new file mode 100644
index 0000000..46e368a
--- /dev/null
+++ b/gmp-6.3.0/mini-gmp/tests/testutils.c
@@ -0,0 +1,196 @@
+/*
+
+Copyright 2013-2015, 2018 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 "testutils.h"
+
+/* Include it here, so we we could tweak, e.g., how MPZ_REALLOC
+ works. */
+#include "../mini-gmp.c"
+#include "../mini-mpq.c"
+
+static size_t total_alloc = 0;
+
+/* Custom memory allocation to track memory usage, and add a small red
+ zone.
+
+ About alignment: In general, getting a block from malloc, and
+ incrementing it by sizeof(size_t), like we do here, might give a
+ pointer which is not properly aligned for all types. But the
+ largest type we allocate space for is unsigned long (mp_limb_t),
+ which shouldn't have stricter alignment requirements than
+ size_t. */
+
+static unsigned char block_end[8] =
+ { 0x7c, 0x37, 0xd6, 0x12, 0xa8, 0x6c, 0x01, 0xd1 };
+
+static void *
+block_init (size_t *block, size_t size)
+{
+ char *p;
+ *block++ = size;
+
+ p = (char *) block;
+ memcpy (p + size, block_end, sizeof(block_end));
+
+ total_alloc += size;
+ return p;
+}
+
+/* Check small redzone, return pointer to malloced block. */
+static size_t *
+block_check (void *p)
+{
+ size_t *block = (size_t *) p - 1;
+ size_t size = block[0];
+
+ if (memcmp ((char *)p + size, block_end, sizeof(block_end)) != 0)
+ {
+ fprintf (stderr, "red zone overwritten.\n");
+ abort ();
+ }
+ total_alloc -= size;
+ return block;
+}
+
+static void *
+tu_alloc (size_t size)
+{
+ size_t *block = (size_t *) malloc (sizeof(size_t) + size + sizeof(block_end));
+ if (!block)
+ {
+ fprintf (stderr, "Virtual memory exhausted.\n");
+ abort ();
+ }
+
+ return block_init (block, size);
+}
+
+static void *
+tu_realloc (void *p, size_t old_size, size_t new_size)
+{
+ size_t *block;
+ size_t *old_block = block_check (p);
+ if (old_block[0] != old_size)
+ {
+ fprintf (stderr, "%s:%d: bad old_size: want %ld, got %ld.\n", __FILE__, __LINE__,
+ (long)old_block[0], (long)old_size);
+ abort ();
+ }
+
+ block = (size_t *) realloc (old_block, sizeof(size_t) + new_size + sizeof(block_end));
+ if (!block)
+ {
+ fprintf (stderr, "Virtual memory exhausted.\n");
+ abort ();
+ }
+
+ return block_init (block, new_size);
+}
+
+static void
+tu_free (void *p, size_t old_size)
+{
+ size_t *old_block = block_check (p);
+ if (old_block[0] != old_size && old_size != 0)
+ {
+ fprintf (stderr, "%s:%d: bad old_size: want %ld, got %ld.\n", __FILE__, __LINE__,
+ (long)old_block[0], (long)old_size);
+ abort ();
+ }
+ free (old_block);
+}
+
+/* Free memory allocated via mini-gmp allocation function. */
+void
+testfree (void *p, size_t size)
+{
+ void (*freefunc) (void *, size_t);
+ mp_get_memory_functions (NULL, NULL, &freefunc);
+
+ freefunc (p, size);
+}
+
+int
+main (int argc, char **argv)
+{
+ hex_random_init ();
+
+ mp_set_memory_functions (tu_alloc, tu_realloc, tu_free);
+
+ /* Currently, t-comb seems to be the only program accepting any
+ arguments. It might make sense to parse common arguments here. */
+ testmain (argc, argv);
+
+ if (total_alloc != 0)
+ {
+ fprintf (stderr, "Memory leaked: %lu bytes.\n",
+ (unsigned long) total_alloc);
+ abort ();
+ }
+ return 0;
+}
+
+void
+testhalves (int count, void (*tested_fun) (int))
+{
+ void (*freefunc) (void *, size_t);
+ void *(*reallocfunc) (void *, size_t, size_t);
+ void *(*allocfunc) (size_t);
+ size_t initial_alloc;
+
+ mp_get_memory_functions (&allocfunc, &reallocfunc, &freefunc);
+ initial_alloc = total_alloc;
+ (*tested_fun) (count / 2);
+ if (initial_alloc != total_alloc)
+ {
+ fprintf (stderr, "First half, memory leaked: %lu bytes.\n",
+ (unsigned long) total_alloc - initial_alloc);
+ abort ();
+ }
+ mp_set_memory_functions (NULL, NULL, NULL);
+ (*tested_fun) (count / 2);
+ mp_set_memory_functions (allocfunc, reallocfunc, freefunc);
+}
+
+void
+dump (const char *label, const mpz_t x)
+{
+ char *buf = mpz_get_str (NULL, 16, x);
+ fprintf (stderr, "%s: %s\n", label, buf);
+ testfree (buf, strlen(buf) + 1);
+}
+
+void
+mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
+{
+ if (mpz_set_str (z, str, base) != 0)
+ {
+ fprintf (stderr, "ERROR: mpz_set_str failed\n");
+ fprintf (stderr, " str = \"%s\"\n", str);
+ fprintf (stderr, " base = %d\n", base);
+ abort();
+ }
+}
+
+int
+mpz_lucas_mod (mpz_t V, mpz_t Qk, long Q,
+ mp_bitcnt_t b0, const mpz_t n)
+{
+ return gmp_lucas_mod (V, Qk, Q, b0, n);
+}