summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2009-03-19 17:05:09 +0000
committerenge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2009-03-19 17:05:09 +0000
commit4c14321905768e1a782384c38c49a9c66e3c1308 (patch)
treef27a1e4344bbd162916d9f2eab8f3fb5d8f49569
parent2e8fe025b2ac45daec5a2c1b0437b71b7e36c1a6 (diff)
downloadmpc-4c14321905768e1a782384c38c49a9c66e3c1308.tar.gz
inp_str, out_str: totally rewritten according to the format of strtoc;
inp_str sets the number to nan+i*nan in case of an error git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@483 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r--doc/mpc.texi40
-rw-r--r--src/get_str.c2
-rw-r--r--src/inp_str.c147
-rw-r--r--src/out_str.c36
-rw-r--r--tests/inp_str.dat14
5 files changed, 124 insertions, 115 deletions
diff --git a/doc/mpc.texi b/doc/mpc.texi
index ed99f2d..4364964 100644
--- a/doc/mpc.texi
+++ b/doc/mpc.texi
@@ -913,42 +913,20 @@ When using any of these functions, you need to include @file{stdio.h}
@emph{before} @file{mpc.h}.
@deftypefun size_t mpc_out_str (FILE *@var{stream}, int @var{base}, size_t @var{n_digits}, mpc_t @var{op}, mpc_rnd_t @var{rnd})
-Output @var{op} on stdio stream @var{stream}, in
-base @var{base}, rounded according to @var{rnd}.
-First the real part is printed, then @code{+I*} followed by the imaginary part.
-The base may vary from 2 to 36. Print at most
-@var{n_digits} significant digits for each part,
-or if @var{n_digits} is 0, enough digits so that
-@var{op} can be read back exactly rounding to nearest.
-
-In addition to the significant digits, a decimal point at the right of the
-first digit and a
-trailing exponent, in the form @samp{eNNN}, are printed. If @var{base}
-is greater than 10, @samp{@@} will be used instead of @samp{e} as
-exponent delimiter.
+Output @var{op} on stdio stream @var{stream} in
+base @var{base}, rounded according to @var{rnd}, in the same format
+as for @code{mpc_strtoc}
Return the number of characters written.
@end deftypefun
@deftypefun size_t mpc_inp_str (mpc_t @var{rop}, FILE *@var{stream}, int @var{base}, mpc_rnd_t @var{rnd})
-Input a string in base @var{base} from stdio stream @var{stream},
-rounded according to @var{rnd}, and put the
-read complex in @var{rop}.
-Each of the real and imaginary part should be of the form @samp{M@@N} or,
-if the base is 10 or less, alternatively @samp{MeN} or @samp{MEN}.
-@samp{M} is the mantissa and
-@samp{N} is the exponent. The mantissa is always in the specified base. The
-exponent is always read in decimal.
-This function first reads the real part, then @code{+} or @code{-} followed by
-@code{I*} or @code{i*} and the absolute value of the imaginary part.
-
-The argument @var{base} may be in the range 2 to 36.
-
-Note: since the real part is read with @code{mpfr_inp_str}, it should be
-followed by a whitespace, thus @code{17+I*42} is invalid, but
-@code{17 +I*42} is valid.
-
-Return the number of bytes read, or if an error occurred, return 0.
+Input a string in base @var{base} in the same format as for
+@code{mpc_strtoc} from stdio stream @var{stream},
+rounded according to @var{rnd}, and put the read complex number into @var{rop}.
+Return the number of bytes read.
+
+If an error occurs, set @var{rop} to @code{NaN + i * NaN} and return 0.
@end deftypefun
@node Miscellaneous Complex Functions, Advanced Functions, I/O of Complex Numbers, Complex Functions
diff --git a/src/get_str.c b/src/get_str.c
index 8b065ae..aaa3fff 100644
--- a/src/get_str.c
+++ b/src/get_str.c
@@ -42,7 +42,7 @@ MA 02111-1307, USA. */
#endif
static char *
-mpc_alloc_str (int len) {
+mpc_alloc_str (size_t len) {
void * (*allocfunc) (size_t);
mp_get_memory_functions (&allocfunc, NULL, NULL);
return (char *) ((*allocfunc) (len * sizeof (char)));
diff --git a/src/inp_str.c b/src/inp_str.c
index 31565f8..1b25fa0 100644
--- a/src/inp_str.c
+++ b/src/inp_str.c
@@ -1,6 +1,6 @@
/* mpc_inp_str -- Input a complex number from a given stream.
-Copyright (C) 2002, 2009 Andreas Enge, Paul Zimmermann, Philippe Th\'eveny
+Copyright (C) 2009 Andreas Enge
This file is part of the MPC Library.
@@ -21,60 +21,99 @@ MA 02111-1307, USA. */
#include <stdio.h>
#include <ctype.h>
+#include <string.h>
#include "mpc-impl.h"
-size_t
-mpc_inp_str (mpc_ptr rop, FILE *stream, int base, mpc_rnd_t rnd_mode)
-{
- size_t size, size_im;
- int c;
- int sign;
-
- if (stream == NULL)
- stream = stdin;
-
- /* input real part */
- size = mpfr_inp_str (MPC_RE(rop), stream, base, MPC_RND_RE(rnd_mode));
- if (size == 0) /* error while reading the real part */
- return 0;
-
- /* get 'i' or 'I' followed by '*' */
- do
- {
+static size_t
+skip_whitespace (FILE *stream) {
+ int c = getc (stream);
+ size_t size = 0;
+ while (c != EOF && isspace ((unsigned char) c)) {
c = getc (stream);
- size ++;
- }
- while (isspace (c));
-
- switch (c)
- {
- case '+':
- sign = 0;
- break;
- case '-':
- sign = 1;
- break;
- default:
- /* error */
- return 0;
- }
-
- c = getc (stream);
- size ++;
- if (c != 'I' && c != 'i')
- return 0; /* error */
-
- c = getc (stream);
- size ++;
- if (c != '*')
- return 0; /* error */
-
- size_im = mpfr_inp_str (MPC_IM(rop), stream, base, MPC_RND_IM(rnd_mode));
- if (size_im == 0) /* error while reading the imaginary part */
- return 0;
-
- if (sign)
- mpfr_setsign (MPC_IM (rop), MPC_IM (rop), sign, GMP_RNDN);
-
- return size + size_im;
+ size++;
+ }
+ if (c != EOF)
+ ungetc (c, stream);
+ return size;
+}
+
+
+static char *
+mpc_alloc_str (size_t len) {
+ void * (*allocfunc) (size_t);
+ mp_get_memory_functions (&allocfunc, NULL, NULL);
+ return (char *) ((*allocfunc) (len * sizeof (char)));
+}
+
+
+static char *
+mpc_realloc_str (char * str, size_t oldlen, size_t newlen) {
+ void * (*reallocfunc) (void *, size_t, size_t);
+ mp_get_memory_functions (NULL, &reallocfunc, NULL);
+ return (char *) ((*reallocfunc) (str, oldlen * sizeof (char),
+ newlen * sizeof (char)));
+}
+
+
+static void
+mpc_free_str_len (char *str, size_t len) {
+ void (*freefunc) (void *, size_t);
+ mp_get_memory_functions (NULL, NULL, &freefunc);
+ (*freefunc) (str, len * sizeof (char));
+}
+
+
+
+size_t
+mpc_inp_str (mpc_ptr rop, FILE *stream, int base, mpc_rnd_t rnd_mode) {
+ size_t size, nread;
+ int c;
+
+ if (stream == NULL)
+ stream = stdin;
+
+ size = skip_whitespace (stream);
+ c = getc (stream);
+ if (c != EOF) {
+ if (c != '(') {
+ /* real number without parentheses */
+ ungetc (c, stream);
+ nread = mpfr_inp_str (MPC_RE(rop), stream, base, MPC_RND_RE(rnd_mode));
+ if (nread != 0) {
+ size += nread;
+ mpfr_set_ui (MPC_IM(rop), 0ul, GMP_RNDN);
+ return size;
+ }
+ }
+ else {
+ /* Complex number in parentheses; read everything from '(' to ')'
+ into a string and have mpc_setstr do the work */
+ size_t strsize = 100;
+ char *str = mpc_alloc_str (strsize);
+ nread = 0;
+ while (c != EOF && c != ')') {
+ str [nread] = (char) c;
+ nread++;
+ if (nread == strsize) {
+ str = mpc_realloc_str (str, strsize, 2 * strsize);
+ strsize *= 2;
+ }
+ c = getc (stream);
+ }
+ if (c != EOF) {
+ str [nread] = ')';
+ nread++;
+ str = mpc_realloc_str (str, strsize, nread + 1);
+ str [nread] = '\0';
+ size += nread;
+ if (mpc_set_str (rop, str, base, rnd_mode) != -1)
+ return size;
+ }
+ mpc_free_str_len (str, strsize);
+ }
+ }
+
+ mpfr_set_nan (MPC_RE(rop));
+ mpfr_set_nan (MPC_IM(rop));
+ return 0;
}
diff --git a/src/out_str.c b/src/out_str.c
index f0a724f..080130e 100644
--- a/src/out_str.c
+++ b/src/out_str.c
@@ -1,6 +1,6 @@
/* mpc_out_str -- Output a complex number on a given stream.
-Copyright (C) 2002, 2009 Andreas Enge, Paul Zimmermann, Philippe Th\'eveny
+Copyright (C) 2009 Andreas Enge
This file is part of the MPC Library.
@@ -24,25 +24,17 @@ MA 02111-1307, USA. */
#include "mpc-impl.h"
size_t
-mpc_out_str (FILE *stream, int base, size_t n, mpc_srcptr op, mpc_rnd_t rnd)
-{
- mpfr_t positive_imag;
- size_t size;
-
- if (stream == NULL)
- stream = stdout; /* fprintf does not allow NULL as first argument */
-
- size = mpfr_out_str (stream, base, n, MPC_RE(op), MPC_RND_RE(rnd));
-
- positive_imag[0] = MPC_IM (op)[0];
- if (mpfr_signbit (MPC_IM (op)))
- {
- size += fprintf (stream, " -I*");
- mpfr_setsign (positive_imag, positive_imag, 0, GMP_RNDN);
- }
- else
- size += fprintf (stream, " +I*");
- size += mpfr_out_str (stream, base, n, positive_imag, MPC_RND_IM(rnd));
-
- return size;
+mpc_out_str (FILE *stream, int base, size_t n, mpc_srcptr op, mpc_rnd_t rnd) {
+ size_t size = 3; /* for '(', ' ' and ')' */
+
+ if (stream == NULL)
+ stream = stdout; /* fprintf does not allow NULL as first argument */
+
+ fprintf (stream, "(");
+ size += mpfr_out_str (stream, base, n, MPC_RE(op), MPC_RND_RE(rnd));
+ fprintf (stream, " ");
+ size += mpfr_out_str (stream, base, n, MPC_IM(op), MPC_RND_RE(rnd));
+ fprintf (stream, ")");
+
+ return size;
}
diff --git a/tests/inp_str.dat b/tests/inp_str.dat
index 418c697..1416581 100644
--- a/tests/inp_str.dat
+++ b/tests/inp_str.dat
@@ -19,10 +19,10 @@
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
#
-1 +I*1
-1 -i*1
-invalid_real_part +I*1
-17 invalid_imaginary_part
-17 +unvalid_imaginary_part
-17 +Iunvalid_imaginary_part
-17 +I*unvalid_imaginary_part
+(1 1)
+(1 -1)
+(invalid_real_part 1)
+(17 invalid_imaginary_part)
+(17 +unvalid_imaginary_part)
+(17 +unvalid_imaginary_part)
+(17 +unvalid_imaginary_part)