summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorThomas Heller <theller@ctypes.org>2003-04-17 18:55:45 (GMT)
committerThomas Heller <theller@ctypes.org>2003-04-17 18:55:45 (GMT)
commita4ea603b055533e71920a088acb1c106e4895dbd (patch)
treec50efc24264738dee727367ed0e55bc3e6aedf84 /Objects
parente13ddc9ec85287b17fd03454f836f495c1167de9 (diff)
downloadcpython-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.c91
-rw-r--r--Objects/longobject.c55
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 */