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