PyObject * PyInt_FromUnicode(Py_UNICODE *s, int length, int base) { char buffer[256]; if (length >= sizeof(buffer)) { PyErr_SetString(PyExc_ValueError, "int() literal too large to convert"); return NULL; } if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) return NULL; return PyInt_FromString(buffer, NULL, base); }
PyObject* PyInt_FromUnicode(Py_UNICODE* s, Py_ssize_t length, int base) noexcept { PyObject* result; char* buffer = (char*)PyMem_MALLOC(length + 1); if (buffer == NULL) return PyErr_NoMemory(); if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) { PyMem_FREE(buffer); return NULL; } result = PyInt_FromString(buffer, NULL, base); PyMem_FREE(buffer); return result; }
static PyObject * complex_subtype_from_string(PyTypeObject *type, PyObject *v) { const char *s; PyObject *result = NULL; #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 exit; s = s_buffer; len = strlen(s); } #endif else { PyErr_SetString(PyExc_TypeError, "complex() arg is not a string"); return NULL; } result = _Py_string_to_number_with_underscores(s, len, "complex", v, type, complex_from_string_inner); exit: #ifdef Py_USING_UNICODE if (s_buffer) PyMem_FREE(s_buffer); #endif return result; }
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_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; char s_buffer[256]; Py_ssize_t len; 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); } 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 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(type, x, y); parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); return NULL; }
static PyObject *next(PyObject *self) { ligolw_Tokenizer *tokenizer = (ligolw_Tokenizer *) self; PyObject *type; PyObject *token; Py_UNICODE *start, *end; /* * Identify the start and end of the next token. */ do { type = next_token(tokenizer, &start, &end); if(!type) return NULL; } while(type == Py_None); /* * Extract token as desired type. */ if(start == NULL) { /* * unquoted zero-length string == None */ Py_INCREF(Py_None); token = Py_None; } else if(type == (PyObject *) &PyFloat_Type) { char ascii_buffer[end - start + 1]; char *ascii_end; if(PyUnicode_EncodeDecimal(start, end - start, ascii_buffer, NULL)) return NULL; token = PyFloat_FromDouble(strtod(ascii_buffer, &ascii_end)); if(ascii_end == ascii_buffer || *ascii_end != 0) { /* * strtod() couldn't convert the token, emulate * float()'s error message */ Py_XDECREF(token); PyErr_Format(PyExc_ValueError, "invalid literal for float(): '%s'", ascii_buffer); token = NULL; } } else if(type == (PyObject *) &PyUnicode_Type) { token = PyUnicode_FromUnicode(start, end - start); } else if(type == (PyObject *) &PyString_Type) { token = PyUnicode_Encode(start, end - start, NULL, NULL); } else if(type == (PyObject *) &PyInt_Type) { token = PyInt_FromUnicode(start, end - start, 0); } else if(type == (PyObject *) &PyLong_Type) { token = PyLong_FromUnicode(start, end - start, 0); } else { token = PyObject_CallFunction(type, "u#", start, end - start); } /* * Done. */ return token; }