diff options
author | Barry Warsaw <barry@python.org> | 1999-10-12 19:54:53 (GMT) |
---|---|---|
committer | Barry Warsaw <barry@python.org> | 1999-10-12 19:54:53 (GMT) |
commit | 226ae6ca122f814dabdc40178c7b9656caf729c2 (patch) | |
tree | abaa15aae569a2334c7516b50ea486ec40bfce66 /Objects/abstract.c | |
parent | 75260275fe3bcc5d177a1b3ff30fd60681809585 (diff) | |
download | cpython-226ae6ca122f814dabdc40178c7b9656caf729c2.zip cpython-226ae6ca122f814dabdc40178c7b9656caf729c2.tar.gz cpython-226ae6ca122f814dabdc40178c7b9656caf729c2.tar.bz2 |
Mainlining the string_methods branch. See branch revision log
messages for specific changes.
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r-- | Objects/abstract.c | 180 |
1 files changed, 61 insertions, 119 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index be986f5..c120769 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -53,123 +53,6 @@ null_error() return NULL; } -/* Copied with modifications from stropmodule.c: atoi, atof, atol */ - -static PyObject * -int_from_string(v) - PyObject *v; -{ - char *s, *end; - long x; - char buffer[256]; /* For errors */ - - s = PyString_AS_STRING(v); - while (*s && isspace(Py_CHARMASK(*s))) - s++; - errno = 0; - x = PyOS_strtol(s, &end, 10); - if (end == s || !isdigit(end[-1])) - goto bad; - while (*end && isspace(Py_CHARMASK(*end))) - end++; - if (*end != '\0') { - bad: - sprintf(buffer, "invalid literal for int(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - return NULL; - } - else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) { - PyErr_SetString(PyExc_ValueError, - "null byte in argument for int()"); - return NULL; - } - else if (errno != 0) { - sprintf(buffer, "int() literal too large: %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - return NULL; - } - return PyInt_FromLong(x); -} - -static PyObject * -long_from_string(v) - PyObject *v; -{ - char *s, *end; - PyObject *x; - char buffer[256]; /* For errors */ - - s = PyString_AS_STRING(v); - while (*s && isspace(Py_CHARMASK(*s))) - s++; - x = PyLong_FromString(s, &end, 10); - if (x == NULL) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) - goto bad; - return NULL; - } - while (*end && isspace(Py_CHARMASK(*end))) - end++; - if (*end != '\0') { - bad: - sprintf(buffer, "invalid literal for long(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - Py_XDECREF(x); - return NULL; - } - else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) { - PyErr_SetString(PyExc_ValueError, - "null byte in argument for long()"); - return NULL; - } - return x; -} - -static PyObject * -float_from_string(v) - PyObject *v; -{ - extern double strtod Py_PROTO((const char *, char **)); - char *s, *last, *end; - double x; - char buffer[256]; /* For errors */ - - s = PyString_AS_STRING(v); - last = s + PyString_GET_SIZE(v); - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (s[0] == '\0') { - PyErr_SetString(PyExc_ValueError, "empty string for float()"); - return NULL; - } - errno = 0; - PyFPE_START_PROTECT("float_from_string", return 0) - x = strtod(s, &end); - PyFPE_END_PROTECT(x) - /* Believe it or not, Solaris 2.6 can move end *beyond* the null - byte at the end of the string, when the input is inf(inity) */ - if (end > last) - end = last; - while (*end && isspace(Py_CHARMASK(*end))) - end++; - if (*end != '\0') { - sprintf(buffer, "invalid literal for float(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - return NULL; - } - else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) { - PyErr_SetString(PyExc_ValueError, - "null byte in argument for float()"); - return NULL; - } - else if (errno != 0) { - sprintf(buffer, "float() literal too large: %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - return NULL; - } - return PyFloat_FromDouble(x); -} - /* Operations on any object */ int @@ -713,7 +596,7 @@ PyNumber_Int(o) if (o == NULL) return null_error(); if (PyString_Check(o)) - return int_from_string(o); + return PyInt_FromString(PyString_AS_STRING(o), NULL, 10); m = o->ob_type->tp_as_number; if (m && m->nb_int) return m->nb_int(o); @@ -721,6 +604,61 @@ PyNumber_Int(o) return type_error("object can't be converted to int"); } +/* There are two C API functions for converting a string to a long, + * PyNumber_Long() and PyLong_FromString(). Both are used in builtin_long, + * reachable from Python with the built-in function long(). + * + * The difference is this: PyNumber_Long will raise an exception when the + * string cannot be converted to a long. The most common situation is + * where a float string is passed in; this raises a ValueError. + * PyLong_FromString does not raise an exception; it silently truncates the + * float to an integer. + * + * You can see the different behavior from Python with the following: + * + * long('9.5') + * => ValueError: invalid literal for long(): 9.5 + * + * long('9.5', 10) + * => 9L + * + * The first example ends up calling PyNumber_Long(), while the second one + * calls PyLong_FromString(). + */ +static PyObject * +long_from_string(v) + PyObject *v; +{ + char *s, *end; + PyObject *x; + char buffer[256]; /* For errors */ + + s = PyString_AS_STRING(v); + while (*s && isspace(Py_CHARMASK(*s))) + s++; + x = PyLong_FromString(s, &end, 10); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_ValueError)) + goto bad; + return NULL; + } + while (*end && isspace(Py_CHARMASK(*end))) + end++; + if (*end != '\0') { + bad: + sprintf(buffer, "invalid literal for long(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); + Py_XDECREF(x); + return NULL; + } + else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for long()"); + return NULL; + } + return x; +} + PyObject * PyNumber_Long(o) PyObject *o; @@ -730,6 +668,10 @@ PyNumber_Long(o) if (o == NULL) return null_error(); if (PyString_Check(o)) + /* need to do extra error checking that PyLong_FromString() + * doesn't do. In particular long('9.5') must raise an + * exception, not truncate the float. + */ return long_from_string(o); m = o->ob_type->tp_as_number; if (m && m->nb_long) @@ -747,7 +689,7 @@ PyNumber_Float(o) if (o == NULL) return null_error(); if (PyString_Check(o)) - return float_from_string(o); + return PyFloat_FromString(o, NULL); m = o->ob_type->tp_as_number; if (m && m->nb_float) return m->nb_float(o); |