xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpz/io.c (revision 1daf83e636cd998f45e5597a8f995a540e2d5b4a)
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
debug_mp(mpz_t x,int base)35 debug_mp (mpz_t x, int base)
36 {
37   mpz_out_str (stdout, base, x); fputc ('\n', stdout);
38 }
39 
40 int
main(int argc,char ** argv)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