diff options
author | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2005-07-13 16:49:47 +0000 |
---|---|---|
committer | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2005-07-13 16:49:47 +0000 |
commit | 7233ff9095194b38586ce438379f08691a0fecdd (patch) | |
tree | 8c14b8899914b4ae9e0d6f62e14dd6b3519983cd /src/plugin.c | |
parent | fad788d3f02564486039886b1de1cbf976776ac3 (diff) | |
download | librcc-7233ff9095194b38586ce438379f08691a0fecdd.tar.gz librcc-7233ff9095194b38586ce438379f08691a0fecdd.tar.bz2 librcc-7233ff9095194b38586ce438379f08691a0fecdd.tar.xz librcc-7233ff9095194b38586ce438379f08691a0fecdd.zip |
Engine Plugins
Diffstat (limited to 'src/plugin.c')
-rw-r--r-- | src/plugin.c | 142 |
1 files changed, 134 insertions, 8 deletions
diff --git a/src/plugin.c b/src/plugin.c index 7935491..274cab9 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -1,5 +1,7 @@ #include <stdio.h> +#include <string.h> +#include "internal.h" #include "plugin.h" #ifdef RCC_PLUGINS @@ -13,25 +15,149 @@ rcc_library_handle rccLibraryOpen(char *filename) { #ifdef RCC_PLUGINS - return (rcc_library_handle)dlopen(filename, RTLD_NOW); -#else - return NULL; + if (filename) return (rcc_library_handle)dlopen(filename, RTLD_NOW); #endif /* RCC_PLUGINS */ + + return NULL; } void rccLibraryClose(rcc_library_handle handle) { #ifdef RCC_PLUGINS - puts("HHHHHHHHHHHHHHHHHHHH"); - dlclose(handle); + if (handle) dlclose(handle); #endif /* RCC_PLUGINS */ } void* rccLibraryFind(rcc_library_handle handle, const char *symbol) { #ifdef RCC_PLUGINS - return dlsym(handle, symbol); -#else - return NULL; + if ((handle)||(symbol)) return dlsym(handle, symbol); #endif /* RCC_PLUGINS */ + + return NULL; +} + + +static rcc_plugin_handle_s rcc_engine_handles[RCC_MAX_PLUGINS]; + +int rccPluginInit() { + unsigned int i; + + for (i=0;i<RCC_MAX_PLUGINS;i++) + rcc_engine_handles[i].sn = NULL; + + return 0; +} + +void rccPluginFree() { + unsigned int i; + + for (i=0;i<RCC_MAX_PLUGINS;i++) + if (rcc_engine_handles[i].sn) { + rccLibraryClose(rcc_engine_handles[i].handle); + free(rcc_engine_handles[i].sn); + rcc_engine_handles[i].sn = NULL; + } +} + + +rcc_plugin_handle rccPluginGetHandleByName(rcc_plugin_type type, const char *name) { + unsigned int i; + + rcc_plugin_handle handles; + + if (!name) return NULL; + + switch(type) { + case RCC_PLUGIN_TYPE_ENGINE: + handles = rcc_engine_handles; + break; + default: + return NULL; + } + + for (i=0;i<RCC_MAX_PLUGINS;i++) + if ((handles[i].sn)&&(!strcasecmp(handles[i].sn, name))) return handles+i; + + return NULL; +} + +rcc_plugin_handle rccPluginGetFreeHandle(rcc_plugin_type type) { + unsigned int i; + + rcc_plugin_handle handles; + + switch(type) { + case RCC_PLUGIN_TYPE_ENGINE: + handles = rcc_engine_handles; + break; + default: + return NULL; + } + + for (i=0;i<RCC_MAX_PLUGINS;i++) + if (!handles[i].sn) return handles+i; + + return NULL; +} + +rcc_plugin_handle rccPluginLoad(rcc_plugin_type type, const char *name) { + FILE *f; + void *res; + void *infofunc; + char *pluginfn; + + rcc_plugin_handle plugin; + + if (!name) return NULL; + + plugin = rccPluginGetHandleByName(type, name); + if (plugin) return plugin; + + plugin = rccPluginGetFreeHandle(type); + if (!plugin) return plugin; + + switch (type) { + case RCC_PLUGIN_TYPE_ENGINE: + pluginfn = (char*)malloc((32 + strlen(rcc_home_dir) + strlen(name))*sizeof(char)); + if (!pluginfn) return NULL; + + sprintf(pluginfn, "%s/.rcc/engines/lib%s.so", rcc_home_dir, name); + res = dlopen(pluginfn, RTLD_NOW); + if (!res) { + sprintf(pluginfn, LIBRCC_DATA_DIR "/engines/lib%s.so", name); + res = dlopen(pluginfn, RTLD_NOW); + } + free(pluginfn); + + if (res) { + infofunc = rccLibraryFind(res, "rccGetInfo"); + if (infofunc) { + plugin->sn = strdup(name); + if (plugin->sn) { + plugin->handle = (rcc_library_handle)res; + plugin->info_function = infofunc; + return plugin; + } else rccLibraryClose(res); + } else rccLibraryClose(res); + } + break; + } + + return NULL; +} + + +rcc_engine *rccPluginEngineGetInfo(const char *name, const char *language) { + int err; + rcc_plugin_handle handle; + rcc_plugin_engine_info_function infofunc; + + handle = rccPluginLoad(RCC_PLUGIN_TYPE_ENGINE, name); + if (!handle) return NULL; + + infofunc = (rcc_plugin_engine_info_function)(handle->info_function); + if (!infofunc) return NULL; + + return infofunc(language); } |