Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
The GNU MP Library 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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
perhaps not always since it might upset cutting and pasting into bc or
whatever. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gmp.h"
#include "gmp-impl.h"
#include "tests.h"
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;
}
}
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");
}
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);
}
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");
}
"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);
}
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);
}
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
}
"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);
}
"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);
}
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();
}
}
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)
{
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);
}