Annotation of OpenXM_contrib/gmp/mpz/set_str.c, Revision 1.1.1.2
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.2 ! maekawa 7: Copyright (C) 1991, 1993, 1994, 1996, 1997, 1998, 2000 Free Software
! 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: #if __STDC__
! 35: digit_value_in_base (int c, int base)
! 36: #else
1.1 maekawa 37: digit_value_in_base (c, base)
38: int c;
39: int base;
1.1.1.2 ! maekawa 40: #endif
1.1 maekawa 41: {
42: int digit;
43:
44: if (isdigit (c))
45: digit = c - '0';
46: else if (islower (c))
47: digit = c - 'a' + 10;
48: else if (isupper (c))
49: digit = c - 'A' + 10;
50: else
51: return -1;
52:
53: if (digit < base)
54: return digit;
55: return -1;
56: }
57:
58: int
59: #if __STDC__
60: mpz_set_str (mpz_ptr x, const char *str, int base)
61: #else
62: mpz_set_str (x, str, base)
63: mpz_ptr x;
64: const char *str;
65: int base;
66: #endif
67: {
68: size_t str_size;
69: char *s, *begs;
70: size_t i;
71: mp_size_t xsize;
72: int c;
73: int negative;
74: TMP_DECL (marker);
75:
76: /* Skip whitespace. */
77: do
78: c = *str++;
79: while (isspace (c));
80:
81: negative = 0;
82: if (c == '-')
83: {
84: negative = 1;
85: c = *str++;
86: }
87:
88: if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
89: return -1; /* error if no digits */
90:
91: /* If BASE is 0, try to find out the base by looking at the initial
92: characters. */
93: if (base == 0)
94: {
95: base = 10;
96: if (c == '0')
97: {
98: base = 8;
99: c = *str++;
100: if (c == 'x' || c == 'X')
101: {
102: base = 16;
103: c = *str++;
104: }
1.1.1.2 ! maekawa 105: else if (c == 'b' || c == 'B')
! 106: {
! 107: base = 2;
! 108: c = *str++;
! 109: }
1.1 maekawa 110: }
111: }
112:
1.1.1.2 ! maekawa 113: /* Skip leading zeros. */
! 114: while (c == '0')
! 115: c = *str++;
! 116: /* Make sure the string does not become empty, mpn_set_str would fail. */
! 117: if (c == 0)
! 118: {
! 119: x->_mp_size = 0;
! 120: return 0;
! 121: }
! 122:
1.1 maekawa 123: TMP_MARK (marker);
124: str_size = strlen (str - 1);
125: s = begs = (char *) TMP_ALLOC (str_size + 1);
126:
1.1.1.2 ! maekawa 127: /* Remove spaces from the string and convert the result from ASCII to a
! 128: byte array. */
1.1 maekawa 129: for (i = 0; i < str_size; i++)
130: {
131: if (!isspace (c))
132: {
133: int dig = digit_value_in_base (c, base);
134: if (dig < 0)
135: {
136: TMP_FREE (marker);
137: return -1;
138: }
139: *s++ = dig;
140: }
141: c = *str++;
142: }
143:
144: str_size = s - begs;
145:
1.1.1.2 ! maekawa 146: xsize = (((mp_size_t) (str_size / __mp_bases[base].chars_per_bit_exactly))
! 147: / BITS_PER_MP_LIMB + 2);
1.1 maekawa 148: if (x->_mp_alloc < xsize)
149: _mpz_realloc (x, xsize);
150:
1.1.1.2 ! maekawa 151: /* Convert the byte array in base BASE to our bignum format. */
1.1 maekawa 152: xsize = mpn_set_str (x->_mp_d, (unsigned char *) begs, str_size, base);
153: x->_mp_size = negative ? -xsize : xsize;
154:
155: TMP_FREE (marker);
156: return 0;
157: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>