Annotation of OpenXM_contrib/gmp/mpz/inp_str.c, Revision 1.1.1.1
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:
4: Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
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
9: it under the terms of the GNU Library General Public License as published by
10: the Free Software Foundation; either version 2 of the License, or (at your
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
15: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
16: License for more details.
17:
18: You should have received a copy of the GNU Library General Public License
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
29: digit_value_in_base (c, base)
30: int c;
31: int base;
32: {
33: int digit;
34:
35: if (isdigit (c))
36: digit = c - '0';
37: else if (islower (c))
38: digit = c - 'a' + 10;
39: else if (isupper (c))
40: digit = c - 'A' + 10;
41: else
42: return -1;
43:
44: if (digit < base)
45: return digit;
46: return -1;
47: }
48:
49: size_t
50: #if __STDC__
51: mpz_inp_str (mpz_ptr dest, FILE *stream, int base)
52: #else
53: mpz_inp_str (dest, stream, base)
54: mpz_ptr dest;
55: FILE *stream;
56: int base;
57: #endif
58: {
59: char *str;
60: size_t alloc_size, str_size;
61: int c;
62: int negative;
63: mp_size_t dest_size;
64: size_t nread;
65:
66: if (stream == 0)
67: stream = stdin;
68:
69: alloc_size = 100;
70: str = (char *) (*_mp_allocate_func) (alloc_size);
71: str_size = 0;
72: nread = 0;
73:
74: /* Skip whitespace. */
75: do
76: {
77: c = getc (stream);
78: nread++;
79: }
80: while (isspace (c));
81:
82: negative = 0;
83: if (c == '-')
84: {
85: negative = 1;
86: c = getc (stream);
87: }
88:
89: if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
90: return 0; /* error if no digits */
91:
92: /* If BASE is 0, try to find out the base by looking at the initial
93: characters. */
94: if (base == 0)
95: {
96: base = 10;
97: if (c == '0')
98: {
99: base = 8;
100: c = getc (stream);
101: nread++;
102: if (c == 'x' || c == 'X')
103: {
104: base = 16;
105: c = getc (stream);
106: nread++;
107: }
108: }
109: }
110:
111: for (;;)
112: {
113: int dig;
114: if (str_size >= alloc_size)
115: {
116: size_t old_alloc_size = alloc_size;
117: alloc_size = alloc_size * 3 / 2;
118: str = (char *) (*_mp_reallocate_func) (str, old_alloc_size, alloc_size);
119: }
120: dig = digit_value_in_base (c, base);
121: if (dig < 0)
122: break;
123: str[str_size++] = dig;
124: c = getc (stream);
125: }
126:
127: ungetc (c, stream);
128:
129: dest_size = str_size / __mp_bases[base].chars_per_limb + 1;
130: if (dest->_mp_alloc < dest_size)
131: _mpz_realloc (dest, dest_size);
132:
133: dest_size = mpn_set_str (dest->_mp_d, (unsigned char *) str, str_size, base);
134: dest->_mp_size = negative ? -dest_size : dest_size;
135:
136: (*_mp_free_func) (str, alloc_size);
137: return str_size + nread;
138: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>