aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-08-05 13:55:56 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:17:08 -0300
commit50aef1dd4836b5019c60d31c54501ebcd37f72cd (patch)
tree3e9f41435c3ee0da5fdb5ee32b5b9900ad5a5259
parent08f29f0d8f456eb1f994b05c21fd04468c95329c (diff)
Improved guessCPythonCheckFunction method to produce an AbstractMetaType for known types.
This is in opposition of simply returning a string with a custom type check. The details are in the docstring in ShibokenGenerator header. Also added a new modification test and refactored here and there in the sample binding type system.
-rw-r--r--generator/cppgenerator.cpp19
-rw-r--r--generator/shibokengenerator.cpp51
-rw-r--r--generator/shibokengenerator.h12
-rw-r--r--tests/libsample/modifications.cpp7
-rw-r--r--tests/libsample/modifications.h3
-rw-r--r--tests/samplebinding/modifications_test.py7
-rw-r--r--tests/samplebinding/typesystem_sample.xml27
7 files changed, 102 insertions, 24 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index 9e8007f6d..687a24499 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -1471,12 +1471,21 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb
void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType)
{
- if (!customType.isEmpty())
- s << guessCPythonCheckFunction(customType);
- else if (argType->isEnum())
- s << cpythonIsConvertibleFunction(argType, false);
+ AbstractMetaType* metaType;
+ std::auto_ptr<AbstractMetaType> metaType_autoptr;
+ QString customCheck;
+ if (!customType.isEmpty()) {
+ customCheck = guessCPythonCheckFunction(customType, &metaType);
+ if (metaType) {
+ metaType_autoptr = std::auto_ptr<AbstractMetaType>(metaType);
+ argType = metaType;
+ }
+ }
+
+ if (customCheck.isEmpty())
+ s << cpythonIsConvertibleFunction(argType, argType->isEnum() ? false : isNumber);
else
- s << cpythonIsConvertibleFunction(argType, isNumber);
+ s << customCheck;
s << '(' << argumentName << ')';
}
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp
index 3e5b8eabb..17cd31a91 100644
--- a/generator/shibokengenerator.cpp
+++ b/generator/shibokengenerator.cpp
@@ -860,8 +860,18 @@ bool ShibokenGenerator::visibilityModifiedToPrivate(const AbstractMetaFunction*
QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType)
{
- if (metaType->typeEntry()->isCustom())
- return guessCPythonCheckFunction(metaType->typeEntry()->name());
+ AbstractMetaType* type;
+ std::auto_ptr<AbstractMetaType> type_autoptr;
+ QString customCheck;
+ if (metaType->typeEntry()->isCustom()) {
+ customCheck = guessCPythonCheckFunction(metaType->typeEntry()->name(), &type);
+ if (type) {
+ type_autoptr = std::auto_ptr<AbstractMetaType>(type);
+ metaType = type;
+ }
+ if (!customCheck.isEmpty())
+ return customCheck;
+ }
QString baseName = cpythonBaseName(metaType);
if (isNumber(baseName))
@@ -878,8 +888,17 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType
QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool genericNumberType)
{
- if (type->isCustom())
- return guessCPythonCheckFunction(type->name());
+ AbstractMetaType* metaType;
+ std::auto_ptr<AbstractMetaType> metaType_autoptr;
+ QString customCheck;
+ if (type->isCustom()) {
+ customCheck = guessCPythonCheckFunction(type->name(), &metaType);
+ if (metaType) {
+ metaType_autoptr = std::auto_ptr<AbstractMetaType>(metaType);
+ return cpythonCheckFunction(metaType, genericNumberType);
+ }
+ return customCheck;
+ }
QString baseName = cpythonBaseName(type);
if (isNumber(baseName))
@@ -892,18 +911,18 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool gene
return QString("%1checkType").arg(baseName);
}
-QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type)
+QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type, AbstractMetaType** metaType)
{
+ *metaType = 0;
if (type == "PyTypeObject")
return "PyType_Check";
if (type == "PyBuffer")
return "Shiboken::Buffer::checkType";
- AbstractMetaType* metaType = buildAbstractMetaTypeFromString(type);
- std::auto_ptr<const AbstractMetaType> metaType_autoptr(metaType);
- if (metaType && !metaType->typeEntry()->isCustom())
- return cpythonCheckFunction(metaType);
+ *metaType = buildAbstractMetaTypeFromString(type);
+ if (*metaType && !(*metaType)->typeEntry()->isCustom())
+ return QString();
return QString("%1_Check").arg(type);
}
@@ -939,8 +958,18 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry* type, b
QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType)
{
- if (metaType->typeEntry()->isCustom())
- return guessCPythonCheckFunction(metaType->typeEntry()->name());
+ AbstractMetaType* type;
+ std::auto_ptr<AbstractMetaType> type_autoptr;
+ QString customCheck;
+ if (metaType->typeEntry()->isCustom()) {
+ customCheck = guessCPythonCheckFunction(metaType->typeEntry()->name(), &type);
+ if (type) {
+ type_autoptr = std::auto_ptr<AbstractMetaType>(type);
+ metaType = type;
+ }
+ if (!customCheck.isEmpty())
+ return customCheck;
+ }
QString baseName = cpythonBaseName(metaType);
if (isNumber(baseName))
diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h
index 674bbeab2..729dc0bc0 100644
--- a/generator/shibokengenerator.h
+++ b/generator/shibokengenerator.h
@@ -296,7 +296,17 @@ public:
QString cpythonTypeNameExt(const TypeEntry* type);
QString cpythonCheckFunction(const TypeEntry* type, bool genericNumberType = false);
QString cpythonCheckFunction(const AbstractMetaType* metaType, bool genericNumberType = false);
- QString guessCPythonCheckFunction(const QString& type);
+ /**
+ * Receives the argument \p type and tries to find the appropriate AbstractMetaType for it
+ * or a custom type check.
+ * \param type A string representing the type to be discovered.
+ * \param metaType A pointer to an AbstractMetaType pointer, to where write a new meta type object
+ * if one is produced from the \p type string. This object must be deallocated by
+ * the caller. It will set the target variable to NULL, is \p type is a Python type.
+ * \return A custom check if \p type is a custom type, or an empty string if \p metaType
+ * receives an existing type object.
+ */
+ QString guessCPythonCheckFunction(const QString& type, AbstractMetaType** metaType);
QString cpythonIsConvertibleFunction(const TypeEntry* type, bool genericNumberType = false, bool checkExact = false);
QString cpythonIsConvertibleFunction(const AbstractMetaType* metaType, bool genericNumberType = false);
QString cpythonIsConvertibleFunction(const AbstractMetaArgument* metaArg, bool genericNumberType = false)
diff --git a/tests/libsample/modifications.cpp b/tests/libsample/modifications.cpp
index 00a0cdf0c..72c3f40ed 100644
--- a/tests/libsample/modifications.cpp
+++ b/tests/libsample/modifications.cpp
@@ -96,3 +96,10 @@ Modifications::sumPointArray(int arraySize, const Point pointArray[])
point = point + pointArray[i];
return point;
}
+
+int
+Modifications::getSize(const void* data, int size)
+{
+ (void)data;
+ return size;
+}
diff --git a/tests/libsample/modifications.h b/tests/libsample/modifications.h
index 5f7b58995..1b6fb8240 100644
--- a/tests/libsample/modifications.h
+++ b/tests/libsample/modifications.h
@@ -95,6 +95,9 @@ public:
virtual const char* className();
Point sumPointArray(int arraySize, const Point pointArray[]);
+
+ // Replace 'const void*' by 'ByteArray&'.
+ int getSize(const void* data, int size);
};
class LIBSAMPLE_API AbstractModifications : public Modifications
diff --git a/tests/samplebinding/modifications_test.py b/tests/samplebinding/modifications_test.py
index b23165ff6..b37d74635 100644
--- a/tests/samplebinding/modifications_test.py
+++ b/tests/samplebinding/modifications_test.py
@@ -28,7 +28,7 @@
import unittest
-from sample import Modifications, Point
+from sample import Modifications, Point, ByteArray
class ExtModifications(Modifications):
def __init__(self):
@@ -138,5 +138,10 @@ class ModificationsTest(unittest.TestCase):
summedPoint = Point(1, 1) + Point(2, 2)
self.assertEqual(self.mods.sumPointArray(points), summedPoint)
+ def testTypeSystemVariableReplacementInFunctionModification(self):
+ ba = ByteArray('12345')
+ self.assertEqual(self.mods.getSize(ba), len(ba))
+ self.assertEqual(self.mods.getSize(ba, 20), 20)
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index be0f8fe88..27c265f3f 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -697,6 +697,21 @@
</conversion-rule>
</modify-argument>
</modify-function>
+ <modify-function signature="getSize(const void*,int)">
+ <modify-argument index="1">
+ <replace-type modified-type="ByteArray&amp;"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <replace-default-expression with="-1"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int size = (%2 &lt; 0) ? %1.size() : %2;
+ %BEGIN_ALLOW_THREADS
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME((const void*) %1.data(), size);
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
</object-type>
<object-type name="AbstractModifications">
@@ -833,9 +848,9 @@
</modify-function>
<template name="fix_int*,int*,int*,int*">
int a0, a1, a2, a3;
- PyThreadState* _save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS
+ %BEGIN_ALLOW_THREADS
%CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a0, &amp;a1, &amp;a2, &amp;a3);
- PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS
+ %END_ALLOW_THREADS
%PYARG_0 = Shiboken::makeTuple(a0, a1, a2, a3);
</template>
<template name="fix_native_return_int*,int*,int*,int*">
@@ -1373,10 +1388,10 @@
<insert-template name="buffer_argument">
<replace from="%out" to="argOut" />
</insert-template>
- PyThreadState* _save = PyEval_SaveThread();
- %RETURN_TYPE cppResult = %CPPSELF.%FUNCTION_NAME(argOut, %2);
- PyEval_RestoreThread(_save);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](cppResult);
+ %BEGIN_ALLOW_THREADS
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(argOut, %2);
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
</inject-code>
</add-function>
</object-type>