? Objects/_intobject.c ? Python/_getargs.c ? Python/getargs_2.c Index: Include/intobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/intobject.h,v retrieving revision 2.29 diff -c -r2.29 intobject.h *** Include/intobject.h 1 Jan 2003 15:18:32 -0000 2.29 --- Include/intobject.h 17 Apr 2003 17:14:30 -0000 *************** *** 36,41 **** --- 36,46 ---- #endif PyAPI_FUNC(PyObject *) PyInt_FromLong(long); PyAPI_FUNC(long) PyInt_AsLong(PyObject *); + PyAPI_FUNC(unsigned long) PyInt_AsUnsignedLongMask(PyObject *); + #ifdef HAVE_LONG_LONG + PyAPI_FUNC(unsigned PY_LONG_LONG) PyInt_AsUnsignedLongLongMask(PyObject *); + #endif + PyAPI_FUNC(long) PyInt_GetMax(void); /* Macro, trading safety for speed */ Index: Include/longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.29 diff -c -r2.29 longobject.h *** Include/longobject.h 29 Mar 2003 10:04:54 -0000 2.29 --- Include/longobject.h 17 Apr 2003 17:14:30 -0000 *************** *** 19,24 **** --- 19,25 ---- PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); PyAPI_FUNC(long) PyLong_AsLong(PyObject *); PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); + PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); /* _PyLong_AsScaledDouble returns a double x and an exponent e such that the true value is approximately equal to x * 2**(SHIFT*e). e is >= 0. *************** *** 37,42 **** --- 38,44 ---- PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG); PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLong(PyObject *); PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(PyObject *); + PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *); #endif /* HAVE_LONG_LONG */ PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int); Index: Objects/intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.103 diff -c -r2.103 intobject.c *** Objects/intobject.c 20 Feb 2003 20:32:11 -0000 2.103 --- Objects/intobject.c 17 Apr 2003 17:14:30 -0000 *************** *** 169,174 **** --- 169,175 ---- } else { + Py_DECREF(io); PyErr_SetString(PyExc_TypeError, "nb_int should return int object"); return -1; *************** *** 180,185 **** --- 181,276 ---- 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; + } + } + + val = PyInt_AS_LONG(io); + Py_DECREF(io); + + 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) Index: Objects/longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.157 diff -c -r1.157 longobject.c *** Objects/longobject.c 29 Mar 2003 10:04:55 -0000 1.157 --- Objects/longobject.c 17 Apr 2003 17:14:30 -0000 *************** *** 260,265 **** --- 260,293 ---- 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,784 **** --- 807,839 ---- 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 */ Index: Python/getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.97 diff -c -r2.97 getargs.c *** Python/getargs.c 29 Mar 2003 10:04:55 -0000 2.97 --- Python/getargs.c 17 Apr 2003 17:14:31 -0000 *************** *** 448,466 **** long ival; if (float_argument_error(arg)) return NULL; ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf, bufsize); - else if (ival < SCHAR_MIN) { - PyErr_SetString(PyExc_OverflowError, - "byte-sized integer bitfield is less than minimum"); - return converterr("integer", arg, msgbuf, bufsize); - } - else if (ival > (int)UCHAR_MAX) { - PyErr_SetString(PyExc_OverflowError, - "byte-sized integer bitfield is greater than maximum"); return converterr("integer", arg, msgbuf, bufsize); - } else *p = (unsigned char) ival; break; --- 448,456 ---- long ival; if (float_argument_error(arg)) return NULL; ! ival = PyInt_AsUnsignedLongMask(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); else *p = (unsigned char) ival; break; *************** *** 474,485 **** ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); ! else if (ival < SHRT_MIN) { PyErr_SetString(PyExc_OverflowError, "signed short integer is less than minimum"); return converterr("integer", arg, msgbuf, bufsize); } ! else if (ival > SHRT_MAX) { PyErr_SetString(PyExc_OverflowError, "signed short integer is greater than maximum"); return converterr("integer", arg, msgbuf, bufsize); --- 464,475 ---- ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); ! else if (ival < 0) { PyErr_SetString(PyExc_OverflowError, "signed short integer is less than minimum"); return converterr("integer", arg, msgbuf, bufsize); } ! else if (ival > USHRT_MAX) { PyErr_SetString(PyExc_OverflowError, "signed short integer is greater than maximum"); return converterr("integer", arg, msgbuf, bufsize); *************** *** 495,513 **** long ival; if (float_argument_error(arg)) return NULL; ! ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); - else if (ival < SHRT_MIN) { - PyErr_SetString(PyExc_OverflowError, - "short integer bitfield is less than minimum"); - return converterr("integer", arg, msgbuf, bufsize); - } - else if (ival > USHRT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "short integer bitfield is greater than maximum"); - return converterr("integer", arg, msgbuf, bufsize); - } else *p = (unsigned short) ival; break; --- 485,493 ---- long ival; if (float_argument_error(arg)) return NULL; ! ival = PyInt_AsUnsignedLongMask(arg); if (ival == -1 && PyErr_Occurred()) return converterr("integer", arg, msgbuf, bufsize); else *p = (unsigned short) ival; break; *************** *** 536,541 **** --- 516,535 ---- break; } + case 'I': { /* int sized bitfield, both signed and + unsigned allowed */ + unsigned int *p = va_arg(*p_va, unsigned int *); + unsigned int ival; + if (float_argument_error(arg)) + return NULL; + ival = PyInt_AsUnsignedLongMask(arg); + if (ival == -1 && PyErr_Occurred()) + return converterr("integer", arg, msgbuf, bufsize); + else + *p = ival; + break; + } + case 'l': {/* long int */ long *p = va_arg(*p_va, long *); long ival; *************** *** 548,553 **** --- 542,560 ---- *p = ival; break; } + + case 'k': { /* long sized bitfield */ + unsigned long *p = va_arg(*p_va, unsigned long *); + unsigned long ival; + if (PyInt_Check(arg)) + ival = PyInt_AsUnsignedLongMask(arg); + else if (PyLong_Check(arg)) + ival = PyLong_AsUnsignedLongMask(arg); + else + return converterr("integer", arg, msgbuf, bufsize); + *p = ival; + break; + } #ifdef HAVE_LONG_LONG case 'L': {/* PY_LONG_LONG */ *************** *** 558,563 **** --- 565,585 ---- } else { *p = ival; } + break; + } + + case 'K': { /* long long sized bitfield */ + unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *); + unsigned PY_LONG_LONG ival; + if (float_argument_error(arg)) + return NULL; + if (PyInt_Check(arg)) + ival = PyInt_AsUnsignedLongMask(arg); + else if (PyLong_Check(arg)) + ival = PyLong_AsUnsignedLongLongMask(arg); + else + return converterr("integer", arg, msgbuf, bufsize); + *p = ival; break; } #endif Index: Modules/_testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.20 diff -c -r1.20 _testcapimodule.c *** Modules/_testcapimodule.c 29 Mar 2003 10:04:54 -0000 1.20 --- Modules/_testcapimodule.c 17 Apr 2003 17:14:31 -0000 *************** *** 290,295 **** --- 290,428 ---- #endif /* ifdef HAVE_LONG_LONG */ + /* Call PyArg_ParseTuple, and return the result as unsigned long */ + static PyObject * + getargs_ul(PyObject *self, PyObject *args) + { + PyObject *ob, *result = NULL, *argtuple; + char *fmt; + unsigned long value = 0; + + if (!PyArg_ParseTuple(args, "sO", &fmt, &ob)) + return NULL; + argtuple = PyTuple_New(1); + Py_INCREF(ob); + PyTuple_SET_ITEM(argtuple, 0, ob); + if (PyArg_ParseTuple(argtuple, fmt, &value)) + result = PyLong_FromUnsignedLong(value); + Py_DECREF(argtuple); + return result; + } + + /* Call PyArg_ParseTuple, and return the result as signed long */ + static PyObject * + getargs_l(PyObject *self, PyObject *args) + { + PyObject *ob, *result = NULL, *argtuple; + char *fmt; + long value = 0; + + if (!PyArg_ParseTuple(args, "sO", &fmt, &ob)) + return NULL; + argtuple = PyTuple_New(1); + Py_INCREF(ob); + PyTuple_SET_ITEM(argtuple, 0, ob); + if (PyArg_ParseTuple(argtuple, fmt, &value)) + result = PyLong_FromLong(value); + Py_DECREF(argtuple); + return result; + } + + #ifdef HAVE_LONG_LONG + /* Call PyArg_ParseTuple, and return the result as signed long long */ + static PyObject * + getargs_ll(PyObject *self, PyObject *args) + { + PyObject *ob, *result = NULL, *argtuple; + char *fmt; + PY_LONG_LONG value = 0; + + if (!PyArg_ParseTuple(args, "sO", &fmt, &ob)) + return NULL; + argtuple = PyTuple_New(1); + Py_INCREF(ob); + PyTuple_SET_ITEM(argtuple, 0, ob); + if (PyArg_ParseTuple(argtuple, fmt, &value)) + result = PyLong_FromLongLong(value); + Py_DECREF(argtuple); + return result; + } + + /* Call PyArg_ParseTuple, and return the result as unsigned long long */ + static PyObject * + getargs_ull(PyObject *self, PyObject *args) + { + PyObject *ob, *result = NULL, *argtuple; + char *fmt; + unsigned PY_LONG_LONG value = 0; + + if (!PyArg_ParseTuple(args, "sO", &fmt, &ob)) + return NULL; + argtuple = PyTuple_New(1); + Py_INCREF(ob); + PyTuple_SET_ITEM(argtuple, 0, ob); + if (PyArg_ParseTuple(argtuple, fmt, &value)) + result = PyLong_FromUnsignedLongLong(value); + Py_DECREF(argtuple); + return result; + } + #endif + + /* This function not only tests the 'k' getargs code, but also the + PyInt_AsUnsignedLongMask() and PyInt_AsUnsignedLongMask() functions. */ + static PyObject * + test_k_code(PyObject *self) + { + PyObject *tuple, *num; + unsigned long value; + + tuple = PyTuple_New(1); + if (tuple == NULL) + return NULL; + + /* a number larger than UINT_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + + value = PyInt_AsUnsignedLongMask(num); + if (value != UINT_MAX) + return raiseTestError("test_k_code", + "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0) + return NULL; + if (value != UINT_MAX) + return raiseTestError("test_k_code", + "k code returned wrong value for long 0xFFF...FFF"); + + Py_DECREF(num); + num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); + if (num == NULL) + return NULL; + + value = PyInt_AsUnsignedLongMask(num); + if (value != (unsigned long)-0x42) + return raiseTestError("test_k_code", + "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0) + return NULL; + if (value != (unsigned long)-0x42) + return raiseTestError("test_k_code", + "k code returned wrong value for long -0xFFF..000042"); + + Py_DECREF(tuple); + Py_INCREF(Py_None); + return Py_None; + } + #ifdef Py_USING_UNICODE /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case *************** *** 409,415 **** --- 542,553 ---- {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS}, {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS}, {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, + {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, + {"getargs_ul", (PyCFunction)getargs_ul, METH_VARARGS}, + {"getargs_l", (PyCFunction)getargs_l, METH_VARARGS}, #ifdef HAVE_LONG_LONG + {"getargs_ll", (PyCFunction)getargs_ll, METH_VARARGS}, + {"getargs_ull", (PyCFunction)getargs_ull, METH_VARARGS}, {"test_longlong_api", (PyCFunction)test_longlong_api, METH_NOARGS}, {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, #endif *************** *** 419,430 **** --- 557,586 ---- {NULL, NULL} /* sentinel */ }; + #define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);} + PyMODINIT_FUNC init_testcapi(void) { PyObject *m; m = Py_InitModule("_testcapi", TestMethods); + + PyModule_AddObject(m, "UCHAR_MAX", PyInt_FromLong(UCHAR_MAX)); + PyModule_AddObject(m, "USHRT_MAX", PyInt_FromLong(USHRT_MAX)); + PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX)); + PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX)); + + /* + #ifdef HAVE_LONG_LONG + PyModule_AddObject(m, "LLONG_MAX", PyLong_FromLongLong(LLONG_MAX)); + PyModule_AddObject(m, "LLONG_MIN", PyLong_FromLongLong(LLONG_MAX)); + #endif + */ + PyModule_AddObject(m, "INT_MIN", PyInt_FromLong(INT_MIN)); + PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN)); + PyModule_AddObject(m, "INT_MAX", PyInt_FromLong(INT_MAX)); + PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX)); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError);