diff options
author | Guido van Rossum <guido@python.org> | 1999-03-25 21:16:07 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1999-03-25 21:16:07 (GMT) |
commit | 1195023b8987a44be54399a075bbfe26c693786c (patch) | |
tree | 79a300e3282ff8884efa8b6d536e18836659dc02 | |
parent | 5fc9c869ddcbc6680969ebd026c819f71525a761 (diff) | |
download | cpython-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.c | 137 |
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; |