github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-io_raw.c (about) 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 test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://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 }