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