mirror of https://github.com/python/cpython
Patch #1549049: Rewrite type conversion in structmember.
Fixes #1545696 and #1566140. Will backport to 2.5.
This commit is contained in:
parent
efb57072fe
commit
b5bc537c5e
|
@ -0,0 +1,80 @@
|
||||||
|
from _testcapi import test_structmembersType, \
|
||||||
|
CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
|
||||||
|
SHRT_MAX, SHRT_MIN, USHRT_MAX, \
|
||||||
|
INT_MAX, INT_MIN, UINT_MAX, \
|
||||||
|
LONG_MAX, LONG_MIN, ULONG_MAX
|
||||||
|
|
||||||
|
import warnings, exceptions, unittest, test.test_warnings
|
||||||
|
from test import test_support
|
||||||
|
|
||||||
|
ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
|
||||||
|
|
||||||
|
class ReadWriteTests(unittest.TestCase):
|
||||||
|
def test_types(self):
|
||||||
|
ts.T_BYTE=CHAR_MAX
|
||||||
|
self.assertEquals(ts.T_BYTE, CHAR_MAX)
|
||||||
|
ts.T_BYTE=CHAR_MIN
|
||||||
|
self.assertEquals(ts.T_BYTE, CHAR_MIN)
|
||||||
|
ts.T_UBYTE=UCHAR_MAX
|
||||||
|
self.assertEquals(ts.T_UBYTE, UCHAR_MAX)
|
||||||
|
|
||||||
|
ts.T_SHORT=SHRT_MAX
|
||||||
|
self.assertEquals(ts.T_SHORT, SHRT_MAX)
|
||||||
|
ts.T_SHORT=SHRT_MIN
|
||||||
|
self.assertEquals(ts.T_SHORT, SHRT_MIN)
|
||||||
|
ts.T_USHORT=USHRT_MAX
|
||||||
|
self.assertEquals(ts.T_USHORT, USHRT_MAX)
|
||||||
|
|
||||||
|
ts.T_INT=INT_MAX
|
||||||
|
self.assertEquals(ts.T_INT, INT_MAX)
|
||||||
|
ts.T_INT=INT_MIN
|
||||||
|
self.assertEquals(ts.T_INT, INT_MIN)
|
||||||
|
ts.T_UINT=UINT_MAX
|
||||||
|
self.assertEquals(ts.T_UINT, UINT_MAX)
|
||||||
|
|
||||||
|
ts.T_LONG=LONG_MAX
|
||||||
|
self.assertEquals(ts.T_LONG, LONG_MAX)
|
||||||
|
ts.T_LONG=LONG_MIN
|
||||||
|
self.assertEquals(ts.T_LONG, LONG_MIN)
|
||||||
|
ts.T_ULONG=ULONG_MAX
|
||||||
|
self.assertEquals(ts.T_ULONG, ULONG_MAX)
|
||||||
|
|
||||||
|
class TestWarnings(test.test_warnings.TestModule):
|
||||||
|
def has_warned(self):
|
||||||
|
self.assertEqual(test.test_warnings.msg.category,
|
||||||
|
exceptions.RuntimeWarning.__name__)
|
||||||
|
|
||||||
|
def test_byte_max(self):
|
||||||
|
ts.T_BYTE=CHAR_MAX+1
|
||||||
|
self.has_warned()
|
||||||
|
|
||||||
|
def test_byte_min(self):
|
||||||
|
ts.T_BYTE=CHAR_MIN-1
|
||||||
|
self.has_warned()
|
||||||
|
|
||||||
|
def test_ubyte_max(self):
|
||||||
|
ts.T_UBYTE=UCHAR_MAX+1
|
||||||
|
self.has_warned()
|
||||||
|
|
||||||
|
def test_short_max(self):
|
||||||
|
ts.T_SHORT=SHRT_MAX+1
|
||||||
|
self.has_warned()
|
||||||
|
|
||||||
|
def test_short_min(self):
|
||||||
|
ts.T_SHORT=SHRT_MIN-1
|
||||||
|
self.has_warned()
|
||||||
|
|
||||||
|
def test_ushort_max(self):
|
||||||
|
ts.T_USHORT=USHRT_MAX+1
|
||||||
|
self.has_warned()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_main(verbose=None):
|
||||||
|
test_support.run_unittest(
|
||||||
|
ReadWriteTests,
|
||||||
|
TestWarnings
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_main(verbose=True)
|
|
@ -633,6 +633,7 @@ Stephen Turner
|
||||||
Bill Tutt
|
Bill Tutt
|
||||||
Doobee R. Tzeck
|
Doobee R. Tzeck
|
||||||
Lionel Ulmer
|
Lionel Ulmer
|
||||||
|
Roger Upole
|
||||||
Michael Urman
|
Michael Urman
|
||||||
Hector Urtubia
|
Hector Urtubia
|
||||||
Dmitry Vasiliev
|
Dmitry Vasiliev
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Patch #1549049: Support long values in structmember, issue warnings
|
||||||
|
if the assigned value for structmember fields gets truncated.
|
||||||
|
|
||||||
- Update the peephole optimizer to remove more dead code (jumps after returns)
|
- Update the peephole optimizer to remove more dead code (jumps after returns)
|
||||||
and inline unconditional jumps to returns.
|
and inline unconditional jumps to returns.
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include <values.h>
|
||||||
|
#include "structmember.h"
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
#include "pythread.h"
|
#include "pythread.h"
|
||||||
|
@ -35,13 +37,13 @@ raiseTestError(const char* test_name, const char* msg)
|
||||||
platforms have these hardcoded. Better safe than sorry.
|
platforms have these hardcoded. Better safe than sorry.
|
||||||
*/
|
*/
|
||||||
static PyObject*
|
static PyObject*
|
||||||
sizeof_error(const char* fatname, const char* typename,
|
sizeof_error(const char* fatname, const char* typname,
|
||||||
int expected, int got)
|
int expected, int got)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
PyOS_snprintf(buf, sizeof(buf),
|
PyOS_snprintf(buf, sizeof(buf),
|
||||||
"%.200s #define == %d but sizeof(%.200s) == %d",
|
"%.200s #define == %d but sizeof(%.200s) == %d",
|
||||||
fatname, expected, typename, got);
|
fatname, expected, typname, got);
|
||||||
PyErr_SetString(TestError, buf);
|
PyErr_SetString(TestError, buf);
|
||||||
return (PyObject*)NULL;
|
return (PyObject*)NULL;
|
||||||
}
|
}
|
||||||
|
@ -615,7 +617,7 @@ _make_call(void *callable)
|
||||||
{
|
{
|
||||||
PyObject *rc;
|
PyObject *rc;
|
||||||
PyGILState_STATE s = PyGILState_Ensure();
|
PyGILState_STATE s = PyGILState_Ensure();
|
||||||
rc = PyObject_CallFunction(callable, "");
|
rc = PyObject_CallFunction((PyObject *)callable, "");
|
||||||
Py_XDECREF(rc);
|
Py_XDECREF(rc);
|
||||||
PyGILState_Release(s);
|
PyGILState_Release(s);
|
||||||
}
|
}
|
||||||
|
@ -756,6 +758,105 @@ static PyMethodDef TestMethods[] = {
|
||||||
|
|
||||||
#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);}
|
#define AddSym(d, n, f, v) {PyObject *o = f(v); PyDict_SetItemString(d, n, o); Py_DECREF(o);}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char byte_member;
|
||||||
|
unsigned char ubyte_member;
|
||||||
|
short short_member;
|
||||||
|
unsigned short ushort_member;
|
||||||
|
int int_member;
|
||||||
|
unsigned int uint_member;
|
||||||
|
long long_member;
|
||||||
|
unsigned long ulong_member;
|
||||||
|
float float_member;
|
||||||
|
double double_member;
|
||||||
|
} all_structmembers;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
all_structmembers structmembers;
|
||||||
|
} test_structmembers;
|
||||||
|
|
||||||
|
static struct PyMemberDef test_members[] = {
|
||||||
|
{"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
|
||||||
|
{"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
|
||||||
|
{"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
|
||||||
|
{"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
|
||||||
|
{"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
|
||||||
|
{"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
|
||||||
|
{"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
|
||||||
|
{"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
|
||||||
|
{"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
|
||||||
|
{"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){
|
||||||
|
static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT",
|
||||||
|
"T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", NULL};
|
||||||
|
test_structmembers *ob=PyObject_New(test_structmembers, type);
|
||||||
|
if (ob==NULL)
|
||||||
|
return NULL;
|
||||||
|
memset(&ob->structmembers, 0, sizeof(all_structmembers));
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|bBhHiIlkfd", keywords,
|
||||||
|
&ob->structmembers.byte_member, &ob->structmembers.ubyte_member,
|
||||||
|
&ob->structmembers.short_member, &ob->structmembers.ushort_member,
|
||||||
|
&ob->structmembers.int_member, &ob->structmembers.uint_member,
|
||||||
|
&ob->structmembers.long_member, &ob->structmembers.ulong_member,
|
||||||
|
&ob->structmembers.float_member, &ob->structmembers.double_member)){
|
||||||
|
Py_DECREF(ob);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (PyObject *)ob;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_structmembers_free(PyObject *ob){
|
||||||
|
PyObject_FREE(ob);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyTypeObject test_structmembersType = {
|
||||||
|
PyObject_HEAD_INIT(NULL)
|
||||||
|
0,
|
||||||
|
"test_structmembersType",
|
||||||
|
sizeof(test_structmembers), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
test_structmembers_free, /* destructor tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_hash */
|
||||||
|
0, /* tp_call */
|
||||||
|
0, /* tp_str */
|
||||||
|
PyObject_GenericGetAttr,
|
||||||
|
PyObject_GenericSetAttr,
|
||||||
|
0, /* tp_as_buffer */
|
||||||
|
0, /* tp_flags */
|
||||||
|
"Type containing all structmember types",
|
||||||
|
0, /* traverseproc tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
test_members, /* tp_members */
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
test_structmembers_new, /* tp_new */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
init_testcapi(void)
|
init_testcapi(void)
|
||||||
{
|
{
|
||||||
|
@ -765,16 +866,28 @@ init_testcapi(void)
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
test_structmembersType.ob_type=&PyType_Type;
|
||||||
|
Py_INCREF(&test_structmembersType);
|
||||||
|
PyModule_AddObject(m, "test_structmembersType", (PyObject *)&test_structmembersType);
|
||||||
|
|
||||||
|
PyModule_AddObject(m, "CHAR_MAX", PyInt_FromLong(CHAR_MAX));
|
||||||
|
PyModule_AddObject(m, "CHAR_MIN", PyInt_FromLong(CHAR_MIN));
|
||||||
PyModule_AddObject(m, "UCHAR_MAX", PyInt_FromLong(UCHAR_MAX));
|
PyModule_AddObject(m, "UCHAR_MAX", PyInt_FromLong(UCHAR_MAX));
|
||||||
|
PyModule_AddObject(m, "SHRT_MAX", PyInt_FromLong(SHRT_MAX));
|
||||||
|
PyModule_AddObject(m, "SHRT_MIN", PyInt_FromLong(SHRT_MIN));
|
||||||
PyModule_AddObject(m, "USHRT_MAX", PyInt_FromLong(USHRT_MAX));
|
PyModule_AddObject(m, "USHRT_MAX", PyInt_FromLong(USHRT_MAX));
|
||||||
|
PyModule_AddObject(m, "INT_MAX", PyLong_FromLong(INT_MAX));
|
||||||
|
PyModule_AddObject(m, "INT_MIN", PyLong_FromLong(INT_MIN));
|
||||||
PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX));
|
PyModule_AddObject(m, "UINT_MAX", PyLong_FromUnsignedLong(UINT_MAX));
|
||||||
PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX));
|
|
||||||
PyModule_AddObject(m, "INT_MIN", PyInt_FromLong(INT_MIN));
|
|
||||||
PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN));
|
|
||||||
PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
|
|
||||||
PyModule_AddObject(m, "INT_MAX", PyInt_FromLong(INT_MAX));
|
|
||||||
PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX));
|
PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX));
|
||||||
|
PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN));
|
||||||
|
PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX));
|
||||||
|
PyModule_AddObject(m, "FLT_MAX", PyFloat_FromDouble(FLT_MAX));
|
||||||
|
PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN));
|
||||||
|
PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX));
|
||||||
|
PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN));
|
||||||
PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX));
|
PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX));
|
||||||
|
PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
|
||||||
|
|
||||||
TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
|
TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
|
||||||
Py_INCREF(TestError);
|
Py_INCREF(TestError);
|
||||||
|
|
|
@ -62,29 +62,28 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)
|
||||||
addr += l->offset;
|
addr += l->offset;
|
||||||
switch (l->type) {
|
switch (l->type) {
|
||||||
case T_BYTE:
|
case T_BYTE:
|
||||||
v = PyInt_FromLong(
|
v = PyInt_FromLong(*(char*)addr);
|
||||||
(long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80));
|
|
||||||
break;
|
break;
|
||||||
case T_UBYTE:
|
case T_UBYTE:
|
||||||
v = PyInt_FromLong((long) *(char*)addr & 0xff);
|
v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
|
||||||
break;
|
break;
|
||||||
case T_SHORT:
|
case T_SHORT:
|
||||||
v = PyInt_FromLong((long) *(short*)addr);
|
v = PyInt_FromLong(*(short*)addr);
|
||||||
break;
|
break;
|
||||||
case T_USHORT:
|
case T_USHORT:
|
||||||
v = PyInt_FromLong((long) *(unsigned short*)addr);
|
v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
|
||||||
break;
|
break;
|
||||||
case T_INT:
|
case T_INT:
|
||||||
v = PyInt_FromLong((long) *(int*)addr);
|
v = PyInt_FromLong(*(int*)addr);
|
||||||
break;
|
break;
|
||||||
case T_UINT:
|
case T_UINT:
|
||||||
v = PyInt_FromLong((long) *(unsigned int*)addr);
|
v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
|
||||||
break;
|
break;
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
v = PyInt_FromLong(*(long*)addr);
|
v = PyInt_FromLong(*(long*)addr);
|
||||||
break;
|
break;
|
||||||
case T_ULONG:
|
case T_ULONG:
|
||||||
v = PyLong_FromDouble((double) *(unsigned long*)addr);
|
v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
|
||||||
break;
|
break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
v = PyFloat_FromDouble((double)*(float*)addr);
|
v = PyFloat_FromDouble((double)*(float*)addr);
|
||||||
|
@ -175,68 +174,107 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||||
}
|
}
|
||||||
addr += l->offset;
|
addr += l->offset;
|
||||||
switch (l->type) {
|
switch (l->type) {
|
||||||
case T_BYTE:
|
case T_BYTE:{
|
||||||
case T_UBYTE:
|
long long_val;
|
||||||
if (!PyInt_Check(v)) {
|
long_val = PyInt_AsLong(v);
|
||||||
PyErr_BadArgument();
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
}
|
/* XXX: For compatibility, only warn about truncations
|
||||||
*(char*)addr = (char) PyInt_AsLong(v);
|
for now. */
|
||||||
|
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to char");
|
||||||
|
*(char*)addr = (char)long_val;
|
||||||
break;
|
break;
|
||||||
case T_SHORT:
|
|
||||||
case T_USHORT:
|
|
||||||
if (!PyInt_Check(v)) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
*(short*)addr = (short) PyInt_AsLong(v);
|
case T_UBYTE:{
|
||||||
break;
|
long long_val;
|
||||||
case T_UINT:
|
long_val = PyInt_AsLong(v);
|
||||||
case T_INT:
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
if (!PyInt_Check(v)) {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return -1;
|
return -1;
|
||||||
|
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned char");
|
||||||
|
*(unsigned char*)addr = (unsigned char)long_val;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*(int*)addr = (int) PyInt_AsLong(v);
|
case T_SHORT:{
|
||||||
break;
|
long long_val;
|
||||||
case T_LONG:
|
long_val = PyInt_AsLong(v);
|
||||||
if (!PyInt_Check(v)) {
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
PyErr_BadArgument();
|
|
||||||
return -1;
|
return -1;
|
||||||
|
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to short");
|
||||||
|
*(short*)addr = (short)long_val;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*(long*)addr = PyInt_AsLong(v);
|
case T_USHORT:{
|
||||||
break;
|
long long_val;
|
||||||
case T_ULONG:
|
long_val = PyInt_AsLong(v);
|
||||||
if (PyInt_Check(v))
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
*(long*)addr = PyInt_AsLong(v);
|
|
||||||
else if (PyLong_Check(v))
|
|
||||||
*(long*)addr = PyLong_AsLong(v);
|
|
||||||
else {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return -1;
|
return -1;
|
||||||
|
if ((long_val > USHRT_MAX) || (long_val < 0))
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned short");
|
||||||
|
*(unsigned short*)addr = (unsigned short)long_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case T_INT:{
|
||||||
|
long long_val;
|
||||||
|
long_val = PyInt_AsLong(v);
|
||||||
|
if ((long_val == -1) && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to int");
|
||||||
|
*(int *)addr = (int)long_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case T_UINT:{
|
||||||
|
unsigned long ulong_val;
|
||||||
|
ulong_val = PyLong_AsUnsignedLong(v);
|
||||||
|
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
|
||||||
|
/* XXX: For compatibility, accept negative int values
|
||||||
|
as well. */
|
||||||
|
PyErr_Clear();
|
||||||
|
ulong_val = PyLong_AsLong(v);
|
||||||
|
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
||||||
|
}
|
||||||
|
if (ulong_val > UINT_MAX)
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
|
||||||
|
*(unsigned int *)addr = (unsigned int)ulong_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case T_LONG:{
|
||||||
|
*(long*)addr = PyLong_AsLong(v);
|
||||||
|
if ((*(long*)addr == -1) && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case T_ULONG:{
|
||||||
|
*(unsigned long*)addr = PyLong_AsUnsignedLong(v);
|
||||||
|
if ((*(unsigned long*)addr == (unsigned long)-1)
|
||||||
|
&& PyErr_Occurred()) {
|
||||||
|
/* XXX: For compatibility, accept negative int values
|
||||||
|
as well. */
|
||||||
|
PyErr_Clear();
|
||||||
|
*(unsigned long*)addr = PyLong_AsLong(v);
|
||||||
|
if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_FLOAT:
|
|
||||||
if (PyInt_Check(v))
|
|
||||||
*(float*)addr =
|
|
||||||
(float) PyInt_AsLong(v);
|
|
||||||
else if (PyFloat_Check(v))
|
|
||||||
*(float*)addr =
|
|
||||||
(float) PyFloat_AsDouble(v);
|
|
||||||
else {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
case T_FLOAT:{
|
||||||
|
double double_val;
|
||||||
|
double_val = PyFloat_AsDouble(v);
|
||||||
|
if ((double_val == -1) && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
*(float*)addr = (float)double_val;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
if (PyInt_Check(v))
|
*(double*)addr = PyFloat_AsDouble(v);
|
||||||
*(double*)addr = (double) PyInt_AsLong(v);
|
if ((*(double*)addr == -1) && PyErr_Occurred())
|
||||||
else if (PyFloat_Check(v))
|
|
||||||
*(double*)addr = PyFloat_AsDouble(v);
|
|
||||||
else {
|
|
||||||
PyErr_BadArgument();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
case T_OBJECT_EX:
|
case T_OBJECT_EX:
|
||||||
|
|
Loading…
Reference in New Issue