mirror of https://github.com/python/cpython.git
Changed the ``add/sub_offset'' hacks for dealing with C's unsigned
int/long types, and use the new PyLong_FromUnsignedLong() and PyLong_AsUnsignedLong() interfaces instead. Semantic change: the 'I' format will now always return a long int.
This commit is contained in:
parent
04ebf5ca5d
commit
6c87ecaff1
|
@ -73,81 +73,6 @@ typedef struct { char c; double x; } s_double;
|
||||||
#pragma options align=reset
|
#pragma options align=reset
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Global that will contain 2**<bits-per-long> */
|
|
||||||
|
|
||||||
static PyObject *offset = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper to create 2**<bits-per-long> */
|
|
||||||
/* XXX This assumes 2's complement arithmetic */
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
init_offset()
|
|
||||||
{
|
|
||||||
PyObject *result = NULL;
|
|
||||||
PyObject *one = PyLong_FromLong(1L);
|
|
||||||
PyObject *shiftcount = PyLong_FromLong(8 * sizeof(long));
|
|
||||||
if (one == NULL || shiftcount == NULL)
|
|
||||||
goto finally;
|
|
||||||
result = PyNumber_Lshift(one, shiftcount);
|
|
||||||
finally:
|
|
||||||
Py_XDECREF(one);
|
|
||||||
Py_XDECREF(shiftcount);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper to add offset to a number */
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
add_offset(v)
|
|
||||||
PyObject *v;
|
|
||||||
{
|
|
||||||
PyObject *result = NULL;
|
|
||||||
if (offset == NULL) {
|
|
||||||
if ((offset = init_offset()) == NULL)
|
|
||||||
goto finally;
|
|
||||||
}
|
|
||||||
result = PyNumber_Add(v, offset);
|
|
||||||
finally:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Same, but subtracting */
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
sub_offset(v)
|
|
||||||
PyObject *v;
|
|
||||||
{
|
|
||||||
PyObject *result = NULL;
|
|
||||||
if (offset == NULL) {
|
|
||||||
if ((offset = init_offset()) == NULL)
|
|
||||||
goto finally;
|
|
||||||
}
|
|
||||||
result = PyNumber_Subtract(v, offset);
|
|
||||||
finally:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper routine to turn a (signed) long into an unsigned long */
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
make_ulong(x)
|
|
||||||
long x;
|
|
||||||
{
|
|
||||||
PyObject *v = PyLong_FromLong(x);
|
|
||||||
if (x < 0 && v != NULL) {
|
|
||||||
PyObject *w = add_offset(v);
|
|
||||||
Py_DECREF(v);
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper routine to get a Python integer and raise the appropriate error
|
/* Helper routine to get a Python integer and raise the appropriate error
|
||||||
if it isn't one */
|
if it isn't one */
|
||||||
|
|
||||||
|
@ -175,30 +100,17 @@ get_ulong(v, p)
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
unsigned long *p;
|
unsigned long *p;
|
||||||
{
|
{
|
||||||
long x = PyInt_AsLong(v);
|
if (PyLong_Check(v)) {
|
||||||
PyObject *exc;
|
unsigned long x = PyLong_AsUnsignedLong(v);
|
||||||
if (x == -1 && (exc = PyErr_Occurred()) != NULL) {
|
if (x == (unsigned long)(-1) && PyErr_Occurred())
|
||||||
if (exc == PyExc_OverflowError) {
|
|
||||||
/* Try again after subtracting offset */
|
|
||||||
PyObject *w;
|
|
||||||
PyErr_Clear();
|
|
||||||
if ((w = sub_offset(v)) == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
x = PyInt_AsLong(w);
|
|
||||||
Py_DECREF(w);
|
|
||||||
if (x != -1 || (exc = PyErr_Occurred()) == NULL)
|
|
||||||
goto okay;
|
|
||||||
}
|
|
||||||
if (exc == PyExc_TypeError)
|
|
||||||
PyErr_SetString(StructError,
|
|
||||||
"required argument is not an integer");
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
okay:
|
|
||||||
*p = x;
|
*p = x;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return get_long(v, (long *)p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Floating point helpers */
|
/* Floating point helpers */
|
||||||
|
@ -548,11 +460,7 @@ nu_uint(p, f)
|
||||||
const formatdef *f;
|
const formatdef *f;
|
||||||
{
|
{
|
||||||
unsigned int x = *(unsigned int *)p;
|
unsigned int x = *(unsigned int *)p;
|
||||||
#if INT_MAX == LONG_MAX
|
return PyLong_FromUnsignedLong((unsigned long)x);
|
||||||
return make_ulong((long)x);
|
|
||||||
#else
|
|
||||||
return PyInt_FromLong((long)x);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -568,7 +476,7 @@ nu_ulong(p, f)
|
||||||
const char *p;
|
const char *p;
|
||||||
const formatdef *f;
|
const formatdef *f;
|
||||||
{
|
{
|
||||||
return make_ulong(*(long *)p);
|
return PyLong_FromUnsignedLong(*(unsigned long *)p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -756,15 +664,12 @@ bu_uint(p, f)
|
||||||
const char *p;
|
const char *p;
|
||||||
const formatdef *f;
|
const formatdef *f;
|
||||||
{
|
{
|
||||||
long x = 0;
|
unsigned long x = 0;
|
||||||
int i = f->size;
|
int i = f->size;
|
||||||
do {
|
do {
|
||||||
x = (x<<8) | (*p++ & 0xFF);
|
x = (x<<8) | (*p++ & 0xFF);
|
||||||
} while (--i > 0);
|
} while (--i > 0);
|
||||||
if (f->size == sizeof(long))
|
return PyLong_FromUnsignedLong(x);
|
||||||
return make_ulong(x);
|
|
||||||
else
|
|
||||||
return PyLong_FromLong(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -889,15 +794,12 @@ lu_uint(p, f)
|
||||||
const char *p;
|
const char *p;
|
||||||
const formatdef *f;
|
const formatdef *f;
|
||||||
{
|
{
|
||||||
long x = 0;
|
unsigned long x = 0;
|
||||||
int i = f->size;
|
int i = f->size;
|
||||||
do {
|
do {
|
||||||
x = (x<<8) | (p[--i] & 0xFF);
|
x = (x<<8) | (p[--i] & 0xFF);
|
||||||
} while (i > 0);
|
} while (i > 0);
|
||||||
if (f->size == sizeof(long))
|
return PyLong_FromUnsignedLong(x);
|
||||||
return make_ulong(x);
|
|
||||||
else
|
|
||||||
return PyLong_FromLong(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Reference in New Issue