diff options
author | npmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56> | 2010-02-14 00:04:12 +0000 |
---|---|---|
committer | npmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56> | 2010-02-14 00:04:12 +0000 |
commit | 79ec18bc210cb6d1823ccb51229959bcccd50af3 (patch) | |
tree | be1919d89a15502ae3f041f0bdae9f5e829d80d2 /libmodman | |
parent | bff77d678636923790e3c473b0c95bd5d9af6270 (diff) | |
download | libproxy-git-79ec18bc210cb6d1823ccb51229959bcccd50af3.tar.gz |
rework libmodman to not use a struct in the module metadata
Diffstat (limited to 'libmodman')
-rw-r--r-- | libmodman/module.hpp | 44 | ||||
-rw-r--r-- | libmodman/module_manager.cpp | 133 | ||||
-rw-r--r-- | libmodman/module_manager.hpp | 1 | ||||
-rw-r--r-- | libmodman/test/modules/module.cpp.in | 5 |
4 files changed, 95 insertions, 88 deletions
diff --git a/libmodman/module.hpp b/libmodman/module.hpp index 39cab52..f908c00 100644 --- a/libmodman/module.hpp +++ b/libmodman/module.hpp @@ -24,35 +24,40 @@ #include <cstdlib> #ifdef WIN32 -#define __MOD_DEF_PREFIX extern "C" #define __MM_DLL_EXPORT __declspec(dllexport) +#define __MM_FUNC_DEF_PREFIX extern "C" __MM_DLL_EXPORT +#define __MM_SCLR_DEF_PREFIX extern "C" __MM_DLL_EXPORT #else -#define __MOD_DEF_PREFIX #define __MM_DLL_EXPORT __attribute__ ((visibility("default"))) +#define __MM_FUNC_DEF_PREFIX __MM_DLL_EXPORT +#define __MM_SCLR_DEF_PREFIX extern "C" __MM_DLL_EXPORT #endif #define MM_MODULE_VERSION 1 -#define MM_MODULE_NAME __module -#define MM_MODULE_DEFINE __MOD_DEF_PREFIX struct libmodman::module __MM_DLL_EXPORT MM_MODULE_NAME[] -#define MM_MODULE_LAST { MM_MODULE_VERSION, NULL, NULL, NULL, NULL, NULL } -#define MM_MODULE_RECORD(type, init, test, symb, smod) \ - { MM_MODULE_VERSION, type::base_type(), init, test, symb, smod } +#define MM_MODULE_VARNAME(name) __mm_ ## name +#define MM_MODULE_INIT(mtype, minit) \ + template <class T> static const char* mtype ## _type() { return T::base_type(); } \ + __MM_SCLR_DEF_PREFIX const unsigned int MM_MODULE_VARNAME(vers) = MM_MODULE_VERSION; \ + __MM_FUNC_DEF_PREFIX const char* (*MM_MODULE_VARNAME(type))() = mtype ## _type<mtype>; \ + __MM_FUNC_DEF_PREFIX base_extension** (*MM_MODULE_VARNAME(init))() = minit; +#define MM_MODULE_TEST(mtest) \ + __MM_FUNC_DEF_PREFIX bool (*MM_MODULE_VARNAME(test))() = mtest; +#define MM_MODULE_SYMB(msymb, msmod) \ + __MM_SCLR_DEF_PREFIX const char* const MM_MODULE_VARNAME(symb) = msymb; \ + __MM_SCLR_DEF_PREFIX const char* const MM_MODULE_VARNAME(smod) = msmod; -#define MM_MODULE_EZ(clsname, cond, symb, smod) \ - static bool clsname ## _test() { \ - return (cond); \ - } \ +#define MM_MODULE_INIT_EZ(clsname) \ static libmodman::base_extension** clsname ## _init() { \ libmodman::base_extension** retval = new libmodman::base_extension*[2]; \ retval[0] = new clsname(); \ retval[1] = NULL; \ return retval; \ } \ - MM_MODULE_DEFINE = { \ - MM_MODULE_RECORD(clsname, clsname ## _init, clsname ## _test, symb, smod), \ - MM_MODULE_LAST, \ - }; + MM_MODULE_INIT(clsname, clsname ## _init) +#define MM_MODULE_TEST_EZ(clsname, mtest) \ + static bool clsname ## _test() { return mtest; } \ + MM_MODULE_TEST(clsname ## _test) namespace libmodman { @@ -71,15 +76,6 @@ public: static const char* base_type() { return typeid(T).name(); } }; -struct module { - const unsigned int vers; - const char* const type; - base_extension** (*init)(); - bool (*test)(); - const char* const symb; - const char* const smod; -}; - } #endif /* MODULE_HPP_ */ diff --git a/libmodman/module_manager.cpp b/libmodman/module_manager.cpp index 65f985d..f959105 100644 --- a/libmodman/module_manager.cpp +++ b/libmodman/module_manager.cpp @@ -31,6 +31,8 @@ #include "module_manager.hpp" using namespace libmodman; +#include <cstdio> + #ifdef WIN32 #define pdlmtype HMODULE #define pdlopen(filename) LoadLibrary(filename) @@ -67,7 +69,7 @@ static string pdlerror() { return dlerror(); } -static bool pdlsymlinked(const char* modn, const char* symb) { +bool pdlsymlinked(const char* modn, const char* symb) { void* mod = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); if (mod) { void* sym = dlsym(mod, symb); @@ -95,30 +97,15 @@ module_manager::~module_manager() { pdlclose(*i); this->modules.clear(); } - +/* bool module_manager::load_module(module* mi) { const char* debug = getenv("_MM_DEBUG"); bool loaded = false; for (unsigned int i=0 ; mi[i].vers == MM_MODULE_VERSION && mi[i].type && mi[i].init ; i++) { - // If our execution test succeeds, call init() - if (mi[i].test()) { - base_extension** extensions = mi[i].init(); - if (extensions) { - // init() returned extensions we need to register - loaded = true; - for (unsigned int j=0 ; extensions[j] ; j++) { - if (debug) - cerr << "\tRegistering " - << typeid(*extensions[j]).name() << "(" - << mi[i].type << ")" << endl; - this->extensions[mi[i].type].push_back(extensions[j]); - } - delete extensions; - } - } + } return loaded; -} +}*/ bool module_manager::load_file(string filename, bool symbreq) { const char* debug = getenv("_MM_DEBUG"); @@ -148,68 +135,90 @@ bool module_manager::load_file(string filename, bool symbreq) { return true; } - // Get the module_info struct - module* mi = (module*) pdlsym(dlobj, __str(MM_MODULE_NAME)); - if (!mi) { + // Get the module info + const unsigned int* vers = (unsigned int*) pdlsym(dlobj, __str(MM_MODULE_VARNAME(vers))); + const char* const (**type)() = (const char* const (**)()) pdlsym(dlobj, __str(MM_MODULE_VARNAME(type))); + base_extension** (**init)() = (base_extension** (**)()) pdlsym(dlobj, __str(MM_MODULE_VARNAME(init))); + bool (**test)() = (bool (**)()) pdlsym(dlobj, __str(MM_MODULE_VARNAME(test))); + const char** const symb = (const char** const) pdlsym(dlobj, __str(MM_MODULE_VARNAME(symb))); + const char** const smod = (const char** const) pdlsym(dlobj, __str(MM_MODULE_VARNAME(smod))); + if (!vers || !type || !init || !*type || !*init || *vers != MM_MODULE_VERSION) { if (debug) cerr << "failed!" << endl - << "\tUnable to find struct: " __str(MM_MODULE_NAME) << endl; + << "\tUnable to find basic module info!" << endl; pdlclose(dlobj); return false; } - bool tryload = false; - for (unsigned int i=0 ; mi[i].vers == MM_MODULE_VERSION && mi[i].type && mi[i].init ; i++) { - // Make sure the type is registered - if (this->extensions.find(mi[i].type) == this->extensions.end()) { + // Make sure the type is registered + if (this->extensions.find((*type)()) == this->extensions.end()) { + if (debug) + cerr << "failed!" << endl + << "\tUnknown extension type: " << (*type)() << endl; + pdlclose(dlobj); + return false; + } + + // If this is a singleton and we already have an instance, don't instantiate + if (this->singletons.find((*type)()) != this->singletons.end() && + this->extensions[(*type)()].size() > 0) { + if (debug) + cerr << "failed!" << endl + << "\tNot loading subsequent singleton for: " << (*type)() << endl; + pdlclose(dlobj); + return false; + } + + // If a symbol is defined, we'll search for it in the main process + if (symb && *symb && smod && *smod && !pdlsymlinked(*smod, *symb)) { + // If the symbol is not found and the symbol is required, error + if (symbreq) { if (debug) cerr << "failed!" << endl - << "\tUnknown extension type: " << mi[i].type << endl; - continue; + << "\tUnable to find required symbol: " + << symb << endl; + pdlclose(dlobj); + return false; } - // If this is a singleton and we already have an instance, don't instantiate - if (this->singletons.find(mi[i].type) != this->singletons.end() && - this->extensions[mi[i].type].size() > 0) { + // If the symbol is not found and not required, we'll load only + // if there are no other modules of this type + else if (this->extensions[(*type)()].size() > 0) { if (debug) cerr << "failed!" << endl - << "\tNot loading subsequent singleton for: " << mi[i].type << endl; - continue; + << "\tUnable to find required symbol: " + << symb << endl; + pdlclose(dlobj); + return false; } + } - // If a symbol is defined, we'll search for it in the main process - if (mi[i].symb) { - // Try to find the symbol in the main process - if (!pdlsymlinked(mi[i].smod, mi[i].symb)) { - // If the symbol is not found and the symbol is required, continue - // If the symbol is not found and not required, we'll load only - // if there are no other modules of this type - if (symbreq || this->extensions[mi[i].type].size() > 0) { - if (debug) - cerr << "failed!" << endl - << "\tUnable to find required symbol: " - << mi[i].symb << endl; - continue; - } - } + // If our execution test succeeds, call init() + if ((test && *test && (*test)()) || !test || !*test) { + base_extension** extensions = (*init)(); + if (!extensions) { + pdlclose(dlobj); + return false; } - tryload = true; - } - - // Our tests failed - if (debug) cerr << endl; - if (!tryload) { if (debug) - cerr << "\tNo suitable extension factories to try!" << endl; - pdlclose(dlobj); - return false; - } + cerr << "success" << endl; - // We didn't load this module, so exit - if (!this->load_module(mi)) { + // init() returned extensions we need to register + for (unsigned int i=0 ; extensions[i] ; i++) { + if (debug) + cerr << "\tRegistering " + << typeid(*extensions[i]).name() << "(" + << (*type)() << ")" << endl; + this->extensions[(*type)()].push_back(extensions[i]); + } + delete extensions; + } + else { if (debug) - cerr << "\tAll extension factories failed!" << endl; + cerr << "failed!" << endl + << "\tTest execution failed: " + << symb << endl; pdlclose(dlobj); return false; } diff --git a/libmodman/module_manager.hpp b/libmodman/module_manager.hpp index 9df4285..36bab5d 100644 --- a/libmodman/module_manager.hpp +++ b/libmodman/module_manager.hpp @@ -42,7 +42,6 @@ using namespace std; class __MM_DLL_EXPORT module_manager { public: ~module_manager(); - bool load_module(module* module); bool load_file(string filename, bool symbreq=true); bool load_dir(string dirname, bool symbreq=true, string suffix=_MOD_SUFFIX); diff --git a/libmodman/test/modules/module.cpp.in b/libmodman/test/modules/module.cpp.in index 41ccd25..cefe24a 100644 --- a/libmodman/test/modules/module.cpp.in +++ b/libmodman/test/modules/module.cpp.in @@ -21,4 +21,7 @@ #include <libmodman/module.hpp> class @MODNAME@ : public @MODTYPE@_extension {}; -MM_MODULE_EZ(@MODNAME@, @MODCOND@, @MODSYMB@, @MODSMOD@); +bool test() { return @MODCOND@; } +MM_MODULE_INIT_EZ(@MODNAME@); +MM_MODULE_TEST(test); +MM_MODULE_SYMB(@MODSYMB@, @MODSMOD@); |