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