mirror of
https://github.com/python/cpython.git
synced 2025-07-23 11:15:24 +00:00
Patch by Nick and Stephanie Lockwood to implement complex() with a string
argument. This closes TODO item 2.19.
This commit is contained in:
parent
5fc9c869dd
commit
1195023b89
1 changed files with 133 additions and 4 deletions
|
@ -394,6 +394,133 @@ single (interactive) statement, or 'eval' to compile an expression.";
|
||||||
|
|
||||||
#ifndef WITHOUT_COMPLEX
|
#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 *
|
static PyObject *
|
||||||
builtin_complex(self, args)
|
builtin_complex(self, args)
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
|
@ -407,6 +534,8 @@ builtin_complex(self, args)
|
||||||
i = NULL;
|
i = NULL;
|
||||||
if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i))
|
if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (PyString_Check(r))
|
||||||
|
return complex_from_string(r);
|
||||||
if ((nbr = r->ob_type->tp_as_number) == NULL ||
|
if ((nbr = r->ob_type->tp_as_number) == NULL ||
|
||||||
nbr->nb_float == NULL ||
|
nbr->nb_float == NULL ||
|
||||||
(i != NULL &&
|
(i != NULL &&
|
||||||
|
@ -455,11 +584,11 @@ builtin_complex(self, args)
|
||||||
return NULL;
|
return NULL;
|
||||||
cr.real = PyFloat_AsDouble(tmp);
|
cr.real = PyFloat_AsDouble(tmp);
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
cr.imag = 0.;
|
cr.imag = 0.0;
|
||||||
}
|
}
|
||||||
if (i == NULL) {
|
if (i == NULL) {
|
||||||
ci.real = 0.;
|
ci.real = 0.0;
|
||||||
ci.imag = 0.;
|
ci.imag = 0.0;
|
||||||
}
|
}
|
||||||
else if (PyComplex_Check(i))
|
else if (PyComplex_Check(i))
|
||||||
ci = ((PyComplexObject*)i)->cval;
|
ci = ((PyComplexObject*)i)->cval;
|
||||||
|
@ -2032,7 +2161,7 @@ PyObject *PyExc_ZeroDivisionError;
|
||||||
|
|
||||||
PyObject *PyExc_MemoryErrorInst;
|
PyObject *PyExc_MemoryErrorInst;
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
char* name;
|
char* name;
|
||||||
PyObject** exc;
|
PyObject** exc;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue