[Python-checkins] CVS: python/dist/src/Objects longobject.c,1.74,1.75
Tim Peters
tim_one@users.sourceforge.net
Tue, 12 Jun 2001 17:36:00 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv10010/python/dist/src/Objects
Modified Files:
longobject.c
Log Message:
longobject.c:
Replaced PyLong_{As,From}{Unsigned,}LongLong guts with calls
to _PyLong_{As,From}ByteArray.
_testcapimodule.c:
Added strong tests of PyLong_{As,From}{Unsigned,}LongLong.
Fixes SF bug #432552 PyLong_AsLongLong() problems.
Possible bugfix candidate, but the fix relies on code added to longobject
to support the new q/Q structmodule format codes.
Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -C2 -r1.74 -r1.75
*** longobject.c 2001/06/12 19:17:03 1.74
--- longobject.c 2001/06/13 00:35:57 1.75
***************
*** 523,688 ****
#ifdef HAVE_LONG_LONG
! /*
! * LONG_LONG support by Chris Herborth (chrish@qnx.com)
! *
! * For better or worse :-), I tried to follow the coding style already
! * here.
*/
! /* Create a new long int object from a C LONG_LONG int */
PyObject *
PyLong_FromLongLong(LONG_LONG ival)
{
! #if SIZEOF_LONG_LONG == SIZEOF_LONG
! /* In case the compiler is faking it. */
! return PyLong_FromLong( (long)ival );
! #else
! if ((LONG_LONG)LONG_MIN <= ival && ival <= (LONG_LONG)LONG_MAX) {
! return PyLong_FromLong( (long)ival );
! }
! else if (0 <= ival && ival <= (unsigned LONG_LONG)ULONG_MAX) {
! return PyLong_FromUnsignedLong( (unsigned long)ival );
! }
! else {
! /* Assume a C LONG_LONG fits in at most 10 'digits'.
! * Should be OK if we're assuming long fits in 5.
! */
! PyLongObject *v = _PyLong_New(10);
!
! if (v != NULL) {
! unsigned LONG_LONG t = ival;
! int i;
! if (ival < 0) {
! t = -ival;
! v->ob_size = -(v->ob_size);
! }
!
! for (i = 0; i < 10; i++) {
! v->ob_digit[i] = (digit) (t & MASK);
! t >>= SHIFT;
! }
!
! v = long_normalize(v);
! }
!
! return (PyObject *)v;
! }
! #endif
}
- /* Create a new long int object from a C unsigned LONG_LONG int */
PyObject *
PyLong_FromUnsignedLongLong(unsigned LONG_LONG ival)
{
! #if SIZEOF_LONG_LONG == SIZEOF_LONG
! /* In case the compiler is faking it. */
! return PyLong_FromUnsignedLong( (unsigned long)ival );
! #else
! if( ival <= (unsigned LONG_LONG)ULONG_MAX ) {
! return PyLong_FromUnsignedLong( (unsigned long)ival );
! }
! else {
! /* Assume a C long fits in at most 10 'digits'. */
! PyLongObject *v = _PyLong_New(10);
!
! if (v != NULL) {
! unsigned LONG_LONG t = ival;
! int i;
! for (i = 0; i < 10; i++) {
! v->ob_digit[i] = (digit) (t & MASK);
! t >>= SHIFT;
! }
!
! v = long_normalize(v);
! }
!
! return (PyObject *)v;
! }
! #endif
}
/* Get a C LONG_LONG int from a long int object.
! Returns -1 and sets an error condition if overflow occurs. */
LONG_LONG
PyLong_AsLongLong(PyObject *vv)
{
! #if SIZEOF_LONG_LONG == SIZEOF_LONG
! /* In case the compiler is faking it. */
! return (LONG_LONG)PyLong_AsLong( vv );
! #else
! register PyLongObject *v;
! LONG_LONG x, prev;
! int i, sign;
!
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
return -1;
}
-
- v = (PyLongObject *)vv;
- i = v->ob_size;
- sign = 1;
- x = 0;
-
- if (i < 0) {
- sign = -1;
- i = -(i);
- }
! while (--i >= 0) {
! prev = x;
! x = (x << SHIFT) + v->ob_digit[i];
! if ((x >> SHIFT) != prev) {
! PyErr_SetString(PyExc_OverflowError,
! "long int too long to convert");
! return -1;
! }
! }
! return x * sign;
! #endif
}
unsigned LONG_LONG
PyLong_AsUnsignedLongLong(PyObject *vv)
{
! #if SIZEOF_LONG_LONG == 4
! /* In case the compiler is faking it. */
! return (unsigned LONG_LONG)PyLong_AsUnsignedLong( vv );
! #else
! register PyLongObject *v;
! unsigned LONG_LONG x, prev;
! int i;
!
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
! return (unsigned LONG_LONG) -1;
! }
!
! v = (PyLongObject *)vv;
! i = v->ob_size;
! x = 0;
!
! if (i < 0) {
! PyErr_SetString(PyExc_OverflowError,
! "can't convert negative value to unsigned long");
! return (unsigned LONG_LONG) -1;
}
! while (--i >= 0) {
! prev = x;
! x = (x << SHIFT) + v->ob_digit[i];
! if ((x >> SHIFT) != prev) {
! PyErr_SetString(PyExc_OverflowError,
! "long int too long to convert");
! return (unsigned LONG_LONG) -1;
! }
! }
! return x;
! #endif
}
#endif /* HAVE_LONG_LONG */
--- 523,603 ----
#ifdef HAVE_LONG_LONG
!
! /* Initial LONG_LONG support by Chris Herborth (chrish@qnx.com), later
! * rewritten to use the newer PyLong_{As,From}ByteArray API.
*/
+
+ #define IS_LITTLE_ENDIAN *(char*)&one != '\0'
! /* Create a new long int object from a C LONG_LONG int. */
PyObject *
PyLong_FromLongLong(LONG_LONG ival)
{
! LONG_LONG bytes = ival;
! int one = 1;
! return _PyLong_FromByteArray(
! (unsigned char *)&bytes,
! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
}
+
+ /* Create a new long int object from a C unsigned LONG_LONG int. */
PyObject *
PyLong_FromUnsignedLongLong(unsigned LONG_LONG ival)
{
! unsigned LONG_LONG bytes = ival;
! int one = 1;
! return _PyLong_FromByteArray(
! (unsigned char *)&bytes,
! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
}
/* Get a C LONG_LONG int from a long int object.
! Return -1 and set an error if overflow occurs. */
LONG_LONG
PyLong_AsLongLong(PyObject *vv)
{
! LONG_LONG bytes;
! int one = 1;
! int res;
!
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
return -1;
}
! res = _PyLong_AsByteArray(
! (PyLongObject *)vv, (unsigned char *)&bytes,
! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
! return (LONG_LONG)(res < 0 ? res : bytes);
}
+ /* Get a C unsigned LONG_LONG int from a long int object.
+ Return -1 and set an error if overflow occurs. */
+
unsigned LONG_LONG
PyLong_AsUnsignedLongLong(PyObject *vv)
{
! unsigned LONG_LONG bytes;
! int one = 1;
! int res;
!
if (vv == NULL || !PyLong_Check(vv)) {
PyErr_BadInternalCall();
! return -1;
}
! res = _PyLong_AsByteArray(
! (PyLongObject *)vv, (unsigned char *)&bytes,
! SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
! return (unsigned LONG_LONG)(res < 0 ? res : bytes);
}
+
+ #undef IS_LITTLE_ENDIAN
+
#endif /* HAVE_LONG_LONG */