| OLD | NEW |
| (Empty) |
| 1 /* mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated | |
| 2 string STRING in base BASE to multiple precision integer in | |
| 3 MP_DEST. Allow white space in the string. If BASE == 0 determine | |
| 4 the base in the C standard way, i.e. 0xhh...h means base 16, | |
| 5 0oo...o means base 8, otherwise assume base 10. | |
| 6 | |
| 7 Copyright 1991, 1993, 1994, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005 | |
| 8 Free Software Foundation, Inc. | |
| 9 | |
| 10 This file is part of the GNU MP Library. | |
| 11 | |
| 12 The GNU MP Library is free software; you can redistribute it and/or modify | |
| 13 it under the terms of the GNU Lesser General Public License as published by | |
| 14 the Free Software Foundation; either version 3 of the License, or (at your | |
| 15 option) any later version. | |
| 16 | |
| 17 The GNU MP Library is distributed in the hope that it will be useful, but | |
| 18 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| 19 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
| 20 License for more details. | |
| 21 | |
| 22 You should have received a copy of the GNU Lesser General Public License | |
| 23 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ | |
| 24 | |
| 25 #include <string.h> | |
| 26 #include <ctype.h> | |
| 27 #include "gmp.h" | |
| 28 #include "gmp-impl.h" | |
| 29 | |
| 30 extern const unsigned char __gmp_digit_value_tab[]; | |
| 31 #define digit_value_tab __gmp_digit_value_tab | |
| 32 | |
| 33 int | |
| 34 mpz_set_str (mpz_ptr x, const char *str, int base) | |
| 35 { | |
| 36 size_t str_size; | |
| 37 char *s, *begs; | |
| 38 size_t i; | |
| 39 mp_size_t xsize; | |
| 40 int c; | |
| 41 int negative; | |
| 42 const unsigned char *digit_value; | |
| 43 TMP_DECL; | |
| 44 | |
| 45 digit_value = digit_value_tab; | |
| 46 if (base > 36) | |
| 47 { | |
| 48 /* For bases > 36, use the collating sequence | |
| 49 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz. */ | |
| 50 digit_value += 224; | |
| 51 if (base > 62) | |
| 52 return -1; /* too large base */ | |
| 53 } | |
| 54 | |
| 55 /* Skip whitespace. */ | |
| 56 do | |
| 57 c = (unsigned char) *str++; | |
| 58 while (isspace (c)); | |
| 59 | |
| 60 negative = 0; | |
| 61 if (c == '-') | |
| 62 { | |
| 63 negative = 1; | |
| 64 c = (unsigned char) *str++; | |
| 65 } | |
| 66 | |
| 67 if (digit_value[c] >= (base == 0 ? 10 : base)) | |
| 68 return -1; /* error if no valid digits */ | |
| 69 | |
| 70 /* If BASE is 0, try to find out the base by looking at the initial | |
| 71 characters. */ | |
| 72 if (base == 0) | |
| 73 { | |
| 74 base = 10; | |
| 75 if (c == '0') | |
| 76 { | |
| 77 base = 8; | |
| 78 c = (unsigned char) *str++; | |
| 79 if (c == 'x' || c == 'X') | |
| 80 { | |
| 81 base = 16; | |
| 82 c = (unsigned char) *str++; | |
| 83 } | |
| 84 else if (c == 'b' || c == 'B') | |
| 85 { | |
| 86 base = 2; | |
| 87 c = (unsigned char) *str++; | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 /* Skip leading zeros and white space. */ | |
| 93 while (c == '0' || isspace (c)) | |
| 94 c = (unsigned char) *str++; | |
| 95 /* Make sure the string does not become empty, mpn_set_str would fail. */ | |
| 96 if (c == 0) | |
| 97 { | |
| 98 x->_mp_size = 0; | |
| 99 return 0; | |
| 100 } | |
| 101 | |
| 102 TMP_MARK; | |
| 103 str_size = strlen (str - 1); | |
| 104 s = begs = (char *) TMP_ALLOC (str_size + 1); | |
| 105 | |
| 106 /* Remove spaces from the string and convert the result from ASCII to a | |
| 107 byte array. */ | |
| 108 for (i = 0; i < str_size; i++) | |
| 109 { | |
| 110 if (!isspace (c)) | |
| 111 { | |
| 112 int dig = digit_value[c]; | |
| 113 if (dig >= base) | |
| 114 { | |
| 115 TMP_FREE; | |
| 116 return -1; | |
| 117 } | |
| 118 *s++ = dig; | |
| 119 } | |
| 120 c = (unsigned char) *str++; | |
| 121 } | |
| 122 | |
| 123 str_size = s - begs; | |
| 124 | |
| 125 xsize = (((mp_size_t) (str_size / __mp_bases[base].chars_per_bit_exactly)) | |
| 126 / GMP_NUMB_BITS + 2); | |
| 127 MPZ_REALLOC (x, xsize); | |
| 128 | |
| 129 /* Convert the byte array in base BASE to our bignum format. */ | |
| 130 xsize = mpn_set_str (x->_mp_d, (unsigned char *) begs, str_size, base); | |
| 131 x->_mp_size = negative ? -xsize : xsize; | |
| 132 | |
| 133 TMP_FREE; | |
| 134 return 0; | |
| 135 } | |
| OLD | NEW |