Home | History | Annotate | Line # | Download | only in tests
trace.c revision 1.1.1.3
      1      1.1  mrg /* Support for diagnostic traces.
      2      1.1  mrg 
      3  1.1.1.3  mrg Copyright 1999-2005 Free Software Foundation, Inc.
      4      1.1  mrg 
      5  1.1.1.2  mrg This file is part of the GNU MP Library test suite.
      6      1.1  mrg 
      7  1.1.1.2  mrg The GNU MP Library test suite is free software; you can redistribute it
      8  1.1.1.2  mrg and/or modify it under the terms of the GNU General Public License as
      9  1.1.1.2  mrg published by the Free Software Foundation; either version 3 of the License,
     10  1.1.1.2  mrg or (at your option) any later version.
     11  1.1.1.2  mrg 
     12  1.1.1.2  mrg The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1.1.2  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1.1.2  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1.1.2  mrg Public License for more details.
     16      1.1  mrg 
     17  1.1.1.2  mrg You should have received a copy of the GNU General Public License along with
     18  1.1.1.3  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19      1.1  mrg 
     20      1.1  mrg 
     21      1.1  mrg /* Future: Would like commas printed between limbs in hex or binary, but
     22      1.1  mrg    perhaps not always since it might upset cutting and pasting into bc or
     23      1.1  mrg    whatever.  */
     24      1.1  mrg 
     25      1.1  mrg 
     26      1.1  mrg #include <stdio.h>
     27      1.1  mrg #include <stdlib.h>
     28      1.1  mrg #include <string.h> /* for strlen */
     29      1.1  mrg 
     30      1.1  mrg #include "gmp.h"
     31      1.1  mrg #include "gmp-impl.h"
     32      1.1  mrg 
     33      1.1  mrg #include "tests.h"
     34      1.1  mrg 
     35      1.1  mrg 
     36      1.1  mrg /* Number base for the various trace printing routines.
     37      1.1  mrg    Set this in main() or with the debugger.
     38      1.1  mrg    If hexadecimal is going to be fed into GNU bc, remember to use -16
     39      1.1  mrg    because bc requires upper case.  */
     40      1.1  mrg 
     41      1.1  mrg int  mp_trace_base = 10;
     42      1.1  mrg 
     43      1.1  mrg 
     44      1.1  mrg void
     45      1.1  mrg mp_trace_start (const char *name)
     46      1.1  mrg {
     47      1.1  mrg   if (name != NULL && name[0] != '\0')
     48      1.1  mrg     printf ("%s=", name);
     49      1.1  mrg 
     50      1.1  mrg   switch (ABS (mp_trace_base)) {
     51      1.1  mrg   case  2: printf ("bin:");                         break;
     52      1.1  mrg   case  8: printf ("oct:");                         break;
     53      1.1  mrg   case 10:                                          break;
     54      1.1  mrg   case 16: printf ("0x");                           break;
     55      1.1  mrg   default: printf ("base%d:", ABS (mp_trace_base)); break;
     56      1.1  mrg   }
     57      1.1  mrg }
     58      1.1  mrg 
     59      1.1  mrg /* Print "name=value\n" to stdout for an mpq_t value.  */
     60      1.1  mrg void
     61      1.1  mrg mpq_trace (const char *name, mpq_srcptr q)
     62      1.1  mrg {
     63      1.1  mrg   mp_trace_start (name);
     64      1.1  mrg   if (q == NULL)
     65      1.1  mrg     {
     66      1.1  mrg       printf ("NULL\n");
     67      1.1  mrg       return;
     68      1.1  mrg     }
     69      1.1  mrg 
     70      1.1  mrg   mpq_out_str (stdout, mp_trace_base, q);
     71      1.1  mrg   printf ("\n");
     72      1.1  mrg }
     73      1.1  mrg 
     74      1.1  mrg 
     75      1.1  mrg /* Print "name=value\n" to stdout for an mpz_t value.  */
     76      1.1  mrg void
     77      1.1  mrg mpz_trace (const char *name, mpz_srcptr z)
     78      1.1  mrg {
     79      1.1  mrg   mpq_t      q;
     80      1.1  mrg   mp_limb_t  one;
     81      1.1  mrg 
     82      1.1  mrg   if (z == NULL)
     83      1.1  mrg     {
     84      1.1  mrg       mpq_trace (name, NULL);
     85      1.1  mrg       return;
     86      1.1  mrg     }
     87      1.1  mrg 
     88      1.1  mrg   q->_mp_num._mp_alloc = ALLOC(z);
     89      1.1  mrg   q->_mp_num._mp_size = SIZ(z);
     90      1.1  mrg   q->_mp_num._mp_d = PTR(z);
     91      1.1  mrg 
     92      1.1  mrg   one = 1;
     93      1.1  mrg   q->_mp_den._mp_alloc = 1;
     94      1.1  mrg   q->_mp_den._mp_size = 1;
     95      1.1  mrg   q->_mp_den._mp_d = &one;
     96      1.1  mrg 
     97      1.1  mrg   mpq_trace(name, q);
     98      1.1  mrg }
     99      1.1  mrg 
    100      1.1  mrg 
    101      1.1  mrg /* Print "name=value\n" to stdout for an mpf_t value. */
    102      1.1  mrg void
    103      1.1  mrg mpf_trace (const char *name, mpf_srcptr f)
    104      1.1  mrg {
    105      1.1  mrg   mp_trace_start (name);
    106      1.1  mrg   if (f == NULL)
    107      1.1  mrg     {
    108      1.1  mrg       printf ("NULL\n");
    109      1.1  mrg       return;
    110      1.1  mrg     }
    111      1.1  mrg 
    112      1.1  mrg   mpf_out_str (stdout, ABS (mp_trace_base), 0, f);
    113      1.1  mrg   printf ("\n");
    114      1.1  mrg }
    115      1.1  mrg 
    116      1.1  mrg 
    117      1.1  mrg /* Print "namenum=value\n" to stdout for an mpz_t value.
    118      1.1  mrg    "name" should have a "%d" to get the number. */
    119      1.1  mrg void
    120      1.1  mrg mpz_tracen (const char *name, int num, mpz_srcptr z)
    121      1.1  mrg {
    122      1.1  mrg   if (name != NULL && name[0] != '\0')
    123      1.1  mrg     {
    124      1.1  mrg       printf (name, num);
    125      1.1  mrg       putchar ('=');
    126      1.1  mrg     }
    127      1.1  mrg   mpz_trace (NULL, z);
    128      1.1  mrg }
    129      1.1  mrg 
    130      1.1  mrg 
    131      1.1  mrg /* Print "name=value\n" to stdout for an mpn style ptr,size. */
    132      1.1  mrg void
    133      1.1  mrg mpn_trace (const char *name, mp_srcptr ptr, mp_size_t size)
    134      1.1  mrg {
    135      1.1  mrg   mpz_t  z;
    136      1.1  mrg   if (ptr == NULL)
    137      1.1  mrg     {
    138      1.1  mrg       mpz_trace (name, NULL);
    139      1.1  mrg       return;
    140      1.1  mrg     }
    141      1.1  mrg   MPN_NORMALIZE (ptr, size);
    142      1.1  mrg   PTR(z) = (mp_ptr) ptr;
    143      1.1  mrg   SIZ(z) = size;
    144      1.1  mrg   ALLOC(z) = size;
    145      1.1  mrg   mpz_trace (name, z);
    146      1.1  mrg }
    147      1.1  mrg 
    148      1.1  mrg /* Print "name=value\n" to stdout for a limb, nail doesn't have to be zero. */
    149      1.1  mrg void
    150      1.1  mrg mp_limb_trace (const char *name, mp_limb_t n)
    151      1.1  mrg {
    152      1.1  mrg #if GMP_NAIL_BITS != 0
    153      1.1  mrg   mp_limb_t  a[2];
    154      1.1  mrg   a[0] = n & GMP_NUMB_MASK;
    155      1.1  mrg   a[1] = n >> GMP_NUMB_BITS;
    156      1.1  mrg   mpn_trace (name, a, (mp_size_t) 2);
    157      1.1  mrg #else
    158      1.1  mrg   mpn_trace (name, &n, (mp_size_t) 1);
    159      1.1  mrg #endif
    160      1.1  mrg }
    161      1.1  mrg 
    162      1.1  mrg 
    163      1.1  mrg /* Print "namenum=value\n" to stdout for an mpn style ptr,size.
    164      1.1  mrg    "name" should have a "%d" to get the number.  */
    165      1.1  mrg void
    166      1.1  mrg mpn_tracen (const char *name, int num, mp_srcptr ptr, mp_size_t size)
    167      1.1  mrg {
    168      1.1  mrg   if (name != NULL && name[0] != '\0')
    169      1.1  mrg     {
    170      1.1  mrg       printf (name, num);
    171      1.1  mrg       putchar ('=');
    172      1.1  mrg     }
    173      1.1  mrg   mpn_trace (NULL, ptr, size);
    174      1.1  mrg }
    175      1.1  mrg 
    176      1.1  mrg 
    177      1.1  mrg /* Print "namenum=value\n" to stdout for an array of mpn style ptr,size.
    178      1.1  mrg 
    179      1.1  mrg    "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
    180      1.1  mrg    The formal parameter isn't mp_srcptr because that causes compiler
    181      1.1  mrg    warnings, but the values aren't modified.
    182      1.1  mrg 
    183      1.1  mrg    "name" should have a printf style "%d" to get the array index.  */
    184      1.1  mrg 
    185      1.1  mrg void
    186      1.1  mrg mpn_tracea (const char *name, const mp_ptr *a, int count, mp_size_t size)
    187      1.1  mrg {
    188      1.1  mrg   int i;
    189      1.1  mrg   for (i = 0; i < count; i++)
    190      1.1  mrg     mpn_tracen (name, i, a[i], size);
    191      1.1  mrg }
    192      1.1  mrg 
    193      1.1  mrg 
    194      1.1  mrg /* Print "value\n" to a file for an mpz_t value.  Any previous contents of
    195      1.1  mrg    the file are overwritten, so you need different file names each time this
    196      1.1  mrg    is called.
    197      1.1  mrg 
    198      1.1  mrg    Overwriting the file is a feature, it means you get old data replaced
    199      1.1  mrg    when you run a test program repeatedly.  */
    200      1.1  mrg 
    201      1.1  mrg void
    202      1.1  mrg mpn_trace_file (const char *filename, mp_srcptr ptr, mp_size_t size)
    203      1.1  mrg {
    204      1.1  mrg   FILE   *fp;
    205      1.1  mrg   mpz_t  z;
    206      1.1  mrg 
    207      1.1  mrg   fp = fopen (filename, "w");
    208      1.1  mrg   if (fp == NULL)
    209      1.1  mrg     {
    210      1.1  mrg       perror ("fopen");
    211      1.1  mrg       abort();
    212      1.1  mrg     }
    213      1.1  mrg 
    214      1.1  mrg   MPN_NORMALIZE (ptr, size);
    215      1.1  mrg   PTR(z) = (mp_ptr) ptr;
    216      1.1  mrg   SIZ(z) = (int) size;
    217      1.1  mrg 
    218      1.1  mrg   mpz_out_str (fp, mp_trace_base, z);
    219      1.1  mrg   fprintf (fp, "\n");
    220      1.1  mrg 
    221      1.1  mrg   if (ferror (fp) || fclose (fp) != 0)
    222      1.1  mrg     {
    223      1.1  mrg       printf ("error writing %s\n", filename);
    224      1.1  mrg       abort();
    225      1.1  mrg     }
    226      1.1  mrg }
    227      1.1  mrg 
    228      1.1  mrg 
    229      1.1  mrg /* Print "value\n" to a set of files, one file for each element of the given
    230      1.1  mrg    array of mpn style ptr,size.  Any previous contents of the files are
    231      1.1  mrg    overwritten, so you need different file names each time this is called.
    232      1.1  mrg    Each file is "filenameN" where N is 0 to count-1.
    233      1.1  mrg 
    234      1.1  mrg    "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
    235      1.1  mrg    The formal parameter isn't mp_srcptr because that causes compiler
    236      1.1  mrg    warnings, but the values aren't modified.
    237      1.1  mrg 
    238      1.1  mrg    Overwriting the files is a feature, it means you get old data replaced
    239      1.1  mrg    when you run a test program repeatedly.  The output style isn't
    240      1.1  mrg    particularly pretty, but at least it gets something out, and you can cat
    241      1.1  mrg    the files into bc, or whatever. */
    242      1.1  mrg 
    243      1.1  mrg void
    244      1.1  mrg mpn_tracea_file (const char *filename,
    245      1.1  mrg                  const mp_ptr *a, int count, mp_size_t size)
    246      1.1  mrg {
    247      1.1  mrg   char  *s;
    248      1.1  mrg   int   i;
    249      1.1  mrg   TMP_DECL;
    250      1.1  mrg 
    251      1.1  mrg   TMP_MARK;
    252      1.1  mrg   s = (char *) TMP_ALLOC (strlen (filename) + 50);
    253      1.1  mrg 
    254      1.1  mrg   for (i = 0; i < count; i++)
    255      1.1  mrg     {
    256      1.1  mrg       sprintf (s, "%s%d", filename, i);
    257      1.1  mrg       mpn_trace_file (s, a[i], size);
    258      1.1  mrg     }
    259      1.1  mrg 
    260      1.1  mrg   TMP_FREE;
    261      1.1  mrg }
    262      1.1  mrg 
    263      1.1  mrg 
    264      1.1  mrg void
    265      1.1  mrg byte_trace (const char *name, const void *ptr, mp_size_t size)
    266      1.1  mrg {
    267  1.1.1.2  mrg   const char *fmt;
    268      1.1  mrg   mp_size_t  i;
    269      1.1  mrg 
    270      1.1  mrg   mp_trace_start (name);
    271      1.1  mrg 
    272      1.1  mrg   switch (mp_trace_base) {
    273      1.1  mrg   case   8: fmt = " %o"; break;
    274      1.1  mrg   case  10: fmt = " %d"; break;
    275      1.1  mrg   case  16: fmt = " %x"; break;
    276      1.1  mrg   case -16: fmt = " %X"; break;
    277      1.1  mrg   default: printf ("Oops, unsupported base in byte_trace\n"); abort (); break;
    278      1.1  mrg   }
    279      1.1  mrg 
    280      1.1  mrg   for (i = 0; i < size; i++)
    281      1.1  mrg     printf (fmt, (int) ((unsigned char *) ptr)[i]);
    282      1.1  mrg   printf ("\n");
    283      1.1  mrg }
    284      1.1  mrg 
    285      1.1  mrg void
    286      1.1  mrg byte_tracen (const char *name, int num, const void *ptr, mp_size_t size)
    287      1.1  mrg {
    288      1.1  mrg   if (name != NULL && name[0] != '\0')
    289      1.1  mrg     {
    290      1.1  mrg       printf (name, num);
    291      1.1  mrg       putchar ('=');
    292      1.1  mrg     }
    293      1.1  mrg   byte_trace (NULL, ptr, size);
    294      1.1  mrg }
    295      1.1  mrg 
    296      1.1  mrg 
    297      1.1  mrg void
    298      1.1  mrg d_trace (const char *name, double d)
    299      1.1  mrg {
    300      1.1  mrg   union {
    301      1.1  mrg     double         d;
    302      1.1  mrg     unsigned char  b[sizeof(double)];
    303      1.1  mrg   } u;
    304      1.1  mrg   int  i;
    305      1.1  mrg 
    306      1.1  mrg   if (name != NULL && name[0] != '\0')
    307      1.1  mrg     printf ("%s=", name);
    308      1.1  mrg 
    309      1.1  mrg   u.d = d;
    310      1.1  mrg   printf ("[");
    311      1.1  mrg   for (i = 0; i < sizeof (u.b); i++)
    312      1.1  mrg     {
    313      1.1  mrg       if (i != 0)
    314      1.1  mrg         printf (" ");
    315      1.1  mrg       printf ("%02X", (int) u.b[i]);
    316      1.1  mrg     }
    317      1.1  mrg   printf ("] %.20g\n", d);
    318      1.1  mrg }
    319