diff options
author | Sébastien Sablé <sable@users.sourceforge.net> | 2013-03-01 11:37:20 +0100 |
---|---|---|
committer | Hugo Parente Lima <hugo.lima@openbossa.org> | 2013-03-14 18:09:06 +0100 |
commit | 91142c00a45b78d6dafd9e0a472243cff951a507 (patch) | |
tree | 319ceab133bca02af73c73babfcad801ce086500 | |
parent | 00d80865b7ef20440a4c925940c5576bbc8e248b (diff) |
Fix handling of unsigned long long and provide unittests.
Change-Id: I29674a2d758ebf4650e2fe26cdc2e663c0bae5c7
Reviewed-by: Sébastien Sablé <sable@users.sourceforge.net>
Reviewed-by: Hugo Parente Lima <hugo.lima@openbossa.org>
-rw-r--r-- | libshiboken/conversions.h | 14 | ||||
-rw-r--r-- | libshiboken/sbkconverter_p.h | 12 | ||||
-rw-r--r-- | tests/libsample/functions.cpp | 12 | ||||
-rw-r--r-- | tests/libsample/functions.h | 2 | ||||
-rw-r--r-- | tests/samplebinding/overflow_test.py | 18 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 4 |
6 files changed, 60 insertions, 2 deletions
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index b925770..6a0429e 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -435,7 +435,19 @@ struct Converter<unsigned PY_LONG_LONG> } static inline unsigned PY_LONG_LONG toCpp(PyObject* pyobj) { - return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyobj); + if (PyInt_Check(pyobj)) { + long result = (unsigned PY_LONG_LONG) PyInt_AsLong(pyobj); + if (result < 0) { + PyErr_SetObject(PyExc_OverflowError, 0); + return 0; + } else + return (unsigned PY_LONG_LONG) result; + } else if (PyLong_Check(pyobj)) { + return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyobj); + } else { + PyErr_SetString(PyExc_TypeError, "Invalid type for unsigned long long conversion"); + return 0; + } } }; diff --git a/libshiboken/sbkconverter_p.h b/libshiboken/sbkconverter_p.h index b1d40ee..766e6fa 100644 --- a/libshiboken/sbkconverter_p.h +++ b/libshiboken/sbkconverter_p.h @@ -251,7 +251,17 @@ struct Primitive<unsigned PY_LONG_LONG> : OnePrimitive<unsigned PY_LONG_LONG> } static void toCpp(PyObject* pyIn, void* cppOut) { - *((unsigned PY_LONG_LONG*)cppOut) = (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyIn); + if (PyInt_Check(pyIn)) { + long result = (unsigned PY_LONG_LONG) PyInt_AsLong(pyIn); + if (result < 0) + PyErr_SetObject(PyExc_OverflowError, 0); + else + *((unsigned PY_LONG_LONG*)cppOut) = (unsigned PY_LONG_LONG) result; + } else if (PyLong_Check(pyIn)) { + *((unsigned PY_LONG_LONG*)cppOut) = (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyIn); + } else { + PyErr_SetString(PyExc_TypeError, "Invalid type for unsigned long long conversion"); + } } static PythonToCppFunc isConvertible(PyObject* pyIn) { diff --git a/tests/libsample/functions.cpp b/tests/libsample/functions.cpp index 9a0bf2e..be1e2f9 100644 --- a/tests/libsample/functions.cpp +++ b/tests/libsample/functions.cpp @@ -131,6 +131,18 @@ doubleUnsignedInt(unsigned int value) return value * 2; } +long long +doubleLongLong(long long value) +{ + return value * 2; +} + +unsigned long long +doubleUnsignedLongLong(unsigned long long value) +{ + return value * 2; +} + short doubleShort(short value) { diff --git a/tests/libsample/functions.h b/tests/libsample/functions.h index 848777e..95adb2d 100644 --- a/tests/libsample/functions.h +++ b/tests/libsample/functions.h @@ -62,6 +62,8 @@ LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(int val); LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(double val); LIBSAMPLE_API unsigned int doubleUnsignedInt(unsigned int value); +LIBSAMPLE_API long long doubleLongLong(long long value); +LIBSAMPLE_API unsigned long long doubleUnsignedLongLong(unsigned long long value); LIBSAMPLE_API short doubleShort(short value); LIBSAMPLE_API int acceptInt(int x); diff --git a/tests/samplebinding/overflow_test.py b/tests/samplebinding/overflow_test.py index 4529fe2..ea2dd37 100644 --- a/tests/samplebinding/overflow_test.py +++ b/tests/samplebinding/overflow_test.py @@ -41,6 +41,24 @@ class OverflowTest(unittest.TestCase): val *= -1 self.assertRaises(OverflowError, doubleUnsignedInt, val) + def testLongLong(self): + '''C++ function receives an long long argument and raise OverflowError if the value is negative.''' + val = 100 + self.assertEqual(doubleLongLong(val), 2 * val) + val = long(100) + self.assertEqual(doubleLongLong(val), 2 * val) + val = (2 << 64) + 1 + self.assertRaises(OverflowError, doubleLongLong, val) + + def testUnsignedLongLong(self): + '''C++ function receives an unsigned long long argument and raise OverflowError if the value is negative.''' + val = 100 + self.assertEqual(doubleUnsignedLongLong(val), 2 * val) + val = long(100) + self.assertEqual(doubleUnsignedLongLong(val), 2 * val) + val *= -1 + self.assertRaises(OverflowError, doubleUnsignedLongLong, val) + def testOverflow(self): '''Calls function with unsigned int parameter using an overflowing value.''' self.assertRaises(OverflowError, doubleUnsignedInt, 42415335332353253) diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index 6379dba..0a9a764 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -22,6 +22,8 @@ <primitive-type name="unsigned char"/> <primitive-type name="long"/> <primitive-type name="unsigned long"/> + <primitive-type name="long long"/> + <primitive-type name="unsigned long long"/> <primitive-type name="std::string"/> <primitive-type name="Foo::HANDLE" target-lang-api-name="PyLong"/> @@ -481,6 +483,8 @@ <function signature="transmutePointIntoComplex(const Point&)" /> <function signature="sumComplexPair(std::pair<Complex, Complex>)" /> <function signature="doubleUnsignedInt(unsigned int)" /> + <function signature="doubleLongLong(long long)" /> + <function signature="doubleUnsignedLongLong(unsigned long long)" /> <function signature="doubleShort(short)" /> <function signature="returnNullPrimitivePointer()" /> <function signature="returnNullValueTypePointer()" /> |