39 extern PSplay lumiera_pluginregistry;
40 static char* init_exts_globs (
void);
51 #define LUMIERA_PLUGIN_TYPE_PLANNED(name, ext) 59 #define LUMIERA_PLUGIN_TYPES \ 60 LUMIERA_PLUGIN_TYPE(DYNLIB, ".so") \ 61 LUMIERA_PLUGIN_TYPE(DYNLIB, ".lum") \ 62 LUMIERA_PLUGIN_TYPE_PLANNED(LUA, ".lua") \ 63 LUMIERA_PLUGIN_TYPE_PLANNED(CSOURCE, ".c") 71 LumieraPlugin (*lumiera_plugin_load_fn)(
const char*);
72 void (*lumiera_plugin_unload_fn)(LumieraPlugin);
76 typedef lumiera_plugintype* LumieraPlugintype;
79 #define LUMIERA_PLUGIN_TYPE(type, ext) \ 80 LumieraPlugin lumiera_plugin_load_##type (const char*); \ 81 void lumiera_plugin_unload_##type (LumieraPlugin); 83 #undef LUMIERA_PLUGIN_TYPE 86 #define LUMIERA_PLUGIN_TYPE(type, ext) {lumiera_plugin_load_##type, lumiera_plugin_unload_##type, ext}, 87 static lumiera_plugintype lumiera_plugin_types[] =
92 #undef LUMIERA_PLUGIN_TYPE 115 LumieraInterface plugin;
131 self->error = LUMIERA_ERROR_PLUGIN_INIT;
142 self->plugin = plugin;
143 self->handle = handle;
167 return self?
self->name:NULL;
188 int (*callback_register) (LumieraPlugin))
190 TRACE (pluginloader_dbg);
191 REQUIRE (callback_load);
192 REQUIRE (callback_register);
200 static char* exts_globs = NULL;
202 exts_globs = init_exts_globs ();
206 int flags = GLOB_PERIOD|GLOB_BRACE|GLOB_TILDE_CHECK;
212 TRACE (pluginloader_dbg,
"globbing path '%s'", path);
213 int ret = glob (path, flags, NULL, &globs);
214 if (ret == GLOB_NOSPACE)
217 flags |= GLOB_APPEND;
224 for (
char** itr = globs.gl_pathv; *itr; ++itr)
226 if (!
psplay_find (lumiera_pluginregistry, *itr, 100))
228 TRACE (pluginloader,
"found new plugin '%s'", *itr);
229 callback_register (callback_load (*itr));
243 TRACE (pluginloader_dbg,
"plugin=%s", plugin);
246 const char* ext = strrchr (plugin,
'.');
248 LumieraPlugintype itr = lumiera_plugin_types;
251 if (!strcmp (itr->ext, ext))
252 return itr->lumiera_plugin_load_fn (plugin);
262 TRACE (pluginloader_dbg);
268 if (
psplay_insert (lumiera_pluginregistry, &plugin->node, 100))
276 TRACE (pluginloader,
"registering %s", plugin->name);
279 lumiera_interfaceregistry_bulkregister_interfaces (handle->plugin_interfaces (), plugin);
299 TRACE (pluginloader_dbg);
308 const char* ext = strrchr (self->name,
'.');
310 LumieraPlugintype itr = lumiera_plugin_types;
313 if (!strcmp (itr->ext, ext))
323 lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
327 itr->lumiera_plugin_unload_fn (
self);
340 LumieraPlugin ret = NULL;
344 ret = (LumieraPlugin)
psplay_find (lumiera_pluginregistry, name, 100);
350 static char* init_exts_globs (
void)
354 LumieraPlugintype itr = lumiera_plugin_types;
357 exts_sz += strlen (itr->ext) + 1;
364 itr = lumiera_plugin_types;
365 strcat (exts_globs,
"*{");
369 strcat (exts_globs, itr->ext);
370 strcat (exts_globs,
",");
373 exts_globs[exts_sz-2] =
'}';
374 TRACE (pluginloader_dbg,
"initialised extension glob to '%s'", exts_globs);
379 lumiera_plugin_cmp_fn (
const void* keya,
const void* keyb)
381 return strcmp ((
const char*)keya, (
const char*)keyb);
386 lumiera_plugin_key_fn (
const PSplaynode node)
388 return ((LumieraPlugin)node)->name;
393 lumiera_plugin_delete_fn (PSplaynode node)
395 LumieraPlugin
self = (LumieraPlugin) node;
397 ENSURE (!self->refcnt,
"plugin %s still in use at shutdown", self->name);
399 const char* ext = strrchr (self->name,
'.');
401 LumieraPlugintype itr = lumiera_plugin_types;
404 if (!strcmp (itr->ext, ext))
410 lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
412 TRACE (pluginloader_dbg,
"unloading plugin/module %s", self->name);
413 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.