static PyObject * complex_subtype_from_string(PyTypeObject *type, PyObject *v) { const char *s, *start; char *end; double x=0.0, y=0.0, z; int got_re=0, got_im=0, got_bracket=0, done=0; int digit_or_dot; int sw_error=0; int sign; char buffer[256]; /* For errors */ #ifdef Py_USING_UNICODE char s_buffer[256]; #endif Py_ssize_t len; if (PyString_Check(v)) { s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); } #ifdef Py_USING_UNICODE else if (PyUnicode_Check(v)) { if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) { PyErr_SetString(PyExc_ValueError, "complex() literal too large to convert"); return NULL; } if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), s_buffer, NULL)) return NULL; s = s_buffer; len = strlen(s); } #endif else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, "complex() arg is not a string"); return NULL; } /* position on first nonblank */ start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; if (s[0] == '\0') { PyErr_SetString(PyExc_ValueError, "complex() arg is an empty string"); return NULL; } if (s[0] == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; while (*s && isspace(Py_CHARMASK(*s))) s++; } z = -1.0; sign = 1; do { switch (*s) { case '\0': if (s-start != len) { PyErr_SetString( PyExc_ValueError, "complex() arg contains a null byte"); return NULL; } if(!done) sw_error=1; break; case ')': if (!got_bracket || !(got_re || got_im)) { sw_error=1; break; } got_bracket=0; done=1; s++; while (*s && isspace(Py_CHARMASK(*s))) s++; if (*s) sw_error=1; break; case '-': sign = -1; /* Fallthrough */ case '+': if (done) sw_error=1; s++; if ( *s=='\0'||*s=='+'||*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 && *s != ')') 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 = PyOS_ascii_strtod(s, &end) ; PyFPE_END_PROTECT(z) if (errno != 0) { PyOS_snprintf(buffer, sizeof(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 - start < len && !sw_error); if (sw_error || got_bracket) { PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); return NULL; } return complex_subtype_from_doubles(type, x, y); }
static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *r, *i, *tmp, *f; PyNumberMethods *nbr, *nbi = NULL; Py_complex cr, ci; int own_r = 0; int cr_is_complex = 0; int ci_is_complex = 0; static PyObject *complexstr; static char *kwlist[] = {"real", "imag", 0}; r = Py_False; i = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:complex", kwlist, &r, &i)) return NULL; /* Special-case for a single argument when type(arg) is complex. */ if (PyComplex_CheckExact(r) && i == NULL && type == &PyComplex_Type) { /* Note that we can't know whether it's safe to return a complex *subclass* instance as-is, hence the restriction to exact complexes here. If either the input or the output is a complex subclass, it will be handled below as a non-orthogonal vector. */ Py_INCREF(r); return r; } if (PyString_Check(r) || PyUnicode_Check(r)) { if (i != NULL) { PyErr_SetString(PyExc_TypeError, "complex() can't take second arg" " if first is a string"); return NULL; } return complex_subtype_from_string(type, r); } if (i != NULL && (PyString_Check(i) || PyUnicode_Check(i))) { PyErr_SetString(PyExc_TypeError, "complex() second arg can't be a string"); return NULL; } /* XXX Hack to support classes with __complex__ method */ if (complexstr == NULL) { complexstr = PyString_InternFromString("__complex__"); if (complexstr == NULL) return NULL; } f = PyObject_GetAttr(r, complexstr); if (f == NULL) PyErr_Clear(); else { PyObject *args = PyTuple_New(0); if (args == NULL) return NULL; r = PyEval_CallObject(f, args); Py_DECREF(args); Py_DECREF(f); if (r == NULL) return NULL; own_r = 1; } nbr = r->ob_type->tp_as_number; if (i != NULL) nbi = i->ob_type->tp_as_number; if (nbr == NULL || nbr->nb_float == NULL || ((i != NULL) && (nbi == NULL || nbi->nb_float == NULL))) { PyErr_SetString(PyExc_TypeError, "complex() argument must be a string or a number"); if (own_r) { Py_DECREF(r); } return NULL; } /* If we get this far, then the "real" and "imag" parts should both be treated as numbers, and the constructor should return a complex number equal to (real + imag*1j). Note that we do NOT assume the input to already be in canonical form; the "real" and "imag" parts might themselves be complex numbers, which slightly complicates the code below. */ if (PyComplex_Check(r)) { /* Note that if r is of a complex subtype, we're only retaining its real & imag parts here, and the return value is (properly) of the builtin complex type. */ cr = ((PyComplexObject*)r)->cval; cr_is_complex = 1; if (own_r) { Py_DECREF(r); } } else { /* The "real" part really is entirely real, and contributes nothing in the imaginary direction. Just treat it as a double. */ tmp = PyNumber_Float(r); if (own_r) { /* r was a newly created complex number, rather than the original "real" argument. */ Py_DECREF(r); } if (tmp == NULL) return NULL; if (!PyFloat_Check(tmp)) { PyErr_SetString(PyExc_TypeError, "float(r) didn't return a float"); Py_DECREF(tmp); return NULL; } cr.real = PyFloat_AsDouble(tmp); cr.imag = 0.0; /* Shut up compiler warning */ Py_DECREF(tmp); } if (i == NULL) { ci.real = 0.0; } else if (PyComplex_Check(i)) { ci = ((PyComplexObject*)i)->cval; ci_is_complex = 1; } else { /* The "imag" part really is entirely imaginary, and contributes nothing in the real direction. Just treat it as a double. */ tmp = (*nbi->nb_float)(i); if (tmp == NULL) return NULL; ci.real = PyFloat_AsDouble(tmp); Py_DECREF(tmp); } /* If the input was in canonical form, then the "real" and "imag" parts are real numbers, so that ci.imag and cr.imag are zero. We need this correction in case they were not real numbers. */ if (ci_is_complex) { cr.real -= ci.imag; } if (cr_is_complex) { ci.real += cr.imag; } return complex_subtype_from_doubles(type, cr.real, ci.real); }
static PyObject * complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) /*[clinic end generated code: output=b6c7dd577b537dc1 input=6f6b0bedba29bcb5]*/ { PyObject *tmp; PyNumberMethods *nbr, *nbi = NULL; Py_complex cr, ci; int own_r = 0; int cr_is_complex = 0; int ci_is_complex = 0; /* Special-case for a single argument when type(arg) is complex. */ if (PyComplex_CheckExact(r) && i == NULL && type == &PyComplex_Type) { /* Note that we can't know whether it's safe to return a complex *subclass* instance as-is, hence the restriction to exact complexes here. If either the input or the output is a complex subclass, it will be handled below as a non-orthogonal vector. */ Py_INCREF(r); return r; } if (PyUnicode_Check(r)) { if (i != NULL) { PyErr_SetString(PyExc_TypeError, "complex() can't take second arg" " if first is a string"); return NULL; } return complex_subtype_from_string(type, r); } if (i != NULL && PyUnicode_Check(i)) { PyErr_SetString(PyExc_TypeError, "complex() second arg can't be a string"); return NULL; } tmp = try_complex_special_method(r); if (tmp) { r = tmp; own_r = 1; } else if (PyErr_Occurred()) { return NULL; } nbr = r->ob_type->tp_as_number; if (nbr == NULL || nbr->nb_float == NULL) { PyErr_Format(PyExc_TypeError, "complex() first argument must be a string or a number, " "not '%.200s'", Py_TYPE(r)->tp_name); if (own_r) { Py_DECREF(r); } return NULL; } if (i != NULL) { nbi = i->ob_type->tp_as_number; if (nbi == NULL || nbi->nb_float == NULL) { PyErr_Format(PyExc_TypeError, "complex() second argument must be a number, " "not '%.200s'", Py_TYPE(i)->tp_name); if (own_r) { Py_DECREF(r); } return NULL; } } /* If we get this far, then the "real" and "imag" parts should both be treated as numbers, and the constructor should return a complex number equal to (real + imag*1j). Note that we do NOT assume the input to already be in canonical form; the "real" and "imag" parts might themselves be complex numbers, which slightly complicates the code below. */ if (PyComplex_Check(r)) { /* Note that if r is of a complex subtype, we're only retaining its real & imag parts here, and the return value is (properly) of the builtin complex type. */ cr = ((PyComplexObject*)r)->cval; cr_is_complex = 1; if (own_r) { Py_DECREF(r); } } else { /* The "real" part really is entirely real, and contributes nothing in the imaginary direction. Just treat it as a double. */ tmp = PyNumber_Float(r); if (own_r) { /* r was a newly created complex number, rather than the original "real" argument. */ Py_DECREF(r); } if (tmp == NULL) return NULL; assert(PyFloat_Check(tmp)); cr.real = PyFloat_AsDouble(tmp); cr.imag = 0.0; Py_DECREF(tmp); } if (i == NULL) { ci.real = cr.imag; } else if (PyComplex_Check(i)) { ci = ((PyComplexObject*)i)->cval; ci_is_complex = 1; } else { /* The "imag" part really is entirely imaginary, and contributes nothing in the real direction. Just treat it as a double. */ tmp = (*nbi->nb_float)(i); if (tmp == NULL) return NULL; ci.real = PyFloat_AsDouble(tmp); Py_DECREF(tmp); } /* If the input was in canonical form, then the "real" and "imag" parts are real numbers, so that ci.imag and cr.imag are zero. We need this correction in case they were not real numbers. */ if (ci_is_complex) { cr.real -= ci.imag; } if (cr_is_complex && i != NULL) { ci.real += cr.imag; } return complex_subtype_from_doubles(type, cr.real, ci.real); }
static PyObject * complex_from_string_inner(const char *s, Py_ssize_t len, void *type) { double x=0.0, y=0.0, z; int got_bracket=0; const char *start; char *end; /* position on first nonblank */ start = s; while (Py_ISSPACE(*s)) s++; if (*s == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; while (Py_ISSPACE(*s)) s++; } /* a valid complex string usually takes one of the three forms: <float> - real part only <float>j - imaginary part only <float><signed-float>j - real and imaginary parts where <float> represents any numeric string that's accepted by the float constructor (including 'nan', 'inf', 'infinity', etc.), and <signed-float> is any string of the form <float> whose first character is '+' or '-'. For backwards compatibility, the extra forms <float><sign>j <sign>j j are also accepted, though support for these forms may be removed from a future version of Python. */ /* first look for forms starting with <float> */ z = PyOS_string_to_double(s, &end, NULL); if (z == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else return NULL; } if (end != s) { /* all 4 forms starting with <float> land here */ s = end; if (*s == '+' || *s == '-') { /* <float><signed-float>j | <float><sign>j */ x = z; y = PyOS_string_to_double(s, &end, NULL); if (y == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else return NULL; } if (end != s) /* <float><signed-float>j */ s = end; else { /* <float><sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } else if (*s == 'j' || *s == 'J') { /* <float>j */ s++; y = z; } else /* <float> */ x = z; } else { /* not starting with <float>; must be <sign>j or j */ if (*s == '+' || *s == '-') { /* <sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } else /* j */ y = 1.0; if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } /* trailing whitespace and closing bracket */ while (Py_ISSPACE(*s)) s++; if (got_bracket) { /* if there was an opening parenthesis, then the corresponding closing parenthesis should be right here */ if (*s != ')') goto parse_error; s++; while (Py_ISSPACE(*s)) s++; } /* we should now be at the end of the string */ if (s-start != len) goto parse_error; return complex_subtype_from_doubles((PyTypeObject *)type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); return NULL; }
static PyObject * complex_subtype_from_string(PyTypeObject *type, PyObject *v) { const char *s, *start; char *end; double x=0.0, y=0.0, z; int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len; Py_buffer view = {NULL, NULL}; if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); if (s_buffer == NULL) return NULL; s = PyUnicode_AsUTF8AndSize(s_buffer, &len); if (s == NULL) goto error; } else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { s = (const char *)view.buf; len = view.len; } else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name); return NULL; } /* position on first nonblank */ start = s; while (Py_ISSPACE(*s)) s++; if (*s == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; while (Py_ISSPACE(*s)) s++; } /* a valid complex string usually takes one of the three forms: <float> - real part only <float>j - imaginary part only <float><signed-float>j - real and imaginary parts where <float> represents any numeric string that's accepted by the float constructor (including 'nan', 'inf', 'infinity', etc.), and <signed-float> is any string of the form <float> whose first character is '+' or '-'. For backwards compatibility, the extra forms <float><sign>j <sign>j j are also accepted, though support for these forms may be removed from a future version of Python. */ /* first look for forms starting with <float> */ z = PyOS_string_to_double(s, &end, NULL); if (z == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else goto error; } if (end != s) { /* all 4 forms starting with <float> land here */ s = end; if (*s == '+' || *s == '-') { /* <float><signed-float>j | <float><sign>j */ x = z; y = PyOS_string_to_double(s, &end, NULL); if (y == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else goto error; } if (end != s) /* <float><signed-float>j */ s = end; else { /* <float><sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } else if (*s == 'j' || *s == 'J') { /* <float>j */ s++; y = z; } else /* <float> */ x = z; } else { /* not starting with <float>; must be <sign>j or j */ if (*s == '+' || *s == '-') { /* <sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } else /* j */ y = 1.0; if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } /* trailing whitespace and closing bracket */ while (Py_ISSPACE(*s)) s++; if (got_bracket) { /* if there was an opening parenthesis, then the corresponding closing parenthesis should be right here */ if (*s != ')') goto parse_error; s++; while (Py_ISSPACE(*s)) s++; } /* we should now be at the end of the string */ if (s-start != len) goto parse_error; PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: PyBuffer_Release(&view); Py_XDECREF(s_buffer); return NULL; }
static PyObject * complex_subtype_from_string(PyTypeObject *type, PyObject *v) { const char *s, *start; char *end; double x=0.0, y=0.0, z; int got_bracket=0; #ifdef Py_USING_UNICODE char *s_buffer = NULL; #endif Py_ssize_t len; if (PyString_Check(v)) { s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); } #ifdef Py_USING_UNICODE else if (PyUnicode_Check(v)) { s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1); if (s_buffer == NULL) return PyErr_NoMemory(); if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), s_buffer, NULL)) goto error; s = s_buffer; len = strlen(s); } #endif else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, "complex() arg is not a string"); return NULL; } /* position on first nonblank */ start = s; while (Py_ISSPACE(*s)) s++; if (*s == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; while (Py_ISSPACE(*s)) s++; } /* a valid complex string usually takes one of the three forms: <float> - real part only <float>j - imaginary part only <float><signed-float>j - real and imaginary parts where <float> represents any numeric string that's accepted by the float constructor (including 'nan', 'inf', 'infinity', etc.), and <signed-float> is any string of the form <float> whose first character is '+' or '-'. For backwards compatibility, the extra forms <float><sign>j <sign>j j are also accepted, though support for these forms may be removed from a future version of Python. */ /* first look for forms starting with <float> */ z = PyOS_string_to_double(s, &end, NULL); if (z == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else goto error; } if (end != s) { /* all 4 forms starting with <float> land here */ s = end; if (*s == '+' || *s == '-') { /* <float><signed-float>j | <float><sign>j */ x = z; y = PyOS_string_to_double(s, &end, NULL); if (y == -1.0 && PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_ValueError)) PyErr_Clear(); else goto error; } if (end != s) /* <float><signed-float>j */ s = end; else { /* <float><sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } else if (*s == 'j' || *s == 'J') { /* <float>j */ s++; y = z; } else /* <float> */ x = z; } else { /* not starting with <float>; must be <sign>j or j */ if (*s == '+' || *s == '-') { /* <sign>j */ y = *s == '+' ? 1.0 : -1.0; s++; } else /* j */ y = 1.0; if (!(*s == 'j' || *s == 'J')) goto parse_error; s++; } /* trailing whitespace and closing bracket */ while (Py_ISSPACE(*s)) s++; if (got_bracket) { /* if there was an opening parenthesis, then the corresponding closing parenthesis should be right here */ if (*s != ')') goto parse_error; s++; while (Py_ISSPACE(*s)) s++; } /* we should now be at the end of the string */ if (s-start != len) goto parse_error; #ifdef Py_USING_UNICODE if (s_buffer) PyMem_FREE(s_buffer); #endif return complex_subtype_from_doubles(type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: #ifdef Py_USING_UNICODE if (s_buffer) PyMem_FREE(s_buffer); #endif return NULL; }