Annotation of OpenXM_contrib/gmp/mpz/inp_str.c, Revision 1.1.1.3
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.3 ! ohara 4: OF THE FUNCTIONS IN THIS FILE, ONLY mpz_inp_str IS FOR EXTERNAL USE, THE
! 5: REST ARE INTERNALS AND ARE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE
! 6: CHANGES OR DISAPPEAR COMPLETELY IN FUTURE GNU MP RELEASES.
! 7:
! 8: Copyright 1991, 1993, 1994, 1996, 1998, 2000, 2001, 2002 Free Software
! 9: Foundation, Inc.
1.1 maekawa 10:
11: This file is part of the GNU MP Library.
12:
13: The GNU MP Library is free software; you can redistribute it and/or modify
1.1.1.2 maekawa 14: it under the terms of the GNU Lesser General Public License as published by
15: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1 maekawa 16: option) any later version.
17:
18: The GNU MP Library is distributed in the hope that it will be useful, but
19: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1.1.1.2 maekawa 20: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1.1 maekawa 21: License for more details.
22:
1.1.1.2 maekawa 23: You should have received a copy of the GNU Lesser General Public License
1.1 maekawa 24: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
25: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26: MA 02111-1307, USA. */
27:
28: #include <stdio.h>
29: #include <ctype.h>
30: #include "gmp.h"
31: #include "gmp-impl.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: size_t
1.1.1.2 maekawa 53: mpz_inp_str (mpz_ptr x, FILE *stream, int base)
1.1 maekawa 54: {
55: int c;
56: size_t nread;
57:
58: if (stream == 0)
59: stream = stdin;
60:
61: nread = 0;
62:
63: /* Skip whitespace. */
64: do
65: {
66: c = getc (stream);
67: nread++;
68: }
69: while (isspace (c));
70:
1.1.1.3 ! ohara 71: return mpz_inp_str_nowhite (x, stream, base, c, nread);
! 72: }
! 73:
! 74: /* shared by mpq_inp_str */
! 75: size_t
! 76: mpz_inp_str_nowhite (mpz_ptr x, FILE *stream, int base, int c, size_t nread)
! 77: {
! 78: char *str;
! 79: size_t alloc_size, str_size;
! 80: int negative;
! 81: mp_size_t xsize;
! 82:
1.1 maekawa 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;
1.1.1.3 ! ohara 127: str = (char *) (*__gmp_allocate_func) (alloc_size);
1.1.1.2 maekawa 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;
1.1.1.3 ! ohara 137: str = (char *) (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
1.1 maekawa 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: }
1.1.1.3 ! ohara 145: nread += str_size;
1.1 maekawa 146:
147: ungetc (c, stream);
1.1.1.3 ! ohara 148: nread--;
1.1 maekawa 149:
1.1.1.2 maekawa 150: /* Make sure the string is not empty, mpn_set_str would fail. */
151: if (str_size == 0)
152: {
153: x->_mp_size = 0;
154: }
1.1.1.3 ! ohara 155: else
! 156: {
! 157: xsize = (((mp_size_t)
! 158: (str_size / __mp_bases[base].chars_per_bit_exactly))
! 159: / GMP_NUMB_BITS + 2);
! 160: if (x->_mp_alloc < xsize)
! 161: _mpz_realloc (x, xsize);
! 162:
! 163: /* Convert the byte array in base BASE to our bignum format. */
! 164: xsize = mpn_set_str (x->_mp_d, (unsigned char *) str, str_size, base);
! 165: x->_mp_size = negative ? -xsize : xsize;
! 166: }
! 167: (*__gmp_free_func) (str, alloc_size);
! 168: return nread;
1.1 maekawa 169: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>