diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-10-06 16:50:48 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-10-06 16:50:48 +0000 |
commit | f9717e35cab505cfca95e708b53336bd7bf78f56 (patch) | |
tree | 04c1fd9c4d34b224f9816fd501b18809cc01152e | |
parent | 2fabf1ccd1897c55b58757d8ed722a025f93554f (diff) |
Take advantage of link errors to check API_VERSION at module load time
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11805 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/modules.h | 26 | ||||
-rw-r--r-- | src/modules.cpp | 25 |
2 files changed, 23 insertions, 28 deletions
diff --git a/include/modules.h b/include/modules.h index ca345dbc1..d59bdf05b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -104,8 +104,8 @@ struct ModResult { } }; -/** If you change the module API, change this value. */ -#define API_VERSION 13000 +/** If you change the module API in any way, increment this value. */ +#define API_VERSION 131 class ServerConfig; @@ -226,13 +226,14 @@ do { \ #define IS_AWAY(x) (!x->awaymsg.empty()) /** Holds a module's Version information. - * The four members (set by the constructor only) indicate details as to the version number - * of a module. A class of type Version is returned by the GetVersion method of the Module class. - * The flags and API values represent the module flags and API version of the module. - * The API version of a module must match the API version of the core exactly for the module to - * load successfully. + * The members (set by the constructor only) indicate details as to the version number + * of a module. A class of type Version is returned by the GetVersion method of the Module class. + * + * The core provides only one implementation of the template, causing a run-time linking + * error when attempting to load a module compiled against a different API_VERSION. */ -class CoreExport Version : public classbase +template<int api> +class CoreExport VersionBase : public classbase { public: /** Module description @@ -242,16 +243,17 @@ class CoreExport Version : public classbase */ const std::string version; - /** Flags and API version + /** Flags */ - const int Flags, API; + const int Flags; /** Initialize version class */ - Version(const std::string &desc, int flags, - int api_ver = API_VERSION, const std::string& src_rev = VERSION " r" REVISION); + VersionBase(const std::string &desc, int flags = VF_NONE, int dummy = 0, const std::string& src_rev = VERSION " r" REVISION); }; +typedef VersionBase<API_VERSION> Version; + /** The ModuleMessage class is the base class of Request and Event * This class is used to represent a basic data structure which is passed * between modules for safe inter-module communications. diff --git a/src/modules.cpp b/src/modules.cpp index f7904d07b..36a885ea9 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -27,9 +27,12 @@ // version is a simple class for holding a modules version number -Version::Version(const std::string &modv, int flags, int api_ver, const std::string& rev) -: description(modv), version(rev), Flags(flags), API(api_ver) +template<> +VersionBase<API_VERSION>::VersionBase(const std::string &modv, int flags, int api_ver, const std::string& rev) +: description(modv), version(rev), Flags(flags) { + if (api_ver != API_VERSION) + abort(); } Request::Request(char* anydata, Module* src, Module* dst) @@ -439,19 +442,7 @@ bool ModuleManager::Load(const char* filename) newmod->ModuleDLLFactory = newhandle; Version v = newmod->GetVersion(); - if (v.API != API_VERSION) - { - DetachAll(newmod); - delete newmod; - delete newhandle; - LastModuleError = "Unable to load " + filename_str + ": Incorrect module API version: " + ConvToStr(v.API) + " (our version: " + ConvToStr(API_VERSION) + ")"; - ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError); - return false; - } - else - { - ServerInstance->Logs->Log("MODULE", DEFAULT,"New module introduced: %s (API version %d, Module version %s)%s", filename, v.API, v.version.c_str(), (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]")); - } + ServerInstance->Logs->Log("MODULE", DEFAULT,"New module introduced: %s (Module version %s)%s", filename, v.version.c_str(), (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]")); Modules[filename_str] = newmod; } @@ -463,7 +454,9 @@ bool ModuleManager::Load(const char* filename) return false; } } - /** XXX: Is there anything we can do about this mess? -- Brain */ + /** XXX: Is there anything we can do about this mess? -- Brain + * Yeah, don't use exceptions without RAII. -- Daniel + */ catch (LoadModuleException& modexcept) { DetachAll(newmod); |