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:
Fischlurch 2011-02-06 05:06:16 +01:00
parent 87475fa3c1
commit 88678209bc
12 changed files with 183 additions and 70 deletions

View file

@ -10,3 +10,5 @@
#
gui = gtk_gui.lum
modulepath = $ORIGIN/modules
configpath = /usr/share/lumiera/config:~/.lumiera
version = 0.pre.01

View file

@ -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();

View file

@ -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. */

View file

@ -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());

View file

@ -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");
}
};

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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

View file

@ -98,4 +98,3 @@ extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */
}
}

View file

@ -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!

View file

@ -13,7 +13,7 @@ return: 0
END
PLANNED "basic application state" Appconfig_test <<END
TEST "basic application state" Appconfig_test <<END
return: 0
END

View file

@ -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