1/* mpfr_inp_str -- input a number in base BASE from stdio stream STREAM
2                   and store the result in ROP
3
4Copyright 1999, 2001, 2002, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
5Contributed by the AriC and Caramel projects, INRIA.
6
7This file is part of the GNU MPFR Library.
8
9The GNU MPFR Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 3 of the License, or (at your
12option) any later version.
13
14The GNU MPFR Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
21http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2251 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24#include <ctype.h>
25
26#include "mpfr-impl.h"
27
28/* The original version of this function came from GMP's mpf/inp_str.c;
29   it has been adapted for MPFR. */
30
31size_t
32mpfr_inp_str (mpfr_ptr rop, FILE *stream, int base, mpfr_rnd_t rnd_mode)
33{
34  unsigned char *str;
35  size_t alloc_size, str_size;
36  int c;
37  int retval;
38  size_t nread;
39
40  if (stream == NULL)
41    stream = stdin;
42
43  alloc_size = 100;
44  str = (unsigned char *) (*__gmp_allocate_func) (alloc_size);
45  str_size = 0;
46  nread = 0;
47
48  /* Skip whitespace.  */
49  do
50    {
51      c = getc (stream);
52      nread++;
53    }
54  while (isspace (c));
55
56  /* number of characters read is nread */
57
58  for (;;)
59    {
60      if (str_size >= alloc_size)
61        {
62          size_t old_alloc_size = alloc_size;
63          alloc_size = alloc_size * 3 / 2;
64          str = (unsigned char *)
65            (*__gmp_reallocate_func) (str, old_alloc_size, alloc_size);
66        }
67      if (c == EOF || isspace (c))
68        break;
69      str[str_size++] = (unsigned char) c;
70      c = getc (stream);
71    }
72  ungetc (c, stream);
73
74  /* number of characters read is nread + str_size - 1 */
75
76  /* we can exit the for loop only by the break instruction,
77     then necessarily str_size >= alloc_size was checked, so
78     now str_size < alloc_size */
79
80  str[str_size] = '\0';
81
82  retval = mpfr_set_str (rop, (char *) str, base, rnd_mode);
83  (*__gmp_free_func) (str, alloc_size);
84
85  if (retval == -1)
86    return 0;                   /* error */
87
88 return str_size + nread - 1;
89}
90