/* * Copyright (C) 2004-2016 ZNC, see the NOTICE file for details. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ %module znc_core %{ #include #include "znc/Utils.h" #include "znc/Threads.h" #include "znc/Config.h" #include "znc/Socket.h" #include "znc/Modules.h" #include "znc/Nick.h" #include "znc/Chan.h" #include "znc/User.h" #include "znc/IRCNetwork.h" #include "znc/Client.h" #include "znc/IRCSock.h" #include "znc/Listener.h" #include "znc/HTTPSock.h" #include "znc/Template.h" #include "znc/WebModules.h" #include "znc/znc.h" #include "znc/Server.h" #include "znc/ZNCString.h" #include "znc/FileUtils.h" #include "znc/ZNCDebug.h" #include "znc/ExecSock.h" #include "znc/Buffer.h" #include "modpython/module.h" #include "modpython/ret.h" #define stat struct stat using std::allocator; %} %apply long { off_t }; %apply long { uint16_t }; %apply long { uint32_t }; %apply long { uint64_t }; // Just makes generated python code slightly more beautiful. %feature("python:defaultargs"); // Probably can be removed when swig is fixed to not produce bad code for some cases %feature("python:defaultargs", "0") CDir::MakeDir; // 0700 doesn't work in python3 %feature("python:defaultargs", "0") CUtils::GetNumInput; // SyntaxError: non-default argument follows default argument %feature("python:defaultargs", "0") CModules::GetAvailableMods; // NameError: name 'UserModule' is not defined %feature("python:defaultargs", "0") CModules::GetDefaultMods; // NameError: name 'UserModule' is not defined %begin %{ #include "znc/zncconfig.h" %} %include %include %include %include %include %include %include %shared_ptr(CAuthBase); %shared_ptr(CWebSession); %shared_ptr(CClientAuth); %include "modpython/cstring.i" %template(_stringlist) std::list; %typemap(out) CModules::ModDirList %{ $result = PyList_New($1.size()); if ($result) { for (size_t i = 0; !$1.empty(); $1.pop(), ++i) { PyList_SetItem($result, i, Py_BuildValue("ss", $1.front().first.c_str(), $1.front().second.c_str())); } } %} %template(VIRCNetworks) std::vector; %template(VChannels) std::vector; %template(MNicks) std::map; %template(SModInfo) std::set; %template(SCString) std::set; typedef std::set SCString; %template(VCString) std::vector; typedef std::vector VCString; %template(PyMCString) std::map; %template(PyMStringVString) std::map; class MCString : public std::map {}; %template(PyModulesVector) std::vector; %template(VListeners) std::vector; %template(BufLines) std::deque; %template(VVString) std::vector; %template(VClients) std::vector; #define REGISTER_ZNC_MESSAGE(M) \ %template(As_ ## M) CMessage::As; %typemap(in) CString& { String* p; int res = SWIG_IsOK(SWIG_ConvertPtr($input, (void**)&p, SWIG_TypeQuery("String*"), 0)); if (SWIG_IsOK(res)) { $1 = &p->s; } else { SWIG_exception_fail(SWIG_ArgError(res), "need znc.String object as argument $argnum $1_name"); } } %typemap(out) CString&, CString* { if ($1) { $result = CPyRetString::wrap(*$1); } else { $result = Py_None; Py_INCREF(Py_None); } } %typemap(typecheck) CString&, CString* { String* p; $1 = SWIG_IsOK(SWIG_ConvertPtr($input, (void**)&p, SWIG_TypeQuery("String*"), 0)); } /*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 "znc/zncconfig.h" #include "znc/ZNCString.h" %include "znc/defines.h" %include "znc/Translation.h" %include "znc/Utils.h" %include "znc/Threads.h" %include "znc/Config.h" %include "znc/Csocket.h" %template(ZNCSocketManager) TSocketManager; %include "znc/Socket.h" %include "znc/FileUtils.h" %include "znc/Message.h" %include "znc/Modules.h" %include "znc/Nick.h" %include "znc/Chan.h" %include "znc/User.h" %include "znc/IRCNetwork.h" %include "znc/Client.h" %include "znc/IRCSock.h" %include "znc/Listener.h" %include "znc/HTTPSock.h" %include "znc/Template.h" %include "znc/WebModules.h" %include "znc/znc.h" %include "znc/Server.h" %include "znc/ZNCDebug.h" %include "znc/ExecSock.h" %include "znc/Buffer.h" %include "modpython/module.h" /* Really it's CString& inside, but SWIG shouldn't know that :) */ class CPyRetString { CPyRetString(); public: CString s; }; %extend CPyRetString { CString __str__() { return $self->s; } }; %extend String { CString __str__() { return $self->s; } }; class CPyRetBool { CPyRetBool(); public: bool b; }; %extend CPyRetBool { bool __bool__() { return $self->b; } } %extend Csock { PyObject* WriteBytes(PyObject* data) { if (!PyBytes_Check(data)) { PyErr_SetString(PyExc_TypeError, "socket.WriteBytes needs bytes as argument"); return nullptr; } char* buffer; Py_ssize_t length; if (-1 == PyBytes_AsStringAndSize(data, &buffer, &length)) { return nullptr; } if ($self->Write(buffer, length)) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } } %extend CModule { CString __str__() { return $self->GetModName(); } MCString_iter BeginNV_() { return MCString_iter($self->BeginNV()); } bool ExistsNV(const CString& sName) { return $self->EndNV() != $self->FindNV(sName); } } %extend CModules { bool removeModule(CModule* p) { for (CModules::iterator i = $self->begin(); $self->end() != i; ++i) { if (*i == p) { $self->erase(i); return true; } } return false; } } %extend CUser { CString __str__() { return $self->GetUserName(); } CString __repr__() { return "GetUserName() + ">"; } std::vector GetNetworks_() { return $self->GetNetworks(); } }; %extend CIRCNetwork { CString __str__() { return $self->GetName(); } CString __repr__() { return "GetName() + ">"; } std::vector GetChans_() { return $self->GetChans(); } } %extend CChan { CString __str__() { return $self->GetName(); } CString __repr__() { return "GetName() + ">"; } std::map GetNicks_() { return $self->GetNicks(); } }; %extend CNick { CString __str__() { return $self->GetNick(); } CString __repr__() { return "GetHostMask() + ">"; } }; %extend CMessage { CString __str__() { return $self->ToString(); } CString __repr__() { return $self->ToString(); } }; %extend CZNC { PyObject* GetUserMap_() { PyObject* result = PyDict_New(); auto user_type = SWIG_TypeQuery("CUser*"); for (const auto& p : $self->GetUserMap()) { PyObject* user = SWIG_NewInstanceObj(p.second, user_type, 0); PyDict_SetItemString(result, p.first.c_str(), user); Py_CLEAR(user); } return result; } }; /* 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; %template(VPair) std::vector >; typedef std::vector > VPair; %template(VWebSubPages) std::vector; %inline %{ void VPair_Add2Str_(VPair* self, const CString& a, const CString& b) { self->push_back(std::make_pair(a, b)); } %} %extend CTemplate { void set(const CString& key, const CString& value) { DEBUG("WARNING: modpython's CTemplate.set is deprecated and will be removed. Use normal dict's operations like Tmpl['foo'] = 'bar'"); (*$self)[key] = value; } } %inline %{ TWebSubPage CreateWebSubPage_(const CString& sName, const CString& sTitle, const VPair& vParams, unsigned int uFlags) { return std::make_shared(sName, sTitle, vParams, uFlags); } %} /* vim: set filetype=cpp: */