github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-str.c (about) 1 /* 2 3 Copyright 2012-2014, 2016 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 <assert.h> 21 #include <limits.h> 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 26 #include "testutils.h" 27 28 #define MAXBITS 400 29 #define COUNT 2000 30 31 #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) 32 #define MAXLIMBS ((MAXBITS + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS) 33 34 static void 35 test_small (void) 36 { 37 struct { 38 const char *input; 39 const char *decimal; 40 } data[] = { 41 { "183407", "183407" }, 42 { " 763959", "763959 " }, 43 { "9 81999", "981999" }, 44 { "10\t7398 ", "107398" }, 45 { "-9585 44", "-00958544" }, 46 { "-0", "0000" }, 47 { " -000 ", "0" }, 48 { "0704436", "231710" }, 49 /* Check the case of large number of leading zeros. */ 50 { "0000000000000000000000000", "0000000000000000000000000" }, 51 { "000000000000000000000000704436", "000000000000000000000000231710" }, 52 { " 02503517", "689999" }, 53 { "0 1312143", "365667" }, 54 { "-03 274062", "-882738" }, 55 { "012\t242", "005282" }, 56 { "0b11010111110010001111", "883855" }, 57 { " 0b11001010010100001", "103585" }, 58 { "-0b101010110011101111", "-175343" }, 59 { "0b 1111111011011100110", "521958" }, 60 { "0b1 1111110111001000011", "1044035" }, 61 { " 0x53dfc", "343548" }, 62 { "0xfA019", "1024025" }, 63 { "0x 642d1", "410321" }, 64 { "0x5 8067", "360551" }, 65 { "-0xd6Be6", "-879590" }, 66 { "\t0B1110000100000000011", "460803" }, 67 { "0B\t1111110010010100101", "517285" }, 68 { "0B1\t010111101101110100", "359284" }, 69 { "-0B101\t1001101111111001", "-367609" }, 70 { "0B10001001010111110000", "562672" }, 71 { "0Xe4B7e", "936830" }, 72 { "0X1E4bf", "124095" }, 73 { "-0Xfdb90", "-1039248" }, 74 { "0X7fc47", "523335" }, 75 { "0X8167c", "530044" }, 76 /* Some invalid inputs */ 77 { "", NULL }, 78 { "0x", NULL }, 79 { "0b", NULL }, 80 { "0z", NULL }, 81 { "-", NULL }, 82 { "-0x ", NULL }, 83 { "0|1", NULL }, 84 { "4+4", NULL }, 85 { "0ab", NULL }, 86 { "10x0", NULL }, 87 { "0xxab", NULL }, 88 { "ab", NULL }, 89 { "0%#", NULL }, 90 { "$foo", NULL }, 91 { NULL, NULL } 92 }; 93 unsigned i; 94 mpz_t a, b; 95 mpz_init (b); 96 97 for (i = 0; data[i].input; i++) 98 { 99 int res = mpz_init_set_str (a, data[i].input, 0); 100 if (data[i].decimal) 101 { 102 if (res != 0) 103 { 104 fprintf (stderr, "mpz_set_str returned -1, input: %s\n", 105 data[i].input); 106 abort (); 107 } 108 if (mpz_set_str (b, data[i].decimal, 10) != 0) 109 { 110 fprintf (stderr, "mpz_set_str returned -1, decimal input: %s\n", 111 data[i].input); 112 abort (); 113 } 114 if (mpz_cmp (a, b) != 0) 115 { 116 fprintf (stderr, "mpz_set_str failed for input: %s\n", 117 data[i].input); 118 119 dump ("got", a); 120 dump ("ref", b); 121 abort (); 122 } 123 } 124 else if (res != -1) 125 { 126 fprintf (stderr, "mpz_set_str returned %d, invalid input: %s\n", 127 res, data[i].input); 128 abort (); 129 } 130 mpz_clear (a); 131 } 132 133 mpz_clear (b); 134 } 135 136 void 137 testmain (int argc, char **argv) 138 { 139 unsigned i; 140 char *ap; 141 char *bp; 142 char *rp; 143 size_t bn, rn, arn; 144 145 mpz_t a, b; 146 147 FILE *tmp; 148 149 test_small (); 150 151 mpz_init (a); 152 mpz_init (b); 153 154 tmp = tmpfile (); 155 if (!tmp) 156 fprintf (stderr, 157 "Failed to create temporary file. Skipping mpz_out_str tests.\n"); 158 159 for (i = 0; i < COUNT; i++) 160 { 161 int base; 162 for (base = 0; base <= 36; base += 1 + (base == 0)) 163 { 164 hex_random_str_op (MAXBITS, i&1 ? base: -base, &ap, &rp); 165 if (mpz_set_str (a, ap, 16) != 0) 166 { 167 fprintf (stderr, "mpz_set_str failed on input %s\n", ap); 168 abort (); 169 } 170 171 rn = strlen (rp); 172 arn = rn - (rp[0] == '-'); 173 174 bn = mpz_sizeinbase (a, base ? base : 10); 175 if (bn < arn || bn > (arn + 1)) 176 { 177 fprintf (stderr, "mpz_sizeinbase failed:\n"); 178 dump ("a", a); 179 fprintf (stderr, "r = %s\n", rp); 180 fprintf (stderr, " base %d, correct size %u, got %u\n", 181 base, (unsigned) arn, (unsigned)bn); 182 abort (); 183 } 184 bp = mpz_get_str (NULL, i&1 ? base: -base, a); 185 if (strcmp (bp, rp)) 186 { 187 fprintf (stderr, "mpz_get_str failed:\n"); 188 dump ("a", a); 189 fprintf (stderr, "b = %s\n", bp); 190 fprintf (stderr, " base = %d\n", base); 191 fprintf (stderr, "r = %s\n", rp); 192 abort (); 193 } 194 195 /* Just a few tests with file i/o. */ 196 if (tmp && i < 20) 197 { 198 size_t tn; 199 rewind (tmp); 200 tn = mpz_out_str (tmp, i&1 ? base: -base, a); 201 if (tn != rn) 202 { 203 fprintf (stderr, "mpz_out_str, bad return value:\n"); 204 dump ("a", a); 205 fprintf (stderr, "r = %s\n", rp); 206 fprintf (stderr, " base %d, correct size %u, got %u\n", 207 base, (unsigned) rn, (unsigned)tn); 208 abort (); 209 } 210 rewind (tmp); 211 memset (bp, 0, rn); 212 tn = fread (bp, 1, rn, tmp); 213 if (tn != rn) 214 { 215 fprintf (stderr, 216 "fread failed, expected %lu bytes, got only %lu.\n", 217 (unsigned long) rn, (unsigned long) tn); 218 abort (); 219 } 220 221 if (memcmp (bp, rp, rn) != 0) 222 { 223 fprintf (stderr, "mpz_out_str failed:\n"); 224 dump ("a", a); 225 fprintf (stderr, "b = %s\n", bp); 226 fprintf (stderr, " base = %d\n", base); 227 fprintf (stderr, "r = %s\n", rp); 228 abort (); 229 } 230 } 231 232 mpz_set_str (b, rp, base); 233 234 if (mpz_cmp (a, b)) 235 { 236 fprintf (stderr, "mpz_set_str failed:\n"); 237 fprintf (stderr, "r = %s\n", rp); 238 fprintf (stderr, " base = %d\n", base); 239 fprintf (stderr, "r = %s\n", ap); 240 fprintf (stderr, " base = 16\n"); 241 dump ("b", b); 242 dump ("r", a); 243 abort (); 244 } 245 246 /* Test mpn interface */ 247 if (base && mpz_sgn (a)) 248 { 249 size_t i; 250 const char *absr; 251 mp_limb_t t[MAXLIMBS]; 252 mp_size_t tn = mpz_size (a); 253 254 assert (tn <= MAXLIMBS); 255 mpn_copyi (t, a->_mp_d, tn); 256 257 bn = mpn_get_str ((unsigned char *) bp, base, t, tn); 258 if (bn != arn) 259 { 260 fprintf (stderr, "mpn_get_str failed:\n"); 261 fprintf (stderr, "returned length: %lu (bad)\n", (unsigned long) bn); 262 fprintf (stderr, "expected: %lu\n", (unsigned long) arn); 263 fprintf (stderr, " base = %d\n", base); 264 fprintf (stderr, "r = %s\n", ap); 265 fprintf (stderr, " base = 16\n"); 266 dump ("b", b); 267 dump ("r", a); 268 abort (); 269 } 270 absr = rp + (rp[0] == '-'); 271 272 for (i = 0; i < bn; i++) 273 { 274 unsigned char digit = absr[i]; 275 unsigned value; 276 if (digit >= '0' && digit <= '9') 277 value = digit - '0'; 278 else if (digit >= 'a' && digit <= 'z') 279 value = digit - 'a' + 10; 280 else if (digit >= 'A' && digit <= 'Z') 281 value = digit - 'A' + 10; 282 else 283 { 284 fprintf (stderr, "Internal error in test.\n"); 285 abort(); 286 } 287 if (bp[i] != value) 288 { 289 fprintf (stderr, "mpn_get_str failed:\n"); 290 fprintf (stderr, "digit %lu: %d (bad)\n", (unsigned long) i, bp[i]); 291 fprintf (stderr, "expected: %d\n", value); 292 fprintf (stderr, " base = %d\n", base); 293 fprintf (stderr, "r = %s\n", ap); 294 fprintf (stderr, " base = 16\n"); 295 dump ("b", b); 296 dump ("r", a); 297 abort (); 298 } 299 } 300 tn = mpn_set_str (t, (unsigned char *) bp, bn, base); 301 if (tn != mpz_size (a) || mpn_cmp (t, a->_mp_d, tn)) 302 { 303 fprintf (stderr, "mpn_set_str failed:\n"); 304 fprintf (stderr, "r = %s\n", rp); 305 fprintf (stderr, " base = %d\n", base); 306 fprintf (stderr, "r = %s\n", ap); 307 fprintf (stderr, " base = 16\n"); 308 dump ("r", a); 309 abort (); 310 } 311 } 312 free (ap); 313 free (rp); 314 testfree (bp); 315 } 316 } 317 mpz_clear (a); 318 mpz_clear (b); 319 }