From ad9f1f8ab9a60391ce93ff9979d8afa58de01789 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 11 Jun 2011 17:19:36 +0700 Subject: [PATCH] Change a way for modules to provide description. Now there're only 2 functions which modules export: ZNCModVersion() and ZNCModInfo(). ZNCModInfo() returns CModInfo instance, which contains description, globality, function for loading the module. It needs to be deleted afterwise. --- Modules.cpp | 105 ++++++++++++++++++---------------------------------- Modules.h | 82 ++++++++++++++++++++++------------------ 2 files changed, 82 insertions(+), 105 deletions(-) diff --git a/Modules.cpp b/Modules.cpp index aa28c2b2..1692cbad 100644 --- a/Modules.cpp +++ b/Modules.cpp @@ -816,16 +816,15 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p GLOBALMODULECALL(OnModuleLoading(sModule, sArgs, bSuccess, sRetMsg), pUser, NULL, return bSuccess); CString sModPath, sDataPath; - CString sDesc; bool bVersionMismatch; - bool bIsGlobal; + CModInfo* Info; if (!FindModPath(sModule, sModPath, sDataPath)) { sRetMsg = "Unable to find module [" + sModule + "]"; return false; } - ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, bIsGlobal, sDesc, sRetMsg); + ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, Info, sRetMsg); if (!p) return false; @@ -836,10 +835,11 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p return false; } - if ((pUser == NULL) != bIsGlobal) { + if ((pUser == NULL) != Info->IsGlobal()) { + delete Info; dlclose(p); sRetMsg = "Module [" + sModule + "] is "; - sRetMsg += (bIsGlobal) ? "" : "not "; + sRetMsg += Info->IsGlobal() ? "" : "not "; sRetMsg += "a global module."; return false; } @@ -847,37 +847,19 @@ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CUser* p CModule* pModule = NULL; if (pUser) { - typedef CModule* (*fp)(ModHandle, CUser* pUser, - const CString& sModName, const CString& sDataPath); - fp Load = (fp) dlsym(p, "ZNCModLoad"); - - if (!Load) { - dlclose(p); - sRetMsg = "Could not find ZNCModLoad() in module [" + sModule + "]"; - return false; - } - - pModule = Load(p, pUser, sModule, sDataPath); + pModule = Info->GetLoader()(p, pUser, sModule, sDataPath); } else { - typedef CModule* (*fp)(ModHandle, const CString& sModName, - const CString& sDataPath); - fp Load = (fp) dlsym(p, "ZNCModLoad"); - - if (!Load) { - dlclose(p); - sRetMsg = "Could not find ZNCModLoad() in module [" + sModule + "]"; - return false; - } - - pModule = Load(p, sModule, sDataPath); + pModule = Info->GetGlobalLoader()(p, sModule, sDataPath); } - pModule->SetDescription(sDesc); - pModule->SetGlobal(bIsGlobal); + pModule->SetDescription(Info->GetDescription()); + pModule->SetGlobal(Info->IsGlobal()); pModule->SetArgs(sArgs); pModule->SetModPath(CDir::ChangeDir(CZNC::Get().GetCurPath(), sModPath)); push_back(pModule); + delete Info; + bool bLoaded; try { bLoaded = pModule->OnLoad(sArgs, sRetMsg); @@ -923,27 +905,19 @@ bool CModules::UnloadModule(const CString& sModule, CString& sRetMsg) { ModHandle p = pModule->GetDLL(); if (p) { - typedef void (*fp)(CModule*); - fp Unload = (fp)dlsym(p, "ZNCModUnload"); + delete pModule; - if (Unload) { - Unload(pModule); - - for (iterator it = begin(); it != end(); ++it) { - if (*it == pModule) { - erase(it); - break; - } + for (iterator it = begin(); it != end(); ++it) { + if (*it == pModule) { + erase(it); + break; } - - dlclose(p); - sRetMsg = "Module [" + sMod + "] unloaded"; - - return true; - } else { - sRetMsg = "Unable to unload module [" + sMod + "] could not find ZNCModUnload()"; - return false; } + + dlclose(p); + sRetMsg = "Module [" + sMod + "] unloaded"; + + return true; } sRetMsg = "Unable to unload module [" + sMod + "]"; @@ -980,17 +954,18 @@ bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule, CString& sR } bool CModules::GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const CString& sModPath, CString& sRetMsg) { - CString sDesc; bool bVersionMismatch; - bool bIsGlobal; + CModInfo* Info; - ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, bIsGlobal, sDesc, sRetMsg); + ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, Info, sRetMsg); if (!p) return false; - ModInfo.SetGlobal(bIsGlobal); - ModInfo.SetDescription(sDesc); + if (Info) { + ModInfo.SetGlobal(Info->IsGlobal()); + ModInfo.SetDescription(Info->GetDescription()); + } ModInfo.SetName(sModule); ModInfo.SetPath(sModPath); @@ -998,6 +973,7 @@ bool CModules::GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const C ModInfo.SetDescription("--- Version mismatch, recompile this module. ---"); } + delete Info; dlclose(p); return true; @@ -1082,11 +1058,10 @@ CModules::ModDirList CModules::GetModDirs() { } ModHandle CModules::OpenModule(const CString& sModule, const CString& sModPath, bool &bVersionMismatch, - bool &bIsGlobal, CString& sDesc, CString& sRetMsg) { + CModInfo*& Info, CString& sRetMsg) { // Some sane defaults in case anything errors out below bVersionMismatch = false; - bIsGlobal = false; - sDesc.clear(); + Info = NULL; sRetMsg.clear(); for (unsigned int a = 0; a < sModule.length(); a++) { @@ -1124,21 +1099,12 @@ ModHandle CModules::OpenModule(const CString& sModule, const CString& sModPath, return NULL; } - typedef bool (*bFP)(); - bFP IsGlobal = (bFP) dlsym(p, "ZNCModGlobal"); + typedef CModInfo* (*InfoFP)(); + InfoFP ZNCModInfo = (InfoFP) dlsym(p, "ZNCModInfo"); - if (!IsGlobal) { + if (!ZNCModInfo) { dlclose(p); - sRetMsg = "Could not find ZNCModGlobal() in module [" + sModule + "]"; - return NULL; - } - - typedef const char *(*sFP)(); - sFP GetDesc = (sFP) dlsym(p, "ZNCModDescription"); - - if (!GetDesc) { - dlclose(p); - sRetMsg = "Could not find ZNCModDescription() in module [" + sModule + "]"; + sRetMsg = "Could not find ZNCModInfo() in module [" + sModule + "]"; return NULL; } @@ -1146,10 +1112,9 @@ ModHandle CModules::OpenModule(const CString& sModule, const CString& sModPath, bVersionMismatch = true; sRetMsg = "Version mismatch, recompile this module."; } else { + Info = ZNCModInfo(); sRetMsg = ""; bVersionMismatch = false; - bIsGlobal = IsGlobal(); - sDesc = GetDesc(); } return p; diff --git a/Modules.h b/Modules.h index 9b50fab2..f216b6d3 100644 --- a/Modules.h +++ b/Modules.h @@ -24,6 +24,9 @@ class CClient; class CWebSock; class CTemplate; class CIRCSock; +class CModule; +class CGlobalModule; +class CModInfo; // !Forward Declarations // User Module Macros @@ -39,13 +42,28 @@ class CIRCSock; typedef void* ModHandle; -#define MODCOMMONDEFS(DESCRIPTION, GLOBAL) \ - const char *ZNCModDescription(); \ - bool ZNCModGlobal(); \ - double ZNCModVersion(); \ - const char *ZNCModDescription() { return DESCRIPTION; } \ - double ZNCModVersion() { return VERSION; } \ - bool ZNCModGlobal() { return GLOBAL; } \ +template CModule* TModLoad(ModHandle p, CUser* pUser, + const CString& sModName, const CString& sModPath) { + return new M(p, pUser, sModName, sModPath); +} +template CGlobalModule* TModLoadGlobal(ModHandle p, + const CString& sModName, const CString& sModPath) { + return new M(p, sModName, sModPath); +} + +#define MODCOMMONDEFS(CLASS, DESCRIPTION, GLOBAL, LOADER) \ + extern "C" { \ + double ZNCModVersion(); \ + double ZNCModVersion() { return VERSION; } \ + CModInfo* ZNCModInfo(); \ + CModInfo* ZNCModInfo() { \ + CModInfo* Info = new CModInfo(); \ + Info->SetDescription(DESCRIPTION); \ + Info->SetGlobal(GLOBAL); \ + LOADER; \ + return Info; \ + } \ + } /** Instead of writing a constructor, you should call this macro. It accepts all * the necessary arguments and passes them on to CModule's constructor. You @@ -75,17 +93,7 @@ typedef void* ModHandle; * @see For global modules you need GLOBALMODULEDEFS. */ #define MODULEDEFS(CLASS, DESCRIPTION) \ - extern "C" { \ - MODCOMMONDEFS(DESCRIPTION, false) \ - /* First the definitions to shut up some compiler warnings */ \ - CModule* ZNCModLoad(ModHandle p, CUser* pUser, const CString& sModName, \ - const CString& sModPath); \ - void ZNCModUnload(CModule* pMod); \ - CModule* ZNCModLoad(ModHandle p, CUser* pUser, const CString& sModName, \ - const CString& sModPath) \ - { return new CLASS(p, pUser, sModName, sModPath); } \ - void ZNCModUnload(CModule* pMod) { if (pMod) { delete pMod; } } \ - } + MODCOMMONDEFS(CLASS, DESCRIPTION, false, Info->SetLoader(TModLoad)) // !User Module Macros // Global Module Macros @@ -96,17 +104,7 @@ typedef void* ModHandle; /** This works exactly like MODULEDEFS, but for global modules. */ #define GLOBALMODULEDEFS(CLASS, DESCRIPTION) \ - extern "C" { \ - MODCOMMONDEFS(DESCRIPTION, true) \ - /* First the definitions to shut up some compiler warnings */ \ - CGlobalModule* ZNCModLoad(ModHandle p, const CString& sModName, \ - const CString& sModPath); \ - void ZNCModUnload(CGlobalModule* pMod); \ - CGlobalModule* ZNCModLoad(ModHandle p, const CString& sModName, \ - const CString& sModPath) \ - { return new CLASS(p, sModName, sModPath); } \ - void ZNCModUnload(CGlobalModule* pMod) { if (pMod) { delete pMod; } } \ - } + MODCOMMONDEFS(CLASS, DESCRIPTION, true, Info->SetGlobalLoader(TModLoadGlobal)) // !Global Module Macros // Forward Declarations @@ -166,11 +164,19 @@ private: class CModInfo { public: - CModInfo() {} + typedef CModule* (*ModLoader)(ModHandle p, CUser* pUser, const CString& sModName, const CString& sModPath); + typedef CGlobalModule* (*GlobalModLoader)(ModHandle p, const CString& sModName, const CString& sModPath); + + CModInfo() { + m_fGlobalLoader = NULL; + m_fLoader = NULL; + } CModInfo(const CString& sName, const CString& sPath, bool bGlobal) { m_bGlobal = bGlobal; m_sName = sName; m_sPath = sPath; + m_fGlobalLoader = NULL; + m_fLoader = NULL; } ~CModInfo() {} @@ -183,6 +189,8 @@ public: const CString& GetPath() const { return m_sPath; } const CString& GetDescription() const { return m_sDescription; } bool IsGlobal() const { return m_bGlobal; } + ModLoader GetLoader() const { return m_fLoader; } + GlobalModLoader GetGlobalLoader() const { return m_fGlobalLoader; } // !Getters // Setters @@ -190,13 +198,17 @@ public: void SetPath(const CString& s) { m_sPath = s; } void SetDescription(const CString& s) { m_sDescription = s; } void SetGlobal(bool b) { m_bGlobal = b; } + void SetLoader(ModLoader fLoader) { m_fLoader = fLoader; } + void SetGlobalLoader(GlobalModLoader fGlobalLoader) { m_fGlobalLoader = fGlobalLoader; } // !Setters private: protected: - bool m_bGlobal; - CString m_sName; - CString m_sPath; - CString m_sDescription; + bool m_bGlobal; + CString m_sName; + CString m_sPath; + CString m_sDescription; + ModLoader m_fLoader; + GlobalModLoader m_fGlobalLoader; }; /** A helper class for handling commands in modules. */ @@ -964,7 +976,7 @@ public: private: static ModHandle OpenModule(const CString& sModule, const CString& sModPath, - bool &bVersionMismatch, bool &bIsGlobal, CString& sDesc, CString& sRetMsg); + bool &bVersionMismatch, CModInfo*& Info, CString& sRetMsg); protected: CUser* m_pUser;