summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1999-03-25 21:16:07 (GMT)
committerGuido van Rossum <guido@python.org>1999-03-25 21:16:07 (GMT)
commit1195023b8987a44be54399a075bbfe26c693786c (patch)
tree79a300e3282ff8884efa8b6d536e18836659dc02
parent5fc9c869ddcbc6680969ebd026c819f71525a761 (diff)
downloadcpython-1195023b8987a44be54399a075bbfe26c693786c.zip
cpython-1195023b8987a44be54399a075bbfe26c693786c.tar.gz
cpython-1195023b8987a44be54399a075bbfe26c693786c.tar.bz2
Patch by Nick and Stephanie Lockwood to implement complex() with a string
argument. This closes TODO item 2.19.
-rw-r--r--Python/bltinmodule.c137
1 files changed, 133 insertions, 4 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index b07597c..ec87492 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -395,6 +395,133 @@ single (interactive) statement, or 'eval' to compile an expression.";
#ifndef WITHOUT_COMPLEX
static PyObject *
+complex_from_string(v)
+ PyObject *v;
+{
+ extern double strtod Py_PROTO((const char *, char **));
+ char a, *s, *start, *end;
+ double x=0.0, y=0.0, z;
+ int got_re=0, got_im=0, done=0;
+ int digit_or_dot;
+ int sw_error=0;
+ int sign;
+ char buffer[256]; /* For errors */
+
+ start = s = PyString_AS_STRING(v);
+
+ /* position on first nonblank */
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] == '\0') {
+ PyErr_SetString(PyExc_ValueError,
+ "empty string for complex()");
+ return NULL;
+ }
+
+ z = -1.0;
+ sign = 1;
+ do {
+
+ switch (*s) {
+
+ case '\0':
+ if (s-start != PyString_GET_SIZE(v)) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "null byte in argument for complex()");
+ return NULL;
+ }
+ if(!done) sw_error=1;
+ break;
+
+ case '-':
+ sign = -1;
+ /* Fallthrough */
+ case '+':
+ if (done) sw_error=1;
+ s++;
+ if ( *s=='\0'||*s=='+'||*s=='-' ||
+ isspace(Py_CHARMASK(*s)) ) sw_error=1;
+ break;
+
+ case 'J':
+ case 'j':
+ if (got_im || done) {
+ sw_error = 1;
+ break;
+ }
+ if (z<0.0) {
+ y=sign;
+ }
+ else{
+ y=sign*z;
+ }
+ got_im=1;
+ s++;
+ if (*s!='+' && *s!='-' )
+ done=1;
+ break;
+
+ default:
+ if (isspace(Py_CHARMASK(*s))) {
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] != '\0')
+ sw_error=1;
+ else
+ done = 1;
+ break;
+ }
+ digit_or_dot =
+ (*s=='.' || isdigit(Py_CHARMASK(*s)));
+ if (done||!digit_or_dot) {
+ sw_error=1;
+ break;
+ }
+ errno = 0;
+ PyFPE_START_PROTECT("strtod", return 0)
+ z = strtod(s, &end) ;
+ PyFPE_END_PROTECT(z)
+ if (errno != 0) {
+ sprintf(buffer,
+ "float() out of range: %.150s", s);
+ PyErr_SetString(
+ PyExc_ValueError,
+ buffer);
+ return NULL;
+ }
+ s=end;
+ if (*s=='J' || *s=='j') {
+
+ break;
+ }
+ if (got_re) {
+ sw_error=1;
+ break;
+ }
+
+ /* accept a real part */
+ x=sign*z;
+ got_re=1;
+ if (got_im) done=1;
+ z = -1.0;
+ sign = 1;
+ break;
+
+ } /* end of switch */
+
+ } while (*s!='\0' && !sw_error);
+
+ if (sw_error) {
+ PyErr_SetString(PyExc_ValueError,
+ "malformed string for complex()");
+ return NULL;
+ }
+
+ return PyComplex_FromDoubles(x,y);
+}
+
+static PyObject *
builtin_complex(self, args)
PyObject *self;
PyObject *args;
@@ -407,6 +534,8 @@ builtin_complex(self, args)
i = NULL;
if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i))
return NULL;
+ if (PyString_Check(r))
+ return complex_from_string(r);
if ((nbr = r->ob_type->tp_as_number) == NULL ||
nbr->nb_float == NULL ||
(i != NULL &&
@@ -455,11 +584,11 @@ builtin_complex(self, args)
return NULL;
cr.real = PyFloat_AsDouble(tmp);
Py_DECREF(tmp);
- cr.imag = 0.;
+ cr.imag = 0.0;
}
if (i == NULL) {
- ci.real = 0.;
- ci.imag = 0.;
+ ci.real = 0.0;
+ ci.imag = 0.0;
}
else if (PyComplex_Check(i))
ci = ((PyComplexObject*)i)->cval;
@@ -2032,7 +2161,7 @@ PyObject *PyExc_ZeroDivisionError;
PyObject *PyExc_MemoryErrorInst;
-static struct
+static struct
{
char* name;
PyObject** exc;