aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Sablé <sable@users.sourceforge.net>2013-03-01 11:37:20 +0100
committerHugo Parente Lima <hugo.lima@openbossa.org>2013-03-14 18:09:06 +0100
commit91142c00a45b78d6dafd9e0a472243cff951a507 (patch)
tree319ceab133bca02af73c73babfcad801ce086500
parent00d80865b7ef20440a4c925940c5576bbc8e248b (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.h14
-rw-r--r--libshiboken/sbkconverter_p.h12
-rw-r--r--tests/libsample/functions.cpp12
-rw-r--r--tests/libsample/functions.h2
-rw-r--r--tests/samplebinding/overflow_test.py18
-rw-r--r--tests/samplebinding/typesystem_sample.xml4
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&amp;)" />
<function signature="sumComplexPair(std::pair&lt;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()" />