Revision 205fd264
Von admin vor fast 3 Jahren hinzugefügt
src/base/plugin.c | ||
---|---|---|
static GWEN_PLUGIN *_findPluginInListByName(GWEN_PLUGIN_MANAGER *pm, const char *s);
|
||
static GWEN_PLUGIN *_createPluginFromLibloader(GWEN_PLUGIN_MANAGER *pm, GWEN_LIBLOADER *libLoader, const char *modname);
|
||
static GWEN_LIBLOADER *_searchAndLoadModule(GWEN_PLUGIN_MANAGER *pm, const char *modname);
|
||
static GWEN_PLUGIN_DESCRIPTION_LIST2 *_getPluginDescrsFromPluginList(GWEN_PLUGIN_MANAGER *pm);
|
||
static GWEN_PLUGIN_DESCRIPTION_LIST2 *_loadPluginDescrs(GWEN_PLUGIN_MANAGER *pm);
|
||
static GWEN_PLUGIN_DESCRIPTION_LIST2 *_combinedPluginDescrList(const GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlLoaded,
|
||
const GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlFromPluginList);
|
||
static GWEN_PLUGIN_DESCRIPTION *_findPluginDescrByNameInList2(const GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl, const char *name);
|
||
|
||
|
||
|
||
... | ... | |
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *GWEN_PluginManager_GetPluginDescrs(GWEN_PLUGIN_MANAGER *pm)
|
||
{
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pl;
|
||
GWEN_STRINGLIST *sl;
|
||
GWEN_STRINGLISTENTRY *se;
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlLoaded;
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlFromPluginList;
|
||
|
||
sl=GWEN_PathManager_GetPaths(pm->destLib, pm->name);
|
||
if (sl==NULL) {
|
||
DBG_ERROR(GWEN_LOGDOMAIN, "No paths for plugins (%s)", pm->name);
|
||
return NULL;
|
||
}
|
||
se=GWEN_StringList_FirstEntry(sl);
|
||
if (!se) {
|
||
DBG_ERROR(GWEN_LOGDOMAIN, "No paths given");
|
||
GWEN_StringList_free(sl);
|
||
return 0;
|
||
}
|
||
|
||
pl=GWEN_PluginDescription_List2_new();
|
||
while (se) {
|
||
int rv;
|
||
const char *path;
|
||
pdlFromPluginList=_getPluginDescrsFromPluginList(pm);
|
||
pdlLoaded=_loadPluginDescrs(pm);
|
||
|
||
path=GWEN_StringListEntry_Data(se);
|
||
assert(path);
|
||
rv=GWEN_LoadPluginDescrsByType(path, pm->name, pl);
|
||
if (rv) {
|
||
DBG_INFO(GWEN_LOGDOMAIN,
|
||
"Error loading plugin description in \"%s\"", path);
|
||
}
|
||
se=GWEN_StringListEntry_Next(se);
|
||
} /* while */
|
||
if (pdlFromPluginList && pdlLoaded){
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlOut;
|
||
|
||
if (GWEN_PluginDescription_List2_GetSize(pl)==0) {
|
||
GWEN_PluginDescription_List2_free(pl);
|
||
GWEN_StringList_free(sl);
|
||
return 0;
|
||
pdlOut=_combinedPluginDescrList(pdlLoaded, pdlFromPluginList);
|
||
GWEN_PluginDescription_List2_free(pdlFromPluginList);
|
||
GWEN_PluginDescription_List2_free(pdlLoaded);
|
||
return pdlOut;
|
||
}
|
||
|
||
GWEN_StringList_free(sl);
|
||
return pl;
|
||
else if (pdlFromPluginList) {
|
||
return pdlFromPluginList;
|
||
}
|
||
else
|
||
return pdlLoaded;
|
||
}
|
||
|
||
|
||
|
||
GWEN_STRINGLIST *GWEN_PluginManager_GetPaths(const GWEN_PLUGIN_MANAGER *pm)
|
||
{
|
||
assert(pm);
|
||
... | ... | |
|
||
|
||
|
||
GWEN_PLUGIN_DESCRIPTION *GWEN_PluginManager_GetPluginDescr(GWEN_PLUGIN_MANAGER *pm,
|
||
const char *modName)
|
||
GWEN_PLUGIN_DESCRIPTION *GWEN_PluginManager_GetPluginDescr(GWEN_PLUGIN_MANAGER *pm, const char *modName)
|
||
{
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *dl;
|
||
|
||
... | ... | |
|
||
void GWEN_PluginManager_AddPlugin(GWEN_PLUGIN_MANAGER *pm, GWEN_PLUGIN *p)
|
||
{
|
||
DBG_INFO(GWEN_LOGDOMAIN, "Adding plugin [%s] of type [%s]", p->name, pm->name);
|
||
GWEN_Plugin_List_Add(p, pm->plugins);
|
||
const char *modname;
|
||
|
||
modname=GWEN_Plugin_GetName(p);
|
||
if (modname && *modname) {
|
||
const GWEN_PLUGIN_DESCRIPTION *pdInPlugin;
|
||
|
||
pdInPlugin=GWEN_Plugin_GetPluginDescription(p);
|
||
if (pdInPlugin==NULL) {
|
||
GWEN_PLUGIN_DESCRIPTION *pd;
|
||
|
||
DBG_INFO(GWEN_LOGDOMAIN, "No plugin description for \"%s\", creating one", modname);
|
||
pd=GWEN_PluginDescription_new();
|
||
GWEN_PluginDescription_SetName(pd, modname);
|
||
GWEN_PluginDescription_SetType(pd, pm->name);
|
||
GWEN_Plugin_SetPluginDescription(p, pd);
|
||
}
|
||
DBG_INFO(GWEN_LOGDOMAIN, "Adding plugin [%s] of type [%s]", modname, pm->name);
|
||
GWEN_Plugin_List_Add(p, pm->plugins);
|
||
}
|
||
else {
|
||
DBG_ERROR(GWEN_LOGDOMAIN, "Plugin to add has no name (type %s), not adding", pm->name);
|
||
}
|
||
}
|
||
|
||
|
||
... | ... | |
}
|
||
|
||
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *_getPluginDescrsFromPluginList(GWEN_PLUGIN_MANAGER *pm)
|
||
{
|
||
GWEN_PLUGIN *p;
|
||
|
||
assert(pm);
|
||
p=GWEN_Plugin_List_First(pm->plugins);
|
||
if (p) {
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl;
|
||
|
||
pdl=GWEN_PluginDescription_List2_new();
|
||
while (p) {
|
||
const GWEN_PLUGIN_DESCRIPTION *pd;
|
||
|
||
pd=GWEN_Plugin_GetPluginDescription(p);
|
||
if (pd)
|
||
GWEN_PluginDescription_List2_PushBack(pdl, GWEN_PluginDescription_dup(pd));
|
||
p=GWEN_Plugin_List_Next(p);
|
||
} /* while(p) */
|
||
|
||
if (GWEN_PluginDescription_List2_GetSize(pdl)==0) {
|
||
GWEN_PluginDescription_List2_free(pdl);
|
||
return NULL;
|
||
}
|
||
|
||
return pdl;
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
|
||
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *_loadPluginDescrs(GWEN_PLUGIN_MANAGER *pm)
|
||
{
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pl;
|
||
GWEN_STRINGLIST *sl;
|
||
GWEN_STRINGLISTENTRY *se;
|
||
|
||
sl=GWEN_PathManager_GetPaths(pm->destLib, pm->name);
|
||
if (sl==NULL) {
|
||
DBG_ERROR(GWEN_LOGDOMAIN, "No paths for plugins (%s)", pm->name);
|
||
return NULL;
|
||
}
|
||
se=GWEN_StringList_FirstEntry(sl);
|
||
if (!se) {
|
||
DBG_ERROR(GWEN_LOGDOMAIN, "No paths given");
|
||
GWEN_StringList_free(sl);
|
||
return 0;
|
||
}
|
||
|
||
pl=GWEN_PluginDescription_List2_new();
|
||
while (se) {
|
||
int rv;
|
||
const char *path;
|
||
|
||
path=GWEN_StringListEntry_Data(se);
|
||
assert(path);
|
||
rv=GWEN_LoadPluginDescrsByType(path, pm->name, pl);
|
||
if (rv) {
|
||
DBG_INFO(GWEN_LOGDOMAIN,
|
||
"Error loading plugin description in \"%s\"", path);
|
||
}
|
||
se=GWEN_StringListEntry_Next(se);
|
||
} /* while */
|
||
|
||
if (GWEN_PluginDescription_List2_GetSize(pl)==0) {
|
||
GWEN_PluginDescription_List2_free(pl);
|
||
GWEN_StringList_free(sl);
|
||
return 0;
|
||
}
|
||
|
||
GWEN_StringList_free(sl);
|
||
return pl;
|
||
}
|
||
|
||
|
||
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *_combinedPluginDescrList(const GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlLoaded,
|
||
const GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlFromPluginList)
|
||
{
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2 *pdlOut;
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *iter;
|
||
|
||
pdlOut=GWEN_PluginDescription_List2_new();
|
||
|
||
/* first add entries from loaded list (more details in those entries) */
|
||
iter=GWEN_PluginDescription_List2_First(pdlLoaded);
|
||
if (iter) {
|
||
GWEN_PLUGIN_DESCRIPTION *pd=NULL;
|
||
|
||
pd=GWEN_PluginDescription_List2Iterator_Data(iter);
|
||
while(pd) {
|
||
GWEN_PluginDescription_List2_PushBack(pdlOut, pd);
|
||
pd=GWEN_PluginDescription_List2Iterator_Next(iter);
|
||
}
|
||
|
||
GWEN_PluginDescription_List2Iterator_free(iter);
|
||
}
|
||
|
||
/* only add those entries from pluginList which are not already in the output list */
|
||
iter=GWEN_PluginDescription_List2_First(pdlFromPluginList);
|
||
if (iter) {
|
||
GWEN_PLUGIN_DESCRIPTION *pd=NULL;
|
||
|
||
pd=GWEN_PluginDescription_List2Iterator_Data(iter);
|
||
while(pd) {
|
||
const char *name;
|
||
|
||
name=GWEN_PluginDescription_GetName(pd);
|
||
if (name && *name && NULL==_findPluginDescrByNameInList2(pdlOut, name))
|
||
GWEN_PluginDescription_List2_PushBack(pdlOut, pd);
|
||
pd=GWEN_PluginDescription_List2Iterator_Next(iter);
|
||
}
|
||
|
||
GWEN_PluginDescription_List2Iterator_free(iter);
|
||
}
|
||
|
||
if (GWEN_PluginDescription_List2_GetSize(pdlOut)==0) {
|
||
GWEN_PluginDescription_List2_free(pdlOut);
|
||
return NULL;
|
||
}
|
||
|
||
return pdlOut;
|
||
}
|
||
|
||
|
||
|
||
GWEN_PLUGIN_DESCRIPTION *_findPluginDescrByNameInList2(const GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl, const char *name)
|
||
{
|
||
GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *iter;
|
||
GWEN_PLUGIN_DESCRIPTION *pd=NULL;
|
||
|
||
iter=GWEN_PluginDescription_List2_First(pdl);
|
||
if (iter) {
|
||
|
||
pd=GWEN_PluginDescription_List2Iterator_Data(iter);
|
||
while(pd) {
|
||
const char *nameInList;
|
||
|
||
nameInList=GWEN_PluginDescription_GetName(pd);
|
||
if (nameInList && *nameInList && strcasecmp(nameInList, name)==0)
|
||
break;
|
||
pd=GWEN_PluginDescription_List2Iterator_Next(iter);
|
||
}
|
||
|
||
GWEN_PluginDescription_List2Iterator_free(iter);
|
||
}
|
||
|
||
return pd;
|
||
}
|
||
|
||
|
src/base/plugin.h | ||
---|---|---|
/***************************************************************************
|
||
$RCSfile$
|
||
-------------------
|
||
cvs : $Id$
|
||
begin : Fri Sep 12 2003
|
||
copyright : (C) 2003 by Martin Preuss
|
||
copyright : (C) 2022 by Martin Preuss
|
||
email : martin@libchipcard.de
|
||
|
||
***************************************************************************
|
Auch abrufbar als: Unified diff
plugin: Combine plugin descriptions from disk and added plugins.
Gwenhywfar is able to load plugins. However, this can be restricted when
building gwen in a fully static environment which don't allow for dynamic
loading of plugins.
In such a case plugin providers can add just create a plugin and add it to
Gwen's internal list.
However, an application querying the list of available plugins of a type
previously had to rely on there being a plugin description on disk.
This is no longer the case. Applications or libraries can add plugins to
existing plugin managers and also provide a plugin description for it.