Home | History | Annotate | Line # | Download | only in mpz
      1 /* Test conversion and I/O using mpz_out_str and mpz_inp_str.
      2 
      3 Copyright 1993, 1994, 1996, 2000, 2001, 2012, 2020 Free Software
      4 Foundation, Inc.
      5 
      6 This file is part of the GNU MP Library test suite.
      7 
      8 The GNU MP Library test suite is free software; you can redistribute it
      9 and/or modify it under the terms of the GNU General Public License as
     10 published by the Free Software Foundation; either version 3 of the License,
     11 or (at your option) any later version.
     12 
     13 The GNU MP Library test suite is distributed in the hope that it will be
     14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     16 Public License for more details.
     17 
     18 You should have received a copy of the GNU General Public License along with
     19 the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     20 
     21 #include "config.h"
     22 
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #if HAVE_UNISTD_H
     26 #include <unistd.h>		/* for unlink */
     27 #endif
     28 
     29 #include "gmp-impl.h"
     30 #include "tests.h"
     31 
     32 #define FILENAME  "io.tmp"
     33 
     34 void
     35 debug_mp (mpz_t x, int base)
     36 {
     37   mpz_out_str (stdout, base, x); fputc ('\n', stdout);
     38 }
     39 
     40 int
     41 main (int argc, char **argv)
     42 {
     43   mpz_t  op1, op2;
     44   mp_size_t size;
     45   int i;
     46   int reps = 10000;
     47   FILE *fp;
     48   int base, base_out;
     49   gmp_randstate_ptr rands;
     50   mpz_t bs;
     51   unsigned long bsi, size_range;
     52   size_t nread;
     53 
     54   tests_start ();
     55   rands = RANDS;
     56 
     57   mpz_init (bs);
     58 
     59   if (argc == 2)
     60     reps = atoi (argv[1]);
     61 
     62   mpz_init (op1);
     63   mpz_init (op2);
     64 
     65   fp = fopen (FILENAME, "w+");
     66 
     67   if (mpz_out_str (fp, 63, op1) != 0)
     68     {
     69       printf ("mpz_out_str did not return 0 (error) with base > 62\n");
     70       abort ();
     71     }
     72 
     73   if (mpz_out_str (fp, -37, op1) != 0)
     74     {
     75       printf ("mpz_out_str did not return 0 (error) with base < -37\n");
     76       abort ();
     77     }
     78 
     79   for (i = 0; i < reps; i++)
     80     {
     81       mpz_urandomb (bs, rands, 32);
     82       size_range = mpz_get_ui (bs) % 10 + 2;
     83 
     84       mpz_urandomb (bs, rands, size_range);
     85       size = mpz_get_ui (bs);
     86       mpz_rrandomb (op1, rands, size);
     87       mpz_urandomb (bs, rands, 1);
     88       bsi = mpz_get_ui (bs);
     89       if ((bsi & 1) != 0)
     90 	mpz_neg (op1, op1);
     91 
     92       mpz_urandomb (bs, rands, 16);
     93       bsi = mpz_get_ui (bs);
     94       base = bsi % 62 + 1;
     95       if (base == 1)
     96 	base = 0;
     97 
     98       if (i % 2 == 0 && base <= 36)
     99 	base_out = -base;
    100       else
    101 	base_out = base;
    102 
    103       rewind (fp);
    104       if (mpz_out_str (fp, base_out, op1) == 0
    105 	  || putc (' ', fp) == EOF
    106 	  || fflush (fp) != 0)
    107 	{
    108 	  printf ("mpz_out_str write error\n");
    109 	  abort ();
    110 	}
    111 
    112       rewind (fp);
    113       nread = mpz_inp_str (op2, fp, base);
    114       if (nread == 0)
    115 	{
    116 	  if (ferror (fp))
    117 	    printf ("mpz_inp_str stream read error\n");
    118 	  else
    119 	    printf ("mpz_inp_str data conversion error\n");
    120 	  abort ();
    121 	}
    122 
    123       if (nread != ftell(fp))
    124 	{
    125 	  printf ("mpz_inp_str nread doesn't match ftell\n");
    126 	  printf ("  nread  %lu\n", (unsigned long) nread);
    127 	  printf ("  ftell  %ld\n", ftell(fp));
    128 	  abort ();
    129 	}
    130 
    131       if (mpz_cmp (op1, op2))
    132 	{
    133 	  printf ("ERROR\n");
    134 	  printf ("op1  = "); debug_mp (op1, -16);
    135 	  printf ("op2  = "); debug_mp (op2, -16);
    136 	  printf ("base = %d\n", base);
    137 	  abort ();
    138 	}
    139     }
    140 
    141   fclose (fp);
    142 
    143   unlink (FILENAME);
    144 
    145   mpz_clear (bs);
    146   mpz_clear (op1);
    147   mpz_clear (op2);
    148 
    149   tests_end ();
    150   exit (0);
    151 }
    152