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