diff options
author | Thomas Heller <theller@ctypes.org> | 2003-04-17 18:55:45 (GMT) |
---|---|---|
committer | Thomas Heller <theller@ctypes.org> | 2003-04-17 18:55:45 (GMT) |
commit | a4ea603b055533e71920a088acb1c106e4895dbd (patch) | |
tree | c50efc24264738dee727367ed0e55bc3e6aedf84 /Objects | |
parent | e13ddc9ec85287b17fd03454f836f495c1167de9 (diff) | |
download | cpython-a4ea603b055533e71920a088acb1c106e4895dbd.zip cpython-a4ea603b055533e71920a088acb1c106e4895dbd.tar.gz cpython-a4ea603b055533e71920a088acb1c106e4895dbd.tar.bz2 |
SF # 595026: support for masks in getargs.c.
New functions:
unsigned long PyInt_AsUnsignedLongMask(PyObject *);
unsigned PY_LONG_LONG) PyInt_AsUnsignedLongLongMask(PyObject *);
unsigned long PyLong_AsUnsignedLongMask(PyObject *);
unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *);
New and changed format codes:
b unsigned char 0..UCHAR_MAX
B unsigned char none **
h unsigned short 0..USHRT_MAX
H unsigned short none **
i int INT_MIN..INT_MAX
I * unsigned int 0..UINT_MAX
l long LONG_MIN..LONG_MAX
k * unsigned long none
L long long LLONG_MIN..LLONG_MAX
K * unsigned long long none
Notes:
* New format codes.
** Changed from previous "range-and-a-half" to "none"; the
range-and-a-half checking wasn't particularly useful.
New test test_getargs2.py, to verify all this.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/intobject.c | 91 | ||||
-rw-r--r-- | Objects/longobject.c | 55 |
2 files changed, 146 insertions, 0 deletions
diff --git a/Objects/intobject.c b/Objects/intobject.c index 611aedf..4b5dc55 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -169,6 +169,51 @@ PyInt_AsLong(register PyObject *op) } else { + Py_DECREF(io); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } + } + + val = PyInt_AS_LONG(io); + Py_DECREF(io); + + return val; +} + +unsigned long +PyInt_AsUnsignedLongMask(register PyObject *op) +{ + PyNumberMethods *nb; + PyIntObject *io; + unsigned long val; + + if (op && PyInt_Check(op)) + return PyInt_AS_LONG((PyIntObject*) op); + if (op && PyLong_Check(op)) + return PyLong_AsUnsignedLongMask(op); + + if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + io = (PyIntObject*) (*nb->nb_int) (op); + if (io == NULL) + return -1; + if (!PyInt_Check(io)) { + if (PyLong_Check(io)) { + val = PyLong_AsUnsignedLongMask((PyObject *)io); + Py_DECREF(io); + if (PyErr_Occurred()) + return -1; + return val; + } + else + { + Py_DECREF(io); PyErr_SetString(PyExc_TypeError, "nb_int should return int object"); return -1; @@ -181,6 +226,52 @@ PyInt_AsLong(register PyObject *op) return val; } +#ifdef HAVE_LONG_LONG +unsigned PY_LONG_LONG +PyInt_AsUnsignedLongLongMask(register PyObject *op) +{ + PyNumberMethods *nb; + PyIntObject *io; + unsigned PY_LONG_LONG val; + + if (op && PyInt_Check(op)) + return PyInt_AS_LONG((PyIntObject*) op); + if (op && PyLong_Check(op)) + return PyLong_AsUnsignedLongLongMask(op); + + if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + io = (PyIntObject*) (*nb->nb_int) (op); + if (io == NULL) + return -1; + if (!PyInt_Check(io)) { + if (PyLong_Check(io)) { + val = PyLong_AsUnsignedLongLongMask((PyObject *)io); + Py_DECREF(io); + if (PyErr_Occurred()) + return -1; + return val; + } + else + { + Py_DECREF(io); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } + } + + val = PyInt_AS_LONG(io); + Py_DECREF(io); + + return val; +} +#endif + PyObject * PyInt_FromString(char *s, char **pend, int base) { diff --git a/Objects/longobject.c b/Objects/longobject.c index e02bce4..663befc 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -260,6 +260,34 @@ PyLong_AsUnsignedLong(PyObject *vv) return x; } +/* Get a C unsigned long int from a long int object, ignoring the high bits. + Returns -1 and sets an error condition if an error occurs. */ + +unsigned long +PyLong_AsUnsignedLongMask(PyObject *vv) +{ + register PyLongObject *v; + unsigned long x; + int i, sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long) -1; + } + v = (PyLongObject *)vv; + i = v->ob_size; + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -i; + } + while (--i >= 0) { + x = (x << SHIFT) + v->ob_digit[i]; + } + return x * sign; +} + int _PyLong_Sign(PyObject *vv) { @@ -779,6 +807,33 @@ PyLong_AsUnsignedLongLong(PyObject *vv) return bytes; } +/* Get a C unsigned long int from a long int object, ignoring the high bits. + Returns -1 and sets an error condition if an error occurs. */ + +unsigned PY_LONG_LONG +PyLong_AsUnsignedLongLongMask(PyObject *vv) +{ + register PyLongObject *v; + unsigned PY_LONG_LONG x; + int i, sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long) -1; + } + v = (PyLongObject *)vv; + i = v->ob_size; + sign = 1; + x = 0; + if (i < 0) { + sign = -1; + i = -i; + } + while (--i >= 0) { + x = (x << SHIFT) + v->ob_digit[i]; + } + return x * sign; +} #undef IS_LITTLE_ENDIAN #endif /* HAVE_LONG_LONG */ |