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