diff options
author | Renato Filho <renato.filho@openbossa.org> | 2010-07-27 10:07:18 -0300 |
---|---|---|
committer | Renato Filho <renato.filho@openbossa.org> | 2010-07-27 10:08:29 -0300 |
commit | 1b4094837f983d6273a81daffc5bbffedc82cf2c (patch) | |
tree | b780d13e3aa566df6e9287584f96023fb4f71bac | |
parent | 8a16ff951633c3755cf370228709afaf416b0407 (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.cpp | 25 | ||||
-rw-r--r-- | libshiboken/conversions.h | 26 | ||||
-rw-r--r-- | tests/libsample/mapuser.cpp | 16 | ||||
-rw-r--r-- | tests/libsample/mapuser.h | 13 | ||||
-rw-r--r-- | tests/libsample/protected.h | 21 | ||||
-rw-r--r-- | tests/samplebinding/protected_test.py | 10 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 6 |
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 < 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> |