source: trunk/third/gmp/tests/mpz/t-io_raw.c @ 18191

Revision 18191, 7.4 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18190, which included commits to RCS files with non-trunk default branches.
Line 
1/* Test mpz_inp_raw and mpz_out_raw.
2
3Copyright 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 2.1 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; see the file COPYING.LIB.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 02111-1307, USA. */
21
22#include "config.h"
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#if HAVE_UNISTD_H
28#include <unistd.h>
29#endif
30
31#include "gmp.h"
32#include "gmp-impl.h"
33#include "tests.h"
34
35#define FILENAME  "t-io_raw.tmp"
36
37
38/* In the fopen, "b" selects binary mode on DOS systems, meaning no
39   conversion of '\n' to and from CRLF.  It's believed systems without such
40   nonsense will simply ignore the "b", but in case that's not so a plain
41   "w+" is attempted if "w+b" fails.  */
42
43FILE *
44fopen_wplusb_or_die (const char *filename)
45{
46  FILE  *fp;
47  fp = fopen (filename, "w+b");
48  if (fp == NULL)
49    fp = fopen (filename, "w+");
50
51  if (fp == NULL)
52    {
53      printf ("Cannot create file %s\n", filename);
54      abort ();
55    }
56  return fp;
57}
58
59/* use 0x80 to check nothing bad happens with sign extension etc */
60#define BYTEVAL(i)  (((i) + 1) | 0x80)
61
62void
63check_in (void)
64{
65  int        i, j, zeros, neg, error = 0;
66  mpz_t      want, got;
67  size_t     want_ret, got_ret;
68  mp_size_t  size;
69  FILE       *fp;
70
71  mpz_init (want);
72  mpz_init (got);
73
74  for (i = 0; i < 32; i++)
75    {
76      for (zeros = 0; zeros < 8; zeros++)
77        {
78          for (neg = 0; neg <= 1; neg++)
79            {
80              want_ret = i + zeros + 4;
81
82              /* need this to get the twos complement right */
83              ASSERT_ALWAYS (sizeof (size) >= 4);
84
85              size = i + zeros;
86              if (neg)
87                size = -size;
88
89              fp = fopen_wplusb_or_die (FILENAME);
90              for (j = 3; j >= 0; j--)
91                ASSERT_ALWAYS (putc ((size >> (j*8)) & 0xFF, fp) != EOF);
92              for (j = 0; j < zeros; j++)
93                ASSERT_ALWAYS (putc ('\0', fp) != EOF);
94              for (j = 0; j < i; j++)
95                ASSERT_ALWAYS (putc (BYTEVAL (j), fp) != EOF);
96              /* and some trailing garbage */
97              ASSERT_ALWAYS (putc ('x', fp) != EOF);
98              ASSERT_ALWAYS (putc ('y', fp) != EOF);
99              ASSERT_ALWAYS (putc ('z', fp) != EOF);
100              ASSERT_ALWAYS (fflush (fp) == 0);
101              rewind (fp);
102
103              got_ret = mpz_inp_raw (got, fp);
104              ASSERT_ALWAYS (! ferror(fp));
105              ASSERT_ALWAYS (fclose (fp) == 0);
106
107              MPZ_CHECK_FORMAT (got);
108
109              if (got_ret != want_ret)
110                {
111                  printf ("check_in: return value wrong\n");
112                  error = 1;
113                }
114              if (mpz_cmp (got, want) != 0)
115                {
116                  printf ("check_in: result wrong\n");
117                  error = 1;
118                }
119              if (error)
120                {
121                  printf    ("  i=%d zeros=%d neg=%d\n", i, zeros, neg);
122                  printf    ("  got_ret  %u\n", got_ret);
123                  printf    ("  want_ret %u\n", want_ret);
124                  mpz_trace ("  got      ", got);
125                  mpz_trace ("  want     ", want);
126                  abort ();
127                }
128
129              mpz_neg (want, want);
130            }
131        }
132      mpz_mul_2exp (want, want, 8);
133      mpz_add_ui (want, want, (unsigned long) BYTEVAL (i));
134    }
135
136  mpz_clear (want);
137  mpz_clear (got);
138}
139
140
141void
142check_out (void)
143{
144  int        i, j, neg, error = 0;
145  mpz_t      z;
146  char       want[256], got[256], *p;
147  size_t     want_len, got_ret, got_read;
148  mp_size_t  size;
149  FILE       *fp;
150
151  mpz_init (z);
152
153  for (i = 0; i < 32; i++)
154    {
155      for (neg = 0; neg <= 1; neg++)
156        {
157          want_len = i + 4;
158
159          /* need this to get the twos complement right */
160          ASSERT_ALWAYS (sizeof (size) >= 4);
161
162          size = i;
163          if (neg)
164            size = -size;
165
166          p = want;
167          for (j = 3; j >= 0; j--)
168            *p++ = size >> (j*8);
169          for (j = 0; j < i; j++)
170            *p++ = BYTEVAL (j);
171          ASSERT_ALWAYS (p <= want + sizeof (want));
172
173          fp = fopen_wplusb_or_die (FILENAME);
174          got_ret = mpz_out_raw (fp, z);
175          ASSERT_ALWAYS (fflush (fp) == 0);
176          rewind (fp);
177          got_read = fread (got, 1, sizeof(got), fp);
178          ASSERT_ALWAYS (! ferror(fp));
179          ASSERT_ALWAYS (fclose (fp) == 0);
180
181          if (got_ret != want_len)
182            {
183              printf ("check_out: wrong return value\n");
184              error = 1;
185            }
186          if (got_read != want_len)
187            {
188              printf ("check_out: wrong number of bytes read back\n");
189              error = 1;
190            }
191          if (memcmp (want, got, want_len) != 0)
192            {
193              printf ("check_out: wrong data\n");
194              error = 1;
195            }
196          if (error)
197            {
198              printf    ("  i=%d neg=%d\n", i, neg);
199              mpz_trace ("  z", z);
200              printf    ("  got_ret  %u\n", got_ret);
201              printf    ("  got_read %u\n", got_read);
202              printf    ("  want_len %u\n", want_len);
203              printf    ("  want");
204              for (j = 0; j < want_len; j++)
205                printf (" %02X", (unsigned) (unsigned char) want[j]);
206              printf    ("\n");
207              printf    ("  got ");
208              for (j = 0; j < want_len; j++)
209                printf (" %02X", (unsigned) (unsigned char) got[j]);
210              printf    ("\n");
211              abort ();
212            }
213
214          mpz_neg (z, z);
215        }
216      mpz_mul_2exp (z, z, 8);
217      mpz_add_ui (z, z, (unsigned long) BYTEVAL (i));
218    }
219
220  mpz_clear (z);
221}
222
223
224void
225check_rand (void)
226{
227  gmp_randstate_ptr  rands = RANDS;
228  int        i, error = 0;
229  mpz_t      got, want;
230  size_t     inp_ret, out_ret;
231  FILE       *fp;
232
233  mpz_init (want);
234  mpz_init (got);
235
236  for (i = 0; i < 500; i++)
237    {
238      mpz_erandomb (want, rands, 10*BITS_PER_MP_LIMB);
239      mpz_negrandom (want, rands);
240
241      fp = fopen_wplusb_or_die (FILENAME);
242      out_ret = mpz_out_raw (fp, want);
243      ASSERT_ALWAYS (fflush (fp) == 0);
244      rewind (fp);
245      inp_ret = mpz_inp_raw (got, fp);
246      ASSERT_ALWAYS (fclose (fp) == 0);
247
248      MPZ_CHECK_FORMAT (got);
249
250      if (inp_ret != out_ret)
251        {
252          printf ("check_rand: different inp/out return values\n");
253          error = 1;
254        }
255      if (mpz_cmp (got, want) != 0)
256        {
257          printf ("check_rand: wrong result\n");
258          error = 1;
259        }
260      if (error)
261        {
262          printf    ("  out_ret %u\n", out_ret);
263          printf    ("  inp_ret %u\n", inp_ret);
264          mpz_trace ("  want", want);
265          mpz_trace ("  got ", got);
266          abort ();
267        }
268    }
269
270  mpz_clear (got);
271  mpz_clear (want);
272}
273
274
275int
276main (void)
277{
278  tests_start ();
279  mp_trace_base = -16;
280
281  check_in ();
282  check_out ();
283  check_rand ();
284
285  unlink (FILENAME);
286  tests_end ();
287
288  exit (0);
289}
Note: See TracBrowser for help on using the repository browser.