48 extern PSplay lumiera_pluginregistry;
49 static char* init_exts_globs (
void);
60 #define LUMIERA_PLUGIN_TYPE_PLANNED(name, ext) 68 #define LUMIERA_PLUGIN_TYPES \ 69 LUMIERA_PLUGIN_TYPE(DYNLIB, ".so") \ 70 LUMIERA_PLUGIN_TYPE(DYNLIB, ".lum") \ 71 LUMIERA_PLUGIN_TYPE_PLANNED(LUA, ".lua") \ 72 LUMIERA_PLUGIN_TYPE_PLANNED(CSOURCE, ".c") 80 LumieraPlugin (*lumiera_plugin_load_fn)(
const char*);
81 void (*lumiera_plugin_unload_fn)(LumieraPlugin);
85 typedef lumiera_plugintype* LumieraPlugintype;
88 #define LUMIERA_PLUGIN_TYPE(type, ext) \ 89 LumieraPlugin lumiera_plugin_load_##type (const char*); \ 90 void lumiera_plugin_unload_##type (LumieraPlugin); 92 #undef LUMIERA_PLUGIN_TYPE 95 #define LUMIERA_PLUGIN_TYPE(type, ext) {lumiera_plugin_load_##type, lumiera_plugin_unload_##type, ext}, 96 static lumiera_plugintype lumiera_plugin_types[] =
101 #undef LUMIERA_PLUGIN_TYPE 124 LumieraInterface plugin;
140 self->error = LUMIERA_ERROR_PLUGIN_INIT;
151 self->plugin = plugin;
152 self->handle = handle;
176 return self?
self->name:NULL;
197 int (*callback_register) (LumieraPlugin))
199 TRACE (pluginloader_dbg);
200 REQUIRE (callback_load);
201 REQUIRE (callback_register);
209 static char* exts_globs = NULL;
211 exts_globs = init_exts_globs ();
215 int flags = GLOB_PERIOD|GLOB_BRACE|GLOB_TILDE_CHECK;
221 TRACE (pluginloader_dbg,
"globbing path '%s'", path);
222 int ret = glob (path, flags, NULL, &globs);
223 if (ret == GLOB_NOSPACE)
226 flags |= GLOB_APPEND;
233 for (
char** itr = globs.gl_pathv; *itr; ++itr)
235 if (!
psplay_find (lumiera_pluginregistry, *itr, 100))
237 TRACE (pluginloader,
"found new plugin '%s'", *itr);
238 callback_register (callback_load (*itr));
252 TRACE (pluginloader_dbg,
"plugin=%s", plugin);
255 const char* ext = strrchr (plugin,
'.');
257 LumieraPlugintype itr = lumiera_plugin_types;
260 if (!strcmp (itr->ext, ext))
261 return itr->lumiera_plugin_load_fn (plugin);
271 TRACE (pluginloader_dbg);
277 if (
psplay_insert (lumiera_pluginregistry, &plugin->node, 100))
285 TRACE (pluginloader,
"registering %s", plugin->name);
288 lumiera_interfaceregistry_bulkregister_interfaces (handle->plugin_interfaces (), plugin);
308 TRACE (pluginloader_dbg);
317 const char* ext = strrchr (self->name,
'.');
319 LumieraPlugintype itr = lumiera_plugin_types;
322 if (!strcmp (itr->ext, ext))
332 lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
336 itr->lumiera_plugin_unload_fn (
self);
349 LumieraPlugin ret = NULL;
353 ret = (LumieraPlugin)
psplay_find (lumiera_pluginregistry, name, 100);
359 static char* init_exts_globs (
void)
363 LumieraPlugintype itr = lumiera_plugin_types;
366 exts_sz += strlen (itr->ext) + 1;
373 itr = lumiera_plugin_types;
374 strcat (exts_globs,
"*{");
378 strcat (exts_globs, itr->ext);
379 strcat (exts_globs,
",");
382 exts_globs[exts_sz-2] =
'}';
383 TRACE (pluginloader_dbg,
"initialised extension glob to '%s'", exts_globs);
388 lumiera_plugin_cmp_fn (
const void* keya,
const void* keyb)
390 return strcmp ((
const char*)keya, (
const char*)keyb);
395 lumiera_plugin_key_fn (
const PSplaynode node)
397 return ((LumieraPlugin)node)->name;
402 lumiera_plugin_delete_fn (PSplaynode node)
404 LumieraPlugin
self = (LumieraPlugin) node;
406 ENSURE (!self->refcnt,
"plugin %s still in use at shutdown", self->name);
408 const char* ext = strrchr (self->name,
'.');
410 LumieraPlugintype itr = lumiera_plugin_types;
413 if (!strcmp (itr->ext, ext))
419 lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
421 TRACE (pluginloader_dbg,
"unloading plugin/module %s", self->name);
422 itr->lumiera_plugin_unload_fn (
self);
LumieraPlugin lumiera_plugin_lookup(const char *name)
Lookup a plugin handle in the pluginregistry.
Portable and safe wrappers around some C-Lib functions.
#define LUMIERA_PLUGIN_TYPES
Supported (and planned) plugin types and their file extensions This maps filename extensions to imple...
#define LUMIERA_ERROR_SET(flag, err, extra)
Helper macro to raise an error for the current thread.
#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx)
Recursive Mutual exclusive section.
lumiera_err lumiera_error_peek(void)
Check current error state without clearing it Please avoid this function and use lumiera_error() if p...
LumieraPlugin lumiera_plugin_new(const char *name)
Allocates an preinitialises a plugin structure.
const char * lumiera_plugin_name(LumieraPlugin self)
Query the plugin name The name is the path and filename under which it was loaded.
int lumiera_plugin_register(LumieraPlugin plugin)
Register a plugin and its interfaces.
LumieraPlugin lumiera_plugin_load(const char *plugin)
Tries to load a plugin Creates a new plugin structure and tries to load and initialise the plugin...
record the extension and a callback function for loading the associated plugin for each plugin type ...
Lumiera plugins define 'interfaces' as shown in interface.h, the plugin system handles the loading of...
Interface for a lumiera configuration system (draft).
unsigned lumiera_interface_version(LumieraInterface self, const char *iname)
Runtime check for interface type and version.
This header is for including and configuring NoBug.
Mutual exclusion locking, header.
Round robin temporary buffers.
Lumiera error handling (C interface).
PSplaynode psplay_find(PSplay self, const void *key, int splayfactor)
Find a element in a splay tree.
PSplaynode psplay_insert(PSplay self, PSplaynode node, int splayfactor)
Insert a element into a splay tree.
unsigned lumiera_plugin_unload(LumieraPlugin self)
Tries to unload a plugin.
void lumiera_plugin_refinc(LumieraPlugin self)
#define LUMIERA_INTERFACE_CAST(name, version)
Construct a cast to the target interface type Used to cast a generic LumieraInterface to the real typ...
The lumiera::Config wrapper class addresses two issues.
#define LUMIERA_ERROR_SET_CRITICAL(flag, err, extra)
Helper macro to raise an error for the current thread.
#define LUMIERA_DIE(err)
Abort unconditionally with a 'Fatal Error!' message.
LumieraConfigitem lumiera_config_setdefault(const char *line)
Installs a default value for a config key.
Probabilistic splay tree.
int lumiera_plugin_discover(LumieraPlugin(*callback_load)(const char *plugin), int(*callback_register)(LumieraPlugin))
discover new plugins traverses the configured plugin paths and calls the callback_load function for a...
lumiera_err lumiera_error(void)
Get and clear current error state.
void * lumiera_malloc(size_t size)
Allocate memory.
const char * lumiera_config_wordlist_get_nth(const char *key, unsigned nth, const char *delims)
return nth word of a wordlist
lumiera_err lumiera_plugin_error(LumieraPlugin self)
Query the error state of a plugin.
Global registry for interfaces (extension points).
PSplaynode psplay_remove(PSplay self, PSplaynode node)
Remove a node from a splay tree.
LumieraPlugin lumiera_plugin_init(LumieraPlugin self, void *handle, LumieraInterface plugin)
#define LUMIERA_INTERFACE_HANDLE(interface, version)
create a handle for a interface (WIP)
char * lumiera_strndup(const char *str, size_t len)
Duplicate a C string.
void * lumiera_plugin_handle(LumieraPlugin self)
Query the plugin handle.
PSplaynode psplaynode_init(PSplaynode self)
Initialise a splay tree node The user has to place this nodes within his datastructure and must Initi...
lumiera_err error
bulk loading plugins must not fail entirely, just because one plugin doesn't comply.
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
void lumiera_plugin_refdec(LumieraPlugin self)
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.