From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/tests/trace.c | 317 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 gmp-6.3.0/tests/trace.c (limited to 'gmp-6.3.0/tests/trace.c') diff --git a/gmp-6.3.0/tests/trace.c b/gmp-6.3.0/tests/trace.c new file mode 100644 index 0000000..de397f5 --- /dev/null +++ b/gmp-6.3.0/tests/trace.c @@ -0,0 +1,317 @@ +/* Support for diagnostic traces. + +Copyright 1999-2005 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/. */ + + +/* Future: Would like commas printed between limbs in hex or binary, but + perhaps not always since it might upset cutting and pasting into bc or + whatever. */ + + +#include +#include +#include /* for strlen */ + +#include "gmp-impl.h" + +#include "tests.h" + + +/* Number base for the various trace printing routines. + Set this in main() or with the debugger. + If hexadecimal is going to be fed into GNU bc, remember to use -16 + because bc requires upper case. */ + +int mp_trace_base = 10; + + +void +mp_trace_start (const char *name) +{ + if (name != NULL && name[0] != '\0') + printf ("%s=", name); + + switch (ABS (mp_trace_base)) { + case 2: printf ("bin:"); break; + case 8: printf ("oct:"); break; + case 10: break; + case 16: printf ("0x"); break; + default: printf ("base%d:", ABS (mp_trace_base)); break; + } +} + +/* Print "name=value\n" to stdout for an mpq_t value. */ +void +mpq_trace (const char *name, mpq_srcptr q) +{ + mp_trace_start (name); + if (q == NULL) + { + printf ("NULL\n"); + return; + } + + mpq_out_str (stdout, mp_trace_base, q); + printf ("\n"); +} + + +/* Print "name=value\n" to stdout for an mpz_t value. */ +void +mpz_trace (const char *name, mpz_srcptr z) +{ + mpq_t q; + mp_limb_t one; + + if (z == NULL) + { + mpq_trace (name, NULL); + return; + } + + q->_mp_num._mp_alloc = ALLOC(z); + q->_mp_num._mp_size = SIZ(z); + q->_mp_num._mp_d = PTR(z); + + one = 1; + q->_mp_den._mp_alloc = 1; + q->_mp_den._mp_size = 1; + q->_mp_den._mp_d = &one; + + mpq_trace(name, q); +} + + +/* Print "name=value\n" to stdout for an mpf_t value. */ +void +mpf_trace (const char *name, mpf_srcptr f) +{ + mp_trace_start (name); + if (f == NULL) + { + printf ("NULL\n"); + return; + } + + mpf_out_str (stdout, ABS (mp_trace_base), 0, f); + printf ("\n"); +} + + +/* Print "namenum=value\n" to stdout for an mpz_t value. + "name" should have a "%d" to get the number. */ +void +mpz_tracen (const char *name, int num, mpz_srcptr z) +{ + if (name != NULL && name[0] != '\0') + { + printf (name, num); + putchar ('='); + } + mpz_trace (NULL, z); +} + + +/* Print "name=value\n" to stdout for an mpn style ptr,size. */ +void +mpn_trace (const char *name, mp_srcptr ptr, mp_size_t size) +{ + mpz_t z; + if (ptr == NULL) + { + mpz_trace (name, NULL); + return; + } + MPN_NORMALIZE (ptr, size); + PTR(z) = (mp_ptr) ptr; + SIZ(z) = size; + ALLOC(z) = size; + mpz_trace (name, z); +} + +/* Print "name=value\n" to stdout for a limb, nail doesn't have to be zero. */ +void +mp_limb_trace (const char *name, mp_limb_t n) +{ +#if GMP_NAIL_BITS != 0 + mp_limb_t a[2]; + a[0] = n & GMP_NUMB_MASK; + a[1] = n >> GMP_NUMB_BITS; + mpn_trace (name, a, (mp_size_t) 2); +#else + mpn_trace (name, &n, (mp_size_t) 1); +#endif +} + + +/* Print "namenum=value\n" to stdout for an mpn style ptr,size. + "name" should have a "%d" to get the number. */ +void +mpn_tracen (const char *name, int num, mp_srcptr ptr, mp_size_t size) +{ + if (name != NULL && name[0] != '\0') + { + printf (name, num); + putchar ('='); + } + mpn_trace (NULL, ptr, size); +} + + +/* Print "namenum=value\n" to stdout for an array of mpn style ptr,size. + + "a" is an array of pointers, each a[i] is a pointer to "size" many limbs. + The formal parameter isn't mp_srcptr because that causes compiler + warnings, but the values aren't modified. + + "name" should have a printf style "%d" to get the array index. */ + +void +mpn_tracea (const char *name, const mp_ptr *a, int count, mp_size_t size) +{ + int i; + for (i = 0; i < count; i++) + mpn_tracen (name, i, a[i], size); +} + + +/* Print "value\n" to a file for an mpz_t value. Any previous contents of + the file are overwritten, so you need different file names each time this + is called. + + Overwriting the file is a feature, it means you get old data replaced + when you run a test program repeatedly. */ + +void +mpn_trace_file (const char *filename, mp_srcptr ptr, mp_size_t size) +{ + FILE *fp; + mpz_t z; + + fp = fopen (filename, "w"); + if (fp == NULL) + { + perror ("fopen"); + abort(); + } + + MPN_NORMALIZE (ptr, size); + PTR(z) = (mp_ptr) ptr; + SIZ(z) = (int) size; + + mpz_out_str (fp, mp_trace_base, z); + fprintf (fp, "\n"); + + if (ferror (fp) || fclose (fp) != 0) + { + printf ("error writing %s\n", filename); + abort(); + } +} + + +/* Print "value\n" to a set of files, one file for each element of the given + array of mpn style ptr,size. Any previous contents of the files are + overwritten, so you need different file names each time this is called. + Each file is "filenameN" where N is 0 to count-1. + + "a" is an array of pointers, each a[i] is a pointer to "size" many limbs. + The formal parameter isn't mp_srcptr because that causes compiler + warnings, but the values aren't modified. + + Overwriting the files is a feature, it means you get old data replaced + when you run a test program repeatedly. The output style isn't + particularly pretty, but at least it gets something out, and you can cat + the files into bc, or whatever. */ + +void +mpn_tracea_file (const char *filename, + const mp_ptr *a, int count, mp_size_t size) +{ + char *s; + int i; + TMP_DECL; + + TMP_MARK; + s = (char *) TMP_ALLOC (strlen (filename) + 50); + + for (i = 0; i < count; i++) + { + sprintf (s, "%s%d", filename, i); + mpn_trace_file (s, a[i], size); + } + + TMP_FREE; +} + + +void +byte_trace (const char *name, const void *ptr, mp_size_t size) +{ + const char *fmt; + mp_size_t i; + + mp_trace_start (name); + + switch (mp_trace_base) { + case 8: fmt = " %o"; break; + case 10: fmt = " %d"; break; + case 16: fmt = " %x"; break; + case -16: fmt = " %X"; break; + default: printf ("Oops, unsupported base in byte_trace\n"); abort (); break; + } + + for (i = 0; i < size; i++) + printf (fmt, (int) ((unsigned char *) ptr)[i]); + printf ("\n"); +} + +void +byte_tracen (const char *name, int num, const void *ptr, mp_size_t size) +{ + if (name != NULL && name[0] != '\0') + { + printf (name, num); + putchar ('='); + } + byte_trace (NULL, ptr, size); +} + + +void +d_trace (const char *name, double d) +{ + union { + double d; + unsigned char b[sizeof(double)]; + } u; + int i; + + if (name != NULL && name[0] != '\0') + printf ("%s=", name); + + u.d = d; + printf ("["); + for (i = 0; i < sizeof (u.b); i++) + { + if (i != 0) + printf (" "); + printf ("%02X", (int) u.b[i]); + } + printf ("] %.20g\n", d); +} -- cgit v1.2.3