Tizen 2.1 base
[external/gmp.git] / tests / mpz / t-io_raw.c
1 /* Test mpz_inp_raw and mpz_out_raw.
2
3 Copyright 2001 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library.
6
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along 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 #include <string.h>
25 #if HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #include "gmp.h"
30 #include "gmp-impl.h"
31 #include "tests.h"
32
33 #define FILENAME  "t-io_raw.tmp"
34
35
36 /* In the fopen, "b" selects binary mode on DOS systems, meaning no
37    conversion of '\n' to and from CRLF.  It's believed systems without such
38    nonsense will simply ignore the "b", but in case that's not so a plain
39    "w+" is attempted if "w+b" fails.  */
40
41 FILE *
42 fopen_wplusb_or_die (const char *filename)
43 {
44   FILE  *fp;
45   fp = fopen (filename, "w+b");
46   if (fp == NULL)
47     fp = fopen (filename, "w+");
48
49   if (fp == NULL)
50     {
51       printf ("Cannot create file %s\n", filename);
52       abort ();
53     }
54   return fp;
55 }
56
57 /* use 0x80 to check nothing bad happens with sign extension etc */
58 #define BYTEVAL(i)  (((i) + 1) | 0x80)
59
60 void
61 check_in (void)
62 {
63   int        i, j, zeros, neg, error = 0;
64   mpz_t      want, got;
65   size_t     want_ret, got_ret;
66   mp_size_t  size;
67   FILE       *fp;
68
69   mpz_init (want);
70   mpz_init (got);
71
72   for (i = 0; i < 32; i++)
73     {
74       for (zeros = 0; zeros < 8; zeros++)
75         {
76           for (neg = 0; neg <= 1; neg++)
77             {
78               want_ret = i + zeros + 4;
79
80               /* need this to get the twos complement right */
81               ASSERT_ALWAYS (sizeof (size) >= 4);
82
83               size = i + zeros;
84               if (neg)
85                 size = -size;
86
87               fp = fopen_wplusb_or_die (FILENAME);
88               for (j = 3; j >= 0; j--)
89                 ASSERT_ALWAYS (putc ((size >> (j*8)) & 0xFF, fp) != EOF);
90               for (j = 0; j < zeros; j++)
91                 ASSERT_ALWAYS (putc ('\0', fp) != EOF);
92               for (j = 0; j < i; j++)
93                 ASSERT_ALWAYS (putc (BYTEVAL (j), fp) != EOF);
94               /* and some trailing garbage */
95               ASSERT_ALWAYS (putc ('x', fp) != EOF);
96               ASSERT_ALWAYS (putc ('y', fp) != EOF);
97               ASSERT_ALWAYS (putc ('z', fp) != EOF);
98               ASSERT_ALWAYS (fflush (fp) == 0);
99               rewind (fp);
100
101               got_ret = mpz_inp_raw (got, fp);
102               ASSERT_ALWAYS (! ferror(fp));
103               ASSERT_ALWAYS (fclose (fp) == 0);
104
105               MPZ_CHECK_FORMAT (got);
106
107               if (got_ret != want_ret)
108                 {
109                   printf ("check_in: return value wrong\n");
110                   error = 1;
111                 }
112               if (mpz_cmp (got, want) != 0)
113                 {
114                   printf ("check_in: result wrong\n");
115                   error = 1;
116                 }
117               if (error)
118                 {
119                   printf    ("  i=%d zeros=%d neg=%d\n", i, zeros, neg);
120                   printf    ("  got_ret  %lu\n", (unsigned long) got_ret);
121                   printf    ("  want_ret %lu\n", (unsigned long) want_ret);
122                   mpz_trace ("  got      ", got);
123                   mpz_trace ("  want     ", want);
124                   abort ();
125                 }
126
127               mpz_neg (want, want);
128             }
129         }
130       mpz_mul_2exp (want, want, 8);
131       mpz_add_ui (want, want, (unsigned long) BYTEVAL (i));
132     }
133
134   mpz_clear (want);
135   mpz_clear (got);
136 }
137
138
139 void
140 check_out (void)
141 {
142   int        i, j, neg, error = 0;
143   mpz_t      z;
144   char       want[256], got[256], *p;
145   size_t     want_len, got_ret, got_read;
146   mp_size_t  size;
147   FILE       *fp;
148
149   mpz_init (z);
150
151   for (i = 0; i < 32; i++)
152     {
153       for (neg = 0; neg <= 1; neg++)
154         {
155           want_len = i + 4;
156
157           /* need this to get the twos complement right */
158           ASSERT_ALWAYS (sizeof (size) >= 4);
159
160           size = i;
161           if (neg)
162             size = -size;
163
164           p = want;
165           for (j = 3; j >= 0; j--)
166             *p++ = size >> (j*8);
167           for (j = 0; j < i; j++)
168             *p++ = BYTEVAL (j);
169           ASSERT_ALWAYS (p <= want + sizeof (want));
170
171           fp = fopen_wplusb_or_die (FILENAME);
172           got_ret = mpz_out_raw (fp, z);
173           ASSERT_ALWAYS (fflush (fp) == 0);
174           rewind (fp);
175           got_read = fread (got, 1, sizeof(got), fp);
176           ASSERT_ALWAYS (! ferror(fp));
177           ASSERT_ALWAYS (fclose (fp) == 0);
178
179           if (got_ret != want_len)
180             {
181               printf ("check_out: wrong return value\n");
182               error = 1;
183             }
184           if (got_read != want_len)
185             {
186               printf ("check_out: wrong number of bytes read back\n");
187               error = 1;
188             }
189           if (memcmp (want, got, want_len) != 0)
190             {
191               printf ("check_out: wrong data\n");
192               error = 1;
193             }
194           if (error)
195             {
196               printf    ("  i=%d neg=%d\n", i, neg);
197               mpz_trace ("  z", z);
198               printf    ("  got_ret  %lu\n", (unsigned long) got_ret);
199               printf    ("  got_read %lu\n", (unsigned long) got_read);
200               printf    ("  want_len %lu\n", (unsigned long) want_len);
201               printf    ("  want");
202               for (j = 0; j < want_len; j++)
203                 printf (" %02X", (unsigned) (unsigned char) want[j]);
204               printf    ("\n");
205               printf    ("  got ");
206               for (j = 0; j < want_len; j++)
207                 printf (" %02X", (unsigned) (unsigned char) got[j]);
208               printf    ("\n");
209               abort ();
210             }
211
212           mpz_neg (z, z);
213         }
214       mpz_mul_2exp (z, z, 8);
215       mpz_add_ui (z, z, (unsigned long) BYTEVAL (i));
216     }
217
218   mpz_clear (z);
219 }
220
221
222 void
223 check_rand (void)
224 {
225   gmp_randstate_ptr  rands = RANDS;
226   int        i, error = 0;
227   mpz_t      got, want;
228   size_t     inp_ret, out_ret;
229   FILE       *fp;
230
231   mpz_init (want);
232   mpz_init (got);
233
234   for (i = 0; i < 500; i++)
235     {
236       mpz_erandomb (want, rands, 10*GMP_LIMB_BITS);
237       mpz_negrandom (want, rands);
238
239       fp = fopen_wplusb_or_die (FILENAME);
240       out_ret = mpz_out_raw (fp, want);
241       ASSERT_ALWAYS (fflush (fp) == 0);
242       rewind (fp);
243       inp_ret = mpz_inp_raw (got, fp);
244       ASSERT_ALWAYS (fclose (fp) == 0);
245
246       MPZ_CHECK_FORMAT (got);
247
248       if (inp_ret != out_ret)
249         {
250           printf ("check_rand: different inp/out return values\n");
251           error = 1;
252         }
253       if (mpz_cmp (got, want) != 0)
254         {
255           printf ("check_rand: wrong result\n");
256           error = 1;
257         }
258       if (error)
259         {
260           printf    ("  out_ret %lu\n", (unsigned long) out_ret);
261           printf    ("  inp_ret %lu\n", (unsigned long) inp_ret);
262           mpz_trace ("  want", want);
263           mpz_trace ("  got ", got);
264           abort ();
265         }
266     }
267
268   mpz_clear (got);
269   mpz_clear (want);
270 }
271
272
273 int
274 main (void)
275 {
276   tests_start ();
277   mp_trace_base = -16;
278
279   check_in ();
280   check_out ();
281   check_rand ();
282
283   unlink (FILENAME);
284   tests_end ();
285
286   exit (0);
287 }