1/* Test conversion and I/O using mpz_out_str and mpz_inp_str.
2
3Copyright 1993, 1994, 1996, 2000, 2001 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20#include "config.h"
21
22#include <stdio.h>
23#include <stdlib.h>
24#if HAVE_UNISTD_H
25#include <unistd.h>		/* for unlink */
26#endif
27
28#include "gmp.h"
29#include "gmp-impl.h"
30#include "tests.h"
31
32#define FILENAME  "io.tmp"
33
34void
35debug_mp (mpz_t x, int base)
36{
37  mpz_out_str (stdout, base, x); fputc ('\n', stdout);
38}
39
40int
41main (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;
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  for (i = 0; i < reps; i++)
68    {
69      mpz_urandomb (bs, rands, 32);
70      size_range = mpz_get_ui (bs) % 10 + 2;
71
72      mpz_urandomb (bs, rands, size_range);
73      size = mpz_get_ui (bs);
74      mpz_rrandomb (op1, rands, size);
75      mpz_urandomb (bs, rands, 1);
76      bsi = mpz_get_ui (bs);
77      if ((bsi & 1) != 0)
78	mpz_neg (op1, op1);
79
80      mpz_urandomb (bs, rands, 16);
81      bsi = mpz_get_ui (bs);
82      base = bsi % 36 + 1;
83      if (base == 1)
84	base = 0;
85
86      rewind (fp);
87      if (mpz_out_str (fp, base, op1) == 0
88	  || putc (' ', fp) == EOF
89	  || fflush (fp) != 0)
90	{
91	  printf ("mpz_out_str write error\n");
92	  abort ();
93	}
94
95      rewind (fp);
96      nread = mpz_inp_str (op2, fp, base);
97      if (nread == 0)
98	{
99	  if (ferror (fp))
100	    printf ("mpz_inp_str stream read error\n");
101	  else
102	    printf ("mpz_inp_str data conversion error\n");
103	  abort ();
104	}
105
106      if (nread != ftell(fp))
107	{
108	  printf ("mpz_inp_str nread doesn't match ftell\n");
109	  printf ("  nread  %lu\n", (unsigned long) nread);
110	  printf ("  ftell  %ld\n", ftell(fp));
111	  abort ();
112	}
113
114      if (mpz_cmp (op1, op2))
115	{
116	  printf ("ERROR\n");
117	  printf ("op1  = "); debug_mp (op1, -16);
118	  printf ("op2  = "); debug_mp (op2, -16);
119	  printf ("base = %d\n", base);
120	  abort ();
121	}
122    }
123
124  fclose (fp);
125
126  unlink (FILENAME);
127
128  mpz_clear (bs);
129  mpz_clear (op1);
130  mpz_clear (op2);
131
132  tests_end ();
133  exit (0);
134}
135