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
This commit is contained in:
parent
87475fa3c1
commit
88678209bc
12 changed files with 183 additions and 70 deletions
|
|
@ -10,3 +10,5 @@
|
|||
#
|
||||
gui = gtk_gui.lum
|
||||
modulepath = $ORIGIN/modules
|
||||
configpath = /usr/share/lumiera/config:~/.lumiera
|
||||
version = 0.pre.01
|
||||
|
|
|
|||
|
|
@ -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<string>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -74,11 +74,17 @@ namespace lumiera {
|
|||
, settings()
|
||||
{
|
||||
syntax.add_options()
|
||||
("BuildsystemDemo.gui", opt::value<string>(),
|
||||
"name of the Lumiera GUI plugin to load")
|
||||
("BuildsystemDemo.modulepath", opt::value<string>(),
|
||||
"search path for loadable modules. "
|
||||
"May us $ORIGIN to refer to the EXE location")
|
||||
("Lumiera.gui", opt::value<string>(),
|
||||
"name of the Lumiera GUI plugin to load")
|
||||
("Lumiera.modulepath", opt::value<string>(),
|
||||
"search path for loadable modules. "
|
||||
"May us $ORIGIN to refer to the EXE location")
|
||||
("Lumiera.configpath", opt::value<string>(),
|
||||
"search path for extended configuration. "
|
||||
"Extended Config system not yet implemented "
|
||||
"Ignored as of 2/2011")
|
||||
("Lumiera.version", opt::value<string>(),
|
||||
"Application version string")
|
||||
;
|
||||
|
||||
ifstream configIn (resolve(bootstrapIni).c_str());
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#define COMMON_BASIC_SETUP_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
|
@ -68,19 +70,27 @@ namespace lumiera {
|
|||
BasicSetup (string bootstrapIni);
|
||||
|
||||
string
|
||||
operator[] (string const& key) const
|
||||
operator[] (lib::Literal key) const
|
||||
{
|
||||
return settings[key].as<string>();
|
||||
return get (key).as<string>();
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <nobug.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@
|
|||
|
||||
*/
|
||||
|
||||
/** @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
|
||||
** @see main.cpp
|
||||
|
|
@ -36,7 +39,13 @@
|
|||
#define INTERFACE_CONFIGFACADE_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus /* ============== C++ Interface ================= */
|
||||
|
||||
#include "lib/singleton.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -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<Config> 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
|
||||
|
|
@ -98,4 +98,3 @@ extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <<END
|
||||
out: found plugin: \.libs/examplepluginc.lum
|
||||
out: found plugin: modules/examplepluginc.lum
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ END
|
|||
|
||||
TEST "C plugin test, nested" plugin_examplepluginc_nested <<END
|
||||
out: config path is: \./
|
||||
out: plugin path is: \.libs
|
||||
out: plugin path is: modules
|
||||
out: Hallo Welt!
|
||||
out: Hello World!
|
||||
out: Bye World!
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "basic application state" Appconfig_test <<END
|
||||
TEST "basic application state" Appconfig_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -23,37 +23,40 @@
|
|||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "include/config-facade.h"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "common/appstate.hpp"
|
||||
|
||||
using lib::Literal;
|
||||
using util::isnil;
|
||||
|
||||
|
||||
|
||||
namespace lumiera {
|
||||
namespace test {
|
||||
namespace test {
|
||||
|
||||
|
||||
class Appconfig_test : public Test
|
||||
{
|
||||
virtual void run (Arg arg)
|
||||
{
|
||||
testAccess("version");
|
||||
UNIMPLEMENTED ("reorganise config access for C++");
|
||||
}
|
||||
|
||||
/** @test accessing a value from lumiera::AppState */
|
||||
void testAccess (const string& key)
|
||||
class Appconfig_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
// string ver = lumiera::AppState::get(key);
|
||||
// CHECK ( !util::isnil(ver));
|
||||
fetchSetupValue();
|
||||
}
|
||||
};
|
||||
|
||||
LAUNCHER (Appconfig_test, "function common");
|
||||
|
||||
|
||||
} // namespace test
|
||||
/** @test accessing a value from setup.ini */
|
||||
void fetchSetupValue ()
|
||||
{
|
||||
Literal key("Lumiera.version");
|
||||
string ver = Config::get(key);
|
||||
CHECK (!isnil(ver));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
|
||||
LAUNCHER (Appconfig_test, "function common");
|
||||
|
||||
|
||||
}} // namespace util::test
|
||||
|
||||
Loading…
Reference in a new issue