aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2010-07-27 10:07:18 -0300
committerRenato Filho <renato.filho@openbossa.org>2010-07-27 10:08:29 -0300
commit1b4094837f983d6273a81daffc5bbffedc82cf2c (patch)
treeb780d13e3aa566df6e9287584f96023fb4f71bac
parent8a16ff951633c3755cf370228709afaf416b0407 (diff)
Fix char* converter
Fix tests. Created warnning about return last ref of python object. Reviewer: Marcelo Lira <marcelo.lira@openbossa.org> Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r--cppgenerator.cpp25
-rw-r--r--libshiboken/conversions.h26
-rw-r--r--tests/libsample/mapuser.cpp16
-rw-r--r--tests/libsample/mapuser.h13
-rw-r--r--tests/libsample/protected.h21
-rw-r--r--tests/samplebinding/protected_test.py10
-rw-r--r--tests/samplebinding/typesystem_sample.xml6
7 files changed, 81 insertions, 36 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 6fea1db6a..04d90c79d 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -643,12 +643,15 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
}
}
+ bool transferReturnToCpp = false;
foreach (FunctionModification func_mod, func->modifications()) {
foreach (ArgumentModification arg_mod, func_mod.argument_mods) {
- if (!arg_mod.resetAfterUse)
- continue;
- s << INDENT << "BindingManager::instance().invalidateWrapper(PyTuple_GET_ITEM(pyargs, ";
- s << (arg_mod.index - 1) << "));" << endl;
+ if (arg_mod.resetAfterUse) {
+ s << INDENT << "BindingManager::instance().invalidateWrapper(PyTuple_GET_ITEM(pyargs, ";
+ s << (arg_mod.index - 1) << "));" << endl;
+ } else if ((arg_mod.index == 0) && (arg_mod.ownerships[TypeSystem::TargetLangCode] == TypeSystem::TargetLangOwnership)) {
+ transferReturnToCpp = true;
+ }
}
}
@@ -658,8 +661,20 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
writeCodeSnips(s, snips, CodeSnip::End, TypeSystem::NativeCode, func, lastArg);
}
- if (type)
+ if (type) {
+ if (!transferReturnToCpp && (func->type()->isObject() || func->type()->isValuePointer()) ) {
+ s << INDENT << "if (" << PYTHON_RETURN_VAR << "->ob_refcnt < 2) {" << endl;
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "PyErr_SetString(PyExc_ReferenceError, \"Returning last python reference on virutal function: "
+ << func->ownerClass()->name() << "." << func->name() << "\");" << endl;
+ s << INDENT << "PyErr_Print();" << endl;
+ s << INDENT << "assert(false);" << endl;
+ }
+ s << INDENT << "}" << endl;
+ }
s << INDENT << "return " CPP_RETURN_VAR ";" << endl;
+ }
s << '}' << endl << endl;
}
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h
index 1cb4f913a..4b6d8e388 100644
--- a/libshiboken/conversions.h
+++ b/libshiboken/conversions.h
@@ -523,8 +523,32 @@ struct Converter_CString
}
};
-template <> struct Converter<char*> : Converter_CString<char*> {};
template <> struct Converter<const char*> : Converter_CString<const char*> {};
+template <> struct Converter<char*> : Converter_CString<char*>
+{
+ static inline char* toCpp(PyObject* pyobj)
+ {
+ if (pyobj == Py_None)
+ return 0;
+ return strdup(PyString_AsString(pyobj));
+ }
+};
+
+template <> struct Converter<std::string> : Converter_CString<std::string>
+{
+ static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<std::string*>(cppobj)); }
+ static inline PyObject* toPython(std::string cppObj)
+ {
+ return PyString_FromString(cppObj.c_str());
+ }
+
+ static inline std::string toCpp(PyObject* pyobj)
+ {
+ if (pyobj == Py_None)
+ return 0;
+ return std::string(PyString_AsString(pyobj));
+ }
+};
// C++ containers -------------------------------------------------------------
// The following container converters are meant to be used for pairs, lists and maps
diff --git a/tests/libsample/mapuser.cpp b/tests/libsample/mapuser.cpp
index fa20e0423..eb29bb62c 100644
--- a/tests/libsample/mapuser.cpp
+++ b/tests/libsample/mapuser.cpp
@@ -37,27 +37,27 @@
using namespace std;
-std::map<const char*, std::pair<Complex, int> >
+std::map<std::string, std::pair<Complex, int> >
MapUser::callCreateMap()
{
return createMap();
}
-std::map<const char*, std::pair<Complex, int> >
+std::map<std::string, std::pair<Complex, int> >
MapUser::createMap()
{
- std::map<const char*, std::pair<Complex, int> > retval;
+ std::map<std::string, std::pair<Complex, int> > retval;
- std::pair<const char *, std::pair<Complex, int> >
+ std::pair<std::string, std::pair<Complex, int> >
item0("zero", std::pair<Complex, int>(Complex(1.2, 3.4), 2));
retval.insert(item0);
- std::pair<const char *, std::pair<Complex, int> >
+ std::pair<std::string, std::pair<Complex, int> >
item1("one", std::pair<Complex, int>(Complex(5.6, 7.8), 3));
retval.insert(item1);
- std::pair<const char *, std::pair<Complex, int> >
+ std::pair<std::string, std::pair<Complex, int> >
item2("two", std::pair<Complex, int>(Complex(9.1, 2.3), 5));
retval.insert(item2);
@@ -65,9 +65,9 @@ MapUser::createMap()
}
void
-MapUser::showMap(std::map<const char*, int> mapping)
+MapUser::showMap(std::map<std::string, int> mapping)
{
- std::map<const char*, int>::iterator it;
+ std::map<std::string, int>::iterator it;
cout << __FUNCTION__ << endl;
for (it = mapping.begin() ; it != mapping.end(); it++)
cout << (*it).first << " => " << (*it).second << endl;
diff --git a/tests/libsample/mapuser.h b/tests/libsample/mapuser.h
index 78cc4f34c..c963743ac 100644
--- a/tests/libsample/mapuser.h
+++ b/tests/libsample/mapuser.h
@@ -38,6 +38,7 @@
#include <map>
#include <list>
#include <utility>
+#include <string>
#include "complex.h"
#include "libsamplemacros.h"
@@ -48,16 +49,16 @@ public:
MapUser() {}
virtual ~MapUser() {}
- virtual std::map<const char*, std::pair<Complex, int> > createMap();
- std::map<const char*, std::pair<Complex, int> > callCreateMap();
+ virtual std::map<std::string, std::pair<Complex, int> > createMap();
+ std::map<std::string, std::pair<Complex, int> > callCreateMap();
- void showMap(std::map<const char*, int> mapping);
+ void showMap(std::map<std::string, int> mapping);
- void setMap(std::map<const char*, std::list<int> > map) { m_map = map; }
- std::map<const char*, std::list<int> > getMap() { return m_map; }
+ void setMap(std::map<std::string, std::list<int> > map) { m_map = map; }
+ std::map<std::string, std::list<int> > getMap() { return m_map; }
private:
- std::map<const char*, std::list<int> > m_map;
+ std::map<std::string, std::list<int> > m_map;
};
#endif // MAPUSER_H
diff --git a/tests/libsample/protected.h b/tests/libsample/protected.h
index 8ba4914f8..0d1ead61d 100644
--- a/tests/libsample/protected.h
+++ b/tests/libsample/protected.h
@@ -36,19 +36,20 @@
#define PROTECTED_H
#include "libsamplemacros.h"
+#include <string>
class LIBSAMPLE_API ProtectedNonPolymorphic
{
public:
- explicit ProtectedNonPolymorphic(const char* name) : m_name(name) {}
+ explicit ProtectedNonPolymorphic(const char *name) : m_name(name) {}
~ProtectedNonPolymorphic() {}
- const char* publicName() { return m_name; }
+ const char* publicName() { return m_name.c_str(); }
static ProtectedNonPolymorphic* create() { return new ProtectedNonPolymorphic("created"); }
protected:
- const char* protectedName() { return m_name; }
+ const char* protectedName() { return m_name.c_str(); }
int protectedSum(int a0, int a1) { return a0 + a1; }
int modifiedProtectedSum(int a0, int a1) { return a0 + a1; }
static const char* protectedStatic() { return "protectedStatic"; }
@@ -57,39 +58,39 @@ protected:
inline const char* dataTypeName(int data) const { return "integer"; }
private:
- const char* m_name;
+ std::string m_name;
};
class LIBSAMPLE_API ProtectedPolymorphic
{
public:
- explicit ProtectedPolymorphic(const char* name) : m_name(name) {}
+ explicit ProtectedPolymorphic(const char *name) : m_name(name) {}
virtual ~ProtectedPolymorphic() {}
- const char* publicName() { return m_name; }
+ const char* publicName() { return m_name.c_str(); }
static ProtectedPolymorphic* create() { return new ProtectedPolymorphic("created"); }
const char* callProtectedName() { return protectedName(); }
protected:
- virtual const char* protectedName() { return m_name; }
+ virtual const char* protectedName() { return m_name.c_str(); }
private:
- const char* m_name;
+ std::string m_name;
};
class LIBSAMPLE_API ProtectedPolymorphicDaughter : public ProtectedPolymorphic
{
public:
- explicit ProtectedPolymorphicDaughter(const char* name) : ProtectedPolymorphic(name) {}
+ explicit ProtectedPolymorphicDaughter(const char *name) : ProtectedPolymorphic(name) {}
static ProtectedPolymorphicDaughter* create() { return new ProtectedPolymorphicDaughter("created"); }
};
class LIBSAMPLE_API ProtectedPolymorphicGrandDaughter: public ProtectedPolymorphicDaughter
{
public:
- explicit ProtectedPolymorphicGrandDaughter(const char* name) : ProtectedPolymorphicDaughter(name) {}
+ explicit ProtectedPolymorphicGrandDaughter(const char *name) : ProtectedPolymorphicDaughter(name) {}
static ProtectedPolymorphicGrandDaughter* create() { return new ProtectedPolymorphicGrandDaughter("created"); }
};
diff --git a/tests/samplebinding/protected_test.py b/tests/samplebinding/protected_test.py
index 356df1f7c..88ac5b59f 100644
--- a/tests/samplebinding/protected_test.py
+++ b/tests/samplebinding/protected_test.py
@@ -40,7 +40,8 @@ class ExtendedProtectedPolymorphic(ProtectedPolymorphic):
self.protectedName_called = False
def protectedName(self):
self.protectedName_called = True
- return 'Extended' + ProtectedPolymorphic.protectedName(self)
+ self._name = 'Extended' + ProtectedPolymorphic.protectedName(self)
+ return self._name
class ExtendedProtectedPolymorphicDaughter(ProtectedPolymorphicDaughter):
def __init__(self, name):
@@ -48,7 +49,8 @@ class ExtendedProtectedPolymorphicDaughter(ProtectedPolymorphicDaughter):
ProtectedPolymorphicDaughter.__init__(self, name)
def protectedName(self):
self.protectedName_called = True
- return 'ExtendedDaughter' + ProtectedPolymorphicDaughter.protectedName(self)
+ self._name = 'ExtendedDaughter' + ProtectedPolymorphicDaughter.protectedName(self)
+ return self._name
class ExtendedProtectedPolymorphicGrandDaughter(ProtectedPolymorphicGrandDaughter):
def __init__(self, name):
@@ -56,7 +58,8 @@ class ExtendedProtectedPolymorphicGrandDaughter(ProtectedPolymorphicGrandDaughte
ProtectedPolymorphicGrandDaughter.__init__(self, name)
def protectedName(self):
self.protectedName_called = True
- return 'ExtendedGrandDaughter' + ProtectedPolymorphicGrandDaughter.protectedName(self)
+ self._name = 'ExtendedGrandDaughter' + ProtectedPolymorphicGrandDaughter.protectedName(self)
+ return self._name
class ExtendedProtectedVirtualDestructor(ProtectedVirtualDestructor):
def __init__(self):
@@ -125,6 +128,7 @@ class ProtectedPolymorphicDaugherTest(unittest.TestCase):
original_name = 'Poly'
p = ExtendedProtectedPolymorphicDaughter(original_name)
name = p.callProtectedName()
+ print "MyName:", name
self.assert_(p.protectedName_called)
self.assertEqual(p.protectedName(), name)
self.assertEqual(ProtectedPolymorphicDaughter.protectedName(p), original_name)
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index 29e9e601d..77e5052e2 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -10,6 +10,7 @@
<primitive-type name="unsigned char"/>
<primitive-type name="long"/>
<primitive-type name="unsigned long"/>
+ <primitive-type name="std::string"/>
<primitive-type name="Complex" target-lang-api-name="PyComplex">
<conversion-rule file="complex_conversions.h"/>
@@ -754,11 +755,10 @@
</conversion-rule>
<conversion-rule class="target">
- Shiboken::AutoDecRef __object__(PyList_New(count));
+ PyObject *%out = PyList_New(count);
for (int i=0; i &lt; count; i++) {
- PyList_SET_ITEM(__object__.object(), i, %CONVERTTOPYTHON[int](%in[i]));
+ PyList_SET_ITEM(%out, i, %CONVERTTOPYTHON[int](%in[i]));
}
- PyObject *%out = __object__.object();
</conversion-rule>
</modify-argument>