diff --git a/modules/modpython.cpp b/modules/modpython.cpp index 3c7f0ffb..b2716fb2 100644 --- a/modules/modpython.cpp +++ b/modules/modpython.cpp @@ -18,7 +18,7 @@ #include "modpython/swigpyrun.h" #include "modpython/module.h" -#include "modpython/retstring.h" +#include "modpython/ret.h" class CModPython: public CModule { @@ -197,6 +197,11 @@ public: Py_CLEAR(pyFunc); return HALT; } + if (!PyObject_IsTrue(pyRes)) { + // python module, but not handled by modpython itself. + // some module-loader written on python loaded it? + return CONTINUE; + } Py_CLEAR(pyFunc); Py_CLEAR(pyRes); bSuccess = true; diff --git a/modules/modpython/codegen.pl b/modules/modpython/codegen.pl index b775354c..59c93207 100644 --- a/modules/modpython/codegen.pl +++ b/modules/modpython/codegen.pl @@ -268,6 +268,13 @@ while (<$in>) { say $out "Py_BuildValue(\"s\", $a->{var}.c_str());"; } } + when (/^bool/) { + if ($a->{mod} eq '&') { + say $out "CPyRetBool::wrap($a->{var});"; + } else { + say $out "Py_BuildValue(\"l\", (long int)$a->{var});"; + } + } when (/\*$/) { (my $t = $a->{type}) =~ s/^const//; say $out "SWIG_NewInstanceObj(const_cast<$t>($a->{var}), SWIG_TypeQuery(\"$t\"), 0);"; @@ -276,9 +283,6 @@ while (<$in>) { (my $b = $a->{base}) =~ s/^const//; say $out "SWIG_NewInstanceObj(const_cast<$b*>(&$a->{var}), SWIG_TypeQuery(\"$b*\"), 0);"; } - when ('bool') { - say $out "Py_BuildValue(\"l\", (long int)$a->{var});"; - } when (/(?:^|::)E/) { say $out "Py_BuildValue(\"i\", (int)$a->{var});"; } diff --git a/modules/modpython/modpython.i b/modules/modpython/modpython.i index db436409..b953f7ca 100644 --- a/modules/modpython/modpython.i +++ b/modules/modpython/modpython.i @@ -31,7 +31,7 @@ #include "../include/znc/Buffer.h" #include "modpython/module.h" -#include "modpython/retstring.h" +#include "modpython/ret.h" #define stat struct stat using std::allocator; @@ -91,6 +91,17 @@ namespace std { } } +/*TODO %typemap(in) bool& to be able to call from python functions which get bool& */ + +%typemap(out) bool&, bool* { + if ($1) { + $result = CPyRetBool::wrap(*$1); + } else { + $result = Py_None; + Py_INCREF(Py_None); + } +} + #define u_short unsigned short #define u_int unsigned int #include "../include/znc/ZNCString.h" @@ -139,6 +150,18 @@ public: } }; +class CPyRetBool { + CPyRetBool(); + public: + bool b; +}; + +%extend CPyRetBool { + bool __bool__() { + return $self->b; + } +} + %extend CModule { CString __str__() { return $self->GetModName(); @@ -211,6 +234,18 @@ public: } }; +/* To allow module-loaders to be written on python. + * They can call CreatePyModule() to create CModule* object, but one of arguments to CreatePyModule() is "CModule* pModPython" + * Pointer to modpython is already accessible to python modules as self.GetModPython(), but it's just a pointer to something, not to CModule*. + * So make it known that CModPython is really a CModule. + */ +class CModPython : public CModule { +private: + CModPython(); + CModPython(const CModPython&); + ~CModPython(); +}; + /* Web */ %template(StrPair) std::pair; diff --git a/modules/modpython/module.h b/modules/modpython/module.h index 8d9ae951..7825fa4f 100644 --- a/modules/modpython/module.h +++ b/modules/modpython/module.h @@ -122,6 +122,7 @@ public: virtual EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg); virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule, bool& bSuccess, CString& sRetMsg); + virtual void OnGetAvailableMods(set& ssMods, CModInfo::EModuleType eType); }; static inline CPyModule* AsPyModule(CModule* p) { diff --git a/modules/modpython/retstring.h b/modules/modpython/ret.h similarity index 69% rename from modules/modpython/retstring.h rename to modules/modpython/ret.h index 5879ae0d..26c09912 100644 --- a/modules/modpython/retstring.h +++ b/modules/modpython/ret.h @@ -18,4 +18,12 @@ public: } }; - +class CPyRetBool { +public: + bool& b; + CPyRetBool(bool& B) : b(B) {} + static PyObject* wrap(bool& B) { + CPyRetBool* x = new CPyRetBool(B); + return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetBool*"), SWIG_POINTER_OWN); + } +}; diff --git a/modules/modpython/znc.py b/modules/modpython/znc.py index eb56b9e6..86930f49 100644 --- a/modules/modpython/znc.py +++ b/modules/modpython/znc.py @@ -549,6 +549,8 @@ def load_module(modname, args, module_type, user, network, retmsg, modpython): def unload_module(module): + if (module not in _py_modules): + return False module.OnShutdown() _py_modules.discard(module) cmod = module._cmod @@ -561,6 +563,7 @@ def unload_module(module): del module._cmod cmod.DeletePyModule() del cmod + return True def unload_all():