Annotation of OpenXM_contrib/gmp/mpz/inp_str.c, Revision 1.1.1.2
1.1 maekawa 1: /* mpz_inp_str(dest_integer, stream, base) -- Input a number in base
2: BASE from stdio stream STREAM and store the result in DEST_INTEGER.
3:
1.1.1.2 ! maekawa 4: Copyright (C) 1991, 1993, 1994, 1996, 1998, 2000 Free Software Foundation, Inc.
1.1 maekawa 5:
6: This file is part of the GNU MP Library.
7:
8: The GNU MP Library is free software; you can redistribute it and/or modify
1.1.1.2 ! maekawa 9: it under the terms of the GNU Lesser General Public License as published by
! 10: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1 maekawa 11: option) any later version.
12:
13: The GNU MP Library is distributed in the hope that it will be useful, but
14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2 ! maekawa 15: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 16: License for more details.
17:
1.1.1.2 ! maekawa 18: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 19: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21: MA 02111-1307, USA. */
22:
23: #include <stdio.h>
24: #include <ctype.h>
25: #include "gmp.h"
26: #include "gmp-impl.h"
27:
28: static int
1.1.1.2 ! maekawa 29: #if __STDC__
! 30: digit_value_in_base (int c, int base)
! 31: #else
1.1 maekawa 32: digit_value_in_base (c, base)
33: int c;
34: int base;
1.1.1.2 ! maekawa 35: #endif
1.1 maekawa 36: {
37: int digit;
38:
39: if (isdigit (c))
40: digit = c - '0';
41: else if (islower (c))
42: digit = c - 'a' + 10;
43: else if (isupper (c))
44: digit = c - 'A' + 10;
45: else
46: return -1;
47:
48: if (digit < base)
49: return digit;
50: return -1;
51: }
52:
53: size_t
54: #if __STDC__
1.1.1.2 ! maekawa 55: mpz_inp_str (mpz_ptr x, FILE *stream, int base)
1.1 maekawa 56: #else
1.1.1.2 ! maekawa 57: mpz_inp_str (x, stream, base)
! 58: mpz_ptr x;
1.1 maekawa 59: FILE *stream;
60: int base;
61: #endif
62: {
63: char *str;
64: size_t alloc_size, str_size;
65: int c;
66: int negative;
1.1.1.2 ! maekawa 67: mp_size_t xsize;
1.1 maekawa 68: size_t nread;
69:
70: if (stream == 0)
71: stream = stdin;
72:
73: nread = 0;
74:
75: /* Skip whitespace. */
76: do
77: {
78: c = getc (stream);
79: nread++;
80: }
81: while (isspace (c));
82:
83: negative = 0;
84: if (c == '-')
85: {
86: negative = 1;
87: c = getc (stream);
1.1.1.2 ! maekawa 88: nread++;
1.1 maekawa 89: }
90:
91: if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
92: return 0; /* error if no digits */
93:
94: /* If BASE is 0, try to find out the base by looking at the initial
95: characters. */
96: if (base == 0)
97: {
98: base = 10;
99: if (c == '0')
100: {
101: base = 8;
102: c = getc (stream);
103: nread++;
104: if (c == 'x' || c == 'X')
105: {
106: base = 16;
107: c = getc (stream);
108: nread++;
109: }
1.1.1.2 ! maekawa 110: else if (c == 'b' || c == 'B')
! 111: {
! 112: base = 2;
! 113: c = getc (stream);
! 114: nread++;
! 115: }
1.1 maekawa 116: }
117: }
118:
1.1.1.2 ! maekawa 119: /* Skip leading zeros. */
! 120: while (c == '0')
! 121: {
! 122: c = getc (stream);
! 123: nread++;
! 124: }
! 125:
! 126: alloc_size = 100;
! 127: str = (char *) (*_mp_allocate_func) (alloc_size);
! 128: str_size = 0;
! 129:
1.1 maekawa 130: for (;;)
131: {
132: int dig;
133: if (str_size >= alloc_size)
134: {
135: size_t old_alloc_size = alloc_size;
136: alloc_size = alloc_size * 3 / 2;
137: str = (char *) (*_mp_reallocate_func) (str, old_alloc_size, alloc_size);
138: }
139: dig = digit_value_in_base (c, base);
140: if (dig < 0)
141: break;
142: str[str_size++] = dig;
143: c = getc (stream);
144: }
145:
146: ungetc (c, stream);
147:
1.1.1.2 ! maekawa 148: /* Make sure the string is not empty, mpn_set_str would fail. */
! 149: if (str_size == 0)
! 150: {
! 151: x->_mp_size = 0;
! 152: (*_mp_free_func) (str, alloc_size);
! 153: return nread;
! 154: }
1.1 maekawa 155:
1.1.1.2 ! maekawa 156: xsize = (((mp_size_t) (str_size / __mp_bases[base].chars_per_bit_exactly))
! 157: / BITS_PER_MP_LIMB + 2);
! 158: if (x->_mp_alloc < xsize)
! 159: _mpz_realloc (x, xsize);
! 160:
! 161: /* Convert the byte array in base BASE to our bignum format. */
! 162: xsize = mpn_set_str (x->_mp_d, (unsigned char *) str, str_size, base);
! 163: x->_mp_size = negative ? -xsize : xsize;
1.1 maekawa 164:
165: (*_mp_free_func) (str, alloc_size);
166: return str_size + nread;
167: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>