From 88678209bc51a6cfebd342fd91941ae419e5d443 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 6 Feb 2011 05:06:16 +0100 Subject: [PATCH] use setup.ini to retrieve the modulepath and configpath connect config-facade with the new BasicSetup implementation to fetch values from setup.ini, instead of the (not implemented) Config-system. Hook this new lookup mechanism into the plugin loader to retrieve the search path from there --- data/config/setup.ini | 2 + src/common/appstate.cpp | 12 ++- src/common/appstate.hpp | 4 + src/common/basic-setup.cpp | 16 ++-- src/common/basic-setup.hpp | 18 ++++- src/common/configfacade.cpp | 80 ++++++++++++++++--- src/common/plugin.c | 34 ++++---- .../{configfacade.hpp => config-facade.h} | 29 ++++++- src/lib/lifecycle.cpp | 1 - tests/31plugin.tests | 6 +- tests/40components.tests | 2 +- ...{appconfigtest.cpp => app-config-test.cpp} | 49 ++++++------ 12 files changed, 183 insertions(+), 70 deletions(-) rename src/include/{configfacade.hpp => config-facade.h} (74%) rename tests/lib/{appconfigtest.cpp => app-config-test.cpp} (64%) diff --git a/data/config/setup.ini b/data/config/setup.ini index c1da6425b..60c92ed0d 100644 --- a/data/config/setup.ini +++ b/data/config/setup.ini @@ -10,3 +10,5 @@ # gui = gtk_gui.lum modulepath = $ORIGIN/modules +configpath = /usr/share/lumiera/config:~/.lumiera +version = 0.pre.01 diff --git a/src/common/appstate.cpp b/src/common/appstate.cpp index c47dea849..c0036fdf9 100644 --- a/src/common/appstate.cpp +++ b/src/common/appstate.cpp @@ -36,9 +36,10 @@ extern "C" { #include "lib/symbol.hpp" #include "lib/util.hpp" -#include "include/configfacade.hpp" //////////TODO: temp hack to force configfacade.o to be linked in + using util::cStr; +using lib::Literal; #define LOCATION_OF_BOOTSTRAP_INI "$ORIGIN/config/setup.ini" @@ -98,6 +99,13 @@ namespace lumiera { + string + AppState::fetchSetupValue (Literal key) + { + return setup_.get(key).as(); + } + + @@ -191,8 +199,6 @@ namespace lumiera { AppState::abort (lumiera::Error& problem) { - INFO (common, "Address of Config Facade = %p", &lumiera::Config::instance()); //////////TODO: a temp hack to force configfacade.cpp to be linked into lumiera exe. - ERROR (common, "Aborting Lumiera after unhandled error: %s", cStr(problem.what())); log_and_clear_unexpected_errorstate(); diff --git a/src/common/appstate.hpp b/src/common/appstate.hpp index 0f2a4ee14..8d44f09cd 100644 --- a/src/common/appstate.hpp +++ b/src/common/appstate.hpp @@ -90,6 +90,10 @@ namespace lumiera { void init (lumiera::Option& options); + /** access basic application setup values (from \c setup.ini) */ + string fetchSetupValue (lib::Literal key); + + /** building on the state determined by #evaluate, decide if the given Subsys * needs to be pulled up and, if necessary, register the Subsys and its * prerequisites to be maintained throughout the application's lifetime. */ diff --git a/src/common/basic-setup.cpp b/src/common/basic-setup.cpp index 1492695c3..5abeee2c0 100644 --- a/src/common/basic-setup.cpp +++ b/src/common/basic-setup.cpp @@ -74,11 +74,17 @@ namespace lumiera { , settings() { syntax.add_options() - ("BuildsystemDemo.gui", opt::value(), - "name of the Lumiera GUI plugin to load") - ("BuildsystemDemo.modulepath", opt::value(), - "search path for loadable modules. " - "May us $ORIGIN to refer to the EXE location") + ("Lumiera.gui", opt::value(), + "name of the Lumiera GUI plugin to load") + ("Lumiera.modulepath", opt::value(), + "search path for loadable modules. " + "May us $ORIGIN to refer to the EXE location") + ("Lumiera.configpath", opt::value(), + "search path for extended configuration. " + "Extended Config system not yet implemented " + "Ignored as of 2/2011") + ("Lumiera.version", opt::value(), + "Application version string") ; ifstream configIn (resolve(bootstrapIni).c_str()); diff --git a/src/common/basic-setup.hpp b/src/common/basic-setup.hpp index ec1759e3d..d35f25d38 100644 --- a/src/common/basic-setup.hpp +++ b/src/common/basic-setup.hpp @@ -25,6 +25,8 @@ #define COMMON_BASIC_SETUP_H #include "lib/error.hpp" +#include "lib/symbol.hpp" +#include "lib/util.hpp" #include #include @@ -68,19 +70,27 @@ namespace lumiera { BasicSetup (string bootstrapIni); string - operator[] (string const& key) const + operator[] (lib::Literal key) const { - return settings[key].as(); + return get (key).as(); } opt::variable_value const& - get (string const& key) + get (lib::Literal key) const { - return settings[key]; + string keyID (key); + __ensure_hasKey(keyID); + return settings[keyID]; } private: + void + __ensure_hasKey (string const& key) const + { + if (!util::contains (settings, key)) + throw error::Logic ("Key \""+key+"\" not found in setup.ini"); + } }; diff --git a/src/common/configfacade.cpp b/src/common/configfacade.cpp index bb91d84a8..f17d9163d 100644 --- a/src/common/configfacade.cpp +++ b/src/common/configfacade.cpp @@ -23,20 +23,39 @@ #include "include/logging.h" #include "include/lifecycle.h" -#include "include/configfacade.hpp" +#include "include/config-facade.h" +#include "common/appstate.hpp" +#include "lib/searchpath.hpp" +#include "lib/util.hpp" extern "C" { #include "common/config.h" } -#ifndef LUMIERA_CONFIG_PATH -#error LUMIERA_CONFIG_PATH not defined -#endif + +/** key to fetch the search path for extended configuration. + * Will corresponding value is defined in the basic setup.ini + * and will be fed to the (planned) full-blown config system + * after the basic application bootstrap was successful. + */ +#define KEY_CONFIG_PATH "Lumiera.configpath" + +/** Similarly, this key is used to fetch the configured default + * plugin/module search path from the basic setup.ini + * This patch is used by the plugin-loader to discover + * lumiera plugins and extensions. + */ +#define KEY_PLUGIN_PATH "Lumiera.modulepath" + namespace lumiera { + using util::cStr; + using util::isnil; + using lib::Literal; + namespace { @@ -47,7 +66,7 @@ namespace lumiera { Config::instance(); } - LifecycleHook trigger__ (ON_BASIC_INIT, &pull_up_ConfigSystem); + LifecycleHook trigger__ (ON_BASIC_INIT, &pull_up_ConfigSystem); } @@ -59,28 +78,63 @@ namespace lumiera { Config::Config () { - lumiera_config_init (LUMIERA_CONFIG_PATH); + string extendedConfigSearchPath = AppState::instance().fetchSetupValue (KEY_CONFIG_PATH); + lumiera_config_init (cStr(extendedConfigSearchPath)); INFO (config, "Config system ready."); - - TODO ("wire Config facade to config interface"); } Config::~Config() { lumiera_config_destroy(); - TRACE (common, "config system closed."); + TRACE (config, "config system closed."); } - const string - Config::get (string const& key) + /** @note because the full-blown Config system isn't implemented yet + * we retrieve the contents of setup.ini as a preliminary solution + */ + string + Config::get (lib::Literal key) { - UNIMPLEMENTED ("config facade access to config value"); - return string("warwohlnix"); + string value = AppState::instance().fetchSetupValue (key); + if (isnil (value)) + throw error::Config ("Configuration value for key=\""+key+"\" is missing"); + + return value; } } // namespace lumiera + + +extern "C" { /* ==== implementation C interface for accessing setup.ini ======= */ + + + using std::string; + using lumiera::Config; + using lib::SearchPathSplitter; + using util::isnil; + using util::cStr; + + + + const char* + lumiera_get_plugin_path_default () + { + static string pathSpec; + if (isnil (pathSpec)) + { + pathSpec += "plugin.path="; // syntax expected by lumiera_config_setdefault + + // fetch plugin search path from setup.ini and expand any $ORIGIN token + SearchPathSplitter pathElement(Config::get (KEY_PLUGIN_PATH)); + while (pathElement) + pathSpec += pathElement.fetch() +":"; + } + + return cStr(pathSpec); + } +} diff --git a/src/common/plugin.c b/src/common/plugin.c index 2638af5d1..373e405e7 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -19,6 +19,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/** @file plugin.c + ** Plugin loader implementation. + */ + + + #include "include/logging.h" #include "lib/safeclib.h" #include "lib/tmpbuf.h" @@ -26,6 +33,7 @@ #include "lib/recmutex.h" #include "lib/error.h" +#include "include/config-facade.h" #include "common/interfaceregistry.h" #include "common/config.h" #include "common/plugin.h" @@ -34,23 +42,15 @@ #include -#ifndef LUMIERA_PLUGIN_PATH -#error please define the plugin search path as -DLUMIERA_PLUGIN_PATH, e.g. as $INSTALL_PREFIX/lib/lumiera -#endif -/** - * @file - * Plugin loader. - */ -/* just some declarations */ extern PSplay lumiera_pluginregistry; static char* init_exts_globs (void); -/* TODO default plugin path should be set by the build system */ + /* errors */ -LUMIERA_ERROR_DEFINE(PLUGIN_INIT, "Initialization error"); +LUMIERA_ERROR_DEFINE(PLUGIN_INIT, "Initialisation error"); LUMIERA_ERROR_DEFINE(PLUGIN_OPEN, "Could not open plugin"); LUMIERA_ERROR_DEFINE(PLUGIN_WTF, "Not a Lumiera plugin"); LUMIERA_ERROR_DEFINE(PLUGIN_REGISTER, "Could not register plugin"); @@ -61,7 +61,7 @@ LUMIERA_ERROR_DEFINE(PLUGIN_VERSION, "Plugin Version unsupported"); /** * Supported (and planned) plugin types and their file extensions * This maps filename extensions to implementations (of the respective _load_NAME and _unload_NAME functions) - * So far we only support platform dynamic libraries, later we may add plugins implemented in lua + * So far we only support platform dynamic libraries, later we may add plugins implemented in Lua * and c source modules which get compiled on the fly. */ #define LUMIERA_PLUGIN_TYPES \ @@ -115,7 +115,8 @@ struct lumiera_plugin_struct /* time when the refcounter dropped to 0 last time */ time_t last; - /* when loading plugins en masse we do not want to fail completely if one doesnt cooperate, instead we record local errors here */ + /** bulk loading plugins must not fail entirely, just because one + * plugin doesn't comply. Thus we're recording local errors here */ lumiera_err error; /* the 'plugin' interface itself */ @@ -198,9 +199,12 @@ lumiera_plugin_discover (LumieraPlugin (*callback_load)(const char* plugin), REQUIRE (callback_load); REQUIRE (callback_register); - lumiera_config_setdefault ("plugin.path ="LUMIERA_PLUGIN_PATH); + // Note: because the full-blown Config system isn't implemented yet, + // as a temporary solution we fetch this basic configuration + // from the setup.ini used to bootstrap the application + lumiera_config_setdefault (lumiera_get_plugin_path_default()); - /* construct glob trail {.so,.c,.foo} ... */ + /* construct glob trail {.so,.lum,.lua} ... */ static char* exts_globs = NULL; if (!exts_globs) exts_globs = init_exts_globs (); @@ -375,7 +379,7 @@ static char* init_exts_globs (void) ++itr; } exts_globs[exts_sz-2] = '}'; - TRACE (pluginloader_dbg, "initialized extension glob to '%s'", exts_globs); + TRACE (pluginloader_dbg, "initialised extension glob to '%s'", exts_globs); return exts_globs; } diff --git a/src/include/configfacade.hpp b/src/include/config-facade.h similarity index 74% rename from src/include/configfacade.hpp rename to src/include/config-facade.h index 850cc74d8..564c49533 100644 --- a/src/include/configfacade.hpp +++ b/src/include/config-facade.h @@ -20,11 +20,14 @@ */ -/** @file configfacade.hpp +/** @file configfacade.h ** The lumiera::Config wrapper class addresses two issues. ** First, it registers startup and shutdown hooks to bring up the config system ** as early as possible. Later, on application main initialisation, the global ** config interface is opened and wrapped for convenient access from C++ code. + ** + ** @todo there ought to be an external Interface for the Config subsystem. + ** But the full-blown Config system isn't implemented yet anyway ** ** @see config.h ** @see lumiera::AppState @@ -36,7 +39,13 @@ #define INTERFACE_CONFIGFACADE_H + + + +#ifdef __cplusplus /* ============== C++ Interface ================= */ + #include "lib/singleton.hpp" +#include "lib/symbol.hpp" #include @@ -56,7 +65,7 @@ namespace lumiera { class Config { public: - static const string get (string const& key); + static string get (lib::Literal key); static lib::Singleton instance; @@ -70,4 +79,20 @@ namespace lumiera { } // namespace lumiera + + + +#else /* =========================== C Interface ====================== */ + + +/** retrieve the default plugin search path from the + * basic applications setup.ini + * @return a fully expanded string suitable to be fed + * to the lumiera_config_setdefault function + * @see lumiera_plugin_discover + */ +const char* lumiera_get_plugin_path_default (); + + +#endif #endif diff --git a/src/lib/lifecycle.cpp b/src/lib/lifecycle.cpp index 2e23081ec..1894ae2fb 100644 --- a/src/lib/lifecycle.cpp +++ b/src/lib/lifecycle.cpp @@ -98,4 +98,3 @@ extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */ } } - diff --git a/tests/31plugin.tests b/tests/31plugin.tests index 6181c224b..e81b1c5a9 100644 --- a/tests/31plugin.tests +++ b/tests/31plugin.tests @@ -6,11 +6,11 @@ out: found plugin: \(null\) return: 0 END -export LUMIERA_PLUGIN_PATH=.libs +export LUMIERA_PLUGIN_PATH=modules export LUMIERA_CONFIG_PATH=./ TEST "discovering plugins" plugin_discover <