Annotation of OpenXM_contrib/gmp/mpz/set_str.c, Revision 1.1.1.3
1.1 maekawa 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:
1.1.1.3 ! ohara 7: Copyright 1991, 1993, 1994, 1996, 1997, 1998, 2000, 2001, 2002 Free Software
1.1.1.2 maekawa 8: Foundation, Inc.
1.1 maekawa 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
1.1.1.2 maekawa 13: it under the terms of the GNU Lesser General Public License as published by
14: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1 maekawa 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
1.1.1.2 maekawa 19: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 20: License for more details.
21:
1.1.1.2 maekawa 22: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 23: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
24: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25: MA 02111-1307, USA. */
26:
1.1.1.2 maekawa 27: #include <string.h>
1.1 maekawa 28: #include <ctype.h>
29: #include "gmp.h"
30: #include "gmp-impl.h"
31: #include "longlong.h"
32:
33: static int
1.1.1.2 maekawa 34: digit_value_in_base (int c, int base)
1.1 maekawa 35: {
36: int digit;
37:
38: if (isdigit (c))
39: digit = c - '0';
40: else if (islower (c))
41: digit = c - 'a' + 10;
42: else if (isupper (c))
43: digit = c - 'A' + 10;
44: else
45: return -1;
46:
47: if (digit < base)
48: return digit;
49: return -1;
50: }
51:
52: int
53: mpz_set_str (mpz_ptr x, const char *str, int base)
54: {
55: size_t str_size;
56: char *s, *begs;
57: size_t i;
58: mp_size_t xsize;
59: int c;
60: int negative;
61: TMP_DECL (marker);
62:
63: /* Skip whitespace. */
64: do
65: c = *str++;
66: while (isspace (c));
67:
68: negative = 0;
69: if (c == '-')
70: {
71: negative = 1;
72: c = *str++;
73: }
74:
75: if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
76: return -1; /* error if no digits */
77:
78: /* If BASE is 0, try to find out the base by looking at the initial
79: characters. */
80: if (base == 0)
81: {
82: base = 10;
83: if (c == '0')
84: {
85: base = 8;
86: c = *str++;
87: if (c == 'x' || c == 'X')
88: {
89: base = 16;
90: c = *str++;
91: }
1.1.1.2 maekawa 92: else if (c == 'b' || c == 'B')
93: {
94: base = 2;
95: c = *str++;
96: }
1.1 maekawa 97: }
98: }
99:
1.1.1.3 ! ohara 100: /* Skip leading zeros and white space. */
! 101: while (c == '0' || isspace (c))
1.1.1.2 maekawa 102: c = *str++;
103: /* Make sure the string does not become empty, mpn_set_str would fail. */
104: if (c == 0)
105: {
106: x->_mp_size = 0;
107: return 0;
108: }
109:
1.1 maekawa 110: TMP_MARK (marker);
111: str_size = strlen (str - 1);
112: s = begs = (char *) TMP_ALLOC (str_size + 1);
113:
1.1.1.2 maekawa 114: /* Remove spaces from the string and convert the result from ASCII to a
115: byte array. */
1.1 maekawa 116: for (i = 0; i < str_size; i++)
117: {
118: if (!isspace (c))
119: {
120: int dig = digit_value_in_base (c, base);
121: if (dig < 0)
122: {
123: TMP_FREE (marker);
124: return -1;
125: }
126: *s++ = dig;
127: }
128: c = *str++;
129: }
130:
131: str_size = s - begs;
132:
1.1.1.2 maekawa 133: xsize = (((mp_size_t) (str_size / __mp_bases[base].chars_per_bit_exactly))
1.1.1.3 ! ohara 134: / GMP_NUMB_BITS + 2);
1.1 maekawa 135: if (x->_mp_alloc < xsize)
136: _mpz_realloc (x, xsize);
137:
1.1.1.2 maekawa 138: /* Convert the byte array in base BASE to our bignum format. */
1.1 maekawa 139: xsize = mpn_set_str (x->_mp_d, (unsigned char *) begs, str_size, base);
140: x->_mp_size = negative ? -xsize : xsize;
141:
142: TMP_FREE (marker);
143: return 0;
144: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>