diff options
Diffstat (limited to 'lib/cpluff/libcpluff')
31 files changed, 0 insertions, 12389 deletions
diff --git a/lib/cpluff/libcpluff/Makefile.am b/lib/cpluff/libcpluff/Makefile.am deleted file mode 100644 index 0f121e012a..0000000000 --- a/lib/cpluff/libcpluff/Makefile.am +++ /dev/null @@ -1,75 +0,0 @@ -## Process this file with automake to produce Makefile.in. - -# Copyright 2007 Johannes Lehtinen -# This Makefile is free software; Johannes Lehtinen gives unlimited -# permission to copy, distribute and modify it. - -SUBDIRS = docsrc - -LIBS = @LIBS_LIBCPLUFF@ @LTLIBINTL@ @LIBS@ - -CPPFLAGS = @CPPFLAGS@ -CPPFLAGS += -I. -DCP_C_API=CP_EXPORT -DCP_HOST="\"$(host)\"" -DCP_DATADIR="\"$(datadir)\"" -# the following symbols are clashing with mariadb symbols -CPPFLAGS += -Dhash_delete=kazlib_hash_delete -Dhash_free=kazlib_hash_free -Dhash_insert=kazlib_hash_insert -Dlist_delete=kazlib_list_delete - -DOXYGEN = doxygen -DOXYGEN_SOURCE = cpluffdef.h $(srcdir)/cpluff.h $(srcdir)/docsrc/*.dox -DOXYGEN_STYLE = $(top_srcdir)/docsrc/doxygen.footer $(top_srcdir)/docsrc/doxygen.css - -lib_LTLIBRARIES = libcpluff.la -libcpluff_la_SOURCES = psymbol.c pscan.c ploader.c pinfo.c pcontrol.c serial.c logging.c context.c cpluff.c util.c ../kazlib/list.c ../kazlib/list.h ../kazlib/hash.c ../kazlib/hash.h internal.h thread.h util.h defines.h -if POSIX_THREADS -libcpluff_la_SOURCES += thread_posix.c -endif -if WINDOWS_THREADS -libcpluff_la_SOURCES += thread_windows.c -endif -libcpluff_la_LDFLAGS = -no-undefined -version-info $(CP_C_LIB_VERSION) - -include_HEADERS = cpluff.h cpluffdef.h - -doc: refdoc - -refdoc: doc/reference/c-api/index.html - -doc/reference/c-api/index.html: $(DOXYGEN_SOURCE) $(top_srcdir)/doc/img/architecture.png docsrc/Doxyfile-ref $(DOXYGEN_STYLE) - rm -rf doxygen-ref - mkdir -p doxygen-ref - cp -p $^ doxygen-ref - cd doxygen-ref && $(DOXYGEN) Doxyfile-ref - mkdir -p doc/reference - rm -rf doc/reference/c-api - mv doxygen-ref/html doc/reference/c-api - rm -rf doxygen-ref - -impldoc: doc/implementation/c-api/index.html - -doc/implementation/c-api/index.html: $(srcdir)/*.h $(srcdir)/*.c cpluffdef.h ../config.h docsrc/Doxyfile-impl $(DOXYGEN_STYLE) - rm -rf doxygen-impl - mkdir -p doxygen-impl - cp -p $^ doxygen-impl - cd doxygen-impl && $(DOXYGEN) Doxyfile-impl - mkdir -p doc/implementation - rm -rf doc/implementation/c-api - mv doxygen-impl/html doc/implementation/c-api - rm -rf doxygen-impl - -dist-hook: refdoc - mkdir -p $(top_distdir)/doc/reference - cp -rp doc/reference/c-api $(top_distdir)/doc/reference - -clean-local: - rm -rf doc - -check-local: - rc=0; \ - find '$(srcdir)' -name '*.c' -print | while read f; do \ - if grep -q -E 'cpi_(debug|warn|error)f?\(.*[^N]_\(' "$$f"; then \ - echo "invalid use of cpi_(debug|warn|error)f? macros in $$f."; \ - rc=1; \ - fi; \ - done; \ - exit $$rc - -.PHONY: doc refdoc impldoc diff --git a/lib/cpluff/libcpluff/context.c b/lib/cpluff/libcpluff/context.c deleted file mode 100644 index 0a38c6d516..0000000000 --- a/lib/cpluff/libcpluff/context.c +++ /dev/null @@ -1,530 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Plug-in context implementation - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <stdarg.h> -#include <string.h> -#include "../kazlib/list.h" -#include "cpluff.h" -#include "util.h" -#ifdef CP_THREADS -#include "thread.h" -#endif -#include "internal.h" - - -/* ------------------------------------------------------------------------ - * Variables - * ----------------------------------------------------------------------*/ - -/// Existing contexts -static list_t *contexts = NULL; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -// Generic - -static void free_plugin_env(cp_plugin_env_t *env) { - assert(env != NULL); - - // Free environment data - if (env->plugin_listeners != NULL) { - cpi_unregister_plisteners(env->plugin_listeners, NULL); - list_destroy(env->plugin_listeners); - env->plugin_listeners = NULL; - } - if (env->loggers != NULL) { - cpi_unregister_loggers(env->loggers, NULL); - list_destroy(env->loggers); - env->loggers = NULL; - } - if (env->plugin_dirs != NULL) { - list_process(env->plugin_dirs, NULL, cpi_process_free_ptr); - list_destroy(env->plugin_dirs); - env->plugin_dirs = NULL; - } - if (env->infos != NULL) { - assert(hash_isempty(env->infos)); - hash_destroy(env->infos); - env->infos = NULL; - } - if (env->plugins != NULL) { - assert(hash_isempty(env->plugins)); - hash_destroy(env->plugins); - env->plugins = NULL; - } - if (env->started_plugins != NULL) { - assert(list_isempty(env->started_plugins)); - list_destroy(env->started_plugins); - env->started_plugins = NULL; - } - if (env->ext_points != NULL) { - assert(hash_isempty(env->ext_points)); - hash_destroy(env->ext_points); - } - if (env->extensions != NULL) { - assert(hash_isempty(env->extensions)); - hash_destroy(env->extensions); - } - if (env->run_funcs != NULL) { - assert(list_isempty(env->run_funcs)); - list_destroy(env->run_funcs); - } - - // Destroy mutex -#ifdef CP_THREADS - if (env->mutex != NULL) { - cpi_destroy_mutex(env->mutex); - } -#endif - - // Free environment - free(env); - -} - -CP_HIDDEN void cpi_free_context(cp_context_t *context) { - assert(context != NULL); - - // Free environment if this is the client program context - if (context->plugin == NULL && context->env != NULL) { - free_plugin_env(context->env); - } - - // Destroy symbol lists - if (context->resolved_symbols != NULL) { - assert(hash_isempty(context->resolved_symbols)); - hash_destroy(context->resolved_symbols); - } - if (context->symbol_providers != NULL) { - assert(hash_isempty(context->symbol_providers)); - hash_destroy(context->symbol_providers); - } - - // Free context - free(context); -} - -CP_HIDDEN cp_context_t * cpi_new_context(cp_plugin_t *plugin, cp_plugin_env_t *env, cp_status_t *error) { - cp_context_t *context = NULL; - cp_status_t status = CP_OK; - - assert(env != NULL); - assert(error != NULL); - - do { - - // Allocate memory for the context - if ((context = malloc(sizeof(cp_context_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Initialize context - context->plugin = plugin; - context->env = env; - context->resolved_symbols = NULL; - context->symbol_providers = NULL; - - } while (0); - - // Free context on error - if (status != CP_OK && context != NULL) { - free(context); - context = NULL; - } - - *error = status; - return context; -} - -CP_C_API cp_context_t * cp_create_context(cp_status_t *error) { - cp_plugin_env_t *env = NULL; - cp_context_t *context = NULL; - cp_status_t status = CP_OK; - - // Initialize internal state - do { - - // Allocate memory for the plug-in environment - if ((env = malloc(sizeof(cp_plugin_env_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Initialize plug-in environment - memset(env, 0, sizeof(cp_plugin_env_t)); -#ifdef CP_THREADS - env->mutex = cpi_create_mutex(); -#endif - env->argc = 0; - env->argv = NULL; - env->plugin_listeners = list_create(LISTCOUNT_T_MAX); - env->loggers = list_create(LISTCOUNT_T_MAX); - env->log_min_severity = CP_LOG_NONE; - env->plugin_dirs = list_create(LISTCOUNT_T_MAX); - env->infos = hash_create(HASHCOUNT_T_MAX, cpi_comp_ptr, cpi_hashfunc_ptr); - env->plugins = hash_create(HASHCOUNT_T_MAX, - (int (*)(const void *, const void *)) strcmp, NULL); - env->started_plugins = list_create(LISTCOUNT_T_MAX); - env->ext_points = hash_create(HASHCOUNT_T_MAX, - (int (*)(const void *, const void *)) strcmp, NULL); - env->extensions = hash_create(HASHCOUNT_T_MAX, - (int (*)(const void *, const void *)) strcmp, NULL); - env->run_funcs = list_create(LISTCOUNT_T_MAX); - env->run_wait = NULL; - if (env->plugin_listeners == NULL - || env->loggers == NULL -#ifdef CP_THREADS - || env->mutex == NULL -#endif - || env->plugin_dirs == NULL - || env->infos == NULL - || env->plugins == NULL - || env->started_plugins == NULL - || env->ext_points == NULL - || env->extensions == NULL - || env->run_funcs == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Create the plug-in context - if ((context = cpi_new_context(NULL, env, &status)) == NULL) { - break; - } - env = NULL; - - // Create a context list, if necessary, and add context to the list - cpi_lock_framework(); - if (contexts == NULL) { - if ((contexts = list_create(LISTCOUNT_T_MAX)) == NULL) { - status = CP_ERR_RESOURCE; - } - } - if (status == CP_OK) { - lnode_t *node; - - if ((node = lnode_create(context)) == NULL) { - status = CP_ERR_RESOURCE; - } else { - list_append(contexts, node); - } - } - cpi_unlock_framework(); - - } while (0); - - // Release resources on failure - if (status != CP_OK) { - if (env != NULL) { - free_plugin_env(env); - } - if (context != NULL) { - cpi_free_context(context); - } - context = NULL; - } - - // Return the final status - if (error != NULL) { - *error = status; - } - - // Return the context (or NULL on failure) - return context; -} - -CP_C_API void cp_destroy_context(cp_context_t *context) { - CHECK_NOT_NULL(context); - if (context->plugin != NULL) { - cpi_fatalf(_("Only the main program can destroy a plug-in context.")); - } - - // Check invocation - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - cpi_unlock_context(context); - -#ifdef CP_THREADS - assert(context->env->mutex == NULL || !cpi_is_mutex_locked(context->env->mutex)); -#else - assert(!context->env->locked); -#endif - - // Remove context from the context list - cpi_lock_framework(); - if (contexts != NULL) { - lnode_t *node; - - if ((node = list_find(contexts, context, cpi_comp_ptr)) != NULL) { - list_delete(contexts, node); - lnode_destroy(node); - } - } - cpi_unlock_framework(); - - // Unload all plug-ins - cp_uninstall_plugins(context); - - // Release remaining information objects - cpi_release_infos(context); - - // Free context - cpi_free_context(context); -} - -CP_HIDDEN void cpi_destroy_all_contexts(void) { - cpi_lock_framework(); - if (contexts != NULL) { - lnode_t *node; - - while ((node = list_last(contexts)) != NULL) { - cpi_unlock_framework(); - cp_destroy_context(lnode_get(node)); - cpi_lock_framework(); - } - list_destroy(contexts); - contexts = NULL; - } - cpi_unlock_framework(); -} - - -// Plug-in directories - -CP_C_API cp_status_t cp_register_pcollection(cp_context_t *context, const char *dir) { - char *d = NULL; - lnode_t *node = NULL; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(dir); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - do { - - // Check if directory has already been registered - if (list_find(context->env->plugin_dirs, dir, (int (*)(const void *, const void *)) strcmp) != NULL) { - break; - } - - // Allocate resources - d = malloc(sizeof(char) * (strlen(dir) + 1)); - node = lnode_create(d); - if (d == NULL || node == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Register directory - strcpy(d, dir); - list_append(context->env->plugin_dirs, node); - - } while (0); - - // Report error or success - if (status != CP_OK) { - cpi_errorf(context, N_("The plug-in collection in path %s could not be registered due to insufficient memory."), dir); - } else { - cpi_debugf(context, N_("The plug-in collection in path %s was registered."), dir); - } - cpi_unlock_context(context); - - // Release resources on failure - if (status != CP_OK) { - if (d != NULL) { - free(d); - } - if (node != NULL) { - lnode_destroy(node); - } - } - - return status; -} - -CP_C_API void cp_unregister_pcollection(cp_context_t *context, const char *dir) { - char *d; - lnode_t *node; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(dir); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - node = list_find(context->env->plugin_dirs, dir, (int (*)(const void *, const void *)) strcmp); - if (node != NULL) { - d = lnode_get(node); - list_delete(context->env->plugin_dirs, node); - lnode_destroy(node); - free(d); - } - cpi_debugf(context, N_("The plug-in collection in path %s was unregistered."), dir); - cpi_unlock_context(context); -} - -CP_C_API void cp_unregister_pcollections(cp_context_t *context) { - CHECK_NOT_NULL(context); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - list_process(context->env->plugin_dirs, NULL, cpi_process_free_ptr); - cpi_debug(context, N_("All plug-in collections were unregistered.")); - cpi_unlock_context(context); -} - - -// Startup arguments - -CP_C_API void cp_set_context_args(cp_context_t *ctx, char **argv) { - int argc; - - CHECK_NOT_NULL(ctx); - CHECK_NOT_NULL(argv); - for (argc = 0; argv[argc] != NULL; argc++); - if (argc < 1) { - cpi_fatalf(_("At least one startup argument must be given in call to function %s."), __func__); - } - cpi_lock_context(ctx); - ctx->env->argc = argc; - ctx->env->argv = argv; - cpi_unlock_context(ctx); -} - -CP_C_API char **cp_get_context_args(cp_context_t *ctx, int *argc) { - char **argv; - - CHECK_NOT_NULL(ctx); - cpi_lock_context(ctx); - if (argc != NULL) { - *argc = ctx->env->argc; - } - argv = ctx->env->argv; - cpi_unlock_context(ctx); - return argv; -} - - -// Checking API call invocation - -CP_HIDDEN void cpi_check_invocation(cp_context_t *ctx, int funcmask, const char *func) { - assert(ctx != NULL); - assert(funcmask != 0); - assert(func != NULL); - assert(cpi_is_context_locked(ctx)); - if ((funcmask & CPI_CF_LOGGER) - &&ctx->env->in_logger_invocation) { - cpi_fatalf(_("Function %s was called from within a logger invocation."), func); - } - if ((funcmask & CPI_CF_LISTENER) - && ctx->env->in_event_listener_invocation) { - cpi_fatalf(_("Function %s was called from within an event listener invocation."), func); - } - if ((funcmask & CPI_CF_START) - && ctx->env->in_start_func_invocation) { - cpi_fatalf(_("Function %s was called from within a plug-in start function invocation."), func); - } - if ((funcmask & CPI_CF_STOP) - && ctx->env->in_stop_func_invocation) { - cpi_fatalf(_("Function %s was called from within a plug-in stop function invocation."), func); - } - if (ctx->env->in_create_func_invocation) { - cpi_fatalf(_("Function %s was called from within a plug-in create function invocation."), func); - } - if (ctx->env->in_destroy_func_invocation) { - cpi_fatalf(_("Function %s was called from within a plug-in destroy function invocation."), func); - } -} - - -// Locking - -#if defined(CP_THREADS) || !defined(NDEBUG) - -CP_HIDDEN void cpi_lock_context(cp_context_t *context) { -#if defined(CP_THREADS) - cpi_lock_mutex(context->env->mutex); -#elif !defined(NDEBUG) - context->env->locked++; -#endif -} - -CP_HIDDEN void cpi_unlock_context(cp_context_t *context) { -#if defined(CP_THREADS) - cpi_unlock_mutex(context->env->mutex); -#elif !defined(NDEBUG) - assert(context->env->locked > 0); - context->env->locked--; -#endif -} - -CP_HIDDEN void cpi_wait_context(cp_context_t *context) { -#if defined(CP_THREADS) - cpi_wait_mutex(context->env->mutex); -#elif !defined(NDEBUG) - assert(context->env->locked > 0); - assert(0); -#endif -} - -CP_HIDDEN void cpi_signal_context(cp_context_t *context) { -#if defined(CP_THREADS) - cpi_signal_mutex(context->env->mutex); -#elif !defined(NDEBUG) - assert(context->env->locked > 0); -#endif -} - - -// Debug helpers - -CP_HIDDEN char *cpi_context_owner(cp_context_t *ctx, char *name, size_t size) { - if (ctx->plugin != NULL) { - /* TRANSLATORS: The context owner (when it is a plug-in) used in some strings. - Search for "context owner" to find these strings. */ - snprintf(name, size, _("Plug-in %s"), ctx->plugin->plugin->identifier); - } else { - /* TRANSLATORS: The context owner (when it is the main program) used in some strings. - Search for "context owner" to find these strings. */ - strncpy(name, _("The main program"), size); - } - assert(size >= 4); - strcpy(name + size - 4, "..."); - return name; -} - -#endif diff --git a/lib/cpluff/libcpluff/cpluff.c b/lib/cpluff/libcpluff/cpluff.c deleted file mode 100644 index 59b6d5ab77..0000000000 --- a/lib/cpluff/libcpluff/cpluff.c +++ /dev/null @@ -1,188 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Core framework functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> -#ifdef DLOPEN_LIBTOOL -#include <ltdl.h> -#endif -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#ifdef CP_THREADS -#include "thread.h" -#endif -#include "internal.h" - - -/* ------------------------------------------------------------------------ - * Variables - * ----------------------------------------------------------------------*/ - -/// Number of initializations -static int initialized = 0; - -#ifdef CP_THREADS - -/// Framework mutex -static cpi_mutex_t *framework_mutex = NULL; - -#elif !defined(NDEBUG) - -/// Framework locking count -static int framework_locked = 0; - -#endif - -/// Fatal error handler, or NULL for default -static cp_fatal_error_func_t fatal_error_handler = NULL; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -CP_C_API const char *cp_get_version(void) { - return CP_VERSION; -} - -CP_C_API const char *cp_get_host_type(void) { - return CP_HOST; -} - -CP_HIDDEN void cpi_lock_framework(void) { -#if defined(CP_THREADS) - cpi_lock_mutex(framework_mutex); -#elif !defined(NDEBUG) - framework_locked++; -#endif -} - -CP_HIDDEN void cpi_unlock_framework(void) { -#if defined(CP_THREADS) - cpi_unlock_mutex(framework_mutex); -#elif !defined(NDEBUG) - assert(framework_locked > 0); - framework_locked--; -#endif -} - -static void reset(void) { -#ifdef CP_THREADS - if (framework_mutex != NULL) { - cpi_destroy_mutex(framework_mutex); - framework_mutex = NULL; - } -#endif -} - -CP_C_API cp_status_t cp_init(void) { - cp_status_t status = CP_OK; - - // Initialize if necessary - do { - if (!initialized) { - bindtextdomain(PACKAGE, CP_DATADIR CP_FNAMESEP_STR "locale"); -#ifdef CP_THREADS - if ((framework_mutex = cpi_create_mutex()) == NULL) { - status = CP_ERR_RESOURCE; - break; - } -#endif -#ifdef DLOPEN_LIBTOOL - if (lt_dlinit()) { - status = CP_ERR_RESOURCE; - break; - } -#endif - } - initialized++; - } while (0); - - // Rollback on failure - if (status != CP_OK) { - reset(); - } - - return status; -} - -CP_C_API void cp_destroy(void) { - if (initialized <= 0) { - cpi_fatalf(_("Attempt to destroy uninitialized framework.")); - } - initialized--; - if (!initialized) { -#ifdef CP_THREADS - assert(framework_mutex == NULL || !cpi_is_mutex_locked(framework_mutex)); -#else - assert(!framework_locked); -#endif - cpi_destroy_all_contexts(); -#ifdef DLOPEN_LIBTOOL - lt_dlexit(); -#endif - reset(); - } -} - -CP_C_API void cp_set_fatal_error_handler(cp_fatal_error_func_t error_handler) { - fatal_error_handler = error_handler; -} - -CP_HIDDEN void cpi_fatalf(const char *msg, ...) { - va_list params; - char fmsg[256]; - - // Format message - assert(msg != NULL); - va_start(params, msg); - vsnprintf(fmsg, sizeof(fmsg), msg, params); - va_end(params); - fmsg[sizeof(fmsg)/sizeof(char) - 1] = '\0'; - - // Call error handler or print the error message - if (fatal_error_handler != NULL) { - fatal_error_handler(fmsg); - } else { - fprintf(stderr, _("C-Pluff: FATAL ERROR: %s\n"), fmsg); - } - - // Abort if still alive - abort(); -} - -CP_HIDDEN void cpi_fatal_null_arg(const char *arg, const char *func) { - cpi_fatalf(_("Argument %s has illegal NULL value in call to function %s."), arg, func); -} diff --git a/lib/cpluff/libcpluff/cpluff.h b/lib/cpluff/libcpluff/cpluff.h deleted file mode 100644 index d497af3dc7..0000000000 --- a/lib/cpluff/libcpluff/cpluff.h +++ /dev/null @@ -1,1520 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * C-Pluff C API header file. - * The elements declared here constitute the C-Pluff C API. To use the - * API include this file and link the main program and plug-in runtime - * libraries with the C-Pluff C library. In addition to local declarations, - * this file also includes cpluffdef.h header file for defines common to C - * and C++ API. - */ - -#ifndef CPLUFF_H_ -#define CPLUFF_H_ - -/** - * @defgroup cDefines Defines - * Preprocessor defines. - */ - -#ifdef _WIN32 -#include "win32/cpluffdef.h" -#else -#include "cpluffdef.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /*__cplusplus*/ - - -/* ------------------------------------------------------------------------ - * Defines - * ----------------------------------------------------------------------*/ - -/** - * @def CP_C_API - * @ingroup cDefines - * - * Marks a symbol declaration to be part of the C-Pluff C API. - * This macro declares the symbol to be imported from the C-Pluff library. - */ - -#ifndef CP_C_API -#define CP_C_API CP_IMPORT -#endif - - -/** - * @defgroup cScanFlags Flags for plug-in scanning - * @ingroup cDefines - * - * These constants can be orred together for the flags - * parameter of ::cp_scan_plugins. - */ -/*@{*/ - -/** - * This flag enables upgrades of installed plug-ins by unloading - * the old version and installing the new version. - */ -#define CP_SP_UPGRADE 0x01 - -/** - * This flag causes all plug-ins to be stopped before any - * plug-ins are to be upgraded. - */ -#define CP_SP_STOP_ALL_ON_UPGRADE 0x02 - -/** - * This flag causes all plug-ins to be stopped before any - * plugins are to be installed (also if new version is to be installed - * as part of an upgrade). - */ -#define CP_SP_STOP_ALL_ON_INSTALL 0x04 - -/** - * Setting this flag causes the currently active plug-ins to be restarted - * after all changes to the plug-ins have been made (if they were stopped). - */ -#define CP_SP_RESTART_ACTIVE 0x08 - -/*@}*/ - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -/** - * @defgroup cEnums Enumerations - * Constant value enumerations. - */ - -/** - * @defgroup cTypedefs Typedefs - * Typedefs of various kind. - */ - -/** - * @defgroup cStructs Data structures - * Data structure definitions. - */ - - -/* Enumerations */ - -/** - * @ingroup cEnums - * - * An enumeration of status codes returned by API functions. - * Most of the interface functions return a status code. The returned - * status code either indicates successful completion of the operation - * or some specific kind of error. Some functions do not return a status - * code because they never fail. - */ -enum cp_status_t { - - /** - * Operation was performed successfully (equals to zero). - * @showinitializer - */ - CP_OK = 0, - - /** Not enough memory or other operating system resources available */ - CP_ERR_RESOURCE, - - /** The specified object is unknown to the framework */ - CP_ERR_UNKNOWN, - - /** An I/O error occurred */ - CP_ERR_IO, - - /** Malformed plug-in descriptor was encountered when loading a plug-in */ - CP_ERR_MALFORMED, - - /** Plug-in or symbol conflicts with another plug-in or symbol. */ - CP_ERR_CONFLICT, - - /** Plug-in dependencies could not be satisfied. */ - CP_ERR_DEPENDENCY, - - /** Plug-in runtime signaled an error. */ - CP_ERR_RUNTIME - -}; - -/** - * @ingroup cEnums - * An enumeration of possible plug-in states. Plug-in states are controlled - * by @ref cFuncsPlugin "plug-in management functions". Plug-in states can be - * observed by @ref cp_register_plistener "registering" a - * @ref cp_plugin_listener_func_t "plug-in listener function" - * or by calling ::cp_get_plugin_state. - * - * @sa cp_plugin_listener_t - * @sa cp_get_plugin_state - */ -enum cp_plugin_state_t { - - /** - * Plug-in is not installed. No plug-in information has been - * loaded. - */ - CP_PLUGIN_UNINSTALLED, - - /** - * Plug-in is installed. At this stage the plug-in information has - * been loaded but its dependencies to other plug-ins has not yet - * been resolved. The plug-in runtime has not been loaded yet. - * The extension points and extensions provided by the plug-in - * have been registered. - */ - CP_PLUGIN_INSTALLED, - - /** - * Plug-in dependencies have been resolved. At this stage it has - * been verified that the dependencies of the plug-in are satisfied - * and the plug-in runtime has been loaded but it is not active - * (it has not been started or it has been stopped). - * Plug-in is resolved when a dependent plug-in is being - * resolved or before the plug-in is started. Plug-in is put - * back to installed stage if its dependencies are being - * uninstalled. - */ - CP_PLUGIN_RESOLVED, - - /** - * Plug-in is starting. The plug-in has been resolved and the start - * function (if any) of the plug-in runtime is about to be called. - * A plug-in is started when explicitly requested by the main - * program or when a dependent plug-in is about to be started or when - * a dynamic symbol defined by the plug-in is being resolved. This state - * is omitted and the state changes directly from resolved to active - * if the plug-in runtime does not define a start function. - */ - CP_PLUGIN_STARTING, - - /** - * Plug-in is stopping. The stop function (if any) of the plug-in - * runtime is about to be called. A plug-in is stopped if the start - * function fails or when stopping is explicitly - * requested by the main program or when its dependencies are being - * stopped. This state is omitted and the state changes directly from - * active to resolved if the plug-in runtime does not define a stop - * function. - */ - CP_PLUGIN_STOPPING, - - /** - * Plug-in has been successfully started and it has not yet been - * stopped. - */ - CP_PLUGIN_ACTIVE - -}; - -/** - * @ingroup cEnums - * An enumeration of possible message severities for framework logging. These - * constants are used when passing a log message to a - * @ref cp_logger_func_t "logger function" and when - * @ref cp_register_logger "registering" a logger function. - */ -enum cp_log_severity_t { - - /** Used for detailed debug messages */ - CP_LOG_DEBUG, - - /** Used for informational messages such as plug-in state changes */ - CP_LOG_INFO, - - /** Used for messages warning about possible problems */ - CP_LOG_WARNING, - - /** Used for messages reporting errors */ - CP_LOG_ERROR - -}; - -/*@}*/ - - -/* Typedefs */ - -/** - * @defgroup cTypedefsOpaque Opaque types - * @ingroup cTypedefs - * Opaque data type definitions. - */ -/*@{*/ - -/** - * A plug-in context represents the co-operation environment of a set of - * plug-ins from the perspective of a particular participating plug-in or - * the perspective of the main program. It is used as an opaque handle to - * the shared resources but the framework also uses the context to identify - * the plug-in or the main program invoking framework functions. Therefore - * a plug-in should not generally expose its context instance to other - * plug-ins or the main program and neither should the main program - * expose its context instance to plug-ins. The main program creates - * plug-in contexts using ::cp_create_context and plug-ins receive their - * plug-in contexts via @ref cp_plugin_runtime_t::create. - */ -typedef struct cp_context_t cp_context_t; - -/*@}*/ - - /** - * @defgroup cTypedefsShorthand Shorthand type names - * @ingroup cTypedefs - * Shorthand type names for structs and enumerations. - */ -/*@{*/ - -/** A type for cp_plugin_info_t structure. */ -typedef struct cp_plugin_info_t cp_plugin_info_t; - -/** A type for cp_plugin_import_t structure. */ -typedef struct cp_plugin_import_t cp_plugin_import_t; - -/** A type for cp_ext_point_t structure. */ -typedef struct cp_ext_point_t cp_ext_point_t; - -/** A type for cp_extension_t structure. */ -typedef struct cp_extension_t cp_extension_t; - -/** A type for cp_cfg_element_t structure. */ -typedef struct cp_cfg_element_t cp_cfg_element_t; - -/** A type for cp_plugin_runtime_t structure. */ -typedef struct cp_plugin_runtime_t cp_plugin_runtime_t; - -/** A type for cp_status_t enumeration. */ -typedef enum cp_status_t cp_status_t; - -/** A type for cp_plugin_state_t enumeration. */ -typedef enum cp_plugin_state_t cp_plugin_state_t; - -/** A type for cp_log_severity_t enumeration. */ -typedef enum cp_log_severity_t cp_log_severity_t; - -/*@}*/ - -/** - * @defgroup cTypedefsFuncs Callback function types - * @ingroup cTypedefs - * Typedefs for client supplied callback functions. - */ -/*@{*/ - -/** - * A listener function called synchronously after a plugin state change. - * The function should return promptly. - * @ref cFuncsInit "Library initialization", - * @ref cFuncsContext "plug-in context management", - * @ref cFuncsPlugin "plug-in management", - * listener registration (::cp_register_plistener and ::cp_unregister_plistener) - * and @ref cFuncsSymbols "dynamic symbol" functions must not be called from - * within a plug-in listener invocation. Listener functions are registered - * using ::cp_register_plistener. - * - * @param plugin_id the plug-in identifier - * @param old_state the old plug-in state - * @param new_state the new plug-in state - * @param user_data the user data pointer supplied at listener registration - */ -typedef void (*cp_plugin_listener_func_t)(const char *plugin_id, cp_plugin_state_t old_state, cp_plugin_state_t new_state, void *user_data); - -/** - * A logger function called to log selected plug-in framework messages. The - * messages may be localized. Plug-in framework API functions must not - * be called from within a logger function invocation. In a multi-threaded - * environment logger function invocations are serialized by the framework. - * Logger functions are registered using ::cp_register_logger. - * - * @param severity the severity of the message - * @param msg the message to be logged, possibly localized - * @param apid the identifier of the activating plug-in or NULL for the main program - * @param user_data the user data pointer given when the logger was registered - */ -typedef void (*cp_logger_func_t)(cp_log_severity_t severity, const char *msg, const char *apid, void *user_data); - -/** - * A fatal error handler for handling unrecoverable errors. If the error - * handler returns then the framework aborts the program. Plug-in framework - * API functions must not be called from within a fatal error handler - * invocation. The fatal error handler function is set using - * ::cp_set_fatal_error_handler. - * - * @param msg the possibly localized error message - */ -typedef void (*cp_fatal_error_func_t)(const char *msg); - -/** - * A run function registered by a plug-in to perform work. - * The run function should perform a finite chunk of work and it should - * return a non-zero value if there is more work to be done. Run functions - * are registered using ::cp_run_function and the usage is discussed in - * more detail in the @ref cFuncsPluginExec "serial execution" section. - * - * @param plugin_data the plug-in instance data pointer - * @return non-zero if there is more work to be done or zero if finished - */ -typedef int (*cp_run_func_t)(void *plugin_data); - -/*@}*/ - - -/* Data structures */ - -/** - * @ingroup cStructs - * Plug-in information structure captures information about a plug-in. This - * information can be loaded from a plug-in descriptor using - * ::cp_load_plugin_descriptor. Information about installed plug-ins can - * be obtained using ::cp_get_plugin_info and ::cp_get_plugins_info. This - * structure corresponds to the @a plugin element in a plug-in descriptor. - */ -struct cp_plugin_info_t { - - /** - * The obligatory unique identifier of the plugin. A recommended way - * to generate identifiers is to use domain name service (DNS) prefixes - * (for example, org.cpluff.ExamplePlugin) to avoid naming conflicts. This - * corresponds to the @a id attribute of the @a plugin element in a plug-in - * descriptor. - */ - char *identifier; - - /** - * An optional plug-in name. NULL if not available. The plug-in name is - * intended only for display purposes and the value can be localized. - * This corresponds to the @a name attribute of the @a plugin element in - * a plug-in descriptor. - */ - char *name; - - /** - * An optional release version string. NULL if not available. This - * corresponds to the @a version attribute of the @a plugin element in - * a plug-in descriptor. - */ - char *version; - - /** - * An optional provider name. NULL if not available. This is the name of - * the author or the organization providing the plug-in. The - * provider name is intended only for display purposes and the value can - * be localized. This corresponds to the @a provider-name attribute of the - * @a plugin element in a plug-in descriptor. - */ - char *provider_name; - - /** - * Path of the plugin directory or NULL if not known. This is the - * (absolute or relative) path to the plug-in directory containing - * plug-in data and the plug-in runtime library. The value corresponds - * to the path specified to ::cp_load_plugin_descriptor when loading - * the plug-in. - */ - char *plugin_path; - - /** - * Optional ABI compatibility information. NULL if not available. - * This is the earliest version of the plug-in interface the current - * interface is backwards compatible with when it comes to the application - * binary interface (ABI) of the plug-in. That is, plug-in clients compiled against - * any plug-in interface version from @a abi_bw_compatibility to - * @ref version (inclusive) can use the current version of the plug-in - * binary. This describes binary or runtime compatibility. - * The value corresponds to the @a abi-compatibility - * attribute of the @a backwards-compatibility element in a plug-in descriptor. - */ - char *abi_bw_compatibility; - - /** - * Optional API compatibility information. NULL if not available. - * This is the earliest version of the plug-in interface the current - * interface is backwards compatible with when it comes to the - * application programming interface (API) of the plug-in. That is, - * plug-in clients written for any plug-in interface version from - * @a api_bw_compatibility to @ref version (inclusive) can be compiled - * against the current version of the plug-in API. This describes - * source or build time compatibility. The value corresponds to the - * @a api-compatibility attribute of the @a backwards-compatibility - * element in a plug-in descriptor. - */ - char *api_bw_compatibility; - - /** - * Optional C-Pluff version requirement. NULL if not available. - * This is the version of the C-Pluff implementation the plug-in was - * compiled against. It is used to determine the compatibility of - * the plug-in runtime and the linked in C-Pluff implementation. Any - * C-Pluff version that is backwards compatible on binary level with the - * specified version fulfills the requirement. - */ - char *req_cpluff_version; - - /** Number of import entries in the @ref imports array. */ - unsigned int num_imports; - - /** - * An array of @ref num_imports import entries. These correspond to - * @a import elements in a plug-in descriptor. - */ - cp_plugin_import_t *imports; - - /** - * The base name of the plug-in runtime library, or NULL if none. - * A platform specific prefix (for example, "lib") and an extension - * (for example, ".dll" or ".so") may be added to the base name. - * This corresponds to the @a library attribute of the - * @a runtime element in a plug-in descriptor. - */ - char *runtime_lib_name; - - /** - * The symbol pointing to the plug-in runtime function information or - * NULL if none. The symbol with this name should point to an instance of - * @ref cp_plugin_runtime_t structure. This corresponds to the - * @a funcs attribute of the @a runtime element in a plug-in descriptor. - */ - char *runtime_funcs_symbol; - - /** Number of extension points in @ref ext_points array. */ - unsigned int num_ext_points; - - /** - * An array of @ref num_ext_points extension points provided by this - * plug-in. These correspond to @a extension-point elements in a - * plug-in descriptor. - */ - cp_ext_point_t *ext_points; - - /** Number of extensions in @ref extensions array. */ - unsigned int num_extensions; - - /** - * An array of @ref num_extensions extensions provided by this - * plug-in. These correspond to @a extension elements in a plug-in - * descriptor. - */ - cp_extension_t *extensions; - -}; - -/** - * @ingroup cStructs - * Information about plug-in import. Plug-in import structures are - * contained in @ref cp_plugin_info_t::imports. - */ -struct cp_plugin_import_t { - - /** - * The identifier of the imported plug-in. This corresponds to the - * @a plugin attribute of the @a import element in a plug-in descriptor. - */ - char *plugin_id; - - /** - * An optional version requirement. NULL if no version requirement. - * This is the version of the imported plug-in the importing plug-in was - * compiled against. Any version of the imported plug-in that is - * backwards compatible with this version fulfills the requirement. - * This corresponds to the @a if-version attribute of the @a import - * element in a plug-in descriptor. - */ - char *version; - - /** - * Is this import optional. 1 for optional and 0 for mandatory import. - * An optional import causes the imported plug-in to be started if it is - * available but does not stop the importing plug-in from starting if the - * imported plug-in is not available. If the imported plug-in is available - * but the API version conflicts with the API version requirement then the - * importing plug-in fails to start. This corresponds to the @a optional - * attribute of the @a import element in a plug-in descriptor. - */ - int optional; -}; - -/** - * @ingroup cStructs - * Extension point structure captures information about an extension - * point. Extension point structures are contained in - * @ref cp_plugin_info_t::ext_points. - */ -struct cp_ext_point_t { - - /** - * A pointer to plug-in information containing this extension point. - * This reverse pointer is provided to make it easy to get information - * about the plug-in which is hosting a particular extension point. - */ - cp_plugin_info_t *plugin; - - /** - * The local identifier uniquely identifying the extension point within the - * host plug-in. This corresponds to the @name id attribute of an - * @a extension-point element in a plug-in descriptor. - */ - char *local_id; - - /** - * The unique identifier of the extension point. This is automatically - * constructed by concatenating the identifier of the host plug-in and - * the local identifier of the extension point. - */ - char *identifier; - - /** - * An optional extension point name. NULL if not available. The extension - * point name is intended for display purposes only and the value can be - * localized. This corresponds to the @a name attribute of - * an @a extension-point element in a plug-in descriptor. - */ - char *name; - - /** - * An optional path to the extension schema definition. - * NULL if not available. The path is relative to the plug-in directory. - * This corresponds to the @a schema attribute - * of an @a extension-point element in a plug-in descriptor. - */ - char *schema_path; -}; - -/** - * @ingroup cStructs - * Extension structure captures information about an extension. Extension - * structures are contained in @ref cp_plugin_info_t::extensions. - */ -struct cp_extension_t { - - /** - * A pointer to plug-in information containing this extension. - * This reverse pointer is provided to make it easy to get information - * about the plug-in which is hosting a particular extension. - */ - cp_plugin_info_t *plugin; - - /** - * The unique identifier of the extension point this extension is - * attached to. This corresponds to the @a point attribute of an - * @a extension element in a plug-in descriptor. - */ - char *ext_point_id; - - /** - * An optional local identifier uniquely identifying the extension within - * the host plug-in. NULL if not available. This corresponds to the - * @a id attribute of an @a extension element in a plug-in descriptor. - */ - char *local_id; - - /** - * An optional unique identifier of the extension. NULL if not available. - * This is automatically constructed by concatenating the identifier - * of the host plug-in and the local identifier of the extension. - */ - char *identifier; - - /** - * An optional extension name. NULL if not available. The extension name - * is intended for display purposes only and the value can be localized. - * This corresponds to the @a name attribute - * of an @a extension element in a plug-in descriptor. - **/ - char *name; - - /** - * Extension configuration starting with the extension element. - * This includes extension configuration information as a tree of - * configuration elements. These correspond to the @a extension - * element and its contents in a plug-in descriptor. - */ - cp_cfg_element_t *configuration; -}; - -/** - * @ingroup cStructs - * A configuration element contains configuration information for an - * extension. Utility functions ::cp_lookup_cfg_element and - * ::cp_lookup_cfg_value can be used for traversing the tree of - * configuration elements. Pointer to the root configuration element is - * stored at @ref cp_extension_t::configuration and others are contained as - * @ref cp_cfg_element_t::children "children" of parent elements. - */ -struct cp_cfg_element_t { - - /** - * The name of the configuration element. This corresponds to the name of - * the element in a plug-in descriptor. - */ - char *name; - - /** Number of attribute name, value pairs in the @ref atts array. */ - unsigned int num_atts; - - /** - * An array of pointers to alternating attribute names and values. - * Attribute values can be localized. - */ - char **atts; - - /** - * An optional value of this configuration element. NULL if not available. - * The value can be localized. This corresponds to the - * text contents of the element in a plug-in descriptor. - */ - char *value; - - /** A pointer to the parent element or NULL if this is a root element. */ - cp_cfg_element_t *parent; - - /** The index of this element among its siblings (0-based). */ - unsigned int index; - - /** Number of children in the @ref children array. */ - unsigned int num_children; - - /** - * An array of @ref num_children childrens of this element. These - * correspond to child elements in a plug-in descriptor. - */ - cp_cfg_element_t *children; -}; - -/** - * @ingroup cStructs - * Container for plug-in runtime information. A plug-in runtime defines a - * static instance of this structure to pass information to the plug-in - * framework. The plug-in framework then uses the information - * to create and control plug-in instances. The symbol pointing - * to the runtime information instance is named by the @a funcs - * attribute of the @a runtime element in a plug-in descriptor. - * - * The following graph displays how these functions are used to control the - * state of the plug-in instance. - * - * @dot - * digraph lifecycle { - * rankdir=LR; - * node [shape=ellipse, fontname=Helvetica, fontsize=10]; - * edge [fontname=Helvetica, fontsize=10]; - * none [label="no instance"]; - * inactive [label="inactive"]; - * active [label="active"]; - * none -> inactive [label="create", URL="\ref create"]; - * inactive -> active [label="start", URL="\ref start"]; - * active -> inactive [label="stop", URL="\ref stop"]; - * inactive -> none [label="destroy", URL="\ref destroy"]; - * } - * @enddot - */ -struct cp_plugin_runtime_t { - - /** - * An initialization function called to create a new plug-in - * runtime instance. The initialization function initializes and - * returns an opaque plug-in instance data pointer which is then - * passed on to other control functions. This data pointer should - * be used to access plug-in instance specific data. For example, - * the context reference must be stored as part of plug-in instance - * data if the plug-in runtime needs it. On failure, the function - * must return NULL. - * - * C-pluff API functions must not be called from within a create - * function invocation and symbols from imported plug-ins must not be - * used because they may not available yet. - * - * @param ctx the plug-in context of the new plug-in instance - * @return an opaque pointer to plug-in instance data or NULL on failure - */ - void *(*create)(cp_context_t *ctx); - - /** - * A start function called to start a plug-in instance. - * The start function must return zero (CP_OK) on success and non-zero - * on failure. If the start fails then the stop function (if any) is - * called to clean up plug-in state. @ref cFuncsInit "Library initialization", - * @ref cFuncsContext "plug-in context management" and - * @ref cFuncsPlugin "plug-in management" functions must not be - * called from within a start function invocation. The start function - * pointer can be NULL if the plug-in runtime does not have a start - * function. - * - * The start function implementation should set up plug-in and return - * promptly. If there is further work to be done then a plug-in can - * start a thread or register a run function using ::cp_run_function. - * Symbols from imported plug-ins are guaranteed to be available for - * the start function. - * - * @param data an opaque pointer to plug-in instance data - * @return non-zero on success, or zero on failure - */ - int (*start)(void *data); - - /** - * A stop function called to stop a plugin instance. - * This function must cease all plug-in runtime activities. - * @ref cFuncsInit "Library initialization", - * @ref cFuncsContext "plug-in context management", - * @ref cFuncsPlugin "plug-in management" - * functions, ::cp_run_function and ::cp_resolve_symbol must not be called - * from within a stop function invocation. The stop function pointer can - * be NULL if the plug-in runtime does not have a stop function. - * It is guaranteed that no run functions registered by the plug-in are - * called simultaneously or after the call to the stop function. - * - * The stop function should release any external resources hold by - * the plug-in. Dynamically resolved symbols are automatically released - * and dynamically defined symbols and registered run functions are - * automatically unregistered after the call to stop function. - * Resolved external symbols are still available for the stop function - * and symbols provided by the plug-in should remain available - * after the call to stop function (although functionality might be - * limited). Final cleanup can be safely done in the destroy function. - * - * @param data an opaque pointer to plug-in instance data - */ - void (*stop)(void *data); - - /** - * A destroy function called to destroy a plug-in instance. - * This function should release any plug-in instance data. - * The plug-in is stopped before this function is called. - * C-Pluff API functions must not be called from within a destroy - * function invocation and symbols from imported plug-ins must not be - * used because they may not be available anymore. Correspondingly, - * it is guaranteed that the symbols provided by the plug-in are not - * used by other plug-ins when destroy function has been called. - * - * @param data an opaque pointer to plug-in instance data - */ - void (*destroy)(void *data); - -}; - -/*@}*/ - - -/* ------------------------------------------------------------------------ - * Function declarations - * ----------------------------------------------------------------------*/ - -/** - * @defgroup cFuncs Functions - * - * C API functions. The C-Pluff C API functions and - * any data exposed by them are generally thread-safe if the library has been - * compiled with multi-threading support. The - * @ref cFuncsInit "framework initialization functions" - * are exceptions, they are not thread-safe. - */ - -/** - * @defgroup cFuncsFrameworkInfo Framework information - * @ingroup cFuncs - * - * These functions can be used to query runtime information about the - * linked in C-Pluff implementation. They may be used by the main program or - * by a plug-in runtime. - */ -/*@{*/ - -/** - * Returns the release version string of the linked in C-Pluff - * implementation. - * - * @return the C-Pluff release version string - */ -CP_C_API const char *cp_get_version(void) CP_GCC_PURE; - -/** - * Returns the canonical host type associated with the linked in C-Pluff implementation. - * A multi-platform installation manager could use this information to - * determine what plug-in versions to install. - * - * @return the canonical host type - */ -CP_C_API const char *cp_get_host_type(void) CP_GCC_PURE; - -/*@}*/ - - -/** - * @defgroup cFuncsInit Framework initialization - * @ingroup cFuncs - * - * These functions are used for framework initialization. - * They are intended to be used by the main program. These functions are - * not thread safe. - */ -/*@{*/ - -/** - * Sets the fatal error handler called on non-recoverable errors. The default - * error handler prints the error message out to standard error and aborts - * the program. If the user specified error handler returns then the framework - * will abort the program. Setting NULL error handler will restore the default - * handler. This function is not thread-safe and it should be called - * before initializing the framework to catch all fatal errors. - * - * @param error_handler the fatal error handler - */ -CP_C_API void cp_set_fatal_error_handler(cp_fatal_error_func_t error_handler); - -/** - * Initializes the plug-in framework. This function must be called - * by the main program before calling any other plug-in framework - * functions except @ref cFuncsFrameworkInfo "framework information" functions and - * ::cp_set_fatal_error_handler. This function may be - * called several times but it is not thread-safe. Library resources - * should be released by calling ::cp_destroy when the framework is - * not needed anymore. - * - * Additionally, to enable localization support, the main program should - * set the current locale using @code setlocale(LC_ALL, "") @endcode - * before calling this function. - * - * @return @ref CP_OK (zero) on success or error code on failure - */ -CP_C_API cp_status_t cp_init(void); - -/** - * Destroys the plug-in framework and releases the resources used by it. - * The plug-in framework is only destroyed after this function has - * been called as many times as ::cp_init. This function is not - * thread-safe. Plug-in framework functions other than ::cp_init, - * ::cp_get_framework_info and ::cp_set_fatal_error_handler - * must not be called after the plug-in framework has been destroyed. - * All contexts are destroyed and all data references returned by the - * framework become invalid. - */ -CP_C_API void cp_destroy(void); - -/*@}*/ - - -/** - * @defgroup cFuncsContext Plug-in context initialization - * @ingroup cFuncs - * - * These functions are used to manage plug-in contexts from the main - * program perspective. They are not intended to be used by a plug-in runtime. - * From the main program perspective a plug-in context is a container for - * installed plug-ins. There can be several plug-in context instances if there - * are several independent sets of plug-ins. However, different plug-in - * contexts are not very isolated from each other in practice because the - * global symbols exported by a plug-in runtime in one context are visible to - * all plug-ins in all context instances. - */ -/*@{*/ - -/** - * Creates a new plug-in context which can be used as a container for plug-ins. - * Plug-ins are loaded and installed into a specific context. The main - * program may have more than one plug-in context but the plug-ins that - * interact with each other should be placed in the same context. The - * resources associated with the context are released by calling - * ::cp_destroy_context when the context is not needed anymore. Remaining - * contexts are automatically destroyed when the plug-in framework is - * destroyed. - * - * @param status pointer to the location where status code is to be stored, or NULL - * @return the newly created plugin context, or NULL on failure - */ -CP_C_API cp_context_t * cp_create_context(cp_status_t *status); - -/** - * Destroys the specified plug-in context and releases the associated resources. - * Stops and uninstalls all plug-ins in the context. The context must not be - * accessed after calling this function. - * - * @param ctx the context to be destroyed - */ -CP_C_API void cp_destroy_context(cp_context_t *ctx) CP_GCC_NONNULL(1); - -/** - * Registers a plug-in collection with a plug-in context. A plug-in collection - * is a directory that has plug-ins as its immediate subdirectories. The - * plug-in context will scan the directory when ::cp_scan_plugins is called. - * Returns @ref CP_OK if the directory has already been registered. A plug-in - * collection can be unregistered using ::cp_unregister_pcollection or - * ::cp_unregister_pcollections. - * - * @param ctx the plug-in context - * @param dir the directory - * @return @ref CP_OK (zero) on success or @ref CP_ERR_RESOURCE if insufficient memory - */ -CP_C_API cp_status_t cp_register_pcollection(cp_context_t *ctx, const char *dir) CP_GCC_NONNULL(1, 2); - -/** - * Unregisters a previously registered plug-in collection from a - * plug-in context. Plug-ins already loaded from the collection are not - * affected. Does nothing if the directory has not been registered. - * Plug-in collections can be registered using ::cp_register_pcollection. - * - * @param ctx the plug-in context - * @param dir the previously registered directory - */ -CP_C_API void cp_unregister_pcollection(cp_context_t *ctx, const char *dir) CP_GCC_NONNULL(1, 2); - -/** - * Unregisters all plug-in collections from a plug-in context. - * Plug-ins already loaded are not affected. Plug-in collections can - * be registered using ::cp_register_pcollection. - * - * @param ctx the plug-in context - */ -CP_C_API void cp_unregister_pcollections(cp_context_t *ctx) CP_GCC_NONNULL(1); - -/*@}*/ - - -/** - * @defgroup cFuncsLogging Logging - * @ingroup cFuncs - * - * These functions can be used to receive and emit log messages related - * to a particular plug-in context. They can be used by the main program - * or by a plug-in runtime. - */ -/*@{*/ - -/** - * Registers a logger with a plug-in context or updates the settings of a - * registered logger. The logger will receive selected log messages. - * If the specified logger is not yet known, a new logger registration - * is made, otherwise the settings for the existing logger are updated. - * The logger can be unregistered using ::cp_unregister_logger and it is - * automatically unregistered when the registering plug-in is stopped or - * when the context is destroyed. - * - * @param ctx the plug-in context to log - * @param logger the logger function to be called - * @param user_data the user data pointer passed to the logger - * @param min_severity the minimum severity of messages passed to logger - * @return @ref CP_OK (zero) on success or @ref CP_ERR_RESOURCE if insufficient memory - */ -CP_C_API cp_status_t cp_register_logger(cp_context_t *ctx, cp_logger_func_t logger, void *user_data, cp_log_severity_t min_severity) CP_GCC_NONNULL(1, 2); - -/** - * Removes a logger registration. - * - * @param ctx the plug-in context - * @param logger the logger function to be unregistered - */ -CP_C_API void cp_unregister_logger(cp_context_t *ctx, cp_logger_func_t logger) CP_GCC_NONNULL(1, 2); - -/** - * Emits a new log message. - * - * @param ctx the plug-in context - * @param severity the severity of the event - * @param msg the log message (possibly localized) - */ -CP_C_API void cp_log(cp_context_t *ctx, cp_log_severity_t severity, const char *msg) CP_GCC_NONNULL(1, 3); - -/** - * Returns whether a message of the specified severity would get logged. - * - * @param ctx the plug-in context - * @param severity the target logging severity - * @return whether a message of the specified severity would get logged - */ -CP_C_API int cp_is_logged(cp_context_t *ctx, cp_log_severity_t severity) CP_GCC_NONNULL(1); - -/*@}*/ - - -/** - * @defgroup cFuncsPlugin Plug-in management - * @ingroup cFuncs - * - * These functions can be used to manage plug-ins. They are intended to be - * used by the main program. - */ -/*@{*/ - -/** - * Loads a plug-in descriptor from the specified plug-in installation - * path and returns information about the plug-in. The plug-in descriptor - * is validated during loading. Possible loading errors are reported via the - * specified plug-in context. The plug-in is not installed to the context. - * If operation fails or the descriptor - * is invalid then NULL is returned. The caller must release the returned - * information by calling ::cp_release_plugin_info when it does not - * need the information anymore, typically after installing the plug-in. - * The returned plug-in information must not be modified. - * - * @param ctx the plug-in context - * @param path the installation path of the plug-in - * @param status a pointer to the location where status code is to be stored, or NULL - * @return pointer to the information structure or NULL if error occurs - */ -CP_C_API cp_plugin_info_t * cp_load_plugin_descriptor(cp_context_t *ctx, const char *path, cp_status_t *status) CP_GCC_NONNULL(1, 2); - -/** - * Loads a plug-in descriptor from the specified block of memory and returns - * information about the plug-in. The plug-in descriptor - * is validated during loading. Possible loading errors are reported via the - * specified plug-in context. The plug-in is not installed to the context. - * If operation fails or the descriptor - * is invalid then NULL is returned. The caller must release the returned - * information by calling ::cp_release_info when it does not - * need the information anymore, typically after installing the plug-in. - * The returned plug-in information must not be modified. - * - * @param ctx the plug-in context - * @param buffer the buffer containing the plug-in descriptor. - * @param buffer_len the length of the buffer. - * @param status a pointer to the location where status code is to be stored, or NULL - * @return pointer to the information structure or NULL if error occurs - */ -CP_C_API cp_plugin_info_t * cp_load_plugin_descriptor_from_memory(cp_context_t *ctx, const char *buffer, unsigned int buffer_len, cp_status_t *status) CP_GCC_NONNULL(1, 2); - -/** - * Installs the plug-in described by the specified plug-in information - * structure to the specified plug-in context. The plug-in information - * must have been loaded using ::cp_load_plugin_descriptor with the same - * plug-in context. - * The installation fails on #CP_ERR_CONFLICT if the context already - * has an installed plug-in with the same plug-in identifier. Installation - * also fails if the plug-in tries to install an extension point which - * conflicts with an already installed extension point. - * The plug-in information must not be modified but it is safe to call - * ::cp_release_plugin_info after the plug-in has been installed. - * - * @param ctx the plug-in context - * @param pi plug-in information structure - * @return @ref CP_OK (zero) on success or an error code on failure - */ -CP_C_API cp_status_t cp_install_plugin(cp_context_t *ctx, cp_plugin_info_t *pi) CP_GCC_NONNULL(1, 2); - -/** - * Scans for plug-ins in the registered plug-in directories, installing - * new plug-ins and upgrading installed plug-ins. This function can be used to - * initially load the plug-ins and to later rescan for new plug-ins. - * - * When several versions of the same plug-in is available the most recent - * version will be installed. The upgrade behavior depends on the specified - * @ref cScanFlags "flags". If #CP_SP_UPGRADE is set then upgrades to installed plug-ins are - * allowed. The old version is unloaded and the new version installed instead. - * If #CP_SP_STOP_ALL_ON_UPGRADE is set then all active plug-ins are stopped - * if any plug-ins are to be upgraded. If #CP_SP_STOP_ALL_ON_INSTALL is set then - * all active plug-ins are stopped if any plug-ins are to be installed or - * upgraded. Finally, if #CP_SP_RESTART_ACTIVE is set all currently active - * plug-ins will be restarted after the changes (if they were stopped). - * - * When removing plug-in files from the plug-in directories, the - * plug-ins to be removed must be first unloaded. Therefore this function - * does not check for removed plug-ins. - * - * @param ctx the plug-in context - * @param flags the bitmask of flags - * @return @ref CP_OK (zero) on success or an error code on failure - */ -CP_C_API cp_status_t cp_scan_plugins(cp_context_t *ctx, int flags) CP_GCC_NONNULL(1); - -/** - * Starts a plug-in. Also starts any imported plug-ins. If the plug-in is - * already starting then - * this function blocks until the plug-in has started or failed to start. - * If the plug-in is already active then this function returns immediately. - * If the plug-in is stopping then this function blocks until the plug-in - * has stopped and then starts the plug-in. - * - * @param ctx the plug-in context - * @param id identifier of the plug-in to be started - * @return @ref CP_OK (zero) on success or an error code on failure - */ -CP_C_API cp_status_t cp_start_plugin(cp_context_t *ctx, const char *id) CP_GCC_NONNULL(1, 2); - -/** - * Stops a plug-in. First stops any dependent plug-ins that are currently - * active. Then stops the specified plug-in. If the plug-in is already - * stopping then this function blocks until the plug-in has stopped. If the - * plug-in is already stopped then this function returns immediately. If the - * plug-in is starting then this function blocks until the plug-in has - * started (or failed to start) and then stops the plug-in. - * - * @param ctx the plug-in context - * @param id identifier of the plug-in to be stopped - * @return @ref CP_OK (zero) on success or @ref CP_ERR_UNKNOWN if unknown plug-in - */ -CP_C_API cp_status_t cp_stop_plugin(cp_context_t *ctx, const char *id) CP_GCC_NONNULL(1, 2); - -/** - * Stops all active plug-ins. - * - * @param ctx the plug-in context - */ -CP_C_API void cp_stop_plugins(cp_context_t *ctx) CP_GCC_NONNULL(1); - -/** - * Uninstalls the specified plug-in. The plug-in is first stopped if it is active. - * Then uninstalls the plug-in and any dependent plug-ins. - * - * @param ctx the plug-in context - * @param id identifier of the plug-in to be unloaded - * @return @ref CP_OK (zero) on success or @ref CP_ERR_UNKNOWN if unknown plug-in - */ -CP_C_API cp_status_t cp_uninstall_plugin(cp_context_t *ctx, const char *id) CP_GCC_NONNULL(1, 2); - -/** - * Uninstalls all plug-ins. All plug-ins are first stopped and then - * uninstalled. - * - * @param ctx the plug-in context - */ -CP_C_API void cp_uninstall_plugins(cp_context_t *ctx) CP_GCC_NONNULL(1); - -/*@}*/ - - -/** - * @defgroup cFuncsPluginInfo Plug-in and extension information - * @ingroup cFuncs - * - * These functions can be used to query information about the installed - * plug-ins, extension points and extensions or to listen for plug-in state - * changes. They may be used by the main program or by a plug-in runtime. - */ -/*@{*/ - -/** - * Returns static information about the specified plug-in. The returned - * information must not be modified and the caller must - * release the information by calling ::cp_release_info when the - * information is not needed anymore. When a plug-in runtime calls this - * function it may pass NULL as the identifier to get information about the - * plug-in itself. - * - * @param ctx the plug-in context - * @param id identifier of the plug-in to be examined or NULL for self - * @param status a pointer to the location where status code is to be stored, or NULL - * @return pointer to the information structure or NULL on failure - */ -CP_C_API cp_plugin_info_t * cp_get_plugin_info(cp_context_t *ctx, const char *id, cp_status_t *status) CP_GCC_NONNULL(1); - -/** - * Returns static information about the installed plug-ins. The returned - * information must not be modified and the caller must - * release the information by calling ::cp_release_info when the - * information is not needed anymore. - * - * @param ctx the plug-in context - * @param status a pointer to the location where status code is to be stored, or NULL - * @param num a pointer to the location where the number of returned plug-ins is stored, or NULL - * @return pointer to a NULL-terminated list of pointers to plug-in information - * or NULL on failure - */ -CP_C_API cp_plugin_info_t ** cp_get_plugins_info(cp_context_t *ctx, cp_status_t *status, int *num) CP_GCC_NONNULL(1); - -/** - * Returns static information about the currently installed extension points. - * The returned information must not be modified and the caller must - * release the information by calling ::cp_release_info when the - * information is not needed anymore. - * - * @param ctx the plug-in context - * @param status a pointer to the location where status code is to be stored, or NULL - * @param num filled with the number of returned extension points, if non-NULL - * @return pointer to a NULL-terminated list of pointers to extension point - * information or NULL on failure - */ -CP_C_API cp_ext_point_t ** cp_get_ext_points_info(cp_context_t *ctx, cp_status_t *status, int *num) CP_GCC_NONNULL(1); - -/** - * Returns static information about the currently installed extension points. - * The returned information must not be modified and the caller must - * release the information by calling ::cp_release_info when the - * information is not needed anymore. - * - * @param ctx the plug-in context - * @param extpt_id the extension point identifier or NULL for all extensions - * @param status a pointer to the location where status code is to be stored, or NULL - * @param num a pointer to the location where the number of returned extension points is to be stored, or NULL - * @return pointer to a NULL-terminated list of pointers to extension - * information or NULL on failure - */ -CP_C_API cp_extension_t ** cp_get_extensions_info(cp_context_t *ctx, const char *extpt_id, cp_status_t *status, int *num) CP_GCC_NONNULL(1); - -/** - * Releases a previously obtained reference counted information object. The - * documentation for functions returning such information refers - * to this function. The information must not be accessed after it has - * been released. The framework uses reference counting to deallocate - * the information when it is not in use anymore. - * - * @param ctx the plug-in context - * @param info the information to be released - */ -CP_C_API void cp_release_info(cp_context_t *ctx, void *info) CP_GCC_NONNULL(1, 2); - -/** - * Returns the current state of the specified plug-in. Returns - * #CP_PLUGIN_UNINSTALLED if the specified plug-in identifier is unknown. - * - * @param ctx the plug-in context - * @param id the plug-in identifier - * @return the current state of the plug-in - */ -CP_C_API cp_plugin_state_t cp_get_plugin_state(cp_context_t *ctx, const char *id) CP_GCC_NONNULL(1, 2); - -/** - * Registers a plug-in listener with a plug-in context. The listener is called - * synchronously immediately after a plug-in state change. There can be several - * listeners registered with the same context. A plug-in listener can be - * unregistered using ::cp_unregister_plistener and it is automatically - * unregistered when the registering plug-in is stopped or when the context - * is destroyed. - * - * @param ctx the plug-in context - * @param listener the plug-in listener to be added - * @param user_data user data pointer supplied to the listener - * @return @ref CP_OK (zero) on success or @ref CP_ERR_RESOURCE if out of resources - */ -CP_C_API cp_status_t cp_register_plistener(cp_context_t *ctx, cp_plugin_listener_func_t listener, void *user_data) CP_GCC_NONNULL(1, 2); - -/** - * Removes a plug-in listener from a plug-in context. Does nothing if the - * specified listener was not registered. - * - * @param ctx the plug-in context - * @param listener the plug-in listener to be removed - */ -CP_C_API void cp_unregister_plistener(cp_context_t *ctx, cp_plugin_listener_func_t listener) CP_GCC_NONNULL(1, 2); - -/** - * Traverses a configuration element tree and returns the specified element. - * The target element is specified by a base element and a relative path from - * the base element to the target element. The path includes element names - * separated by slash '/'. Two dots ".." can be used to designate a parent - * element. Returns NULL if the specified element does not exist. If there are - * several subelements with the same name, this function chooses the first one - * when traversing the tree. - * - * @param base the base configuration element - * @param path the path to the target element - * @return the target element or NULL if nonexisting - */ -CP_C_API cp_cfg_element_t * cp_lookup_cfg_element(cp_cfg_element_t *base, const char *path) CP_GCC_PURE CP_GCC_NONNULL(1, 2); - -/** - * Traverses a configuration element tree and returns the value of the - * specified element or attribute. The target element or attribute is specified - * by a base element and a relative path from the base element to the target - * element or attributes. The path includes element names - * separated by slash '/'. Two dots ".." can be used to designate a parent - * element. The path may end with '@' followed by an attribute name - * to select an attribute. Returns NULL if the specified element or attribute - * does not exist or does not have a value. If there are several subelements - * with the same name, this function chooses the first one when traversing the - * tree. - * - * @param base the base configuration element - * @param path the path to the target element - * @return the value of the target element or attribute or NULL - */ -CP_C_API char * cp_lookup_cfg_value(cp_cfg_element_t *base, const char *path) CP_GCC_PURE CP_GCC_NONNULL(1, 2); - -/*@}*/ - - -/** - * @defgroup cFuncsPluginExec Plug-in execution - * @ingroup cFuncs - * - * These functions support a plug-in controlled execution model. Started plug-ins can - * use ::cp_run_function to register @ref cp_run_func_t "a run function" which is called when the - * main program calls ::cp_run_plugins or ::cp_run_plugins_step. A run - * function should do a finite chunk of work and then return telling whether - * there is more work to be done. A run function is automatically unregistered - * when the plug-in is stopped. Run functions make it possible for plug-ins - * to control the flow of execution or they can be used as a coarse - * way of task switching if there is no multi-threading support. - * - * The C-Pluff distribution includes a generic main program, cpluff-loader, - * which only acts as a plug-in loader. It loads and starts up the - * specified plug-ins, passing any additional startup arguments to them and - * then just calls run functions of the plug-ins. This - * makes it is possible to put all the application specific logic in - * plug-ins. Application does not necessarily need a main program of its own. - * - * It is also safe, from framework perspective, to call these functions from - * multiple threads. Run functions may then be executed in parallel threads. - */ -/*@{*/ - -/** - * Registers a new run function. The plug-in instance data pointer is given to - * the run function as a parameter. The run function must return zero if it has - * finished its work or non-zero if it should be called again later. The run - * function is unregistered when it returns zero. Plug-in framework functions - * stopping the registering plug-in must not be called from within a run - * function. This function does nothing if the specified run - * function is already registered for the calling plug-in instance. - * - * @param ctx the plug-in context of the registering plug-in - * @param runfunc the run function to be registered - * @return @ref CP_OK (zero) on success or an error code on failure - */ -CP_C_API cp_status_t cp_run_function(cp_context_t *ctx, cp_run_func_t runfunc) CP_GCC_NONNULL(1, 2); - -/** - * Runs the started plug-ins as long as there is something to run. - * This function calls repeatedly run functions registered by started plug-ins - * until there are no more active run functions. This function is normally - * called by a thin main proram, a loader, which loads plug-ins, starts some - * plug-ins and then passes control over to the started plug-ins. - * - * @param ctx the plug-in context containing the plug-ins - */ -CP_C_API void cp_run_plugins(cp_context_t *ctx) CP_GCC_NONNULL(1); - -/** - * Runs one registered run function. This function calls one - * active run function registered by a started plug-in. When the run function - * returns this function also returns and passes control back to the main - * program. The return value can be used to determine whether there are any - * active run functions left. This function does nothing if there are no active - * registered run functions. - * - * @param ctx the plug-in context containing the plug-ins - * @return whether there are active run functions waiting to be run - */ -CP_C_API int cp_run_plugins_step(cp_context_t *ctx) CP_GCC_NONNULL(1); - -/** - * Sets startup arguments for the specified plug-in context. Like for usual - * C main functions, the first argument is expected to be the name of the - * program being executed or an empty string and the argument array should be - * terminated by NULL entry. If the main program is - * about to pass startup arguments to plug-ins it should call this function - * before starting any plug-ins in the context. The arguments are not copied - * and the caller is responsible for keeping the argument data available once - * the arguments have been set until the context is destroyed. Plug-ins can - * access the startup arguments using ::cp_get_context_args. - * - * @param ctx the plug-in context - * @param argv a NULL-terminated array of arguments - */ -CP_C_API void cp_set_context_args(cp_context_t *ctx, char **argv) CP_GCC_NONNULL(1, 2); - -/** - * Returns the startup arguments associated with the specified - * plug-in context. This function is intended to be used by a plug-in runtime. - * Startup arguments are set by the main program using ::cp_set_context_args. - * The returned argument count is zero and the array pointer is NULL if no - * arguments have been set. - * - * @param ctx the plug-in context - * @param argc a pointer to a location where the number of startup arguments is stored, or NULL for none - * @return an argument array terminated by NULL or NULL if not set - */ -CP_C_API char **cp_get_context_args(cp_context_t *ctx, int *argc) CP_GCC_NONNULL(1); - -/*@}*/ - - -/** - * @defgroup cFuncsSymbols Dynamic symbols - * @ingroup cFuncs - * - * These functions can be used to dynamically access symbols exported by the - * plug-ins. They are intended to be used by a plug-in runtime or by the main - * program. - */ -/*@{*/ - -/** - * Defines a context specific symbol. If a plug-in has symbols which have - * a plug-in instance specific value then the plug-in should define those - * symbols when it is started. The defined symbols are cleared - * automatically when the plug-in instance is stopped. Symbols can not be - * redefined. - * - * @param ctx the plug-in context - * @param name the name of the symbol - * @param ptr pointer value for the symbol - * @return @ref CP_OK (zero) on success or a status code on failure - */ -CP_C_API cp_status_t cp_define_symbol(cp_context_t *ctx, const char *name, void *ptr) CP_GCC_NONNULL(1, 2, 3); - -/** - * Resolves a symbol provided by the specified plug-in. The plug-in is started - * automatically if it is not already active. The symbol may be context - * specific or global. The framework first looks for a context specific - * symbol and then falls back to resolving a global symbol exported by the - * plug-in runtime library. The symbol can be released using - * ::cp_release_symbol when it is not needed anymore. Pointers obtained from - * this function must not be passed on to other plug-ins or the main - * program. - * - * When a plug-in runtime calls this function the plug-in framework creates - * a dynamic dependency from the symbol using plug-in to the symbol - * defining plug-in. The symbol using plug-in is stopped automatically if the - * symbol defining plug-in is about to be stopped. If the symbol using plug-in - * does not explicitly release the symbol then it is automatically released - * after a call to the stop function. It is not safe to refer to a dynamically - * resolved symbol in the stop function except to release it using - * ::cp_release_symbol. - * - * When the main program calls this function it is the responsibility of the - * main program to always release the symbol before the symbol defining plug-in - * is stopped. It is a fatal error if the symbol is not released before the - * symbol defining plug-in is stopped. - * - * @param ctx the plug-in context - * @param id the identifier of the symbol defining plug-in - * @param name the name of the symbol - * @param status a pointer to the location where the status code is to be stored, or NULL - * @return the pointer associated with the symbol or NULL on failure - */ -CP_C_API void *cp_resolve_symbol(cp_context_t *ctx, const char *id, const char *name, cp_status_t *status) CP_GCC_NONNULL(1, 2, 3); - -/** - * Releases a previously obtained symbol. The pointer must not be used after - * the symbol has been released. The symbol is released - * only after as many calls to this function as there have been for - * ::cp_resolve_symbol for the same plug-in and symbol. - * - * @param ctx the plug-in context - * @param ptr the pointer associated with the symbol - */ -CP_C_API void cp_release_symbol(cp_context_t *ctx, const void *ptr) CP_GCC_NONNULL(1, 2); - -/*@}*/ - - -#ifdef __cplusplus -} -#endif /*__cplusplus*/ - -#endif /*CPLUFF_H_*/ diff --git a/lib/cpluff/libcpluff/cpluffdef.h.in b/lib/cpluff/libcpluff/cpluffdef.h.in deleted file mode 100644 index 0d2dd15ba6..0000000000 --- a/lib/cpluff/libcpluff/cpluffdef.h.in +++ /dev/null @@ -1,204 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Common defines shared by C-Pluff C and C++ APIs. - * This file is automatically included by the top level C and C++ - * API header files. There should be no need to include it explicitly. - */ - -#ifndef CPLUFFDEF_H_ -#define CPLUFFDEF_H_ - - -/* ------------------------------------------------------------------------ - * Version information - * ----------------------------------------------------------------------*/ - -/** - * @defgroup versionInfo Version information - * @ingroup cDefines cxxDefines - * - * C-Pluff version information. Notice that this version information - * is static version information included in header files. The - * macros introduced here can be used for compile time checks. - */ -/*@{*/ - -/** - * The C-Pluff release version string. This string identifies a specific - * version of the C-Pluff distribution. Compile time software compatibility - * checks should use #CP_VERSION_MAJOR and #CP_VERSION_MINOR instead. - */ -#define CP_VERSION "@PACKAGE_VERSION@" - -/** - * The major version number component of the release version. This is an - * integer. - */ -#define CP_VERSION_MAJOR @CP_VERSION_MAJOR@ - -/** - * The minor version number component of the release version. This is an - * integer. - */ -#define CP_VERSION_MINOR @CP_VERSION_MINOR@ - -/*@}*/ - - -/* ------------------------------------------------------------------------ - * Symbol visibility - * ----------------------------------------------------------------------*/ - -/** - * @defgroup symbolVisibility Symbol visibility - * @ingroup cDefines cxxDefines - * - * Macros for controlling inter-module symbol visibility and linkage. These - * macros have platform specific values. #CP_EXPORT, #CP_IMPORT and #CP_HIDDEN - * can be reused by plug-in implementations for better portability. The - * complexity is mostly due to Windows DLL exports and imports. - * - * @anchor symbolVisibilityExample - * Each module should usually define its own macro to declare API symbols with - * #CP_EXPORT and #CP_IMPORT as necessary. For example, a mobule could define - * a macro @c MY_API in the API header file as follows. - * - * @code - * #ifndef MY_API - * # define MY_API CP_IMPORT - * #endif - * @endcode - * - * By default the API symbols would then be marked for import which is correct - * when client modules are including the API header file. When compiling the - * module itself the option @c -DMY_API=CP_EXPORT would be passed to the compiler to - * override the API header file and to mark the API symbols for export. - * The overriding definition could also be included in module source files or - * in an internal header file before including the API header file. - */ -/*@{*/ - -/** - * @def CP_EXPORT - * - * Declares a symbol to be exported for inter-module usage. When compiling the - * module which defines the symbol this macro should be placed - * at the start of the symbol declaration to ensure that the symbol is exported - * to other modules. However, when compiling other modules the declaration of - * the symbol should start with #CP_IMPORT. - * See @ref symbolVisibilityExample "the example" of how to do this. - */ - -/** - * @def CP_IMPORT - * - * Declares a symbol to be imported from another module. When compiling a - * module which uses the symbol this macro should be placed at the start of - * the symbol declaration to ensure that the symbol is imported from the - * defining module. However, when compiling the defining module the declaration - * of the symbol should start with #CP_EXPORT. - * See @ref symbolVisibilityExample "the example" of how to do this. - */ - -/** - * @def CP_HIDDEN - * - * Declares a symbol hidden from other modules. This macro should be - * placed at the start of the symbol declaration to hide the symbol from other - * modules (if supported by the platform). This macro is not intended to be - * used with symbols declared as "static" which are already internal to the - * object file. Some platforms do not support hiding of symbols and therefore - * unique prefixes should be used for global symbols internal to the module - * even when they are declared using this macro. - */ - -#if defined(_WIN32) -# define CP_EXPORT __declspec(dllexport) -# define CP_IMPORT extern __declspec(dllimport) -# define CP_HIDDEN -#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) -# define CP_EXPORT -# define CP_IMPORT extern -# define CP_HIDDEN __attribute__ ((visibility ("hidden"))) -#else -# define CP_EXPORT -# define CP_IMPORT extern -# define CP_HIDDEN -#endif - -/*@}*/ - - -/* ------------------------------------------------------------------------ - * GCC attributes - * ----------------------------------------------------------------------*/ - -/** - * @defgroup cDefinesGCCAttributes GCC attributes - * @ingroup cDefines cxxDefines - * - * These macros conditionally define GCC attributes for declarations. - * They are used in C-Pluff API declarations to enable better optimization - * and error checking when using GCC. In non-GCC platforms they have - * empty values. - */ -/*@{*/ - -/** - * @def CP_GCC_PURE - * - * Declares a function as pure function having no side effects. - * This attribute is supported in GCC since version 2.96. - * Such functions can be subject to common subexpression elimination - * and loop optimization. - */ - -/** - * @def CP_GCC_NONNULL - * - * Specifies that some pointer arguments to a function should have - * non-NULL values. Takes a variable length list of argument indexes as - * arguments. This attribute is supported in GCC since version 3.3. - * It can be used for enhanced error checking and some optimizations. - */ - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -#define CP_GCC_PURE __attribute__((pure)) -#else -#define CP_GCC_PURE -#endif -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) -#define CP_GCC_NONNULL(...) __attribute__((nonnull (__VA_ARGS__))) -#else -#define CP_GCC_NONNULL(...) -#endif - -/*@}*/ - -#if @DEFINE_EMPTY_CONST@ -#define const -#endif - -#endif /*CPLUFFDEF_H_*/ diff --git a/lib/cpluff/libcpluff/defines.h b/lib/cpluff/libcpluff/defines.h deleted file mode 100644 index 98a0e23447..0000000000 --- a/lib/cpluff/libcpluff/defines.h +++ /dev/null @@ -1,66 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Core internal defines - */ - -#ifndef DEFINES_H_ -#define DEFINES_H_ - -#ifdef ENABLE_NLS -#include <libintl.h> -#endif - - -/* ------------------------------------------------------------------------ - * Defines - * ----------------------------------------------------------------------*/ - -// Gettext defines -#ifdef ENABLE_NLS -#define _(String) dgettext(PACKAGE, String) -#define gettext_noop(String) String -#define N_(String) gettext_noop(String) -#else -#define _(String) (String) -#define N_(String) String -#define textdomain(Domain) -#define bindtextdomain(Package, Directory) -#endif //HAVE_GETTEXT - - -// Additional defines for function attributes (under GCC). -#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) && ! defined(printf) -#define CP_GCC_PRINTF(format_idx, arg_idx) \ - __attribute__((format (printf, format_idx, arg_idx))) -#define CP_GCC_CONST __attribute__((const)) -#define CP_GCC_NORETURN __attribute__((noreturn)) -#else -#define CP_GCC_PRINTF(format_idx, arg_idx) -#define CP_GCC_CONST -#define CP_GCC_NORETURN -#endif - - -#endif //DEFINES_H_ diff --git a/lib/cpluff/libcpluff/docsrc/Doxyfile-impl.in b/lib/cpluff/libcpluff/docsrc/Doxyfile-impl.in deleted file mode 100644 index 3bc1858041..0000000000 --- a/lib/cpluff/libcpluff/docsrc/Doxyfile-impl.in +++ /dev/null @@ -1,1256 +0,0 @@ -# Doxyfile 1.5.1 - -# Copyright 2007 Johannes Lehtinen -# This configuration file is free software; Johannes Lehtinen gives unlimited -# permission to copy, distribute and modify it. - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "@PACKAGE_NAME@ C Implementation" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = "@PACKAGE_VERSION@ (API version @CP_CORE_API_CURRENT@)" - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = YES - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = YES - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = YES - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = YES - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py - -FILE_PATTERNS = *.c *.h - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = doxygen.footer - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = doxygen.css - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = NO - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/lib/cpluff/libcpluff/docsrc/Doxyfile-ref.in b/lib/cpluff/libcpluff/docsrc/Doxyfile-ref.in deleted file mode 100644 index 306d7f4038..0000000000 --- a/lib/cpluff/libcpluff/docsrc/Doxyfile-ref.in +++ /dev/null @@ -1,1256 +0,0 @@ -# Doxyfile 1.5.1 - -# Copyright 2007 Johannes Lehtinen -# This configuration file is free software; Johannes Lehtinen gives unlimited -# permission to copy, distribute and modify it. - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "@PACKAGE_NAME@ C API" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = "@PACKAGE_VERSION@" - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = YES - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = YES - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = YES - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = YES - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 0 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = cpluffdef.h cpluff.h mainpage.dox architecture.dox mainprog.dox plugin.dox - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = . - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = NO - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = doxygen.footer - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = doxygen.css - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = YES - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = CP_GCC_PURE CP_GCC_NONNULL CP_C_API - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = NO - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/lib/cpluff/libcpluff/docsrc/Makefile.am b/lib/cpluff/libcpluff/docsrc/Makefile.am deleted file mode 100644 index 5a2f304b3c..0000000000 --- a/lib/cpluff/libcpluff/docsrc/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -## Process this file with automake to produce Makefile.in. - -# Copyright 2007 Johannes Lehtinen -# This Makefile is free software; Johannes Lehtinen gives unlimited -# permission to copy, distribute and modify it. - -EXTRA_DIST = mainpage.dox architecture.dox mainprog.dox plugin.dox diff --git a/lib/cpluff/libcpluff/docsrc/architecture.dox b/lib/cpluff/libcpluff/docsrc/architecture.dox deleted file mode 100644 index e9e6de5386..0000000000 --- a/lib/cpluff/libcpluff/docsrc/architecture.dox +++ /dev/null @@ -1,66 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** - * @page architecture Plug-in architecture - * - * @section architectureOverview Overview - * - * The plug-in architecture supported by C-Pluff is presented in the - * following figure. There is a thin main program controlling the plug-in - * framework. The main program is responsible for initializing and setting - * up the plug-in environment. Most of the application logic is contained in - * plug-ins which are independent components and can be developed and - * distributed separately. Plug-ins integrate with each other by providing - * extension points and extensions. An extension point is a point into which - * other plug-ins can attach extensions. An extension can be just - * information, expressed in XML format, or the plug-in may also provide - * program logic as part of the plug-in runtime library. The framework - * provides services for accessing extensions and for managing plug-in - * dependencies. - * - * @image html architecture.png "C-Pluff plug-in architecture" - * - * @section architectureExtensions Extensions - * - * The idea behind extension points and extensions is that the extensibility - * is not limited only to few fixed plug-in types supported by the - * core application. Although the core plug-ins typically define the extension - * points for the core application logic, it is possible for any plug-in - * to specify additional extension points. - * - * For example, let us assume that we are developing an extensible text - * editor. One extension point defined by core editor plug-in could be - * auto-completion extension point. A plug-in providing basic Java source code - * support could provide an extension for auto-completing Java code. - * Now, while this extension could do basic auto-completion of plain Java code, - * it is customary that Java source code also includes embedded documentation, - * such as JavaDoc comments and tags, or annotations, such as XDoclet tags, as - * part of doc comments. Instead of trying to support all known tags and their - * semantics, the plug-in providing basic Java support could define another - * extension point for additional plug-ins that know how to perform - * auto-completion of different kind of tags in doc comments. - * This way the extensibility of the application is not limited to the - * extension points defined by the core application but the plug-ins can - * incrementally increase the extensibility of the application. - */ diff --git a/lib/cpluff/libcpluff/docsrc/mainpage.dox b/lib/cpluff/libcpluff/docsrc/mainpage.dox deleted file mode 100644 index 7376c324e3..0000000000 --- a/lib/cpluff/libcpluff/docsrc/mainpage.dox +++ /dev/null @@ -1,57 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** - * @mainpage - * - * This is reference documentation for the - * <a href="http://www.c-pluff.org/">C-Pluff</a> C API. - * C-Pluff is a plug-in framework for C programs. - * It has been strongly inspired by the Java plug-in framework in - * <a href="http://www.eclipse.org/">Eclipse</a>. C-Pluff focuses on - * providing core services for plug-in interaction and plug-in - * management. It aims to be platform neutral and supports dynamic changes to - * plug-in configuration without stopping the whole application or framework. - * It does not yet provide special facilities for distribution such as - * signed plug-in packages or remote plug-in repositories but it is - * possible to build such features on top of the current framework. - * - * Here are links to main topics. - * - * - @ref architecture "Plug-in architecture" - * - @ref cMainProgram "Main program" - * - @ref plugin "Plug-in" - * - * - <a class="el" href="modules.html">API elements</a> - * - <a class="el" href="files.html">Header files</a> - * - * For a "quick start guide" in developing C-Pluff based applications, - * see the example in the examples directory of the source distribution. - * - * The latest version of the framework implementation - * and documentation is available at - * <a href="http://www.c-pluff.org/">C-Pluff web site</a>. - * - * This documentation has been generated from the C-Pluff source code - * using <a href="http://www.doxygen.org">Doxygen</a>. - */ diff --git a/lib/cpluff/libcpluff/docsrc/mainprog.dox b/lib/cpluff/libcpluff/docsrc/mainprog.dox deleted file mode 100644 index 78407d032e..0000000000 --- a/lib/cpluff/libcpluff/docsrc/mainprog.dox +++ /dev/null @@ -1,338 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** - * @page cMainProgram Main program - * - * @section cMainProgramOverview Overview - * - * The main program is the part of executable that is located outside the - * plug-in framework. The main program is responsible for setting up - * the plug-in framework and for loading the desired set of - * @ref plugin "plug-ins". The main program should preferably be very - * thin, a mere plug-in loader, because it can not fully participate in plug-in - * interaction. C-Pluff distribution provides a plug-in loader, - * @ref cpluff-loader, which can be used as a generic main program for - * arbitrary plug-in collections. - * - * @section cMainProgramResponsibilities Responsibilities - * - * The main program has several responsibilities: - * - * - @ref cMainProgramInitFramework "initializing the plug-in framework" - * - @ref cMainProgramCreateContext "creating a plug-in context" - * - @ref cMainProgramLoad "loading plug-ins" - * - @ref cMainProgramExec "controlling plug-in execution" - * - @ref cMainProgramChange "changing plug-in configuration" (opt.) - * - @ref cMainProgramDestroyFramework "destroying the plug-in framework" - * - * @subsection cMainProgramInitFramework Initializing the plug-in framework - * - * Plug-in framework, or the C-Pluff library, must be initialized before its - * services can be used. - * Initialization is not a thread-safe operation and should generally be - * done by the main program before any additional plug-in framework accessing - * threads are started. Initialization is done by calling ::cp_init. - * Additionally, the main program can use ::cp_set_fatal_error_handler to register - * a function that is called when a fatal error occurs. A fatal error is one - * that prevents the framework from continuing operation. For example, - * errors in operating system locking operations and a NULL pointer being - * passed as an argument which is expected to have a non-NULL value are fatal - * erors. - * - * Here is an example of possible initialization code. - * - * @code - * #include <locale.h> - * #include <cpluff.h> - * - * void handle_fatal_error(const char *msg) { - * - * // ... log error, flush logs, send bug report, etc. ... - * - * fprintf(stderr, "A fatal error occurred: %s\n", msg); - * abort(); - * } - * - * void initialize(void) { - * cp_status_t status; - * - * setlocale(LC_ALL, ""); - * cp_set_fatal_error_handler(handle_fatal_error); - * status = cp_init(); - * if (status != CP_OK) { - * // ... handle initialization failure ... - * } - * } - * @endcode - * - * @subsection cMainProgramCreateContext Creating a plug-in context - * - * A plug-in context represents the co-operation environment of a set of - * plug-ins from the perspective of a particular participating plug-in or - * the perspective of the main program. From main program perspective, a - * plug-in context is a container for a set of plug-ins. A plug-in can interact - * with other plug-ins in the same container. - * - * An extensible application can have more than one plug-in container but - * usually one container should suffice. Due to the nature of C programs, - * plug-ins deployed to different containers are not very well insulated from - * each other. For example, global variables provided by a plug-in in one - * container are visible to all plug-ins in all containers. Also, by placing - * all plug-ins in the same container they can more efficiently share common - * base components which themselves might provide extensibility. - * - * A main program creates a plug-in context, to be used as a container for - * plugins, using ::cp_create_context. - * - * @code - * #include <cpluff.h> - * - * cp_context_t *ctx; - * - * void create_context(void) { - * cp_status_t status; - * - * ctx = cp_create_context(&status); - * if (ctx == NULL) { - * // ... handle initialization failure ... - * } - * } - * @endcode - * - * @subsection cMainProgramLoad Loading plug-ins - * - * An extensible application is made of plug-ins that can be added and removed - * dynamically. The plug-ins are loaded by the main program using the services - * provided by the framework. The framework provides couple of alternative - * ways of loading plug-ins. - * - * As a lowest level operation, the main program can - * load individual plug-ins from known locations using - * ::cp_load_plugin_descriptor and ::cp_install_plugin. Here is example code - * that loads a set of plug-ins from file system locations listed in a file. - * - * @code - * #include <stdio.h> - * #include <cpluff.h> - * - * extern cp_context_t *ctx; - * static const char pluginListFile[] = "/etc/example/plugins.list"; - * - * void load_plugins(void) { - * char plugindir[128]; - * FILE *lf; - * - * // Open plug-in list file - * lf = fopen(pluginListFile, "r"); - * if (lf == NULL) { - * // ... handle loading failure ... - * } - * - * // Load each listed plug-in - * while (fgets(plugindir, 128, lf) != NULL) { - * cp_plugin_info_t *plugininfo; - * cp_status_t status; - * int i; - * - * // Remove possible trailing newline from plug-in location - * for (i = 0; plugindir[i + 1] != '\0'; i++); - * if (plugindir[i] == '\n') { - * plugindir[i] = '\0'; - * } - * - * // Load plug-in descriptor - * plugininfo = cp_load_plugin_descriptor(ctx, plugindir, &status); - * if (pinfo == NULL) { - * // ... handle loading failure ... - * } - * - * // Install plug-in descriptor - * status = cp_install_plugin(ctx, plugininfo); - * if (status != CP_OK) { - * // ... handle loading failure ... - * } - * - * // Release plug-in descriptor information - * cp_release_info(ctx, plugininfo); - * } - * - * // Close plug-in list file - * fclose(lf); - * } - * @endcode - * - * Alternatively, the main program can register and load plug-in collections. - * A plug-in collection is a file system directory which includes individual - * plug-ins in subdirectories, one plug-in in each subdirectory. Plug-in - * collections can be registered with a plug-in context using - * ::cp_register_pcollection. Plug-ins of the collection can then be scanned - * and loaded using ::cp_scan_plugins. Here is example code loading plug-ins - * from a plug-in collection. - * - * @code - * #include <cpluff.h> - * - * extern cp_context_t *ctx; - * static const char pluginCollectionDir[] = "/etc/example/plugins"; - * - * void load_plugins(void) { - * cp_status_t status; - * - * status = cp_register_pcollection(ctx, pluginCollectionDir); - * if (status != CP_OK) { - * // ... handle loading failure ... - * } - * status = cp_scan_plugins(ctx, 0); - * if (status != CP_OK) { - * // ... handle loading failure ... - * // (notice that some plug-ins might have been loaded) - * } - * } - * @endcode - * - * @subsection cMainProgramExec Controlling plug-in execution - * - * The main program controls plug-in execution by starting and stopping - * plug-ins and by executing run functions registered by plug-ins. - * Additionally, the main program can pass startup arguments to plug-ins. - * - * When plug-ins are installed they are not yet activated and their - * runtime library is not even loaded at that point. The main program - * typically activates plug-ins by starting a main plug-in - * responsible for user interface or core application logic. This plug-in - * then implicitly causes other plug-ins to be activated via dependencies and - * by dynamically resolving symbols provided by other plug-ins. Plug-ins - * recursively activate each other until all initially needed plug-ins have - * been started. Some plug-ins might be activated at a later time when their - * functionality is needed, for example due to user action. - * - * If a plug-in needs to perform background operations, that is operations - * executed outside the invocation of plug-in provided interface functions, - * then it can either start a new thread or it can register a run function. - * A run function is a function that is typically executed as part of the - * main loop by the main program. - * - * The following example code shows how a main program might initialize - * plug-in startup arguments using ::cp_set_context_args, start the core - * plug-in using ::cp_start_plugin and then execute plug-in run functions - * using ::cp_run_plugins. - * - * @code - * #include <cpluff.h> - * - * extern cp_context_t *ctx; - * static const char corePluginId[] = "org.example.core"; - * - * void run_plugins(char *argv[]) { - * cp_status_t status; - * - * // Set plug-in startup arguments - * cp_set_context_args(ctx, argv); - * - * // Start the core plug-in, possibly activating other plug-ins as well - * status = cp_start_plugin(ctx, corePluginId); - * if (status != CP_OK) { - * // ... handle startup failure ... - * } - * - * // Execute plug-ins until there is no more work to be done - * cp_run_plugins(ctx); - * } - * - * int main(int argc, char *argv[]) { - * // ... do initialization and load plug-ins ... - * - * run_plugins(argv); - * - * // ... do destruction ... - * } - * @endcode - * - * Alternatively, if the main program has some operations it must perform - * as part of the main loop, the call to ::cp_run_plugins can be replaced - * by code using ::cp_run_plugins_step like in the following example. - * - * @code - * void mainloop(void) { - * int finished = 0; - * - * while (!finished) { - * // ... do main program specific operations ... - * - * finished = !cp_run_plugins_step(ctx); - * } - * } - * @endcode - * - * @subsection cMainProgramChange Changing plug-in configuration - * - * C-Pluff has been designed to allow dynamic changes to the plug-in - * configuration, that is plug-ins being added or removed without shutting - * down the application or the framework. It is the responsibility of the - * main program to manage such changes if the application is to support - * dynamic configuration changes. - * - * Adding plug-ins is straightforward because there is no need to - * consider dependencies of active plug-ins. For example, if one uses - * plug-in collections as introduced above then new plug-ins can be - * deployed under the plug-in collection directory while the application is - * running and the main program can load them incrementally by calling - * ::cp_scan_plugins again. This call might be activated by some user interface - * element, for example a plug-in manager component which just downloaded and - * installed new plug-ins as requested by the user. The flags - * #CP_SP_STOP_ALL_ON_INSTALL and #CP_SP_RESTART_ACTIVE - * orred together can be used to cause all active plug-ins to be restarted - * if they do not otherwise notice the extensions provided by new plug-ins. - * - * Upgrading plug-ins is almost as straightforward because the C-Pluff - * framework manages plug-in dependencies (assuming the plug-ins have - * declared their dependencies properly). The new version of a plug-in - * can be deployed under the plug-in collection directory in a - * new subdirectory parallel to the old version while the application is - * running. The main program can then call ::cp_scan_plugins with - * #CP_SP_UPGRADE and #CP_SP_RESTART_ACTIVE orred together. This will stop - * the old version of the upgraded plug-in (implicitly stopping all plug-ins - * that depend on it), unload the plug-in from the framework, install the - * new version of the plug-in and finally restart plug-ins that were - * active before the operation. The old version of the plug-in can now - * be removed from the plug-in collection. Again, #CP_SP_STOP_ALL_ON_UPGRADE - * can be added to restart all active plug-ins. - * - * Deleting plug-ins must be done by first stopping and unloading the - * plug-in to be deleted using ::cp_uninstall_plugin. The the plug-in can - * be removed from the plug-in collection. - * - * @subsection cMainProgramDestroyFramework Destroying the plug-in framework - * - * The plug-in framework can be destroyed and all resources released by - * calling ::cp_destroy as many times as ::cp_init has been called. This - * is not a thread-safe operation and should generally be done by the main - * program just before application exits. The destroy function - * stops and unloads all plug-ins and destroys all plug-in contexts before - * destroying the core framework. - * - * Individual plug-in contexts can be destroyed by calling - * ::cp_destroy_context. The destroy function stops and unloads all plug-ins - * before destroying the context itself. - */ diff --git a/lib/cpluff/libcpluff/docsrc/plugin.dox b/lib/cpluff/libcpluff/docsrc/plugin.dox deleted file mode 100644 index 9b7e954896..0000000000 --- a/lib/cpluff/libcpluff/docsrc/plugin.dox +++ /dev/null @@ -1,286 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** - * @page plugin Plug-in - * - * @section pluginOverview Overview - * - * Plug-in is the core element of an extensible application. The extensions and - * also the main application logic are implemented as plug-ins. Plug-ins can - * be developed, distributed and deployed independently, subject to - * inter-plugin dependencies. Deploying a new plug-in does not require - * recompilation or relinking if the operating system platform supports - * required dynamic linking facilities. - * - * @section pluginStructure Structure - * - * A plug-in includes the following structural elements. - * - * - @ref pluginDescriptor "Plug-in descriptor" - * - @ref pluginRuntime "Plug-in runtime library" - * - @ref pluginData "Static plug-in data" - * - * @subsection pluginDescriptor Plug-in descriptor - * - * A plug-in descriptor is an XML document describing a plug-in. It includes - * information about the contents of the plug-in, the features provided by - * the plug-in, plug-in version information and static dependencies of the - * plug-in. Most of the elements are optional. Most of the descriptor - * information described here is available to software via - * @ref cp_plugin_info_t structure. The plug-in descriptor must be located - * in the plug-in directory as @c plugin.xml. - * - * The formal declaration of plug-in descriptor is available as - * XML Schema Definition in @c plugin.xsd located in the top level source - * directory. Currently there is no namespace associated with the plug-in - * descriptor. Here is an example of a plug-in descriptor. Click element name - * to jump into documentation for that element. - * - * <div class="fragment"> - * <pre class="fragment"> - * <<a class="code" href="#pluginDescPlugin">plugin</a> id=<span class="charliteral">"org.c-pluff.example"</span> name=<span class="charliteral">"Example Plug-in"</span> version=<span class="charliteral">"0.3.2"</span> provider-name=<span class="charliteral">"Johannes Lehtinen"</span>> - * <<a class="code" href="#pluginDescPluginBWC">backwards-compatibility</a> abi=<span class="charliteral">"0.3"</span> api=<span class="charliteral">"0.2.8"</span>/> - * <<a class="code" href="#pluginDescPluginRequires">requires</a>> - * <<a class="code" href="#pluginDescPluginReqCP">c-pluff</a> version=<span class="charliteral">"0.1"</span>/> - * <<a class="code" href="#pluginDescPluginReqImport">import</a> plugin=<span class="charliteral">"org.c-pluff.util"</span> version=<span class="charliteral">"0.2"</span>/> - * <<a class="code" href="#pluginDescPluginReqImport">import</a> plugin=<span class="charliteral">"org.c-pluff.extra"</span> optional=<span class="charliteral">"true"</span>/> - * </<a class="code" href="#pluginDescPluginRequires">requires</a>> - * <<a class="code" href="#pluginDescPluginRuntime">runtime</a> library=<span class="charliteral">"libruntime"</span> funcs=<span class="charliteral">"org_cpluff_example_funcs"</span>/> - * <<a class="code" href="#pluginDescPluginEP">extension-point</a> id=<span class="charliteral">"editors"</span> name=<span class="charliteral">"Text Editors"</span> schema=<span class="charliteral">"editors_schema.xsd"</span>/> - * <<a class="code" href="#pluginDescPluginEP">extension-point</a> id=<span class="charliteral">"url-families"</span>/> - * <<a class="code" href="#pluginDescPluginE">extension</a> point=<span class="charliteral">"org.c-pluff.util.archivers"</span> id=<span class="charliteral">"tar"</span> name=<span class="charliteral">"Tar Archiver Support"</span>> - * <type random-access=<span class="charliteral">"false"</span>/> - * <exec bin=<span class="charliteral">"tar"</span>/> - * </<a class="code" href="#pluginDescPluginE">extension</a>> - * <<a class="code" href="#pluginDescPluginE">extension</a> point=<span class="charliteral">"org.c-pluff.example.editors</span>> - * <editor name=<span class="charliteral">"Text Editor"</span> runtime=<span class="charliteral">"org_cpluff_example_txteditor_runtime"</span>> - * <file-types> - * <file-type mime-type=<span class="charliteral">"text/plain"</span>/> - * </file-types> - * </editor> - * </<a class="code" href="#pluginDescPluginE">extension</a>> - * </<a class="code" href="#pluginDescPlugin">plugin</a>></pre> - * </div> - * - * A descriptor can also be much simpler, depending on the plug-in. - * Here is an example of a minimal descriptor (of a useless plug-in). - * - * <div class="fragment"> - * <pre class="fragment"> - * <<a class="code" href="#pluginDescPlugin">plugin</a> id=<span class="charliteral">"org.c-pluff.useless"</span>/></pre> - * </div> - * - * @subsubsection pluginDescPlugin plugin - * - * This is the top level element of the plug-in descriptor. It can have - * following attributes. - * - * - @a id: A mandatory unique identifier for the plug-in. Plug-in identifiers - * should preferably be generated using a reversed DNS domain name as - * prefix to prevent identifier conflicts. - * - @a name: An optional human-readable name for the plug-in. - * - @a version: An optional version number for the plug-in. Version numbers - * are used for checking compatibility when resolving versioned plug-in - * dependencies. See also information about - * @ref pluginVersions "plug-in versions". - * - @a provider-name: The name of the plug-in provider or author. Optional. - * - * This element can contain following elements. - * - * - @ref pluginDescPluginBWC "backwards-compatibility": Optional information about backwards - * compatibility of this plug-in version. - * - @ref pluginDescPluginRequires "requires": Information about static plug-in dependencies. Can be omitted - * if the plug-in does not have static dependencies. - * - @ref pluginDescPluginRuntime "runtime": Information about the plug-in runtime library. Can be omitted - * if the plug-in does not have a runtime library but only data. - * - @ref pluginDescPluginEP "extension-point": Information about extension points provided by the - * plug-in. This element is repeated if there are multiple extension points - * and omitted if there are none. - * - @ref pluginDescPluginE "extension": Information about extensions provided by the plug-in. - * This element is repeated if there are multiple extensions and omitted - * if there are none. - * - * @subsubsection pluginDescPluginBWC backwards-compatibility - * - * This element includes optional information about the backwards compatibility - * of this plug-in version. It can have following attributes. - * - * - @a abi: Backwards compatibility of the application binary interface (ABI) - * of the plug-in. ABI includes any public symbols exported by the plug-in, - * data structures associated with exported symbols and any extension points - * provided by the plug-in. The ABI of the current plug-in version is - * backwards compatible with any plug-in version from the version specified - * here to the current version. This information is used when resolving - * versioned plug-in dependencies. See also information about - * @ref pluginVersions "plug-in versions". - * - @a api: Backwards compatibility of the application programming interface - * (API) of the plug-in. API compatibility means that source code developed - * against one version of the plug-in also compiles against another version - * of the plug-in. This information is not used by framework but it can be - * used by a developer developing dependent plug-ins. - * - * These apply to plug-ins that provide header files and runtime libraries. - * For example, a plug-in might export global functions to other plug-ins or it - * might provide an extension point where an extension installed by other - * plug-in must conform to data structures defined by the plug-in. - * Both attributes are optional. - * - * @subsubsection pluginDescPluginRequires requires - * - * This element includes information about static plug-in dependencies. - * It can be omitted if there are no dependencies. It can contain following - * elements. - * - * - @ref pluginDescPluginReqCP "c-pluff": An optional version dependency - * on the C-Pluff implementation. - * - @ref pluginDescPluginReqImport "import": Declares a static dependency - * on other plug-in. This element is repeated if there are multiple - * dependencies and omitted if there are none. - * - * @subsubsection pluginDescPluginReqCP c-pluff - * - * This element declares a version dependency on the C-Pluff - * implementation. It can be used to ensure that the plug-in is not loaded by - * incompatible C-Pluff version. It has the following attribute. - * - * - @a version: The required version of the C-Pluff implementation. - * This is used when resolving the plug-in. It is checked that the used - * C-Pluff implementation is backwards compatible with the version specified - * here when it comes to the application binary interface (ABI) of C-Pluff. - * - * @subsubsection pluginDescPluginReqImport import - * - * This element declares a static dependency on other plug-in. It must be - * used when a plug-in uses global symbols or data from other plug-in or when - * a plug-in uses an extension point defined by other plug-in or whenever some - * other plug-in needs to be there for the plug-in to work. The framework takes - * care of resolving and starting the dependencies whenever the plug-in is - * resolved or started. - * - * This element can have following attributes. - * - * - @a plugin: The identifier of the imported plug-in. - * - @a version: An optional version dependency on the imported plug-in. - * The plug-in can be resolved only if the version of the imported plug-in - * is backwards compatible with the version specified here when it comes - * to the application binary interface (ABI) of the imported plug-in. - * - @a optional: Is the import optional or not ("true" or "false"). Default is - * false, a mandatory import. - * An optional import behaves just like the mandatory import as long as the - * imported plug-in is present. However, if it is not present then the - * import is ignored. Optional import can be used if the plug-in works - * in limited capacity even without the specified plug-in. - * - * @subsubsection pluginDescPluginRuntime runtime - * - * This element contains information about the plug-in runtime library. It is - * omitted if the plug-in does not have a runtime library but contains only - * data. It can have following attributes. - * - * - @a library: The name of the plug-in runtime library in the plug-in - * directory. A platform specific extension (for example, ".so" or ".dll") - * is added to the value specified here when loading the library. - * - @a funcs: The functions to be used to create an instance of the plug-in - * runtime. This attribute is optional. It is needed if the plug-in has - * a start or stop function. The value specified here is a name of an - * exported symbol which contains a pointer to @ref cp_plugin_runtime_t - * structure. - * - * @subsubsection pluginDescPluginEP extension-point - * - * This element defines an extension point provided by the plug-in. - * It can have following attributes. - * - * - @a id: The local identifier of the extension point. The value specified - * here is prefixed with the identifier of the plug-in and dot to construct - * the global identifier of the extension point. - * - @a name: An optional human-readable name describing the use of the - * extension point. - * - @a schema: An optional path to the extension point XML schema in - * the plug-in directory. This information is not currently used by the - * framework. But it can be used by a developer to determine what information - * should be provided by extensions attached to this extension point. - * - * @subsubsection pluginDescPluginE extension - * - * This element defines an extension installed into a specified extension - * point provided by the defining plug-in or some other plug-in. - * It can have following attributes. - * - * - @a point: The global identifier of the associated extension point. - * - @a id: An optional local identifier for the extension. The value specified - * here is prefixed with the identifier of the plug-in and dot to construct - * the global identifier for the extension. - * - @a name: An optional human-readable name describing the extension. - * - * The extension element can contain XML elements specific to the associated - * extension point (conforming to the schema defined by the extension point). - * - * @subsection pluginRuntime Plug-in runtime library - * - * A plug-in runtime library is an optional plug-in element. Plug-ins only - * supplying static data in form of XML data and files do not need a runtime - * library. However, a typical plug-in does provide program logic as well. - * - * The plug-in runtime library includes all program logic and program - * data provided by the plug-in. It is simply a shared library, or a - * dynamically linked library, which is linked in to the application when - * the plug-in is started. When plug-in is unloaded, the runtime library is - * unloaded as well. The framework has been designed to manage dependencies - * so that unloading of the runtime library does not cause problems, provided - * that plug-ins behave properly. - * - * A plug-in can expose functionality to other plug-ins either as exported - * global symbols that are directly resolved by other plug-ins or by supplying - * extensions. When other plug-ins are directly using exported symbols the - * plug-in acts just like any standard shared library. Nothing special there. - * The more interesting case is exposing functionality as extensions. Because - * the extension is registered at a specific extension point, the logic in - * other plug-ins can use the extension and the associated program logic even - * if they are not aware of the existence of the extension supplying plug-in. - * - * The extension points accepting program logic as extensions define a way - * to specify the name of the symbol pointing to the supplied logic. This is - * typically an attribute of an XML element contained in the extension - * definition. The plug-in supplying the extension can then export the program - * logic as a global symbol with arbitrary name and then place the name of the - * symbol in extension data. Alternatively, the plug-in can define a virtual - * symbol at runtime using ::cp_define_symbol. Other plug-ins that are using - * extensions registered at the extension point can then resolve the named - * symbol using ::cp_resolve_symbol at runtime. The framework automatically - * creates a dependency from the symbol using plug-in to the symbol supplying - * plug-in to prevent failures in case the symbol supplying plug-in is stopped - * or unloaded. - * - * @subsection pluginData Static plug-in data - * - * Plug-in can supply static data to other plug-ins using at least two - * different mechanisms. A plug-in can easily provide static XML data as part - * of extension elements. Additionally, a plug-in directory can contain - * files that may be accessed by other plug-ins. Currently the platform does - * not provide assistance in accessing data files provided by other plug-ins. - * However, a plug-in can locate the plug-in directory and thus any included - * data files by using plug-in path available in @ref cp_plugin_info_t - * structure of the data providing plug-in. - */ diff --git a/lib/cpluff/libcpluff/internal.h b/lib/cpluff/libcpluff/internal.h deleted file mode 100644 index 5f5761750b..0000000000 --- a/lib/cpluff/libcpluff/internal.h +++ /dev/null @@ -1,576 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Internal data structures and declarations - */ - -#ifndef INTERNAL_H_ -#define INTERNAL_H_ - - -/* ------------------------------------------------------------------------ - * Inclusions - * ----------------------------------------------------------------------*/ - -#include "defines.h" -#include <assert.h> -#if defined(DLOPEN_POSIX) -#include <dlfcn.h> -#elif defined(DLOPEN_LIBTOOL) -#include <ltdl.h> -#endif -#include "../kazlib/list.h" -#include "../kazlib/hash.h" -#include "cpluff.h" -#ifdef CP_THREADS -#include "thread.h" -#endif - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -/* ------------------------------------------------------------------------ - * Constants - * ----------------------------------------------------------------------*/ - -/// Preliminarily OK -#define CP_OK_PRELIMINARY (-1) - -/// Callback function logger function -#define CPI_CF_LOGGER 1 - -/// Callback function plug-in listener function -#define CPI_CF_LISTENER 2 - -/// Callback function start function -#define CPI_CF_START 4 - -/// Callback function stop function -#define CPI_CF_STOP 8 - -/// Bitmask corresponding to any callback function -#define CPI_CF_ANY (~0) - -/// Logging limit for no logging -#define CP_LOG_NONE 1000 - - -/* ------------------------------------------------------------------------ - * Macros - * ----------------------------------------------------------------------*/ - -#if defined(_WIN32) -#define DLHANDLE void * -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) -#define DLOPEN(name) LoadPackagedLibrary(name, 0) -#else -#define DLOPEN(name) LoadLibraryA(name) -#endif -#define DLSYM(handle, symbol) GetProcAddress(handle, symbol) -#define DLCLOSE(handle) CloseHandle(handle) -#define DLERROR() "WIN32 - TODO" -#elif defined(DLOPEN_POSIX) -#define DLHANDLE void * -#define DLOPEN(name) dlopen((name), RTLD_LAZY | RTLD_GLOBAL) -#define DLSYM(handle, symbol) dlsym((handle), (symbol)) -#define DLCLOSE(handle) dlclose(handle) -#define DLERROR() dlerror() -#elif defined(DLOPEN_LIBTOOL) -#define DLHANDLE lt_dlhandle -#define DLOPEN(name) lt_dlopen(name) -#define DLSYM(handle, symbol) lt_dlsym((handle), (symbol)) -#define DLCLOSE(handle) lt_dlclose(handle) -#define DLERROR() lt_dlerror() -#endif - - -/** - * Checks that the specified function argument is not NULL. - * Otherwise, reports a fatal error. - * - * @param arg the argument - */ -#define CHECK_NOT_NULL(arg) do { if ((arg) == NULL) cpi_fatal_null_arg(#arg, __func__); } while (0) - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -typedef struct cp_plugin_t cp_plugin_t; -typedef struct cp_plugin_env_t cp_plugin_env_t; - -// Plug-in context -struct cp_context_t { - - /// The associated plug-in instance or NULL for the main program - cp_plugin_t *plugin; - - /// The associated plug-in environment - cp_plugin_env_t *env; - - /// Information about resolved symbols or NULL if not initialized - hash_t *resolved_symbols; - - /// Information about symbol providing plugins or NULL if not initialized - hash_t *symbol_providers; - -}; - -// Plug-in environment -struct cp_plugin_env_t { - -#if defined(CP_THREADS) - - /// Mutex for accessing this plug-in environment. - /// This mutex is signaled when a run function returns. - cpi_mutex_t *mutex; - -#elif !defined(NDEBUG) - int locked; -#endif - - /// Number of startup arguments - int argc; - - /// An array of startup arguments - char **argv; - - /// Installed plug-in listeners - list_t *plugin_listeners; - - /// Registered loggers - list_t *loggers; - - /// Minimum logger selection severity - int log_min_severity; - - /// List of registered plug-in directories - list_t *plugin_dirs; - - /// Map of in-use reference counter information object - hash_t *infos; - - /// Maps plug-in identifiers to plug-in state structures - hash_t *plugins; - - /// List of started plug-ins in the order they were started - list_t *started_plugins; - - /// Maps extension point names to installed extension points - hash_t *ext_points; - - /// Maps extension point names to installed extensions - hash_t *extensions; - - /// FIFO queue of run functions, currently running functions at front - list_t *run_funcs; - - /// First waiting run function, or NULL if none - lnode_t *run_wait; - - /// Is logger currently being invoked - int in_logger_invocation; - - /// Whether currently in event listener invocation - int in_event_listener_invocation; - - // Whether currently in start function invocation - int in_start_func_invocation; - - // Whether currently in stop function invocation - int in_stop_func_invocation; - - // Whether currently in create function invocation - int in_create_func_invocation; - - // Whether currently in destroy function invocation - int in_destroy_func_invocation; - -}; - -// Plug-in instance -struct cp_plugin_t { - - /// The enclosing context or NULL if none exists - cp_context_t *context; - - /// Plug-in information - cp_plugin_info_t *plugin; - - /// The current state of the plug-in - cp_plugin_state_t state; - - /// The set of imported plug-ins, or NULL if not resolved - list_t *imported; - - /// The set of plug-ins importing this plug-in - list_t *importing; - - /// The runtime library handle, or NULL if not resolved - DLHANDLE runtime_lib; - - /// Plug-in runtime function information, or NULL if not resolved - cp_plugin_runtime_t *runtime_funcs; - - /// Plug-in instance data or NULL if instance does not exist - void *plugin_data; - - /// Context specific symbols defined by the plug-in - hash_t *defined_symbols; - - /// Used by recursive operations: has this plug-in been processed already - int processed; - -}; - - -/** - * Deallocates a reference counted resource when the reference count drops - * to zero. The plug-in context is locked on call to the function. - * - * @param ctx the associated plug-in context - * @param resource the resource - */ -typedef void (*cpi_dealloc_func_t)(cp_context_t *ctx, void *resource); - -typedef struct cpi_plugin_event_t cpi_plugin_event_t; - -/// Plug-in event information -struct cpi_plugin_event_t { - - /// The affect plug-in - const char *plugin_id; - - /// Old state - cp_plugin_state_t old_state; - - /// New state - cp_plugin_state_t new_state; -}; - - -/* ------------------------------------------------------------------------ - * Function declarations - * ----------------------------------------------------------------------*/ - - -// Locking data structures for exclusive access - -#if defined(CP_THREADS) || !defined(NDEBUG) - -/** - * Acquires exclusive access to the framework. Thread having the framework - * lock must not acquire plug-in context lock (it is ok to retain a previously - * acquired plug-in context lock). - */ -CP_HIDDEN void cpi_lock_framework(void); - -/** - * Releases exclusive access to the framework. - */ -CP_HIDDEN void cpi_unlock_framework(void); - -/** - * Acquires exclusive access to a plug-in context and the associated - * plug-in environment. - * - * @param context the plug-in context - */ -CP_HIDDEN void cpi_lock_context(cp_context_t *context) CP_GCC_NONNULL(1); - -/** - * Releases exclusive access to a plug-in context. - * - * @param context the plug-in context - */ -CP_HIDDEN void cpi_unlock_context(cp_context_t *context) CP_GCC_NONNULL(1); - -/** - * Waits until the specified plug-in context is signalled. - * - * @param context the plug-in context - */ -CP_HIDDEN void cpi_wait_context(cp_context_t *context) CP_GCC_NONNULL(1); - -/** - * Signals the specified plug-in context. - * - * @param context the plug-in context - */ -CP_HIDDEN void cpi_signal_context(cp_context_t *context) CP_GCC_NONNULL(1); - -#else -#define cpi_lock_context(dummy) do {} while (0) -#define cpi_unlock_context(dummy) do {} while (0) -#define cpi_wait_context(dummy) do {} while (0) -#define cpi_signal_context(dummy) do {} while (0) -#define cpi_lock_framework() do {} while(0) -#define cpi_unlock_framework() do {} while(0) -#endif - -/** - * @def cpi_is_context_locked - * - * Returns whether the context is locked. This is intended to be used in - * assertions only and it is not defined if debugging is not enabled. - */ - -#ifndef NDEBUG -#ifdef CP_THREADS -#define cpi_is_context_locked(ctx) cpi_is_mutex_locked((ctx)->env->mutex) -#else -#define cpi_is_context_locked(ctx) ((ctx)->env->locked) -#endif -#endif - - -// Logging - -/** - * Logs a message. Calls dgettext for @a msg to localize it before delivering - * it to loggers. The caller must have locked the context. This - * function logs the message unconditionally. Use convenience macros - * @ref cpi_error, @ref cpi_warn, @ref cpi_info and @ref cpi_debug - * to log based on the minimum severity level logged. - * - * @param ctx the related plug-in context - * @param severity the severity of the message - * @param msg the localized message - */ -CP_HIDDEN void cpi_log(cp_context_t *ctx, cp_log_severity_t severity, const char *msg) CP_GCC_NONNULL(1, 3); - -/** - * Formats and logs a message. Calls dgettext for @a msg to localize it before - * formatting the message. The caller must have locked the context. This - * function logs the message unconditionally. Use convenience macros - * @ref cpi_errorf, @ref cpi_warnf, @ref cpi_infof and @ref cpi_debugf - * to log based on the minimum severity level logged. - * - * @param ctx the related plug-in context - * @param severity the severity of the message - * @param msg the localized message format - * @param ... the message parameters - */ -CP_HIDDEN void cpi_logf(cp_context_t *ctx, cp_log_severity_t severity, const char *msg, ...) CP_GCC_PRINTF(3, 4) CP_GCC_NONNULL(1, 3); - -/** - * Returns whether the messages of the specified severity level are - * being logged for the specified context. The caller must have locked the context. - * - * @param ctx the plug-in context - * @param severity the severity - * @return whether the messages of the specified severity level are logged - */ -#define cpi_is_logged(context, severity) (assert(cpi_is_context_locked(context)), (severity) >= (context)->env->log_min_severity) - -// Convenience macros for logging -#define cpi_log_cond(ctx, level, msg) do { if (cpi_is_logged((ctx), (level))) cpi_log((ctx), (level), (msg)); } while (0) -#define cpi_logf_cond(ctx, level, msg, ...) do { if (cpi_is_logged((ctx), (level))) cpi_logf((ctx), (level), (msg), __VA_ARGS__); } while (0) -#define cpi_error(ctx, msg) cpi_log_cond((ctx), CP_LOG_ERROR, (msg)) -#define cpi_errorf(ctx, msg, ...) cpi_logf_cond((ctx), CP_LOG_ERROR, (msg), __VA_ARGS__) -#define cpi_warn(ctx, msg) cpi_log_cond((ctx), CP_LOG_WARNING, (msg)) -#define cpi_warnf(ctx, msg, ...) cpi_logf_cond((ctx), CP_LOG_WARNING, (msg), __VA_ARGS__) -#define cpi_info(ctx, msg) cpi_log_cond((ctx), CP_LOG_INFO, (msg)) -#define cpi_infof(ctx, msg, ...) cpi_logf_cond((ctx), CP_LOG_INFO, (msg), __VA_ARGS__) -#define cpi_debug(ctx, msg) cpi_log_cond((ctx), CP_LOG_DEBUG, (msg)) -#define cpi_debugf(ctx, msg, ...) cpi_logf_cond((ctx), CP_LOG_DEBUG, (msg), __VA_ARGS__) - -/** - * Unregisters loggers in the specified logger list. Either unregisters all - * loggers or only loggers installed by the specified plug-in. - * - * @param loggers the logger list - * @param plugin the plug-in whose loggers to unregister or NULL for all - */ -CP_HIDDEN void cpi_unregister_loggers(list_t *loggers, cp_plugin_t *plugin) CP_GCC_NONNULL(1); - -/** - * Unregisters plug-in listeners in the specified list. Either unregisters all - * listeners or only listeners installed by the specified plug-in. - * - * @param listeners the listener list - * @param plugin the plug-in whose listeners to unregister or NULL for all - */ -CP_HIDDEN void cpi_unregister_plisteners(list_t *listeners, cp_plugin_t *plugin) CP_GCC_NONNULL(1); - -/** - * Returns the owner name for a context. - * - * @param ctx the context - * @param name the location where the name of the owner is to be stored - * @param size maximum size of the owner string, including the terminating zero - * @return the pointer passed in as @a name - */ -CP_HIDDEN char *cpi_context_owner(cp_context_t *ctx, char *name, size_t size) CP_GCC_NONNULL(1); - -/** - * Reports a fatal error. This method does not return. - * - * @param msg the formatted error message - * @param ... parameters - */ -CP_HIDDEN void cpi_fatalf(const char *msg, ...) CP_GCC_NORETURN CP_GCC_PRINTF(1, 2) CP_GCC_NONNULL(1); - -/** - * Reports a fatal NULL argument to an API function. - * - * @param arg the argument name - * @param func the API function name - */ -CP_HIDDEN void cpi_fatal_null_arg(const char *arg, const char *func) CP_GCC_NORETURN CP_GCC_NONNULL(1, 2); - -/** - * Checks that we are currently not in a specific callback function invocation. - * Otherwise, reports a fatal error. The caller must have locked the context - * before calling this function. - * - * @param ctx the associated plug-in context - * @param funcmask the bitmask of disallowed callback functions - * @param func the current plug-in framework function - */ -CP_HIDDEN void cpi_check_invocation(cp_context_t *ctx, int funcmask, const char *func) CP_GCC_NONNULL(1, 3); - - -// Context management - -/** - * Allocates a new plug-in context. - * - * @param plugin the associated plug-in or NULL for the client program - * @param env the associated plug-in environment - * @param status a pointer to the location where the status code is to be stored - * @return the newly allocated context or NULL on failure - */ -CP_HIDDEN cp_context_t * cpi_new_context(cp_plugin_t *plugin, cp_plugin_env_t *env, cp_status_t *status) CP_GCC_NONNULL(2, 3); - -/** - * Frees the resources associated with a plug-in context. Also frees the - * associated plug-in environment if the context is a client program plug-in - * context. - * - * @param context the plug-in context to free - */ -CP_HIDDEN void cpi_free_context(cp_context_t *context) CP_GCC_NONNULL(1); - -/** - * Destroys all contexts and releases the context list resources. - */ -CP_HIDDEN void cpi_destroy_all_contexts(void); - - -// Delivering plug-in events - -/** - * Delivers a plug-in event to registered event listeners. - * - * @param context the plug-in context - * @param event the plug-in event - */ -CP_HIDDEN void cpi_deliver_event(cp_context_t *context, const cpi_plugin_event_t *event) CP_GCC_NONNULL(1, 2); - - -// Plug-in management - -/** - * Frees any resources allocated for a plug-in description. - * - * @param plugin the plug-in to be freed - */ -CP_HIDDEN void cpi_free_plugin(cp_plugin_info_t *plugin) CP_GCC_NONNULL(1); - -/** - * Starts the specified plug-in and its dependencies. - * - * @param context the plug-in context - * @param plugin the plug-in - * @return @ref CP_OK (zero) on success or an error code on failure - */ -CP_HIDDEN cp_status_t cpi_start_plugin(cp_context_t *context, cp_plugin_t *plugin) CP_GCC_NONNULL(1, 2); - - -// Dynamic resource management - -/** - * Registers a new reference counted information object. - * Initializes the reference count to 1. The object is released and - * deallocated using the specified deallocation function @a df when its - * reference count becomes zero. Reference count is incresed by - * ::cpi_use_info and decreased by ::cp_release_info. The caller must have - * locked the plug-in context. - * - * @param ctx the associated plug-in context - * @param res the resource - * @param df the deallocation function - * @return @ref CP_OK (zero) on success or an error code on failure - */ -CP_HIDDEN cp_status_t cpi_register_info(cp_context_t *ctx, void *res, cpi_dealloc_func_t df) CP_GCC_NONNULL(1, 2, 3); - -/** - * Increases the reference count for the specified information object. - * The caller must have locked the plug-in context. - * - * @param ctx the plug-in context - * @param res the resource - */ -CP_HIDDEN void cpi_use_info(cp_context_t *ctx, void *res) CP_GCC_NONNULL(1, 2); - -/** - * Decreases the reference count for the specified information object. - * The caller must have locked the plug-in context. - * - * @param ctx the plug-in context - * @param res the resource - */ -CP_HIDDEN void cpi_release_info(cp_context_t *ctx, void *res) CP_GCC_NONNULL(1, 2); - -/** - * Checks for remaining information objects in the specified plug-in context. - * Does not destroy the infos hash. - * - * @param ctx the plug-in context - */ -CP_HIDDEN void cpi_release_infos(cp_context_t *ctx) CP_GCC_NONNULL(1); - - -// Serialized execution - -/** - * Waits for all the run functions registered by the specified plug-in to - * return and then unregisters them. The caller must have locked the - * associated context. - * - * @param plugin the plug-in to be stopped - */ -CP_HIDDEN void cpi_stop_plugin_run(cp_plugin_t *plugin) CP_GCC_NONNULL(1); - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif /*INTERNAL_H_*/ diff --git a/lib/cpluff/libcpluff/logging.c b/lib/cpluff/libcpluff/logging.c deleted file mode 100644 index f9871c9061..0000000000 --- a/lib/cpluff/libcpluff/logging.c +++ /dev/null @@ -1,262 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Logging functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -/// Contains information about installed loggers -typedef struct logger_t { - - /// Pointer to logger - cp_logger_func_t logger; - - /// Pointer to registering plug-in or NULL for the main program - cp_plugin_t *plugin; - - /// User data pointer - void *user_data; - - /// Minimum severity - cp_log_severity_t min_severity; - - /// Selected environment or NULL - cp_plugin_env_t *env_selection; -} logger_t; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -/** - * Updates the context logging limits. The caller must have locked the - * context. - */ -static void update_logging_limits(cp_context_t *context) { - lnode_t *node; - int nms = CP_LOG_NONE; - - node = list_first(context->env->loggers); - while (node != NULL) { - logger_t *lh = lnode_get(node); - if (lh->min_severity < nms) { - nms = lh->min_severity; - } - node = list_next(context->env->loggers, node); - } - context->env->log_min_severity = nms; -} - -static int comp_logger(const void *p1, const void *p2) { - const logger_t *l1 = p1; - const logger_t *l2 = p2; - return l1->logger != l2->logger; -} - -CP_C_API cp_status_t cp_register_logger(cp_context_t *context, cp_logger_func_t logger, void *user_data, cp_log_severity_t min_severity) { - logger_t l; - logger_t *lh = NULL; - lnode_t *node = NULL; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(logger); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - do { - - // Check if logger already exists and allocate new holder if necessary - l.logger = logger; - if ((node = list_find(context->env->loggers, &l, comp_logger)) == NULL) { - lh = malloc(sizeof(logger_t)); - node = lnode_create(lh); - if (lh == NULL || node == NULL) { - status = CP_ERR_RESOURCE; - break; - } - lh->logger = logger; - lh->plugin = context->plugin; - list_append(context->env->loggers, node); - } else { - lh = lnode_get(node); - } - - // Initialize or update the logger holder - lh->user_data = user_data; - lh->min_severity = min_severity; - - // Update global limits - update_logging_limits(context); - - } while (0); - - // Report error - if (status == CP_ERR_RESOURCE) { - cpi_error(context, N_("Logger could not be registered due to insufficient memory.")); - } else if (cpi_is_logged(context, CP_LOG_DEBUG)) { - char owner[64]; - /* TRANSLATORS: %s is the context owner */ - cpi_debugf(context, N_("%s registered a logger."), cpi_context_owner(context, owner, sizeof(owner))); - } - cpi_unlock_context(context); - - // Release resources on error - if (status != CP_OK) { - if (node != NULL) { - lnode_destroy(node); - } - if (lh != NULL) { - free(lh); - } - } - - return status; -} - -CP_C_API void cp_unregister_logger(cp_context_t *context, cp_logger_func_t logger) { - logger_t l; - lnode_t *node; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(logger); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - - l.logger = logger; - if ((node = list_find(context->env->loggers, &l, comp_logger)) != NULL) { - logger_t *lh = lnode_get(node); - list_delete(context->env->loggers, node); - lnode_destroy(node); - free(lh); - update_logging_limits(context); - } - if (cpi_is_logged(context, CP_LOG_DEBUG)) { - char owner[64]; - /* TRANSLATORS: %s is the context owner */ - cpi_debugf(context, N_("%s unregistered a logger."), cpi_context_owner(context, owner, sizeof(owner))); - } - cpi_unlock_context(context); -} - -static void do_log(cp_context_t *context, cp_log_severity_t severity, const char *msg) { - lnode_t *node; - const char *apid = NULL; - - assert(cpi_is_context_locked(context)); - if (context->env->in_logger_invocation) { - cpi_fatalf(_("Encountered a recursive logging request within a logger invocation.")); - } - if (context->plugin != NULL) { - apid = context->plugin->plugin->identifier; - } - context->env->in_logger_invocation++; - node = list_first(context->env->loggers); - while (node != NULL) { - logger_t *lh = lnode_get(node); - if (severity >= lh->min_severity) { - lh->logger(severity, msg, apid, lh->user_data); - } - node = list_next(context->env->loggers, node); - } - context->env->in_logger_invocation--; -} - -CP_HIDDEN void cpi_log(cp_context_t *context, cp_log_severity_t severity, const char *msg) { - assert(context != NULL); - assert(msg != NULL); - assert(severity >= CP_LOG_DEBUG && severity <= CP_LOG_ERROR); - do_log(context, severity, _(msg)); -} - -CP_HIDDEN void cpi_logf(cp_context_t *context, cp_log_severity_t severity, const char *msg, ...) { - char buffer[256]; - va_list va; - - assert(context != NULL); - assert(msg != NULL); - assert(severity >= CP_LOG_DEBUG && severity <= CP_LOG_ERROR); - - va_start(va, msg); - vsnprintf(buffer, sizeof(buffer), _(msg), va); - va_end(va); - strcpy(buffer + sizeof(buffer)/sizeof(char) - 4, "..."); - do_log(context, severity, buffer); -} - -static void process_unregister_logger(list_t *list, lnode_t *node, void *plugin) { - logger_t *lh = lnode_get(node); - if (plugin == NULL || lh->plugin == plugin) { - list_delete(list, node); - lnode_destroy(node); - free(lh); - } -} - -CP_HIDDEN void cpi_unregister_loggers(list_t *loggers, cp_plugin_t *plugin) { - list_process(loggers, plugin, process_unregister_logger); -} - -CP_C_API void cp_log(cp_context_t *context, cp_log_severity_t severity, const char *msg) { - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(msg); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - if (severity < CP_LOG_DEBUG || severity > CP_LOG_ERROR) { - cpi_fatalf(_("Illegal severity value in call to %s."), __func__); - } - if (cpi_is_logged(context, severity)) { - do_log(context, severity, msg); - } - cpi_unlock_context(context); -} - -CP_C_API int cp_is_logged(cp_context_t *context, cp_log_severity_t severity) { - int is_logged; - - CHECK_NOT_NULL(context); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - is_logged = cpi_is_logged(context, severity); - cpi_unlock_context(context); - return is_logged; -} diff --git a/lib/cpluff/libcpluff/pcontrol.c b/lib/cpluff/libcpluff/pcontrol.c deleted file mode 100644 index 2f475910ff..0000000000 --- a/lib/cpluff/libcpluff/pcontrol.c +++ /dev/null @@ -1,1243 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Core plug-in management functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> -#include <stddef.h> -#include "../kazlib/list.h" -#include "../kazlib/hash.h" -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" -#ifdef _WIN32 -#include <windows.h> -#endif - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -// Plug-in control - -#ifndef NDEBUG -static void assert_processed_zero(cp_context_t *context) { - hscan_t scan; - hnode_t *node; - - hash_scan_begin(&scan, context->env->plugins); - while ((node = hash_scan_next(&scan)) != NULL) { - cp_plugin_t *plugin = hnode_get(node); - assert(plugin->processed == 0); - } -} -#else -#define assert_processed_zero(c) assert(1) -#endif - -static void unregister_extensions(cp_context_t *context, cp_plugin_info_t *plugin) { - unsigned int i; - - for (i = 0; i < plugin->num_ext_points; i++) { - cp_ext_point_t *ep = plugin->ext_points + i; - hnode_t *hnode; - - if ((hnode = hash_lookup(context->env->ext_points, ep->identifier)) != NULL - && hnode_get(hnode) == ep) { - hash_delete_free(context->env->ext_points, hnode); - } - } - for (i = 0; i < plugin->num_extensions; i++) { - cp_extension_t *e = plugin->extensions + i; - hnode_t *hnode; - - if ((hnode = hash_lookup(context->env->extensions, e->ext_point_id)) != NULL) { - list_t *el = hnode_get(hnode); - lnode_t *lnode = list_first(el); - - while (lnode != NULL) { - lnode_t *nn = list_next(el, lnode); - if (lnode_get(lnode) == e) { - list_delete(el, lnode); - lnode_destroy(lnode); - break; - } - lnode = nn; - } - if (list_isempty(el)) { - char *epid = (char *) hnode_getkey(hnode); - hash_delete_free(context->env->extensions, hnode); - free(epid); - list_destroy(el); - } - } - } -} - -CP_C_API cp_status_t cp_install_plugin(cp_context_t *context, cp_plugin_info_t *plugin) { - cp_plugin_t *rp = NULL; - cp_status_t status = CP_OK; - cpi_plugin_event_t event; - unsigned int i; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(plugin); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - do { - - // Check that there is no conflicting plug-in already loaded - if (hash_lookup(context->env->plugins, plugin->identifier) != NULL) { - cpi_errorf(context, - N_("Plug-in %s could not be installed because a plug-in with the same identifier is already installed."), - plugin->identifier); - status = CP_ERR_CONFLICT; - break; - } - - // Increase usage count for the plug-in descriptor - cpi_use_info(context, plugin); - - // Allocate space for the plug-in state - if ((rp = malloc(sizeof(cp_plugin_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Initialize plug-in state - memset(rp, 0, sizeof(cp_plugin_t)); - rp->context = NULL; - rp->plugin = plugin; - rp->state = CP_PLUGIN_INSTALLED; - rp->imported = NULL; - rp->runtime_lib = NULL; - rp->runtime_funcs = NULL; - rp->plugin_data = NULL; - rp->importing = list_create(LISTCOUNT_T_MAX); - if (rp->importing == NULL) { - status = CP_ERR_RESOURCE; - break; - } - if (!hash_alloc_insert(context->env->plugins, plugin->identifier, rp)) { - status = CP_ERR_RESOURCE; - break; - } - - // Register extension points - for (i = 0; status == CP_OK && i < plugin->num_ext_points; i++) { - cp_ext_point_t *ep = plugin->ext_points + i; - hnode_t *hnode; - - if ((hnode = hash_lookup(context->env->ext_points, ep->identifier)) != NULL) { - cpi_errorf(context, N_("Plug-in %s could not be installed because extension point %s conflicts with an already installed extension point."), plugin->identifier, ep->identifier); - status = CP_ERR_CONFLICT; - } else if (!hash_alloc_insert(context->env->ext_points, ep->identifier, ep)) { - status = CP_ERR_RESOURCE; - } - } - - // Register extensions - for (i = 0; status == CP_OK && i < plugin->num_extensions; i++) { - cp_extension_t *e = plugin->extensions + i; - hnode_t *hnode; - lnode_t *lnode; - list_t *el; - - if ((hnode = hash_lookup(context->env->extensions, e->ext_point_id)) == NULL) { - char *epid; - if ((el = list_create(LISTCOUNT_T_MAX)) != NULL - && (epid = strdup(e->ext_point_id)) != NULL) { - if (!hash_alloc_insert(context->env->extensions, epid, el)) { - list_destroy(el); - status = CP_ERR_RESOURCE; - break; - } - } else { - if (el != NULL) { - list_destroy(el); - } - status = CP_ERR_RESOURCE; - break; - } - } else { - el = hnode_get(hnode); - } - if ((lnode = lnode_create(e)) != NULL) { - list_append(el, lnode); - } else { - status = CP_ERR_RESOURCE; - break; - } - } - - // Break if previous loops failed - if (status != CP_OK) { - break; - } - - // Plug-in installed - event.plugin_id = plugin->identifier; - event.old_state = CP_PLUGIN_UNINSTALLED; - event.new_state = rp->state; - cpi_deliver_event(context, &event); - - } while (0); - - // Release resources on failure - if (status != CP_OK) { - if (rp != NULL) { - if (rp->importing != NULL) { - list_destroy(rp->importing); - } - free(rp); - } - unregister_extensions(context, plugin); - } - - // Report possible resource error - if (status == CP_ERR_RESOURCE) { - cpi_errorf(context, - N_("Plug-in %s could not be installed due to insufficient system resources."), plugin->identifier); - } - cpi_unlock_context(context); - - return status; -} - -/** - * Unresolves the plug-in runtime information. - * - * @param plugin the plug-in to unresolve - */ -static void unresolve_plugin_runtime(cp_plugin_t *plugin) { - - // Destroy the plug-in instance, if necessary - if (plugin->context != NULL) { - plugin->context->env->in_destroy_func_invocation++; - plugin->runtime_funcs->destroy(plugin->plugin_data); - plugin->context->env->in_destroy_func_invocation--; - plugin->plugin_data = NULL; - cpi_free_context(plugin->context); - plugin->context = NULL; - } - - // Close plug-in runtime library - plugin->runtime_funcs = NULL; - if (plugin->runtime_lib != NULL) { - DLCLOSE(plugin->runtime_lib); - plugin->runtime_lib = NULL; - } -} - -/** - * Loads and resolves the plug-in runtime library and initialization functions. - * - * @param context the plug-in context - * @param plugin the plugin - * @return CP_OK (zero) on success or error code on failure - */ -static int resolve_plugin_runtime(cp_context_t *context, cp_plugin_t *plugin) { - char *rlpath = NULL; - int rlpath_len; - cp_status_t status = CP_OK; - - assert(plugin->runtime_lib == NULL); - if (plugin->plugin->runtime_lib_name == NULL) { - return CP_OK; - } - - do { - int ppath_len, lname_len; - int cpluff_compatibility = 1; - - // Check C-Pluff compatibility - if (plugin->plugin->req_cpluff_version != NULL) { -#ifdef CP_ABI_COMPATIBILITY - cpluff_compatibility = ( - cpi_vercmp(plugin->plugin->req_cpluff_version, CP_VERSION) <= 0 - && cpi_vercmp(plugin->plugin->req_cpluff_version, CP_ABI_COMPATIBILITY) >= 0); -#else - cpluff_compatibility = (cpi_vercmp(plugin->plugin->req_cpluff_version, CP_VERSION) == 0); -#endif - } - if (!cpluff_compatibility) { - cpi_errorf(context, N_("Plug-in %s could not be resolved due to version incompatibility with C-Pluff."), plugin->plugin->identifier); - status = CP_ERR_DEPENDENCY; - break; - } - - // Construct a path to plug-in runtime library. - /// @todo Add platform specific prefix (for example, "lib") - ppath_len = strlen(plugin->plugin->plugin_path); - lname_len = strlen(plugin->plugin->runtime_lib_name); - rlpath_len = ppath_len + lname_len + strlen(CP_SHREXT) + 2; - if ((rlpath = malloc(rlpath_len * sizeof(char))) == NULL) { - cpi_errorf(context, N_("Plug-in %s runtime library could not be loaded due to insufficient memory."), plugin->plugin->identifier); - status = CP_ERR_RESOURCE; - break; - } - memset(rlpath, 0, rlpath_len * sizeof(char)); - strcpy(rlpath, plugin->plugin->plugin_path); - rlpath[ppath_len] = CP_FNAMESEP_CHAR; - strcpy(rlpath + ppath_len + 1, plugin->plugin->runtime_lib_name); - strcpy(rlpath + ppath_len + 1 + lname_len, CP_SHREXT); - - // Open the plug-in runtime library - plugin->runtime_lib = DLOPEN(rlpath); - if (plugin->runtime_lib == NULL) { - const char *error = DLERROR(); - if (error == NULL) { - error = _("Unspecified error."); - } - cpi_errorf(context, N_("Plug-in %s runtime library %s could not be opened: %s"), plugin->plugin->identifier, rlpath, error); - status = CP_ERR_RUNTIME; - break; - } - - // Resolve plug-in functions - if (plugin->plugin->runtime_funcs_symbol != NULL) { - plugin->runtime_funcs = (cp_plugin_runtime_t *) DLSYM(plugin->runtime_lib, plugin->plugin->runtime_funcs_symbol); - if (plugin->runtime_funcs == NULL) { - const char *error = DLERROR(); - if (error == NULL) { - error = _("Unspecified error."); - } - cpi_errorf(context, N_("Plug-in %s symbol %s containing plug-in runtime information could not be resolved: %s"), plugin->plugin->identifier, plugin->plugin->runtime_funcs_symbol, error); - status = CP_ERR_RUNTIME; - break; - } - if (plugin->runtime_funcs->create == NULL - || plugin->runtime_funcs->destroy == NULL) { - cpi_errorf(context, N_("Plug-in %s is missing a constructor or destructor function."), plugin->plugin->identifier); - status = CP_ERR_RUNTIME; - break; - } - } - - } while (0); - - // Release resources - free(rlpath); - if (status != CP_OK) { - unresolve_plugin_runtime(plugin); - } - - return status; -} - -/** - * Resolves the specified plug-in import into a plug-in pointer. Does not - * try to resolve the imported plug-in. - * - * @param context the plug-in context - * @param plugin the plug-in being resolved - * @param import the plug-in import to resolve - * @param ipptr filled with pointer to the resolved plug-in or NULL - * @return CP_OK on success or error code on failure - */ -static int resolve_plugin_import(cp_context_t *context, cp_plugin_t *plugin, cp_plugin_import_t *import, cp_plugin_t **ipptr) { - cp_plugin_t *ip = NULL; - hnode_t *node; - - // Lookup the plug-in - node = hash_lookup(context->env->plugins, import->plugin_id); - if (node != NULL) { - ip = hnode_get(node); - } - - // Check plug-in version - if (ip != NULL - && import->version != NULL - && (ip->plugin->version == NULL - || (ip->plugin->abi_bw_compatibility == NULL - && cpi_vercmp(import->version, ip->plugin->version) != 0) - || (ip->plugin->abi_bw_compatibility != NULL - && (cpi_vercmp(import->version, ip->plugin->version) > 0 - || cpi_vercmp(import->version, ip->plugin->abi_bw_compatibility) < 0)))) { - cpi_errorf(context, - N_("Plug-in %s could not be resolved due to version incompatibility with plug-in %s."), - plugin->plugin->identifier, - import->plugin_id); - *ipptr = NULL; - return CP_ERR_DEPENDENCY; - } - - // Check if missing mandatory plug-in - if (ip == NULL && !import->optional) { - cpi_errorf(context, - N_("Plug-in %s could not be resolved because it depends on plug-in %s which is not installed."), - plugin->plugin->identifier, - import->plugin_id); - *ipptr = NULL; - return CP_ERR_DEPENDENCY; - } - - // Return imported plug-in - *ipptr = ip; - return CP_OK; -} - -/** - * Resolves the specified plug-in and its dependencies while leaving plug-ins - * with circular dependencies in a preliminarily resolved state. - * - * @param context the plug-in context - * @param plugin the plug-in - * @return CP_OK (zero) or CP_OK_PRELIMINARY or an error code - */ -static int resolve_plugin_prel_rec(cp_context_t *context, cp_plugin_t *plugin) { - cp_status_t status = CP_OK; - int error_reported = 0; - lnode_t *node = NULL; - unsigned int i; - - // Check if already resolved - if (plugin->state >= CP_PLUGIN_RESOLVED) { - return CP_OK; - } - - // Check for dependency loops - if (plugin->processed) { - return CP_OK_PRELIMINARY; - } - plugin->processed = 1; - - do { - - // Recursively resolve the imported plug-ins - assert(plugin->imported == NULL); - if ((plugin->imported = list_create(LISTCOUNT_T_MAX)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - for (i = 0; i < plugin->plugin->num_imports; i++) { - cp_plugin_t *ip; - int s; - - if ((node = lnode_create(NULL)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - if ((s = resolve_plugin_import(context, plugin, plugin->plugin->imports + i, &ip)) != CP_OK) { - error_reported = 1; - status = s; - break; - } - if (ip != NULL) { - lnode_put(node, ip); - list_append(plugin->imported, node); - node = NULL; - if (!cpi_ptrset_add(ip->importing, plugin)) { - status = CP_ERR_RESOURCE; - break; - } else if ((s = resolve_plugin_prel_rec(context, ip)) != CP_OK && s != CP_OK_PRELIMINARY) { - cpi_errorf(context, N_("Plug-in %s could not be resolved because it depends on plug-in %s which could not be resolved."), plugin->plugin->identifier, ip->plugin->identifier); - error_reported = 1; - status = s; - break; - } - } else { - lnode_destroy(node); - node = NULL; - } - } - if (status != CP_OK) { - break; - } - - // Resolve this plug-in - assert(plugin->state == CP_PLUGIN_INSTALLED); - if ((i = resolve_plugin_runtime(context, plugin)) != CP_OK) { - status = i; - error_reported = 1; - break; - } - - // Notify event listeners and update state if completely resolved - if (status == CP_OK) { - cpi_plugin_event_t event; - - plugin->processed = 0; - event.plugin_id = plugin->plugin->identifier; - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_RESOLVED; - cpi_deliver_event(context, &event); - } - - } while (0); - - // Clean up - if (node != NULL) { - lnode_destroy(node); - } - - // Handle errors - if (status == CP_ERR_RESOURCE && !error_reported) { - cpi_errorf(context, N_("Plug-in %s could not be resolved because of insufficient memory."), plugin->plugin->identifier); - } - - return status; -} - -/** - * Recursively commits the resolving process for the specified plug-in and - * its dependencies. - * - * @param context the plug-in context - * @param plugin the plug-in - */ -static void resolve_plugin_commit_rec(cp_context_t *context, cp_plugin_t *plugin) { - - // Check if already committed - if (!plugin->processed) { - return; - } - plugin->processed = 0; - - // Commit if only preliminarily resolved - if (plugin->state < CP_PLUGIN_RESOLVED) { - cpi_plugin_event_t event; - lnode_t *node; - - // Recursively commit dependencies - node = list_first(plugin->imported); - while (node != NULL) { - resolve_plugin_commit_rec(context, (cp_plugin_t *) lnode_get(node)); - node = list_next(plugin->imported, node); - } - - // Notify event listeners and update state - event.plugin_id = plugin->plugin->identifier; - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_RESOLVED; - cpi_deliver_event(context, &event); - } -} - -/** - * Recursively cleans up the specified plug-in and its dependencies after - * a failed resolving attempt. - * - * @param plugin the plug-in - */ -static void resolve_plugin_failed_rec(cp_plugin_t *plugin) { - - // Check if already cleaned up - if (!plugin->processed) { - return; - } - plugin->processed = 0; - - // Clean up if only preliminarily resolved - if (plugin->state < CP_PLUGIN_RESOLVED) { - lnode_t *node; - - // Recursively clean up depedencies - while ((node = list_first(plugin->imported)) != NULL) { - cp_plugin_t *ip = lnode_get(node); - - resolve_plugin_failed_rec(ip); - cpi_ptrset_remove(ip->importing, plugin); - list_delete(plugin->imported, node); - lnode_destroy(node); - } - list_destroy(plugin->imported); - plugin->imported = NULL; - } -} - -/** - * Resolves the specified plug-in and its dependencies. - * - * @param context the plug-in context - * @param plugin the plug-in to be resolved - * @return CP_OK (zero) on success or an error code on failure - */ -static int resolve_plugin(cp_context_t *context, cp_plugin_t *plugin) { - cp_status_t status; - - if ((status = resolve_plugin_prel_rec(context, plugin)) == CP_OK || status == CP_OK_PRELIMINARY) { - status = CP_OK; - resolve_plugin_commit_rec(context, plugin); - } else { - resolve_plugin_failed_rec(plugin); - } - assert_processed_zero(context); - return status; -} - -/** - * Starts the plug-in runtime of the specified plug-in. This function does - * not consider dependencies and assumes that the plug-in is resolved but - * not yet started. - * - * @param context the plug-in context - * @param plugin the plug-in - * @return CP_OK (zero) on success or an error code on failure - */ -static int start_plugin_runtime(cp_context_t *context, cp_plugin_t *plugin) { - cp_status_t status = CP_OK; - cpi_plugin_event_t event; - lnode_t *node = NULL; - - event.plugin_id = plugin->plugin->identifier; - do { - - // Allocate space for the list node - node = lnode_create(plugin); - if (node == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Set up plug-in instance - if (plugin->runtime_funcs != NULL) { - - // Create plug-in instance if necessary - if (plugin->context == NULL) { - if ((plugin->context = cpi_new_context(plugin, context->env, &status)) == NULL) { - break; - } - context->env->in_create_func_invocation++; - plugin->plugin_data = plugin->runtime_funcs->create(plugin->context); - context->env->in_create_func_invocation--; - if (plugin->plugin_data == NULL) { - status = CP_ERR_RUNTIME; - break; - } - } - - // Start plug-in - if (plugin->runtime_funcs->start != NULL) { - int s; - - // About to start the plug-in - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_STARTING; - cpi_deliver_event(context, &event); - - // Start the plug-in - context->env->in_start_func_invocation++; - s = plugin->runtime_funcs->start(plugin->plugin_data); - context->env->in_start_func_invocation--; - - if (s != CP_OK) { - - // Roll back plug-in state - if (plugin->runtime_funcs->stop != NULL) { - - // Update state - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_STOPPING; - cpi_deliver_event(context, &event); - - // Call stop function - context->env->in_stop_func_invocation++; - plugin->runtime_funcs->stop(plugin->plugin_data); - context->env->in_stop_func_invocation--; - } - - // Destroy plug-in object - context->env->in_destroy_func_invocation++; - plugin->runtime_funcs->destroy(plugin->plugin_data); - context->env->in_destroy_func_invocation--; - - status = CP_ERR_RUNTIME; - break; - } - } - } - - // Plug-in active - list_append(context->env->started_plugins, node); - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_ACTIVE; - cpi_deliver_event(context, &event); - - } while (0); - - // Release resources and roll back plug-in state on failure - if (status != CP_OK) { - if (node != NULL) { - lnode_destroy(node); - } - if (plugin->context != NULL) { - cpi_free_context(plugin->context); - plugin->context = NULL; - } - if (plugin->state != CP_PLUGIN_RESOLVED) { - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_RESOLVED; - cpi_deliver_event(context, &event); - } - plugin->plugin_data = NULL; - } - - // Report error on failure - switch (status) { - case CP_ERR_RESOURCE: - cpi_errorf(context, - N_("Plug-in %s could not be started due to insufficient memory."), - plugin->plugin->identifier); - break; - case CP_ERR_RUNTIME: - cpi_errorf(context, - N_("Plug-in %s failed to start due to plug-in runtime error."), - plugin->plugin->identifier); - break; - default: - break; - } - - return status; -} - -static void warn_dependency_loop(cp_context_t *context, cp_plugin_t *plugin, list_t *importing, int dynamic) { - char *msgbase; - char *msg; - int msgsize; - lnode_t *node; - - // Take the message base - if (dynamic) { - msgbase = N_("Detected a runtime plug-in dependency loop: %s"); - } else { - msgbase = N_("Detected a static plug-in dependency loop: %s"); - } - - // Calculate the required message space - msgsize = 0; - msgsize += strlen(plugin->plugin->identifier); - msgsize += 2; - node = list_last(importing); - while (node != NULL) { - cp_plugin_t *p = lnode_get(node); - if (p == plugin) { - break; - } - msgsize += strlen(p->plugin->identifier); - msgsize += 2; - node = list_prev(importing, node); - } - msg = malloc(sizeof(char) * msgsize); - if (msg != NULL) { - strcpy(msg, plugin->plugin->identifier); - node = list_last(importing); - while (node != NULL) { - cp_plugin_t *p = lnode_get(node); - if (p == plugin) { - break; - } - strcat(msg, ", "); - strcat(msg, p->plugin->identifier); - node = list_prev(importing, node); - } - strcat(msg, "."); - cpi_infof(context, msgbase, msg); - free(msg); - } else { - cpi_infof(context, msgbase, plugin->plugin->identifier); - } -} - -/** - * Starts the specified plug-in and its dependencies. - * - * @param context the plug-in context - * @param plugin the plug-in - * @param importing stack of importing plug-ins - * @return CP_OK (zero) on success or an error code on failure - */ -static int start_plugin_rec(cp_context_t *context, cp_plugin_t *plugin, list_t *importing) { - cp_status_t status = CP_OK; - lnode_t *node; - - // Check if already started or starting - if (plugin->state == CP_PLUGIN_ACTIVE) { - return CP_OK; - } else if (plugin->state == CP_PLUGIN_STARTING) { - warn_dependency_loop(context, plugin, importing, 1); - return CP_OK; - } - assert(plugin->state == CP_PLUGIN_RESOLVED); - - // Check for dependency loops - if (cpi_ptrset_contains(importing, plugin)) { - warn_dependency_loop(context, plugin, importing, 0); - return CP_OK; - } - if (!cpi_ptrset_add(importing, plugin)) { - cpi_errorf(context, - N_("Plug-in %s could not be started due to insufficient memory."), - plugin->plugin->identifier); - return CP_ERR_RESOURCE; - } - - // Start up dependencies - node = list_first(plugin->imported); - while (node != NULL) { - cp_plugin_t *ip = lnode_get(node); - - if ((status = start_plugin_rec(context, ip, importing)) != CP_OK) { - break; - } - node = list_next(plugin->imported, node); - } - cpi_ptrset_remove(importing, plugin); - - // Start up this plug-in - if (status == CP_OK) { - status = start_plugin_runtime(context, plugin); - } - - return status; -} - -CP_HIDDEN cp_status_t cpi_start_plugin(cp_context_t *context, cp_plugin_t *plugin) { - cp_status_t status; - - if ((status = resolve_plugin(context, plugin)) == CP_OK) { - list_t *importing = list_create(LISTCOUNT_T_MAX); - if (importing != NULL) { - status = start_plugin_rec(context, plugin, importing); - assert(list_isempty(importing)); - list_destroy(importing); - } else { - cpi_errorf(context, - N_("Plug-in %s could not be started due to insufficient memory."), - plugin->plugin->identifier); - status = CP_ERR_RESOURCE; - } - } - return status; -} - -CP_C_API cp_status_t cp_start_plugin(cp_context_t *context, const char *id) { - hnode_t *node; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(id); - - // Look up and start the plug-in - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - node = hash_lookup(context->env->plugins, id); - if (node != NULL) { - status = cpi_start_plugin(context, hnode_get(node)); - } else { - cpi_warnf(context, N_("Unknown plug-in %s could not be started."), id); - status = CP_ERR_UNKNOWN; - } - cpi_unlock_context(context); - - return status; -} - -/** - * Stops the plug-in runtime of the specified plug-in. This function does - * not consider dependencies and assumes that the plug-in is active. - * - * @param context the plug-in context - * @param plugin the plug-in - */ -static void stop_plugin_runtime(cp_context_t *context, cp_plugin_t *plugin) { - cpi_plugin_event_t event; - - // Destroy plug-in instance - event.plugin_id = plugin->plugin->identifier; - if (plugin->context != NULL) { - - // Wait until possible run functions have stopped - cpi_stop_plugin_run(plugin); - - // Stop the plug-in - if (plugin->runtime_funcs->stop != NULL) { - - // About to stop the plug-in - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_STOPPING; - cpi_deliver_event(context, &event); - - // Invoke stop function - context->env->in_stop_func_invocation++; - plugin->runtime_funcs->stop(plugin->plugin_data); - context->env->in_stop_func_invocation--; - - } - - // Unregister all logger functions - cpi_unregister_loggers(plugin->context->env->loggers, plugin); - - // Unregister all plug-in listeners - cpi_unregister_plisteners(plugin->context->env->plugin_listeners, plugin); - - // Release resolved symbols - if (plugin->context->resolved_symbols != NULL) { - while (!hash_isempty(plugin->context->resolved_symbols)) { - hscan_t scan; - hnode_t *node; - const void *ptr; - - hash_scan_begin(&scan, plugin->context->resolved_symbols); - node = hash_scan_next(&scan); - ptr = hnode_getkey(node); - cp_release_symbol(context, ptr); - } - assert(hash_isempty(plugin->context->resolved_symbols)); - } - if (plugin->context->symbol_providers != NULL) { - assert(hash_isempty(plugin->context->symbol_providers)); - } - - // Release defined symbols - if (plugin->defined_symbols != NULL) { - hscan_t scan; - hnode_t *node; - - hash_scan_begin(&scan, plugin->defined_symbols); - while ((node = hash_scan_next(&scan)) != NULL) { - char *n = (char *) hnode_getkey(node); - hash_scan_delfree(plugin->defined_symbols, node); - free(n); - } - hash_destroy(plugin->defined_symbols); - plugin->defined_symbols = NULL; - } - - } - - // Plug-in stopped - cpi_ptrset_remove(context->env->started_plugins, plugin); - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_RESOLVED; - cpi_deliver_event(context, &event); -} - -/** - * Stops the plug-in and all plug-ins depending on it. - * - * @param context the plug-in context - * @param plugin the plug-in - */ -static void stop_plugin_rec(cp_context_t *context, cp_plugin_t *plugin) { - lnode_t *node; - - // Check if already stopped - if (plugin->state < CP_PLUGIN_ACTIVE) { - return; - } - - // Check for dependency loops - if (plugin->processed) { - return; - } - plugin->processed = 1; - - // Stop the depending plug-ins - node = list_first(plugin->importing); - while (node != NULL) { - stop_plugin_rec(context, lnode_get(node)); - node = list_next(plugin->importing, node); - } - - // Stop this plug-in - assert(plugin->state == CP_PLUGIN_ACTIVE); - stop_plugin_runtime(context, plugin); - assert(plugin->state < CP_PLUGIN_ACTIVE); - - // Clear processed flag - plugin->processed = 0; -} - -static void stop_plugin(cp_context_t *context, cp_plugin_t *plugin) { - stop_plugin_rec(context, plugin); - assert_processed_zero(context); -} - -CP_C_API cp_status_t cp_stop_plugin(cp_context_t *context, const char *id) { - hnode_t *node; - cp_plugin_t *plugin; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(id); - - // Look up and stop the plug-in - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - node = hash_lookup(context->env->plugins, id); - if (node != NULL) { - plugin = hnode_get(node); - stop_plugin(context, plugin); - } else { - cpi_warnf(context, N_("Unknown plug-in %s could not be stopped."), id); - status = CP_ERR_UNKNOWN; - } - cpi_unlock_context(context); - - return status; -} - -CP_C_API void cp_stop_plugins(cp_context_t *context) { - lnode_t *node; - - CHECK_NOT_NULL(context); - - // Stop the active plug-ins in the reverse order they were started - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - while ((node = list_last(context->env->started_plugins)) != NULL) { - stop_plugin(context, lnode_get(node)); - } - cpi_unlock_context(context); -} - -static void unresolve_plugin_rec(cp_context_t *context, cp_plugin_t *plugin) { - lnode_t *node; - cpi_plugin_event_t event; - - // Check if already unresolved - if (plugin->state < CP_PLUGIN_RESOLVED) { - return; - } - assert(plugin->state == CP_PLUGIN_RESOLVED); - - // Clear the list of imported plug-ins (also breaks dependency loops) - while ((node = list_first(plugin->imported)) != NULL) { - cp_plugin_t *ip = lnode_get(node); - - cpi_ptrset_remove(ip->importing, plugin); - list_delete(plugin->imported, node); - lnode_destroy(node); - } - assert(list_isempty(plugin->imported)); - list_destroy(plugin->imported); - plugin->imported = NULL; - - // Unresolve depending plugins - while ((node = list_first(plugin->importing)) != NULL) { - unresolve_plugin_rec(context, lnode_get(node)); - } - - // Unresolve this plug-in - unresolve_plugin_runtime(plugin); - event.plugin_id = plugin->plugin->identifier; - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_INSTALLED; - cpi_deliver_event(context, &event); -} - -/** - * Unresolves a plug-in. - * - * @param context the plug-in context - * @param plug-in the plug-in to be unresolved - */ -static void unresolve_plugin(cp_context_t *context, cp_plugin_t *plugin) { - stop_plugin(context, plugin); - unresolve_plugin_rec(context, plugin); -} - -static void free_plugin_import_content(cp_plugin_import_t *import) { - assert(import != NULL); - free(import->plugin_id); - free(import->version); -} - -static void free_ext_point_content(cp_ext_point_t *ext_point) { - free(ext_point->name); - free(ext_point->local_id); - free(ext_point->identifier); - free(ext_point->schema_path); -} - -static void free_extension_content(cp_extension_t *extension) { - free(extension->name); - free(extension->local_id); - free(extension->identifier); - free(extension->ext_point_id); -} - -static void free_cfg_element_content(cp_cfg_element_t *ce) { - unsigned int i; - - assert(ce != NULL); - free(ce->name); - if (ce->atts != NULL) { - free(ce->atts[0]); - free(ce->atts); - } - free(ce->value); - for (i = 0; i < ce->num_children; i++) { - free_cfg_element_content(ce->children + i); - } - free(ce->children); -} - -CP_HIDDEN void cpi_free_plugin(cp_plugin_info_t *plugin) { - unsigned int i; - - assert(plugin != NULL); - free(plugin->name); - free(plugin->identifier); - free(plugin->version); - free(plugin->provider_name); - free(plugin->plugin_path); - free(plugin->abi_bw_compatibility); - free(plugin->api_bw_compatibility); - free(plugin->req_cpluff_version); - for (i = 0; i < plugin->num_imports; i++) { - free_plugin_import_content(plugin->imports + i); - } - free(plugin->imports); - free(plugin->runtime_lib_name); - free(plugin->runtime_funcs_symbol); - for (i = 0; i < plugin->num_ext_points; i++) { - free_ext_point_content(plugin->ext_points + i); - } - free(plugin->ext_points); - for (i = 0; i < plugin->num_extensions; i++) { - free_extension_content(plugin->extensions + i); - if (plugin->extensions[i].configuration != NULL) { - free_cfg_element_content(plugin->extensions[i].configuration); - free(plugin->extensions[i].configuration); - } - } - free(plugin->extensions); - free(plugin); -} - -/** - * Frees any memory allocated for a registered plug-in. - * - * @param context the plug-in context - * @param plugin the plug-in to be freed - */ -static void free_registered_plugin(cp_context_t *context, cp_plugin_t *plugin) { - assert(context != NULL); - assert(plugin != NULL); - - // Release plug-in information - cpi_release_info(context, plugin->plugin); - - // Release data structures - if (plugin->importing != NULL) { - assert(list_isempty(plugin->importing)); - list_destroy(plugin->importing); - } - assert(plugin->imported == NULL); - - free(plugin); -} - -/** - * Uninstalls a plug-in associated with the specified hash node. - * - * @param context the plug-in context - * @param node the hash node of the plug-in to be uninstalled - */ -static void uninstall_plugin(cp_context_t *context, hnode_t *node) { - cp_plugin_t *plugin; - cpi_plugin_event_t event; - - // Check if already uninstalled - plugin = (cp_plugin_t *) hnode_get(node); - if (plugin->state <= CP_PLUGIN_UNINSTALLED) { - // TODO: Is this possible state? - return; - } - - // Make sure the plug-in is not in resolved state - unresolve_plugin(context, plugin); - assert(plugin->state == CP_PLUGIN_INSTALLED); - - // Plug-in uninstalled - event.plugin_id = plugin->plugin->identifier; - event.old_state = plugin->state; - event.new_state = plugin->state = CP_PLUGIN_UNINSTALLED; - cpi_deliver_event(context, &event); - - // Unregister extension objects - unregister_extensions(context, plugin->plugin); - - // Unregister the plug-in - hash_delete_free(context->env->plugins, node); - - // Free the plug-in data structures - free_registered_plugin(context, plugin); -} - -CP_C_API cp_status_t cp_uninstall_plugin(cp_context_t *context, const char *id) { - hnode_t *node; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(id); - - // Look up and unload the plug-in - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - node = hash_lookup(context->env->plugins, id); - if (node != NULL) { - uninstall_plugin(context, node); - } else { - cpi_warnf(context, N_("Unknown plug-in %s could not be uninstalled."), id); - status = CP_ERR_UNKNOWN; - } - cpi_unlock_context(context); - - return status; -} - -CP_C_API void cp_uninstall_plugins(cp_context_t *context) { - hscan_t scan; - hnode_t *node; - - CHECK_NOT_NULL(context); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - cp_stop_plugins(context); - while (1) { - hash_scan_begin(&scan, context->env->plugins); - if ((node = hash_scan_next(&scan)) != NULL) { - uninstall_plugin(context, node); - } else { - break; - } - } - cpi_unlock_context(context); -} diff --git a/lib/cpluff/libcpluff/pinfo.c b/lib/cpluff/libcpluff/pinfo.c deleted file mode 100644 index 6262c74b48..0000000000 --- a/lib/cpluff/libcpluff/pinfo.c +++ /dev/null @@ -1,726 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Plug-in information functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <stdlib.h> -#include <assert.h> -#include "../kazlib/hash.h" -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -/// Registration of a dynamically allocated information object -typedef struct info_resource_t { - - /// Pointer to the resource - void *resource; - - /// Usage count for the resource - int usage_count; - - /// Deallocation function - cpi_dealloc_func_t dealloc_func; - -} info_resource_t; - -/// A plug-in listener registration -typedef struct el_holder_t { - - /// The plug-in listener - cp_plugin_listener_func_t plugin_listener; - - /// The registering plug-in or NULL for the client program - cp_plugin_t *plugin; - - /// Associated user data - void *user_data; - -} el_holder_t; - - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -// General information object management - -CP_HIDDEN cp_status_t cpi_register_info(cp_context_t *context, void *res, cpi_dealloc_func_t df) { - cp_status_t status = CP_OK; - info_resource_t *ir = NULL; - - assert(context != NULL); - assert(res != NULL); - assert(df != NULL); - assert(cpi_is_context_locked(context)); - do { - if ((ir = malloc(sizeof(info_resource_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - ir->resource = res; - ir->usage_count = 1; - ir->dealloc_func = df; - if (!hash_alloc_insert(context->env->infos, res, ir)) { - status = CP_ERR_RESOURCE; - break; - } - } while (0); - - // Report success - if (status == CP_OK) { - cpi_debugf(context, N_("Registered a new reference counted object at address %p."), res); - } - - // Release resources on failure - if (status != CP_OK) { - if (ir != NULL) { - free(ir); - } - } - - return status; -} - -CP_HIDDEN void cpi_use_info(cp_context_t *context, void *res) { - hnode_t *node; - - assert(context != NULL); - assert(res != NULL); - assert(cpi_is_context_locked(context)); - if ((node = hash_lookup(context->env->infos, res)) != NULL) { - info_resource_t *ir = hnode_get(node); - ir->usage_count++; - cpi_debugf(context, N_("Reference count of the object at address %p increased to %d."), res, ir->usage_count); - } else { - cpi_fatalf(_("Attempt to increase the reference count of an unknown object at address %p."), res); - } -} - -CP_HIDDEN void cpi_release_info(cp_context_t *context, void *info) { - hnode_t *node; - - assert(context != NULL); - assert(info != NULL); - assert(cpi_is_context_locked(context)); - if ((node = hash_lookup(context->env->infos, info)) != NULL) { - info_resource_t *ir = hnode_get(node); - assert(ir != NULL && info == ir->resource); - ir->usage_count--; - cpi_debugf(context, N_("Reference count of the object at address %p decreased to %d."), info, ir->usage_count); - if (ir->usage_count == 0) { - hash_delete_free(context->env->infos, node); - ir->dealloc_func(context, info); - cpi_debugf(context, N_("Deallocated the reference counted object at address %p."), info); - free(ir); - } - } else { - cpi_fatalf(_("Attempt to release an unknown reference counted object at address %p."), info); - } -} - -CP_C_API void cp_release_info(cp_context_t *context, void *info) { - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(info); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - cpi_release_info(context, info); - cpi_unlock_context(context); -} - -CP_HIDDEN void cpi_release_infos(cp_context_t *context) { - hscan_t scan; - hnode_t *node; - - hash_scan_begin(&scan, context->env->infos); - while ((node = hash_scan_next(&scan)) != NULL) { - info_resource_t *ir = hnode_get(node); - cpi_lock_context(context); - cpi_errorf(context, N_("An unreleased information object was encountered at address %p with reference count %d when destroying the associated plug-in context. Not releasing the object."), ir->resource, ir->usage_count); - cpi_unlock_context(context); - hash_scan_delfree(context->env->infos, node); - free(ir); - } -} - - -// Information acquiring functions - -CP_C_API cp_plugin_info_t * cp_get_plugin_info(cp_context_t *context, const char *id, cp_status_t *error) { - hnode_t *node; - cp_plugin_info_t *plugin = NULL; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - if (id == NULL && context->plugin == NULL) { - cpi_fatalf(_("The plug-in identifier argument to cp_get_plugin_info must not be NULL when the main program calls it.")); - } - - // Look up the plug-in and return information - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - do { - - // Lookup plug-in information - if (id != NULL) { - if ((node = hash_lookup(context->env->plugins, id)) == NULL) { - // cpi_warnf(context, N_("Could not return information about unknown plug-in %s."), id); - status = CP_ERR_UNKNOWN; - break; - } - plugin = ((cp_plugin_t *) hnode_get(node))->plugin; - } else { - plugin = context->plugin->plugin; - assert(plugin != NULL); - } - cpi_use_info(context, plugin); - } while (0); - cpi_unlock_context(context); - - if (error != NULL) { - *error = status; - } - return plugin; -} - -static void dealloc_plugins_info(cp_context_t *context, cp_plugin_info_t **plugins) { - int i; - - assert(context != NULL); - assert(plugins != NULL); - for (i = 0; plugins[i] != NULL; i++) { - cpi_release_info(context, plugins[i]); - } - free(plugins); -} - -CP_C_API cp_plugin_info_t ** cp_get_plugins_info(cp_context_t *context, cp_status_t *error, int *num) { - cp_plugin_info_t **plugins = NULL; - int i, n; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - do { - hscan_t scan; - hnode_t *node; - - // Allocate space for pointer array - n = hash_count(context->env->plugins); - if ((plugins = malloc(sizeof(cp_plugin_info_t *) * (n + 1))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Get plug-in information structures - hash_scan_begin(&scan, context->env->plugins); - i = 0; - while ((node = hash_scan_next(&scan)) != NULL) { - cp_plugin_t *rp = hnode_get(node); - - assert(i < n); - cpi_use_info(context, rp->plugin); - plugins[i] = rp->plugin; - i++; - } - plugins[i] = NULL; - - // Register the array - status = cpi_register_info(context, plugins, (void (*)(cp_context_t *, void *)) dealloc_plugins_info); - - } while (0); - - // Report error - if (status != CP_OK) { - cpi_error(context, N_("Plug-in information could not be returned due to insufficient memory.")); - } - cpi_unlock_context(context); - - // Release resources on error - if (status != CP_OK) { - if (plugins != NULL) { - dealloc_plugins_info(context, plugins); - plugins = NULL; - } - } - - assert(status != CP_OK || n == 0 || plugins[n - 1] != NULL); - if (error != NULL) { - *error = status; - } - if (num != NULL && status == CP_OK) { - *num = n; - } - return plugins; -} - -CP_C_API cp_plugin_state_t cp_get_plugin_state(cp_context_t *context, const char *id) { - cp_plugin_state_t state = CP_PLUGIN_UNINSTALLED; - hnode_t *hnode; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(id); - - // Look up the plug-in state - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - if ((hnode = hash_lookup(context->env->plugins, id)) != NULL) { - cp_plugin_t *rp = hnode_get(hnode); - state = rp->state; - } - cpi_unlock_context(context); - return state; -} - -static void dealloc_ext_points_info(cp_context_t *context, cp_ext_point_t **ext_points) { - int i; - - assert(context != NULL); - assert(ext_points != NULL); - for (i = 0; ext_points[i] != NULL; i++) { - cpi_release_info(context, ext_points[i]->plugin); - } - free(ext_points); -} - -CP_C_API cp_ext_point_t ** cp_get_ext_points_info(cp_context_t *context, cp_status_t *error, int *num) { - cp_ext_point_t **ext_points = NULL; - int i, n; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - do { - hscan_t scan; - hnode_t *node; - - // Allocate space for pointer array - n = hash_count(context->env->ext_points); - if ((ext_points = malloc(sizeof(cp_ext_point_t *) * (n + 1))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Get extension point information structures - hash_scan_begin(&scan, context->env->ext_points); - i = 0; - while ((node = hash_scan_next(&scan)) != NULL) { - cp_ext_point_t *ep = hnode_get(node); - - assert(i < n); - cpi_use_info(context, ep->plugin); - ext_points[i] = ep; - i++; - } - ext_points[i] = NULL; - - // Register the array - status = cpi_register_info(context, ext_points, (void (*)(cp_context_t *, void *)) dealloc_ext_points_info); - - } while (0); - - // Report error - if (status != CP_OK) { - cpi_error(context, N_("Extension point information could not be returned due to insufficient memory.")); - } - cpi_unlock_context(context); - - // Release resources on error - if (status != CP_OK) { - if (ext_points != NULL) { - dealloc_ext_points_info(context, ext_points); - ext_points = NULL; - } - } - - assert(status != CP_OK || n == 0 || ext_points[n - 1] != NULL); - if (error != NULL) { - *error = status; - } - if (num != NULL && status == CP_OK) { - *num = n; - } - return ext_points; -} - -static void dealloc_extensions_info(cp_context_t *context, cp_extension_t **extensions) { - int i; - - assert(context != NULL); - assert(extensions != NULL); - for (i = 0; extensions[i] != NULL; i++) { - cpi_release_info(context, extensions[i]->plugin); - } - free(extensions); -} - -CP_C_API cp_extension_t ** cp_get_extensions_info(cp_context_t *context, const char *extpt_id, cp_status_t *error, int *num) { - cp_extension_t **extensions = NULL; - int i, n; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER, __func__); - do { - hscan_t scan; - hnode_t *hnode; - - // Count the number of extensions - if (extpt_id != NULL) { - if ((hnode = hash_lookup(context->env->extensions, extpt_id)) != NULL) { - n = list_count((list_t *) hnode_get(hnode)); - } else { - n = 0; - } - } else { - hscan_t scan; - - n = 0; - hash_scan_begin(&scan, context->env->extensions); - while ((hnode = hash_scan_next(&scan)) != NULL) { - n += list_count((list_t *) hnode_get(hnode)); - } - } - - // Allocate space for pointer array - if ((extensions = malloc(sizeof(cp_extension_t *) * (n + 1))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Get extension information structures - if (extpt_id != NULL) { - i = 0; - if ((hnode = hash_lookup(context->env->extensions, extpt_id)) != NULL) { - list_t *el = hnode_get(hnode); - lnode_t *lnode; - - lnode = list_first(el); - while (lnode != NULL) { - cp_extension_t *e = lnode_get(lnode); - - assert(i < n); - cpi_use_info(context, e->plugin); - extensions[i] = e; - i++; - lnode = list_next(el, lnode); - } - } - extensions[i] = NULL; - } else { - hash_scan_begin(&scan, context->env->extensions); - i = 0; - while ((hnode = hash_scan_next(&scan)) != NULL) { - list_t *el = hnode_get(hnode); - lnode_t *lnode; - - lnode = list_first(el); - while (lnode != NULL) { - cp_extension_t *e = lnode_get(lnode); - - assert(i < n); - cpi_use_info(context, e->plugin); - extensions[i] = e; - i++; - lnode = list_next(el, lnode); - } - } - } - extensions[i] = NULL; - - // Register the array - status = cpi_register_info(context, extensions, (void (*)(cp_context_t *, void *)) dealloc_extensions_info); - - } while (0); - - // Report error - if (status != CP_OK) { - cpi_error(context, N_("Extension information could not be returned due to insufficient memory.")); - } - cpi_unlock_context(context); - - // Release resources on error - if (status != CP_OK) { - if (extensions != NULL) { - dealloc_extensions_info(context, extensions); - extensions = NULL; - } - } - - assert(status != CP_OK || n == 0 || extensions[n - 1] != NULL); - if (error != NULL) { - *error = status; - } - if (num != NULL && status == CP_OK) { - *num = n; - } - return extensions; -} - - -// Plug-in listeners - -/** - * Compares plug-in listener holders. - * - * @param h1 the first holder to be compared - * @param h2 the second holder to be compared - * @return zero if the holders point to the same function, otherwise non-zero - */ -static int comp_el_holder(const void *h1, const void *h2) { - const el_holder_t *plh1 = h1; - const el_holder_t *plh2 = h2; - - return (plh1->plugin_listener != plh2->plugin_listener); -} - -/** - * Processes a node by delivering the specified event to the associated - * plug-in listener. - * - * @param list the list being processed - * @param node the node being processed - * @param event the event - */ -static void process_event(list_t *list, lnode_t *node, void *event) { - el_holder_t *h = lnode_get(node); - cpi_plugin_event_t *e = event; - h->plugin_listener(e->plugin_id, e->old_state, e->new_state, h->user_data); -} - -/** - * Processes a node by unregistering the associated plug-in listener. - * - * @param list the list being processed - * @param node the node being processed - * @param plugin plugin whose listeners are to be unregistered or NULL for all - */ -static void process_unregister_plistener(list_t *list, lnode_t *node, void *plugin) { - el_holder_t *h = lnode_get(node); - if (plugin == NULL || h->plugin == plugin) { - list_delete(list, node); - lnode_destroy(node); - free(h); - } -} - -CP_HIDDEN void cpi_unregister_plisteners(list_t *listeners, cp_plugin_t *plugin) { - list_process(listeners, plugin, process_unregister_plistener); -} - -CP_C_API cp_status_t cp_register_plistener(cp_context_t *context, cp_plugin_listener_func_t listener, void *user_data) { - cp_status_t status = CP_ERR_RESOURCE; - el_holder_t *holder; - lnode_t *node; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(listener); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER | CPI_CF_LISTENER, __func__); - if ((holder = malloc(sizeof(el_holder_t))) != NULL) { - holder->plugin_listener = listener; - holder->plugin = context->plugin; - holder->user_data = user_data; - if ((node = lnode_create(holder)) != NULL) { - list_append(context->env->plugin_listeners, node); - status = CP_OK; - } else { - free(holder); - } - } - - // Report error or success - if (status != CP_OK) { - cpi_error(context, N_("A plug-in listener could not be registered due to insufficient memory.")); - } else if (cpi_is_logged(context, CP_LOG_DEBUG)) { - char owner[64]; - /* TRANSLATORS: %s is the context owner */ - cpi_debugf(context, N_("%s registered a plug-in listener."), cpi_context_owner(context, owner, sizeof(owner))); - } - cpi_unlock_context(context); - - return status; -} - -CP_C_API void cp_unregister_plistener(cp_context_t *context, cp_plugin_listener_func_t listener) { - el_holder_t holder; - lnode_t *node; - - CHECK_NOT_NULL(context); - holder.plugin_listener = listener; - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER | CPI_CF_LISTENER, __func__); - node = list_find(context->env->plugin_listeners, &holder, comp_el_holder); - if (node != NULL) { - process_unregister_plistener(context->env->plugin_listeners, node, NULL); - } - if (cpi_is_logged(context, CP_LOG_DEBUG)) { - char owner[64]; - /* TRANSLATORS: %s is the context owner */ - cpi_debugf(context, N_("%s unregistered a plug-in listener."), cpi_context_owner(context, owner, sizeof(owner))); - } - cpi_unlock_context(context); -} - -CP_HIDDEN void cpi_deliver_event(cp_context_t *context, const cpi_plugin_event_t *event) { - assert(event != NULL); - assert(event->plugin_id != NULL); - cpi_lock_context(context); - context->env->in_event_listener_invocation++; - list_process(context->env->plugin_listeners, (void *) event, process_event); - context->env->in_event_listener_invocation--; - cpi_unlock_context(context); - if (cpi_is_logged(context, CP_LOG_INFO)) { - char *str; - switch (event->new_state) { - case CP_PLUGIN_UNINSTALLED: - str = N_("Plug-in %s has been uninstalled."); - break; - case CP_PLUGIN_INSTALLED: - if (event->old_state < CP_PLUGIN_INSTALLED) { - str = N_("Plug-in %s has been installed."); - } else { - str = N_("Plug-in %s runtime library has been unloaded."); - } - break; - case CP_PLUGIN_RESOLVED: - if (event->old_state < CP_PLUGIN_RESOLVED) { - str = N_("Plug-in %s runtime library has been loaded."); - } else { - str = N_("Plug-in %s has been stopped."); - } - break; - case CP_PLUGIN_STARTING: - str = N_("Plug-in %s is starting."); - break; - case CP_PLUGIN_STOPPING: - str = N_("Plug-in %s is stopping."); - break; - case CP_PLUGIN_ACTIVE: - str = N_("Plug-in %s has been started."); - break; - default: - str = NULL; - break; - } - if (str != NULL) { - cpi_infof(context, str, event->plugin_id); - } - } -} - - -// Configuration element helpers - -static cp_cfg_element_t * lookup_cfg_element(cp_cfg_element_t *base, const char *path, int len) { - int start = 0; - - CHECK_NOT_NULL(base); - CHECK_NOT_NULL(path); - - // Traverse the path - while (base != NULL && path[start] != '\0' && (len == -1 || start < len)) { - int end = start; - while (path[end] != '\0' && path[end] != '/' && (len == -1 || end < len)) - end++; - if (end - start == 2 && !strncmp(path + start, "..", 2)) { - base = base->parent; - } else { - unsigned int i; - int found = 0; - - for (i = 0; !found && i < base->num_children; i++) { - cp_cfg_element_t *e = base->children + i; - if (end - start == strlen(e->name) - && !strncmp(path + start, e->name, end - start)) { - base = e; - found = 1; - } - } - if (!found) { - base = NULL; - } - } - start = end; - if (path[start] == '/') { - start++; - } - } - return base; -} - -CP_C_API cp_cfg_element_t * cp_lookup_cfg_element(cp_cfg_element_t *base, const char *path) { - return lookup_cfg_element(base, path, -1); -} - -CP_C_API char * cp_lookup_cfg_value(cp_cfg_element_t *base, const char *path) { - cp_cfg_element_t *e; - const char *attr; - - CHECK_NOT_NULL(base); - CHECK_NOT_NULL(path); - - if ((attr = strrchr(path, '@')) == NULL) { - e = lookup_cfg_element(base, path, -1); - } else { - e = lookup_cfg_element(base, path, attr - path); - attr++; - } - if (e != NULL) { - if (attr == NULL) { - return e->value; - } else { - unsigned int i; - - for (i = 0; i < e->num_atts; i++) { - if (!strcmp(attr, e->atts[2*i])) { - return e->atts[2*i + 1]; - } - } - return NULL; - } - } else { - return NULL; - } -} diff --git a/lib/cpluff/libcpluff/ploader.c b/lib/cpluff/libcpluff/ploader.c deleted file mode 100644 index 66249381ab..0000000000 --- a/lib/cpluff/libcpluff/ploader.c +++ /dev/null @@ -1,1296 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Plug-in descriptor loader - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <stdarg.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <expat.h> -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" -#if defined(_WIN32) -#include "win32_utils.h" -#endif - -// Use XMLCALL if available -#ifdef XMLCALL -#define CP_XMLCALL XMLCALL -#else -#define CP_XMLCALL -#endif - - -/* ------------------------------------------------------------------------ - * Constants - * ----------------------------------------------------------------------*/ - -/// XML parser buffer size (in bytes) -#define CP_XML_PARSER_BUFFER_SIZE 4096 - -/// Initial configuration element value size -#define CP_CFG_ELEMENT_VALUE_INITSIZE 64 - -/// Plugin descriptor name -#define CP_PLUGIN_DESCRIPTOR "addon.xml" - - -/* ------------------------------------------------------------------------ - * Internal data types - * ----------------------------------------------------------------------*/ - -typedef struct ploader_context_t ploader_context_t; - -/// Parser states -typedef enum parser_state_t { - PARSER_BEGIN, - PARSER_PLUGIN, - PARSER_REQUIRES, - PARSER_EXTENSION, - PARSER_END, - PARSER_UNKNOWN, - PARSER_ERROR -} parser_state_t; - -/// Plug-in loader context -struct ploader_context_t { - - /// The plug-in context, or NULL if none - cp_context_t *context; - - /// The XML parser being used - XML_Parser parser; - - /// The file being parsed - char *file; - - /// The plug-in being constructed - cp_plugin_info_t *plugin; - - /// The configuration element being constructed - cp_cfg_element_t *configuration; - - /// The current parser state - parser_state_t state; - - /// The saved parser state (used in PARSER_UNKNOWN) - parser_state_t saved_state; - - /** - * The current parser depth (used in PARSER_UNKNOWN and PARSER_EXTENSION) - */ - unsigned int depth; - - /// The number of skipped configuration elements - unsigned int skippedCEs; - - /// Size of allocated imports table - size_t imports_size; - - /// Size of allocated extension points table - size_t ext_points_size; - - /// Size of allocated extensions table - size_t extensions_size; - - /// Buffer for a value being read - char *value; - - /// Size of allocated value field - size_t value_size; - - /// Current length of value string - size_t value_length; - - /// The number of parsing errors that have occurred - unsigned int error_count; - - /// The number of resource errors that have occurred - unsigned int resource_error_count; -}; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -/** - * Reports a descriptor error. Does not set the parser to error state but - * increments the error count, unless this is merely a warning. - * - * @param context the parsing context - * @param warn whether this is only a warning - * @param error_msg the error message - * @param ... parameters for the error message - */ -static void descriptor_errorf(ploader_context_t *plcontext, int warn, - const char *error_msg, ...) { - va_list ap; - char message[128]; - - va_start(ap, error_msg); - vsnprintf(message, sizeof(message), error_msg, ap); - va_end(ap); - message[127] = '\0'; - if (warn) { - cpi_warnf(plcontext->context, - N_("Suspicious plug-in descriptor content in %s, line %d, column %d (%s)."), - plcontext->file, - (int) XML_GetCurrentLineNumber(plcontext->parser), - (int) XML_GetCurrentColumnNumber(plcontext->parser) + 1, - message); - } else { - cpi_errorf(plcontext->context, - N_("Invalid plug-in descriptor content in %s, line %d, column %d (%s)."), - plcontext->file, - (int) XML_GetCurrentLineNumber(plcontext->parser), - (int) XML_GetCurrentColumnNumber(plcontext->parser) + 1, - message); - } - if (!warn) { - plcontext->error_count++; - } -} - -/** - * Reports insufficient system resources while parsing and increments the - * resource error count. - * - * @param context the parsing context - */ -static void resource_error(ploader_context_t *plcontext) { - if (plcontext->resource_error_count == 0) { - cpi_errorf(plcontext->context, - N_("Insufficient system resources to parse plug-in descriptor content in %s, line %d, column %d."), - plcontext->file, - (int) XML_GetCurrentLineNumber(plcontext->parser), - (int) XML_GetCurrentColumnNumber(plcontext->parser) + 1); - } - plcontext->resource_error_count++; -} - -/** - * Returns whether the specified NULL-terminated list of strings includes - * the specified string. - * - * @param list the NULL-terminated list of strings, or NULL if none - * @param str the string - * @param step the stepping (1 to check every string or 2 to check every - * other string) - * @return pointer to the location of the string or NULL if not found - */ -static const XML_Char * const *contains_str(const XML_Char * const *list, - const XML_Char *str, int step) { - if (list != NULL) { - while (*list != NULL) { - if (!strcmp(*list, str)) { - return list; - } - list += step; - } - } - return NULL; -} - -/** - * Checks that an element has non-empty values for required attributes. - * Increments the error count for each missing attribute. - * - * @param context the parsing context - * @param elem the element being checked - * @param atts the attribute list for the element - * @param req_atts the required attributes (NULL terminated list, or NULL) - * @return whether the required attributes are present - */ -static int check_req_attributes(ploader_context_t *plcontext, - const XML_Char *elem, const XML_Char * const *atts, - const XML_Char * const *req_atts) { - const XML_Char * const *a; - int error = 0; - - // Check that required attributes have non-empty values - for (a = req_atts; a != NULL && *a != NULL; a++) { - const XML_Char * const *av; - - if ((av = contains_str(atts, *a, 2)) != NULL) { - if ((*(av + 1))[0] == '\0') { - descriptor_errorf(plcontext, 0, - _("required attribute %s for element %s has an empty value"), - *a, elem); - error = 1; - } - } else { - descriptor_errorf(plcontext, 0, - _("required attribute %s missing for element %s"), - *a, elem); - error = 1; - } - } - - return !error; -} - -/** - * Checks that an element has non-empty values for required attributes and - * warns if there are unknown attributes. Increments the error count for - * each missing required attribute. - * - * @param context the parsing context - * @param elem the element being checked - * @param atts the attribute list for the element - * @param req_atts the required attributes (NULL terminated list, or NULL) - * @param opt_atts the optional attributes (NULL terminated list, or NULL) - * @return whether the required attributes are present - */ -static int check_attributes(ploader_context_t *plcontext, - const XML_Char *elem, const XML_Char * const *atts, - const XML_Char * const *req_atts, const XML_Char * const *opt_atts) { - int error = 0; - - // Check required attributes - error = !check_req_attributes(plcontext, elem, atts, req_atts); - - // Warn if there are unknown attributes - for (; *atts != NULL; atts += 2) { - if (contains_str(req_atts, *atts, 1) == NULL - && contains_str(opt_atts, *atts, 1) == NULL) { - descriptor_errorf(plcontext, 1, - _("ignoring unknown attribute %s for element %s"), - *atts, elem); - } - } - - return !error; -} - -/** - * Allocates memory using malloc. Reports a resource error if there is not - * enough available memory. - * - * @param context the parsing context - * @param size the number of bytes to allocate - * @return pointer to the allocated memory, or NULL if memory allocation failed - */ -static void *parser_malloc(ploader_context_t *plcontext, size_t size) { - void *ptr; - - if ((ptr = malloc(size)) == NULL) { - resource_error(plcontext); - } - return ptr; -} - -/** - * Makes a copy of the specified string. The memory is allocated using malloc. - * Reports a resource error if there is not enough available memory. - * - * @param context the parsing context - * @param src the source string to be copied - * @return copy of the string, or NULL if memory allocation failed - */ -static char *parser_strdup(ploader_context_t *plcontext, const char *src) { - char *dup; - - if ((dup = strdup(src)) == NULL) { - resource_error(plcontext); - } - return dup; -} - -/** - * Concatenates the specified strings into a new string. The memory for the concatenated - * string is allocated using malloc. Reports a resource error if there is not - * enough available memory. - * - * @param context the parsing context - * @param ... the strings to be concatenated, terminated by NULL - * @return the concatenated string, or NULL if memory allocation failed - */ -static char *parser_strscat(ploader_context_t *plcontext, ...) { - va_list ap; - const char *str; - char *dst; - size_t len; - - // Calculate the length of the concatenated string - va_start(ap, plcontext); - len = 0; - while ((str = va_arg(ap, const char *)) != NULL) { - len += strlen(str); - } - va_end(ap); - - // Allocate space for the concatenated string - if ((dst = parser_malloc(plcontext, sizeof(char) * (len + 1))) == NULL) { - return NULL; - } - - // Copy the strings - len = 0; - va_start(ap, plcontext); - while ((str = va_arg(ap, const char *)) != NULL) { - strcpy(dst + len, str); - len += strlen(str); - } - va_end(ap); - dst[len] = '\0'; - return dst; -} - -/** - * Puts the parser to a state in which it skips an unknown element. - * Warns error handlers about the unknown element. - * - * @param context the parsing context - * @param elem the element name - */ -static void unexpected_element(ploader_context_t *plcontext, const XML_Char *elem) { - plcontext->saved_state = plcontext->state; - plcontext->state = PARSER_UNKNOWN; - plcontext->depth = 0; - descriptor_errorf(plcontext, 1, _("ignoring unexpected element %s and its contents"), elem); -} - -/** - * Creates a copy of the specified attributes. Reports failed memory - * allocation. - * - * @param context the parser context - * @param src the source attributes to be copied - * @param num pointer to the location where number of attributes is stored, - * or NULL for none - * @return the duplicated attribute array, or NULL if empty or failed - */ -static char **parser_attsdup(ploader_context_t *plcontext, const XML_Char * const *src, - unsigned int *num_atts) { - char **atts = NULL, *attr_data = NULL; - unsigned int i; - unsigned int num; - size_t attr_size; - - // Calculate the number of attributes and the amount of space required - for (num = 0, attr_size = 0; src[num] != NULL; num++) { - attr_size += strlen(src[num]) + 1; - } - assert((num & 1) == 0); - - // Allocate necessary memory and copy attribute data - if (num > 0) { - if ((atts = parser_malloc(plcontext, num * sizeof(char *))) != NULL) { - if ((attr_data = parser_malloc(plcontext, attr_size * sizeof(char))) != NULL) { - size_t offset; - - for (i = 0, offset = 0; i < num; i++) { - strcpy(attr_data + offset, src[i]); - atts[i] = attr_data + offset; - offset += strlen(src[i]) + 1; - } - } - } - } - - // If successful then return duplicates, otherwise free any allocations - if (num == 0 || (atts != NULL && attr_data != NULL)) { - if (num_atts != NULL) { - *num_atts = num / 2; - } - return atts; - } else { - free(attr_data); - free(atts); - return NULL; - } -} - -/** - * Initializes a configuration element. Reports an error if memory allocation fails. - * - * @param context the parser context - * @param ce the configuration element to be initialized - * @param name the element name - * @param atts the element attributes - * @param parent the parent element - */ -static void init_cfg_element(ploader_context_t *plcontext, cp_cfg_element_t *ce, - const XML_Char *name, const XML_Char * const *atts, cp_cfg_element_t *parent) { - - // Initialize the configuration element - memset(ce, 0, sizeof(cp_cfg_element_t)); - ce->name = parser_strdup(plcontext, name); - ce->atts = parser_attsdup(plcontext, atts, &(ce->num_atts)); - ce->value = NULL; - plcontext->value = NULL; - plcontext->value_size = 0; - plcontext->value_length = 0; - ce->parent = parent; - ce->children = NULL; -} - -/** - * Processes the character data while parsing. - * - * @param userData the parsing context - * @param str the string data - * @param len the string length - */ -static void CP_XMLCALL character_data_handler( - void *userData, const XML_Char *str, int len) { - ploader_context_t *plcontext = userData; - - // Ignore leading whitespace - if (plcontext->value == NULL) { - int i; - - for (i = 0; i < len; i++) { - if (str[i] != ' ' && str[i] != '\n' && str[i] != '\r' && str[i] != '\t') { - break; - } - } - str += i; - len -= i; - if (len == 0) { - return; - } - } - - // Allocate more memory for the character data if needed - if (plcontext->value_length + len >= plcontext->value_size) { - size_t ns; - char *nv; - - ns = plcontext->value_size; - while (plcontext->value_length + len >= ns) { - if (ns == 0) { - ns = CP_CFG_ELEMENT_VALUE_INITSIZE; - } else { - ns = 2 * ns; - } - } - if ((nv = realloc(plcontext->value, ns * sizeof(char))) != NULL) { - plcontext->value = nv; - plcontext->value_size = ns; - } else { - resource_error(plcontext); - return; - } - } - - // Copy character data - strncpy(plcontext->value + plcontext->value_length, str, len * sizeof(char)); - plcontext->value_length += len; -} - -/** - * Processes the start of element events while parsing. - * - * @param userData the parsing context - * @param name the element name - * @param atts the element attributes - */ -static void CP_XMLCALL start_element_handler( - void *userData, const XML_Char *name, const XML_Char **atts) { - static const XML_Char * const req_plugin_atts[] = { "id", NULL }; - static const XML_Char * const opt_plugin_atts[] = { "name", "version", "provider-name", NULL }; - static const XML_Char * const req_bwcompatibility_atts[] = { NULL }; - static const XML_Char * const opt_bwcompatibility_atts[] = { "abi", "api", NULL }; - static const XML_Char * const req_cpluff_atts[] = { "version", NULL }; - static const XML_Char * const opt_cpluff_atts[] = { NULL }; - static const XML_Char * const req_import_atts[] = { "addon", NULL }; - static const XML_Char * const opt_import_atts[] = { "version", "optional", NULL }; - static const XML_Char * const req_runtime_atts[] = { "library", NULL }; - static const XML_Char * const opt_runtime_atts[] = { "funcs", NULL }; - static const XML_Char * const req_ext_point_atts[] = { "id", NULL }; - static const XML_Char * const opt_ext_point_atts[] = { "name", "schema", NULL }; - static const XML_Char * const req_extension_atts[] = { "point", NULL }; - //static const XML_Char * const opt_extension_atts[] = { "id", "name", NULL }; - ploader_context_t *plcontext = userData; - unsigned int i; - - // Process element start - switch (plcontext->state) { - - case PARSER_BEGIN: - if (!strcmp(name, "addon")) { - plcontext->state = PARSER_PLUGIN; - if (!check_attributes(plcontext, name, atts, - req_plugin_atts, opt_plugin_atts)) { - break; - } - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "name")) { - plcontext->plugin->name - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "id")) { - plcontext->plugin->identifier - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "version")) { - plcontext->plugin->version - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "provider-name")) { - plcontext->plugin->provider_name - = parser_strdup(plcontext, atts[i+1]); - } - } - } else { - unexpected_element(plcontext, name); - } - break; - - case PARSER_PLUGIN: - if (!strcmp(name, "backwards-compatibility")) { - if (check_attributes(plcontext, name, atts, - req_bwcompatibility_atts, opt_bwcompatibility_atts)) { - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "abi")) { - plcontext->plugin->abi_bw_compatibility = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "api")) { - plcontext->plugin->api_bw_compatibility = parser_strdup(plcontext, atts[i+1]); - } - } - } - } else if (!strcmp(name, "requires")) { - plcontext->state = PARSER_REQUIRES; - } else if (!strcmp(name, "runtime")) { - if (check_attributes(plcontext, name, atts, - req_runtime_atts, opt_runtime_atts)) { - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "library")) { - plcontext->plugin->runtime_lib_name - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "funcs")) { - plcontext->plugin->runtime_funcs_symbol - = parser_strdup(plcontext, atts[i+1]); - } - } - } - } else if (!strcmp(name, "extension-point")) { - if (check_attributes(plcontext, name, atts, - req_ext_point_atts, opt_ext_point_atts)) { - cp_ext_point_t *ext_point; - - // Allocate space for extension points, if necessary - if (plcontext->plugin->num_ext_points == plcontext->ext_points_size) { - cp_ext_point_t *nep; - size_t ns; - - if (plcontext->ext_points_size == 0) { - ns = 4; - } else { - ns = plcontext->ext_points_size * 2; - } - if ((nep = realloc(plcontext->plugin->ext_points, - ns * sizeof(cp_ext_point_t))) == NULL) { - resource_error(plcontext); - break; - } - plcontext->plugin->ext_points = nep; - plcontext->ext_points_size = ns; - } - - // Parse extension point specification - ext_point = plcontext->plugin->ext_points - + plcontext->plugin->num_ext_points; - memset(ext_point, 0, sizeof(cp_ext_point_t)); - ext_point->plugin = plcontext->plugin; - ext_point->name = NULL; - ext_point->local_id = NULL; - ext_point->identifier = NULL; - ext_point->schema_path = NULL; - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "name")) { - ext_point->name - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "id")) { - ext_point->local_id - = parser_strdup(plcontext, atts[i+1]); - ext_point->identifier - = parser_strscat(plcontext, - plcontext->plugin->identifier, ".", atts[i+1], NULL); - } else if (!strcmp(atts[i], "schema")) { - ext_point->schema_path - = parser_strdup(plcontext, atts[i+1]); - } - } - plcontext->plugin->num_ext_points++; - - } - } else if (!(strcmp(name, "extension"))) { - plcontext->state = PARSER_EXTENSION; - plcontext->depth = 0; - if (check_req_attributes( - plcontext, name, atts, req_extension_atts)) { - cp_extension_t *extension; - - // Allocate space for extensions, if necessary - if (plcontext->plugin->num_extensions == plcontext->extensions_size) { - cp_extension_t *ne; - size_t ns; - - if (plcontext->extensions_size == 0) { - ns = 16; - } else { - ns = plcontext->extensions_size * 2; - } - if ((ne = realloc(plcontext->plugin->extensions, - ns * sizeof(cp_extension_t))) == NULL) { - resource_error(plcontext); - break; - } - plcontext->plugin->extensions = ne; - plcontext->extensions_size = ns; - } - - // Parse extension attributes - extension = plcontext->plugin->extensions - + plcontext->plugin->num_extensions; - memset(extension, 0, sizeof(cp_extension_t)); - extension->plugin = plcontext->plugin; - extension->name = NULL; - extension->local_id = NULL; - extension->identifier = NULL; - extension->ext_point_id = NULL; - extension->configuration = NULL; - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "point")) { - extension->ext_point_id - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "id")) { - extension->local_id - = parser_strdup(plcontext, atts[i+1]); - extension->identifier - = parser_strscat(plcontext, - plcontext->plugin->identifier, ".", atts[i+1], NULL); - } else if (!strcmp(atts[i], "name")) { - extension->name - = parser_strdup(plcontext, atts[i+1]); - } - } - plcontext->plugin->num_extensions++; - - // Initialize configuration parsing - if ((extension->configuration = plcontext->configuration - = parser_malloc(plcontext, sizeof(cp_cfg_element_t))) != NULL) { - init_cfg_element(plcontext, plcontext->configuration, name, atts, NULL); - } - XML_SetCharacterDataHandler(plcontext->parser, character_data_handler); - } - } else { - unexpected_element(plcontext, name); - } - break; - - case PARSER_REQUIRES: - if (!strcmp(name, "c-pluff")) { - if (check_attributes(plcontext, name, atts, - req_cpluff_atts, opt_cpluff_atts)) { - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "version")) { - plcontext->plugin->req_cpluff_version = parser_strdup(plcontext, atts[i+1]); - } - } - } - } else if (!strcmp(name, "import")) { - if (check_attributes(plcontext, name, atts, - req_import_atts, opt_import_atts)) { - cp_plugin_import_t *import = NULL; - - // Allocate space for imports, if necessary - if (plcontext->plugin->num_imports == plcontext->imports_size) { - cp_plugin_import_t *ni; - size_t ns; - - if (plcontext->imports_size == 0) { - ns = 16; - } else { - ns = plcontext->imports_size * 2; - } - if ((ni = realloc(plcontext->plugin->imports, - ns * sizeof(cp_plugin_import_t))) == NULL) { - resource_error(plcontext); - break; - } - plcontext->plugin->imports = ni; - plcontext->imports_size = ns; - } - - // Parse import specification - import = plcontext->plugin->imports - + plcontext->plugin->num_imports; - memset(import, 0, sizeof(cp_plugin_import_t)); - import->plugin_id = NULL; - import->version = NULL; - for (i = 0; atts[i] != NULL; i += 2) { - if (!strcmp(atts[i], "addon")) { - import->plugin_id - = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "version")) { - import->version = parser_strdup(plcontext, atts[i+1]); - } else if (!strcmp(atts[i], "optional")) { - if (!strcmp(atts[i+1], "true") - || !strcmp(atts[i+1], "1")) { - import->optional = 1; - } else if (strcmp(atts[i+1], "false") - && strcmp(atts[i+1], "0")) { - descriptor_errorf(plcontext, 0, _("unknown boolean value: %s"), atts[i+1]); - } - } - } - plcontext->plugin->num_imports++; - } - } else { - unexpected_element(plcontext, name); - } - break; - - case PARSER_EXTENSION: - plcontext->depth++; - if (plcontext->configuration != NULL && plcontext->skippedCEs == 0) { - cp_cfg_element_t *ce; - - // Allocate more space for children, if necessary - if (plcontext->configuration->num_children == plcontext->configuration->index) { - cp_cfg_element_t *nce; - size_t ns; - - if (plcontext->configuration->index == 0) { - ns = 16; - } else { - ns = plcontext->configuration->index * 2; - } - if ((nce = realloc(plcontext->configuration->children, - ns * sizeof(cp_cfg_element_t))) == NULL) { - plcontext->skippedCEs++; - resource_error(plcontext); - break; - } - plcontext->configuration->children = nce; - plcontext->configuration->index = ns; - } - - // Save possible value - if (plcontext->value != NULL) { - plcontext->value[plcontext->value_length] = '\0'; - plcontext->configuration->value = plcontext->value; - } - - ce = plcontext->configuration->children + plcontext->configuration->num_children; - init_cfg_element(plcontext, ce, name, atts, plcontext->configuration); - plcontext->configuration->num_children++; - plcontext->configuration = ce; - } - break; - - case PARSER_UNKNOWN: - plcontext->depth++; - break; - default: - unexpected_element(plcontext, name); - break; - } -} - -/** - * Processes the end of element events while parsing. - * - * @param context the parsing context - * @param name the element name - */ -static void CP_XMLCALL end_element_handler( - void *userData, const XML_Char *name) { - ploader_context_t *plcontext = userData; - - // Process element end - switch (plcontext->state) { - - case PARSER_PLUGIN: - if (!strcmp(name, "addon")) { - - // Readjust memory allocated for extension points, if necessary - if (plcontext->ext_points_size != plcontext->plugin->num_ext_points) { - cp_ext_point_t *nep; - - if ((nep = realloc(plcontext->plugin->ext_points, - plcontext->plugin->num_ext_points * - sizeof(cp_ext_point_t))) != NULL - || plcontext->plugin->num_ext_points == 0) { - plcontext->plugin->ext_points = nep; - plcontext->ext_points_size = plcontext->plugin->num_ext_points; - } - } - - // Readjust memory allocated for extensions, if necessary - if (plcontext->extensions_size != plcontext->plugin->num_extensions) { - cp_extension_t *ne; - - if ((ne = realloc(plcontext->plugin->extensions, - plcontext->plugin->num_extensions * - sizeof(cp_extension_t))) != NULL - || plcontext->plugin->num_extensions == 0) { - plcontext->plugin->extensions = ne; - plcontext->extensions_size = plcontext->plugin->num_extensions; - } - } - - plcontext->state = PARSER_END; - } - break; - - case PARSER_REQUIRES: - if (!strcmp(name, "requires")) { - - // Readjust memory allocated for imports, if necessary - if (plcontext->imports_size != plcontext->plugin->num_imports) { - cp_plugin_import_t *ni; - - if ((ni = realloc(plcontext->plugin->imports, - plcontext->plugin->num_imports * - sizeof(cp_plugin_import_t))) != NULL - || plcontext->plugin->num_imports == 0) { - plcontext->plugin->imports = ni; - plcontext->imports_size = plcontext->plugin->num_imports; - } - } - - plcontext->state = PARSER_PLUGIN; - } - break; - - case PARSER_UNKNOWN: - if (plcontext->depth-- == 0) { - plcontext->state = plcontext->saved_state; - } - break; - - case PARSER_EXTENSION: - if (plcontext->skippedCEs > 0) { - plcontext->skippedCEs--; - } else if (plcontext->configuration != NULL) { - - // Readjust memory allocated for children, if necessary - if (plcontext->configuration->index != plcontext->configuration->num_children) { - cp_cfg_element_t *nce; - - if ((nce = realloc(plcontext->configuration->children, - plcontext->configuration->num_children * - sizeof(cp_cfg_element_t))) != NULL - || plcontext->configuration->num_children == 0) { - plcontext->configuration->children = nce; - } - } - - if (plcontext->configuration->parent != NULL) { - plcontext->configuration->index = plcontext->configuration->parent->num_children - 1; - } else { - plcontext->configuration->index = 0; - } - if (plcontext->value != NULL) { - char *v = plcontext->value; - int i; - - // Ignore trailing whitespace - for (i = plcontext->value_length - 1; i >= 0; i--) { - if (v[i] != ' ' && v[i] != '\n' && v[i] != '\r' && v[i] != '\t') { - break; - } - } - if (i < 0) { - free(plcontext->value); - plcontext->value = NULL; - plcontext->value_length = 0; - plcontext->value_size = 0; - } else { - plcontext->value_length = i + 1; - } - } - if (plcontext->value != NULL) { - - // Readjust memory allocated for value, if necessary - if (plcontext->value_size > plcontext->value_length + 1) { - char *nv; - - if ((nv = realloc(plcontext->value, (plcontext->value_length + 1) * sizeof(char))) != NULL) { - plcontext->value = nv; - } - } - - plcontext->value[plcontext->value_length] = '\0'; - plcontext->configuration->value = plcontext->value; - plcontext->value = NULL; - plcontext->value_size = 0; - plcontext->value_length = 0; - } - plcontext->configuration = plcontext->configuration->parent; - - // Restore possible value - if (plcontext->configuration != NULL - && plcontext->configuration->value != NULL) { - plcontext->value = plcontext->configuration->value; - plcontext->value_length = strlen(plcontext->value); - plcontext->value_size = CP_CFG_ELEMENT_VALUE_INITSIZE; - while (plcontext->value_size < plcontext->value_length + 1) { - plcontext->value_size *= 2; - } - } - - } - if (plcontext->depth-- == 0) { - assert(!strcmp(name, "extension")); - plcontext->state = PARSER_PLUGIN; - XML_SetCharacterDataHandler(plcontext->parser, NULL); - } - break; - - default: - descriptor_errorf(plcontext, 0, _("unexpected closing tag for %s"), - name); - return; - } -} - -static void dealloc_plugin_info(cp_context_t *ctx, cp_plugin_info_t *plugin) { - cpi_free_plugin(plugin); -} - -static cp_status_t init_descriptor_parsing(cp_context_t *context, ploader_context_t **plcontextptr, XML_Parser *parserptr, char *file) { - XML_Parser parser; - ploader_context_t *plcontext; - - // Initialize the XML parsing - *parserptr = parser = XML_ParserCreate(NULL); - if (parser == NULL) { - return CP_ERR_RESOURCE; - } - XML_SetElementHandler(parser, - start_element_handler, - end_element_handler); - - // Initialize the parsing context - if ((*plcontextptr = plcontext = malloc(sizeof(ploader_context_t))) == NULL) { - return CP_ERR_RESOURCE; - } - memset(plcontext, 0, sizeof(ploader_context_t)); - if ((plcontext->plugin = malloc(sizeof(cp_plugin_info_t))) == NULL) { - return CP_ERR_RESOURCE; - } - plcontext->context = context; - plcontext->configuration = NULL; - plcontext->value = NULL; - plcontext->parser = parser; - plcontext->file = file; - plcontext->state = PARSER_BEGIN; - memset(plcontext->plugin, 0, sizeof(cp_plugin_info_t)); - plcontext->plugin->name = NULL; - plcontext->plugin->identifier = NULL; - plcontext->plugin->version = NULL; - plcontext->plugin->provider_name = NULL; - plcontext->plugin->abi_bw_compatibility = NULL; - plcontext->plugin->api_bw_compatibility = NULL; - plcontext->plugin->plugin_path = NULL; - plcontext->plugin->req_cpluff_version = NULL; - plcontext->plugin->imports = NULL; - plcontext->plugin->runtime_lib_name = NULL; - plcontext->plugin->runtime_funcs_symbol = NULL; - plcontext->plugin->ext_points = NULL; - plcontext->plugin->extensions = NULL; - XML_SetUserData(parser, plcontext); - - return CP_OK; -} - -static cp_status_t do_descriptor_parsing(XML_Parser parser, cp_context_t *context, ploader_context_t *plcontext, char *file, unsigned int buffer_len) { - int i; - - // Parse the data - if (!(i = XML_ParseBuffer(parser, buffer_len, buffer_len == 0)) - && context != NULL) { - cpi_lock_context(context); - cpi_errorf(context, - N_("XML parsing error in %s, line %d, column %d (%s)."), - file, - (int) XML_GetErrorLineNumber(parser), - (int) (XML_GetErrorColumnNumber(parser) + 1), - XML_ErrorString(XML_GetErrorCode(parser))); - cpi_unlock_context(context); - } - if (!i || plcontext->state == PARSER_ERROR) { - return CP_ERR_MALFORMED; - } else { - return CP_OK; - } -} - -static cp_status_t finish_descriptor_parsing(cp_status_t status, cp_context_t *context, ploader_context_t *plcontext, char **path) { - if (status == CP_OK) { - if (plcontext->state != PARSER_END || plcontext->error_count > 0) { - status = CP_ERR_MALFORMED; - } - if (plcontext->resource_error_count > 0) { - status = CP_ERR_RESOURCE; - } - } - if (status != CP_OK) { - return status; - } - - // Initialize the plug-in path - plcontext->plugin->plugin_path = *path; - *path = NULL; - - // Increase plug-in usage count - status = cpi_register_info(context, plcontext->plugin, (void (*)(cp_context_t *, void *)) dealloc_plugin_info); - return status; - -} - -static void check_cleanup_descriptor_parsing(cp_status_t status, cp_context_t *context, ploader_context_t *plcontext, XML_Parser parser, const char *path, char *file, cp_plugin_info_t **plugin) { - - // Report possible errors - if (status != CP_OK) { - switch (status) { - case CP_ERR_MALFORMED: - cpi_errorf(context, - N_("Plug-in descriptor in %s is invalid."), path); - break; - case CP_ERR_IO: - cpi_debugf(context, - N_("An I/O error occurred while loading a plug-in descriptor from %s."), path); - break; - case CP_ERR_RESOURCE: - cpi_errorf(context, - N_("Insufficient system resources to load a plug-in descriptor from %s."), path); - break; - default: - cpi_errorf(context, - N_("Failed to load a plug-in descriptor from %s."), path); - break; - } - } - cpi_unlock_context(context); - - // Release persistently allocated data on failure - if (status != CP_OK) { - if (file != NULL) { - free(file); - } - if (plcontext != NULL && plcontext->plugin != NULL) { - cpi_free_plugin(plcontext->plugin); - plcontext->plugin = NULL; - } - } - - // Otherwise copy the plug-in pointer - else { - *plugin = plcontext->plugin; - } - - // Release data allocated for parsing - if (parser != NULL) { - XML_ParserFree(parser); - } - if (plcontext != NULL) { - if (plcontext->value != NULL) { - free(plcontext->value); - } - free(plcontext); - plcontext = NULL; - } - -} - -CP_C_API cp_plugin_info_t * cp_load_plugin_descriptor(cp_context_t *context, const char *path, cp_status_t *error) { - char *file = NULL; - cp_status_t status = CP_OK; - FILE *fh = NULL; - XML_Parser parser = NULL; - ploader_context_t *plcontext = NULL; - cp_plugin_info_t *plugin = NULL; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(path); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - do { - int path_len; - - // Construct the file name for the plug-in descriptor - path_len = strlen(path); - if (path_len == 0) { - status = CP_ERR_IO; - break; - } - if (path[path_len - 1] == CP_FNAMESEP_CHAR) { - path_len--; - } - file = malloc((path_len + strlen(CP_PLUGIN_DESCRIPTOR) + 2) * sizeof(char)); - if (file == NULL) { - status = CP_ERR_RESOURCE; - break; - } - strcpy(file, path); - file[path_len] = CP_FNAMESEP_CHAR; - strcpy(file + path_len + 1, CP_PLUGIN_DESCRIPTOR); - -#if defined(_WIN32) - wchar_t* fileW = to_utf16(file, 0); - fh = _wfopen(fileW, L"rb"); - free(fileW); - if (!fh) - { - status = CP_ERR_IO; - break; - } -#else - // Open the file - if ((fh = fopen(file, "rb")) == NULL) { - status = CP_ERR_IO; - break; - } -#endif - - // Initialize descriptor parsing - status = init_descriptor_parsing(context, &plcontext, &parser, file); - if (status != CP_OK) { - break; - } - - // Parse the plug-in descriptor - while (1) { - unsigned int bytes_read; - void *xml_buffer; - - // Get buffer from Expat - if ((xml_buffer = XML_GetBuffer(parser, CP_XML_PARSER_BUFFER_SIZE)) - == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Read data into buffer - bytes_read = fread(xml_buffer, 1, CP_XML_PARSER_BUFFER_SIZE, fh); - if (ferror(fh)) { - status = CP_ERR_IO; - break; - } - - // Parse the data - status = do_descriptor_parsing(parser, context, plcontext, file, bytes_read); - if (status != CP_OK || bytes_read == 0) { - break; - } - } - - // Finish parsing - *(file + path_len) = '\0'; - status = finish_descriptor_parsing(status, context, plcontext, &file); - } while (0); - - // Check and clean up - check_cleanup_descriptor_parsing(status, context, plcontext, parser, path, file, &plugin); - if (fh != NULL) { - fclose(fh); - } - - // Return error code - if (error != NULL) { - *error = status; - } - - return plugin; -} - -CP_C_API cp_plugin_info_t * cp_load_plugin_descriptor_from_memory(cp_context_t *context, const char *buffer, unsigned int buffer_len, cp_status_t *error) { - char *file = NULL; - const char *path = "memory"; - cp_status_t status = CP_OK; - XML_Parser parser = NULL; - ploader_context_t *plcontext = NULL; - cp_plugin_info_t *plugin = NULL; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(buffer); - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - do { - int path_len = 6; - file = malloc((path_len + 1) * sizeof(char)); - if (file == NULL) { - status = CP_ERR_RESOURCE; - break; - } - strcpy(file, path); - - // Initialize descriptor parsing - status = init_descriptor_parsing(context, &plcontext, &parser, file); - if (status != CP_OK) { - break; - } - - // Parse the plug-in descriptor - do { - void *xml_buffer; - - // Get buffer from Expat - if ((xml_buffer = XML_GetBuffer(parser, buffer_len)) - == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Read data into buffer - memcpy(xml_buffer, buffer, buffer_len); - - // Parse the data - status = do_descriptor_parsing(parser, context, plcontext, file, buffer_len); - if (status == CP_OK) { - status = do_descriptor_parsing(parser, context, plcontext, file, 0); - } - } while (0); - - // Finish parsing - *(file + path_len) = '\0'; - status = finish_descriptor_parsing(status, context, plcontext, &file); - - } while (0); - - // Check and clean up - check_cleanup_descriptor_parsing(status, context, plcontext, parser, path, file, &plugin); - - // Return error code - if (error != NULL) { - *error = status; - } - - return plugin; -} diff --git a/lib/cpluff/libcpluff/pscan.c b/lib/cpluff/libcpluff/pscan.c deleted file mode 100644 index 921c8e365f..0000000000 --- a/lib/cpluff/libcpluff/pscan.c +++ /dev/null @@ -1,311 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Plug-in scanning functionality - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <dirent.h> -#include <errno.h> -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -CP_C_API cp_status_t cp_scan_plugins(cp_context_t *context, int flags) { - hash_t *avail_plugins = NULL; - list_t *started_plugins = NULL; - cp_plugin_info_t **plugins = NULL; - char *pdir_path = NULL; - int pdir_path_size = 0; - int plugins_stopped = 0; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_ANY, __func__); - cpi_debug(context, N_("Plug-in scan is starting.")); - do { - lnode_t *lnode; - hscan_t hscan; - hnode_t *hnode; - - // Create a hash for available plug-ins - if ((avail_plugins = hash_create(HASHCOUNT_T_MAX, (int (*)(const void *, const void *)) strcmp, NULL)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Scan plug-in directories for available plug-ins - lnode = list_first(context->env->plugin_dirs); - while (lnode != NULL) { - const char *dir_path; - DIR *dir; - - dir_path = lnode_get(lnode); - dir = opendir(dir_path); - if (dir != NULL) { - int dir_path_len; - struct dirent *de; - - dir_path_len = strlen(dir_path); - if (dir_path[dir_path_len - 1] == CP_FNAMESEP_CHAR) { - dir_path_len--; - } - errno = 0; - while ((de = readdir(dir)) != NULL) { - if (de->d_name[0] != '\0' && de->d_name[0] != '.') { - int pdir_path_len = dir_path_len + 1 + strlen(de->d_name) + 1; - cp_plugin_info_t *plugin; - cp_status_t s; - hnode_t *hnode; - - // Allocate memory for plug-in descriptor path - if (pdir_path_size <= pdir_path_len) { - char *new_pdir_path; - - if (pdir_path_size == 0) { - pdir_path_size = 128; - } - while (pdir_path_size <= pdir_path_len) { - pdir_path_size *= 2; - } - new_pdir_path = realloc(pdir_path, pdir_path_size * sizeof(char)); - if (new_pdir_path == NULL) { - cpi_errorf(context, N_("Could not check possible plug-in location %s%c%s due to insufficient system resources."), dir_path, CP_FNAMESEP_CHAR, de->d_name); - status = CP_ERR_RESOURCE; - // continue loading plug-ins from other directories - continue; - } - pdir_path = new_pdir_path; - } - - // Construct plug-in descriptor path - strcpy(pdir_path, dir_path); - pdir_path[dir_path_len] = CP_FNAMESEP_CHAR; - strcpy(pdir_path + dir_path_len + 1, de->d_name); - - // Try to load a plug-in - plugin = cp_load_plugin_descriptor(context, pdir_path, &s); - if (plugin == NULL) { - status = s; - // continue loading plug-ins from other directories - continue; - } - - // Insert plug-in to the list of available plug-ins - if ((hnode = hash_lookup(avail_plugins, plugin->identifier)) != NULL) { - cp_plugin_info_t *plugin2 = hnode_get(hnode); - if (cpi_vercmp(plugin->version, plugin2->version) > 0) { - hash_delete_free(avail_plugins, hnode); - cp_release_info(context, plugin2); - hnode = NULL; - } - } - if (hnode == NULL) { - if (!hash_alloc_insert(avail_plugins, plugin->identifier, plugin)) { - cpi_errorf(context, N_("Plug-in %s version %s could not be loaded due to insufficient system resources."), plugin->identifier, plugin->version); - cp_release_info(context, plugin); - status = CP_ERR_RESOURCE; - // continue loading plug-ins from other directories - continue; - } - } - - } - errno = 0; - } - if (errno) { - cpi_errorf(context, N_("Could not read plug-in directory %s: %s"), dir_path, strerror(errno)); - status = CP_ERR_IO; - // continue loading plug-ins from other directories - } - closedir(dir); - } else { - cpi_errorf(context, N_("Could not open plug-in directory %s: %s"), dir_path, strerror(errno)); - status = CP_ERR_IO; - // continue loading plug-ins from other directories - } - - lnode = list_next(context->env->plugin_dirs, lnode); - } - - // Copy the list of started plug-ins, if necessary - if ((flags & CP_SP_RESTART_ACTIVE) - && (flags & (CP_SP_UPGRADE | CP_SP_STOP_ALL_ON_INSTALL))) { - int i; - cp_status_t s; - - if ((plugins = cp_get_plugins_info(context, &s, NULL)) == NULL) { - status = s; - break; - } - if ((started_plugins = list_create(LISTCOUNT_T_MAX)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - for (i = 0; plugins[i] != NULL; i++) { - cp_plugin_state_t state; - - state = cp_get_plugin_state(context, plugins[i]->identifier); - if (state == CP_PLUGIN_STARTING || state == CP_PLUGIN_ACTIVE) { - char *pid; - - if ((pid = strdup(plugins[i]->identifier)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - if ((lnode = lnode_create(pid)) == NULL) { - free(pid); - status = CP_ERR_RESOURCE; - break; - } - list_append(started_plugins, lnode); - } - } - cpi_release_info(context, plugins); - plugins = NULL; - } - - // Install/upgrade plug-ins - hash_scan_begin(&hscan, avail_plugins); - while ((hnode = hash_scan_next(&hscan)) != NULL) { - cp_plugin_info_t *plugin; - cp_plugin_t *ip = NULL; - hnode_t *hn2; - int s; - - plugin = hnode_get(hnode); - hn2 = hash_lookup(context->env->plugins, plugin->identifier); - if (hn2 != NULL) { - ip = hnode_get(hn2); - } - - // Unload the installed plug-in if it is to be upgraded - if (ip != NULL - && (flags & CP_SP_UPGRADE) - && ((ip->plugin->version == NULL && plugin->version != NULL) - || (ip->plugin->version != NULL - && plugin->version != NULL - && cpi_vercmp(plugin->version, ip->plugin->version) > 0))) { - if ((flags & (CP_SP_STOP_ALL_ON_UPGRADE | CP_SP_STOP_ALL_ON_INSTALL)) - && !plugins_stopped) { - plugins_stopped = 1; - cp_stop_plugins(context); - } - s = cp_uninstall_plugin(context, plugin->identifier); - assert(s == CP_OK); - ip = NULL; - } - - // Install the plug-in, if to be installed - if (ip == NULL) { - if ((flags & CP_SP_STOP_ALL_ON_INSTALL) && !plugins_stopped) { - plugins_stopped = 1; - cp_stop_plugins(context); - } - if ((s = cp_install_plugin(context, plugin)) != CP_OK) { - status = s; - break; - } - } - - // Remove the plug-in from the hash - hash_scan_delfree(avail_plugins, hnode); - cp_release_info(context, plugin); - } - - // Restart stopped plug-ins if necessary - if (started_plugins != NULL) { - lnode = list_first(started_plugins); - while (lnode != NULL) { - char *pid; - int s; - - pid = lnode_get(lnode); - s = cp_start_plugin(context, pid); - if (s != CP_OK) { - status = s; - } - lnode = list_next(started_plugins, lnode); - } - } - - } while (0); - - // Report error - switch (status) { - case CP_OK: - cpi_info(context, N_("Plug-in scan has completed successfully.")); - break; - case CP_ERR_RESOURCE: - cpi_error(context, N_("Could not scan plug-ins due to insufficient system resources.")); - break; - default: - cpi_warn(context, N_("Not all directories were successfully scanned.")); - break; - } - cpi_unlock_context(context); - - // Release resources - if (pdir_path != NULL) { - free(pdir_path); - } - if (avail_plugins != NULL) { - hscan_t hscan; - hnode_t *hnode; - - hash_scan_begin(&hscan, avail_plugins); - while ((hnode = hash_scan_next(&hscan)) != NULL) { - cp_plugin_info_t *p = hnode_get(hnode); - hash_scan_delfree(avail_plugins, hnode); - cp_release_info(context, p); - } - hash_destroy(avail_plugins); - } - if (started_plugins != NULL) { - list_process(started_plugins, NULL, cpi_process_free_ptr); - list_destroy(started_plugins); - } - if (plugins != NULL) { - cp_release_info(context, plugins); - } - - return status; -} diff --git a/lib/cpluff/libcpluff/psymbol.c b/lib/cpluff/libcpluff/psymbol.c deleted file mode 100644 index 988d903790..0000000000 --- a/lib/cpluff/libcpluff/psymbol.c +++ /dev/null @@ -1,343 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Dynamic plug-in symbols - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include "../kazlib/hash.h" -#include "cpluff.h" -#include "defines.h" -#include "internal.h" -#include "util.h" -#ifdef _WIN32 -#include <windows.h> -#endif - - -/* ------------------------------------------------------------------------ - * Data structures - * ----------------------------------------------------------------------*/ - -/// Information about symbol providing plug-in -typedef struct symbol_provider_info_t { - - // The providing plug-in - cp_plugin_t *plugin; - - // Whether there is also an import dependency for the plug-in - int imported; - - // Total symbol usage count - int usage_count; - -} symbol_provider_info_t; - -/// Information about used symbol -typedef struct symbol_info_t { - - // Symbol usage count - int usage_count; - - // Information about providing plug-in - symbol_provider_info_t *provider_info; - -} symbol_info_t; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -CP_C_API cp_status_t cp_define_symbol(cp_context_t *context, const char *name, void *ptr) { - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(name); - CHECK_NOT_NULL(ptr); - if (context->plugin == NULL) { - cpi_fatalf(_("Only plug-ins can define context specific symbols.")); - } - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER | CPI_CF_LISTENER, __func__); - do { - char *n; - - // Create a symbol hash if necessary - if (context->plugin->defined_symbols == NULL) { - if ((context->plugin->defined_symbols = hash_create(HASHCOUNT_T_MAX, (int (*)(const void *, const void *)) strcmp, NULL)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - } - - // Check for a previously defined symbol - if (hash_lookup(context->plugin->defined_symbols, name) != NULL) { - status = CP_ERR_CONFLICT; - break; - } - - // Insert the symbol into the symbol hash - n = strdup(name); - if (n == NULL || !hash_alloc_insert(context->plugin->defined_symbols, n, ptr)) { - free(n); - status = CP_ERR_RESOURCE; - break; - } - - } while (0); - - // Report error - if (status != CP_OK) { - switch (status) { - case CP_ERR_RESOURCE: - cpi_errorf(context, N_("Plug-in %s could not define symbol %s due to insufficient memory."), context->plugin->plugin->identifier, name); - break; - case CP_ERR_CONFLICT: - cpi_errorf(context, N_("Plug-in %s tried to redefine symbol %s."), context->plugin->plugin->identifier, name); - break; - default: - break; - } - } - cpi_unlock_context(context); - - return status; -} - -CP_C_API void * cp_resolve_symbol(cp_context_t *context, const char *id, const char *name, cp_status_t *error) { - cp_status_t status = CP_OK; - int error_reported = 1; - hnode_t *node; - void *symbol = NULL; - symbol_info_t *symbol_info = NULL; - symbol_provider_info_t *provider_info = NULL; - cp_plugin_t *pp = NULL; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(id); - CHECK_NOT_NULL(name); - - // Resolve the symbol - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER | CPI_CF_LISTENER | CPI_CF_STOP, __func__); - do { - - // Allocate space for symbol hashes, if necessary - if (context->resolved_symbols == NULL) { - context->resolved_symbols = hash_create(HASHCOUNT_T_MAX, cpi_comp_ptr, cpi_hashfunc_ptr); - } - if (context->symbol_providers == NULL) { - context->symbol_providers = hash_create(HASHCOUNT_T_MAX, cpi_comp_ptr, cpi_hashfunc_ptr); - } - if (context->resolved_symbols == NULL - || context->symbol_providers == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Look up the symbol defining plug-in - node = hash_lookup(context->env->plugins, id); - if (node == NULL) { - cpi_warnf(context, N_("Symbol %s in unknown plug-in %s could not be resolved."), name, id); - status = CP_ERR_UNKNOWN; - break; - } - pp = hnode_get(node); - - // Make sure the plug-in has been started - if ((status = cpi_start_plugin(context, pp)) != CP_OK) { - cpi_errorf(context, N_("Symbol %s in plug-in %s could not be resolved because the plug-in could not be started."), name, id); - error_reported = 1; - break; - } - - // Check for a context specific symbol - if (pp->defined_symbols != NULL && (node = hash_lookup(pp->defined_symbols, name)) != NULL) { - symbol = hnode_get(node); - } - - // Fall back to global symbols, if necessary - if (symbol == NULL && pp->runtime_lib != NULL) { - symbol = DLSYM(pp->runtime_lib, name); - } - if (symbol == NULL) { - const char *error = DLERROR(); - if (error == NULL) { - error = _("Unspecified error."); - } - cpi_warnf(context, N_("Symbol %s in plug-in %s could not be resolved: %s"), name, id, error); - status = CP_ERR_UNKNOWN; - break; - } - - // Lookup or initialize symbol provider information - if ((node = hash_lookup(context->symbol_providers, pp)) != NULL) { - provider_info = hnode_get(node); - } else { - if ((provider_info = malloc(sizeof(symbol_provider_info_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - memset(provider_info, 0, sizeof(symbol_provider_info_t)); - provider_info->plugin = pp; - provider_info->imported = (context->plugin == NULL || cpi_ptrset_contains(context->plugin->imported, pp)); - if (!hash_alloc_insert(context->symbol_providers, pp, provider_info)) { - status = CP_ERR_RESOURCE; - break; - } - } - - // Lookup or initialize symbol information - if ((node = hash_lookup(context->resolved_symbols, symbol)) != NULL) { - symbol_info = hnode_get(node); - } else { - if ((symbol_info = malloc(sizeof(symbol_info_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - memset(symbol_info, 0, sizeof(symbol_info_t)); - symbol_info->provider_info = provider_info; - if (!hash_alloc_insert(context->resolved_symbols, symbol, symbol_info)) { - status = CP_ERR_RESOURCE; - break; - } - } - - // Add dependencies (for plug-in) - if (provider_info != NULL - && !provider_info->imported - && provider_info->usage_count == 0) { - if (!cpi_ptrset_add(context->plugin->imported, pp)) { - status = CP_ERR_RESOURCE; - break; - } - if (!cpi_ptrset_add(pp->importing, context->plugin)) { - cpi_ptrset_remove(context->plugin->imported, pp); - status = CP_ERR_RESOURCE; - break; - } - cpi_debugf(context, N_("A dynamic dependency was created from plug-in %s to plug-in %s."), context->plugin->plugin->identifier, pp->plugin->identifier); - } - - // Increase usage counts - symbol_info->usage_count++; - provider_info->usage_count++; - - if (cpi_is_logged(context, CP_LOG_DEBUG)) { - char owner[64]; - /* TRANSLATORS: First %s is the context owner */ - cpi_debugf(context, N_("%s resolved symbol %s defined by plug-in %s."), cpi_context_owner(context, owner, sizeof(owner)), name, id); - } - } while (0); - - // Clean up - if (symbol_info != NULL && symbol_info->usage_count == 0) { - if ((node = hash_lookup(context->resolved_symbols, symbol)) != NULL) { - hash_delete_free(context->resolved_symbols, node); - } - free(symbol_info); - } - if (provider_info != NULL && provider_info->usage_count == 0) { - if ((node = hash_lookup(context->symbol_providers, pp)) != NULL) { - hash_delete_free(context->symbol_providers, node); - } - free(provider_info); - } - - // Report insufficient memory error - if (status == CP_ERR_RESOURCE && !error_reported) { - cpi_errorf(context, N_("Symbol %s in plug-in %s could not be resolved due to insufficient memory."), name, id); - } - cpi_unlock_context(context); - - // Return error code - if (error != NULL) { - *error = status; - } - - // Return symbol - return symbol; -} - -CP_C_API void cp_release_symbol(cp_context_t *context, const void *ptr) { - hnode_t *node; - symbol_info_t *symbol_info; - symbol_provider_info_t *provider_info; - - CHECK_NOT_NULL(context); - CHECK_NOT_NULL(ptr); - - cpi_lock_context(context); - cpi_check_invocation(context, CPI_CF_LOGGER | CPI_CF_LISTENER, __func__); - do { - - // Look up the symbol - if ((node = hash_lookup(context->resolved_symbols, ptr)) == NULL) { - cpi_errorf(context, N_("Could not release unknown symbol at address %p."), ptr); - break; - } - symbol_info = hnode_get(node); - provider_info = symbol_info->provider_info; - - // Decrease usage count - assert(symbol_info->usage_count > 0); - symbol_info->usage_count--; - assert(provider_info->usage_count > 0); - provider_info->usage_count--; - - // Check if the symbol is not being used anymore - if (symbol_info->usage_count == 0) { - hash_delete_free(context->resolved_symbols, node); - free(symbol_info); - if (cpi_is_logged(context, CP_LOG_DEBUG)) { - char owner[64]; - /* TRANSLATORS: First %s is the context owner */ - cpi_debugf(context, N_("%s released the symbol at address %p defined by plug-in %s."), cpi_context_owner(context, owner, sizeof(owner)), ptr, provider_info->plugin->plugin->identifier); - } - } - - // Check if the symbol providing plug-in is not being used anymore - if (provider_info->usage_count == 0) { - node = hash_lookup(context->symbol_providers, provider_info->plugin); - assert(node != NULL); - hash_delete_free(context->symbol_providers, node); - if (!provider_info->imported) { - cpi_ptrset_remove(context->plugin->imported, provider_info->plugin); - cpi_ptrset_remove(provider_info->plugin->importing, context->plugin); - cpi_debugf(context, N_("A dynamic dependency from plug-in %s to plug-in %s was removed."), context->plugin->plugin->identifier, provider_info->plugin->plugin->identifier); - } - free(provider_info); - } - - } while (0); - cpi_unlock_context(context); -} diff --git a/lib/cpluff/libcpluff/serial.c b/lib/cpluff/libcpluff/serial.c deleted file mode 100644 index a7885888c8..0000000000 --- a/lib/cpluff/libcpluff/serial.c +++ /dev/null @@ -1,205 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Serial execution implementation - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include "cpluff.h" -#include "internal.h" - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -/// A holder structure for a run function. -typedef struct run_func_t { - - /// The run function - cp_run_func_t runfunc; - - /// The registering plug-in instance - cp_plugin_t *plugin; - - /// Whether currently in execution - int in_execution; - -} run_func_t; - -CP_C_API cp_status_t cp_run_function(cp_context_t *ctx, cp_run_func_t runfunc) { - lnode_t *node = NULL; - run_func_t *rf = NULL; - cp_status_t status = CP_OK; - - CHECK_NOT_NULL(ctx); - CHECK_NOT_NULL(runfunc); - if (ctx->plugin == NULL) { - cpi_fatalf(_("Only plug-ins can register run functions.")); - } - if (ctx->plugin->state != CP_PLUGIN_ACTIVE - && ctx->plugin->state != CP_PLUGIN_STARTING) { - cpi_fatalf(_("Only starting or active plug-ins can register run functions.")); - } - - cpi_lock_context(ctx); - cpi_check_invocation(ctx, CPI_CF_STOP | CPI_CF_LOGGER, __func__); - do { - int found = 0; - lnode_t *n; - - // Check if already registered - n = list_first(ctx->env->run_funcs); - while (n != NULL && !found) { - run_func_t *r = lnode_get(n); - if (runfunc == r->runfunc && ctx->plugin == r->plugin) { - found = 1; - } - n = list_next(ctx->env->run_funcs, n); - } - if (found) { - break; - } - - // Allocate memory for a new run function entry - if ((rf = malloc(sizeof(run_func_t))) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - if ((node = lnode_create(rf)) == NULL) { - status = CP_ERR_RESOURCE; - break; - } - - // Initialize run function entry - memset(rf, 0, sizeof(run_func_t)); - rf->runfunc = runfunc; - rf->plugin = ctx->plugin; - - // Append the run function to queue - list_append(ctx->env->run_funcs, node); - if (ctx->env->run_wait == NULL) { - ctx->env->run_wait = node; - } - - } while (0); - - // Log error - if (status == CP_ERR_RESOURCE) { - cpi_error(ctx, N_("Could not register a run function due to insufficient memory.")); - } - cpi_unlock_context(ctx); - - // Free resources on error - if (status != CP_OK) { - if (node != NULL) { - lnode_destroy(node); - } - if (rf != NULL) { - free(rf); - } - } - - return status; -} - -CP_C_API void cp_run_plugins(cp_context_t *ctx) { - while (cp_run_plugins_step(ctx)); -} - -CP_C_API int cp_run_plugins_step(cp_context_t *ctx) { - int runnables; - - CHECK_NOT_NULL(ctx); - cpi_lock_context(ctx); - if (ctx->env->run_wait != NULL) { - lnode_t *node = ctx->env->run_wait; - run_func_t *rf = lnode_get(node); - int rerun; - - ctx->env->run_wait = list_next(ctx->env->run_funcs, node); - rf->in_execution = 1; - cpi_unlock_context(ctx); - rerun = rf->runfunc(rf->plugin->plugin_data); - cpi_lock_context(ctx); - rf->in_execution = 0; - list_delete(ctx->env->run_funcs, node); - if (rerun) { - list_append(ctx->env->run_funcs, node); - if (ctx->env->run_wait == NULL) { - ctx->env->run_wait = node; - } - } else { - lnode_destroy(node); - free(rf); - } - cpi_signal_context(ctx); - } - runnables = (ctx->env->run_wait != NULL); - cpi_unlock_context(ctx); - return runnables; -} - -CP_HIDDEN void cpi_stop_plugin_run(cp_plugin_t *plugin) { - int stopped = 0; - cp_context_t *ctx; - - CHECK_NOT_NULL(plugin); - ctx = plugin->context; - assert(cpi_is_context_locked(ctx)); - while (!stopped) { - lnode_t *node; - - stopped = 1; - node = list_first(ctx->env->run_funcs); - while (node != NULL) { - run_func_t *rf = lnode_get(node); - lnode_t *next_node = list_next(ctx->env->run_funcs, node); - - if (rf->plugin == plugin) { - if (rf->in_execution) { - stopped = 0; - } else { - if (ctx->env->run_wait == node) { - ctx->env->run_wait = list_next(ctx->env->run_funcs, node); - } - list_delete(ctx->env->run_funcs, node); - lnode_destroy(node); - free(rf); - } - } - node = next_node; - } - - // If some run functions were in execution, wait for them to finish - if (!stopped) { - cpi_wait_context(ctx); - } - } -} diff --git a/lib/cpluff/libcpluff/thread.h b/lib/cpluff/libcpluff/thread.h deleted file mode 100644 index fff9e39b50..0000000000 --- a/lib/cpluff/libcpluff/thread.h +++ /dev/null @@ -1,120 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Declarations for generic mutex functions and types - */ - -#ifndef THREAD_H_ -#define THREAD_H_ -#ifdef CP_THREADS - -#include "defines.h" - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -// A generic mutex implementation -typedef struct cpi_mutex_t cpi_mutex_t; - - -/* ------------------------------------------------------------------------ - * Function declarations - * ----------------------------------------------------------------------*/ - -// Mutex functions - -/** - * Creates a mutex. The mutex is initially available. - * - * @return the created mutex or NULL if no resources available - */ -CP_HIDDEN cpi_mutex_t * cpi_create_mutex(void); - -/** - * Destroys the specified mutex. - * - * @param mutex the mutex - */ -CP_HIDDEN void cpi_destroy_mutex(cpi_mutex_t *mutex); - -/** - * Waits for the specified mutex to become available and locks it. - * If the calling thread has already locked the mutex then the - * lock count of the mutex is increased. - * - * @param mutex the mutex - */ -CP_HIDDEN void cpi_lock_mutex(cpi_mutex_t *mutex); - -/** - * Unlocks the specified mutex which must have been previously locked - * by this thread. If there has been several calls to cpi_lock_mutex - * by the same thread then the mutex is unlocked only after corresponding - * number of unlock requests. - * - * @param mutex the mutex - */ -CP_HIDDEN void cpi_unlock_mutex(cpi_mutex_t *mutex); - -/** - * Waits on the specified mutex until it is signaled. The calling thread - * must hold the mutex. The mutex is released on call to this function and - * it is reacquired before the function returns. - * - * @param mutex the mutex to wait on - */ -CP_HIDDEN void cpi_wait_mutex(cpi_mutex_t *mutex); - -/** - * Signals the specified mutex waking all the threads currently waiting on - * the mutex. The calling thread must hold the mutex. The mutex is not - * released. - * - * @param mutex the mutex to be signaled - */ -CP_HIDDEN void cpi_signal_mutex(cpi_mutex_t *mutex); - -#if !defined(NDEBUG) - -/** - * Returns whether the mutex is currently locked. This function - * is only intended to be used for assertions. The returned state - * reflects the state of the mutex only at the time of inspection. - */ -CP_HIDDEN int cpi_is_mutex_locked(cpi_mutex_t *mutex); - -#endif - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //CP_THREADS -#endif //THREAD_H_ diff --git a/lib/cpluff/libcpluff/thread_posix.c b/lib/cpluff/libcpluff/thread_posix.c deleted file mode 100644 index 7a77889a63..0000000000 --- a/lib/cpluff/libcpluff/thread_posix.c +++ /dev/null @@ -1,232 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Posix implementation for generic mutex functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <pthread.h> -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" -#include "thread.h" - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -// A generic recursive mutex implementation -struct cpi_mutex_t { - - /// The current lock count - int lock_count; - - /// The underlying operating system mutex - pthread_mutex_t os_mutex; - - /// The condition variable for signaling availability - pthread_cond_t os_cond_lock; - - /// The condition variable for broadcasting a wake request - pthread_cond_t os_cond_wake; - - /// The locking thread if currently locked - pthread_t os_thread; - -}; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -CP_HIDDEN cpi_mutex_t * cpi_create_mutex(void) { - cpi_mutex_t *mutex; - - if ((mutex = malloc(sizeof(cpi_mutex_t))) == NULL) { - return NULL; - } - memset(mutex, 0, sizeof(cpi_mutex_t)); - if (pthread_mutex_init(&(mutex->os_mutex), NULL)) { - return NULL; - } else if (pthread_cond_init(&(mutex->os_cond_lock), NULL)) { - int ec; - - ec = pthread_mutex_destroy(&(mutex->os_mutex)); - assert(!ec); - return NULL; - } else if (pthread_cond_init(&(mutex->os_cond_wake), NULL)) { - int ec; - - ec = pthread_mutex_destroy(&(mutex->os_mutex)); - assert(!ec); - ec = pthread_cond_destroy(&(mutex->os_cond_wake)); - assert(!ec); - return NULL; - } - return mutex; -} - -CP_HIDDEN void cpi_destroy_mutex(cpi_mutex_t *mutex) { - int ec; - - assert(mutex != NULL); - assert(mutex->lock_count == 0); - ec = pthread_mutex_destroy(&(mutex->os_mutex)); - assert(!ec); - ec = pthread_cond_destroy(&(mutex->os_cond_lock)); - assert(!ec); - ec = pthread_cond_destroy(&(mutex->os_cond_wake)); - assert(!ec); - free(mutex); -} - -static void lock_mutex(pthread_mutex_t *mutex) { - int ec; - - if ((ec = pthread_mutex_lock(mutex))) { - cpi_fatalf(_("Could not lock a mutex due to error %d."), ec); - } -} - -static void unlock_mutex(pthread_mutex_t *mutex) { - int ec; - - if ((ec = pthread_mutex_unlock(mutex))) { - cpi_fatalf(_("Could not unlock a mutex due to error %d."), ec); - } -} - -static void lock_mutex_holding(cpi_mutex_t *mutex) { - pthread_t self = pthread_self(); - - while (mutex->lock_count != 0 - && !pthread_equal(self, mutex->os_thread)) { - int ec; - - if ((ec = pthread_cond_wait(&(mutex->os_cond_lock), &(mutex->os_mutex)))) { - cpi_fatalf(_("Could not wait for a condition variable due to error %d."), ec); - } - } - mutex->os_thread = self; - mutex->lock_count++; -} - -CP_HIDDEN void cpi_lock_mutex(cpi_mutex_t *mutex) { - assert(mutex != NULL); - lock_mutex(&(mutex->os_mutex)); - lock_mutex_holding(mutex); - unlock_mutex(&(mutex->os_mutex)); -} - -CP_HIDDEN void cpi_unlock_mutex(cpi_mutex_t *mutex) { - pthread_t self = pthread_self(); - - assert(mutex != NULL); - lock_mutex(&(mutex->os_mutex)); - if (mutex->lock_count > 0 - && pthread_equal(self, mutex->os_thread)) { - if (--mutex->lock_count == 0) { - int ec; - - if ((ec = pthread_cond_signal(&(mutex->os_cond_lock)))) { - cpi_fatalf(_("Could not signal a condition variable due to error %d."), ec); - } - } - } else { - cpi_fatalf(_("Internal C-Pluff error: Unauthorized attempt at unlocking a mutex.")); - } - unlock_mutex(&(mutex->os_mutex)); -} - -CP_HIDDEN void cpi_wait_mutex(cpi_mutex_t *mutex) { - pthread_t self = pthread_self(); - - assert(mutex != NULL); - lock_mutex(&(mutex->os_mutex)); - if (mutex->lock_count > 0 - && pthread_equal(self, mutex->os_thread)) { - int ec; - int lc = mutex->lock_count; - - // Release mutex - mutex->lock_count = 0; - if ((ec = pthread_cond_signal(&(mutex->os_cond_lock)))) { - cpi_fatalf(_("Could not signal a condition variable due to error %d."), ec); - } - - // Wait for signal - if ((ec = pthread_cond_wait(&(mutex->os_cond_wake), &(mutex->os_mutex)))) { - cpi_fatalf(_("Could not wait for a condition variable due to error %d."), ec); - } - - // Re-acquire mutex and restore lock count for this thread - lock_mutex_holding(mutex); - mutex->lock_count = lc; - - } else { - cpi_fatalf(_("Internal C-Pluff error: Unauthorized attempt at waiting on a mutex.")); - } - unlock_mutex(&(mutex->os_mutex)); -} - -CP_HIDDEN void cpi_signal_mutex(cpi_mutex_t *mutex) { - pthread_t self = pthread_self(); - - assert(mutex != NULL); - lock_mutex(&(mutex->os_mutex)); - if (mutex->lock_count > 0 - && pthread_equal(self, mutex->os_thread)) { - int ec; - - // Signal the mutex - if ((ec = pthread_cond_broadcast(&(mutex->os_cond_wake)))) { - cpi_fatalf(_("Could not broadcast a condition variable due to error %d."), ec); - } - - } else { - cpi_fatalf(_("Internal C-Pluff error: Unauthorized attempt at signaling a mutex.")); - } - unlock_mutex(&(mutex->os_mutex)); -} - -#if !defined(NDEBUG) -CP_HIDDEN int cpi_is_mutex_locked(cpi_mutex_t *mutex) { - int locked; - - lock_mutex(&(mutex->os_mutex)); - locked = (mutex->lock_count != 0); - unlock_mutex(&(mutex->os_mutex)); - return locked; -} -#endif diff --git a/lib/cpluff/libcpluff/thread_windows.c b/lib/cpluff/libcpluff/thread_windows.c deleted file mode 100644 index de1f37ed88..0000000000 --- a/lib/cpluff/libcpluff/thread_windows.c +++ /dev/null @@ -1,272 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Windows implementation for generic mutex functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <windows.h> -#include "cpluff.h" -#include "defines.h" -#include "util.h" -#include "internal.h" -#include "thread.h" - - -/* ------------------------------------------------------------------------ - * Data types - * ----------------------------------------------------------------------*/ - -// A generic recursive mutex implementation -struct cpi_mutex_t { - - /// The current lock count - int lock_count; - - /// The underlying operating system mutex - HANDLE os_mutex; - - /// The condition variable for signaling availability - HANDLE os_cond_lock; - - /// The condition variable for signaling a wake request - HANDLE os_cond_wake; - - /// Number of threads currently waiting on this mutex - int num_wait_threads; - - /// The locking thread if currently locked - DWORD os_thread; - -}; - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -CP_HIDDEN cpi_mutex_t * cpi_create_mutex(void) { - cpi_mutex_t *mutex; - - if ((mutex = malloc(sizeof(cpi_mutex_t))) == NULL) { - return NULL; - } - memset(mutex, 0, sizeof(cpi_mutex_t)); - if ((mutex->os_mutex = CreateMutex(NULL, FALSE, NULL)) == NULL) { - return NULL; - } else if ((mutex->os_cond_lock = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) { - int ec; - - ec = CloseHandle(mutex->os_mutex); - assert(ec); - return NULL; - } else if ((mutex->os_cond_wake = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { - int ec; - - ec = CloseHandle(mutex->os_mutex); - assert(ec); - ec = CloseHandle(mutex->os_cond_lock); - assert(ec); - return NULL; - } - return mutex; -} - -CP_HIDDEN void cpi_destroy_mutex(cpi_mutex_t *mutex) { - int ec; - - assert(mutex != NULL); - assert(mutex->lock_count == 0); - ec = CloseHandle(mutex->os_mutex); - assert(ec); - ec = CloseHandle(mutex->os_cond_lock); - assert(ec); - ec = CloseHandle(mutex->os_cond_wake); - assert(ec); - free(mutex); -} - -static char *get_win_errormsg(DWORD error, char *buffer, size_t size) { - if (!FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS - | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - error, - 0, - buffer, - size / sizeof(char), - NULL)) { - strncpy(buffer, _("unknown error"), size); - } - buffer[size/sizeof(char) - 1] = '\0'; - return buffer; -} - -static void lock_mutex(HANDLE mutex) { - DWORD ec; - - if ((ec = WaitForSingleObject(mutex, INFINITE)) != WAIT_OBJECT_0) { - char buffer[256]; - ec = GetLastError(); - cpi_fatalf(_("Could not lock a mutex due to error %ld: %s"), - (long) ec, get_win_errormsg(ec, buffer, sizeof(buffer))); - } -} - -static void unlock_mutex(HANDLE mutex) { - if (!ReleaseMutex(mutex)) { - char buffer[256]; - DWORD ec = GetLastError(); - cpi_fatalf(_("Could not release a mutex due to error %ld: %s"), - (long) ec, get_win_errormsg(ec, buffer, sizeof(buffer))); - } -} - -static void wait_for_event(HANDLE event) { - if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) { - char buffer[256]; - DWORD ec = GetLastError(); - cpi_fatalf(_("Could not wait for an event due to error %ld: %s"), - (long) ec, get_win_errormsg(ec, buffer, sizeof(buffer))); - } -} - -static void set_event(HANDLE event) { - if (!SetEvent(event)) { - char buffer[256]; - DWORD ec = GetLastError(); - cpi_fatalf(_("Could not set an event due to error %ld: %s"), - (long) ec, get_win_errormsg(ec, buffer, sizeof(buffer))); - } -} - -static void reset_event(HANDLE event) { - if (!ResetEvent(event)) { - char buffer[256]; - DWORD ec = GetLastError(); - cpi_fatalf(_("Could not reset an event due to error %ld: %s"), - (long) ec, get_win_errormsg(ec, buffer, sizeof(buffer))); - } -} - -static void lock_mutex_holding(cpi_mutex_t *mutex) { - DWORD self = GetCurrentThreadId(); - - while (mutex->lock_count != 0 - && self != mutex->os_thread) { - unlock_mutex(mutex->os_mutex); - wait_for_event(mutex->os_cond_lock); - lock_mutex(mutex->os_mutex); - } - mutex->os_thread = self; - mutex->lock_count++; -} - -CP_HIDDEN void cpi_lock_mutex(cpi_mutex_t *mutex) { - assert(mutex != NULL); - lock_mutex(mutex->os_mutex); - lock_mutex_holding(mutex); - unlock_mutex(mutex->os_mutex); -} - -CP_HIDDEN void cpi_unlock_mutex(cpi_mutex_t *mutex) { - DWORD self = GetCurrentThreadId(); - - assert(mutex != NULL); - lock_mutex(mutex->os_mutex); - if (mutex->lock_count > 0 - && self == mutex->os_thread) { - if (--mutex->lock_count == 0) { - set_event(mutex->os_cond_lock); - } - } else { - cpi_fatalf(_("Internal C-Pluff error: Unauthorized attempt at unlocking a mutex.")); - } - unlock_mutex(mutex->os_mutex); -} - -CP_HIDDEN void cpi_wait_mutex(cpi_mutex_t *mutex) { - DWORD self = GetCurrentThreadId(); - - assert(mutex != NULL); - lock_mutex(mutex->os_mutex); - if (mutex->lock_count > 0 - && self == mutex->os_thread) { - int lc = mutex->lock_count; - - // Release mutex - mutex->lock_count = 0; - mutex->num_wait_threads++; - set_event(mutex->os_cond_lock); - unlock_mutex(mutex->os_mutex); - - // Wait for signal - wait_for_event(mutex->os_cond_wake); - - // Reset wake signal if last one waking up - lock_mutex(mutex->os_mutex); - if (--mutex->num_wait_threads == 0) { - reset_event(mutex->os_cond_wake); - } - - // Re-acquire mutex and restore lock count for this thread - lock_mutex_holding(mutex); - mutex->lock_count = lc; - - } else { - cpi_fatalf(_("Internal C-Pluff error: Unauthorized attempt at waiting on a mutex.")); - } - unlock_mutex(mutex->os_mutex); -} - -CP_HIDDEN void cpi_signal_mutex(cpi_mutex_t *mutex) { - DWORD self = GetCurrentThreadId(); - - assert(mutex != NULL); - lock_mutex(mutex->os_mutex); - if (mutex->lock_count > 0 - && self == mutex->os_thread) { - set_event(mutex->os_cond_wake); - } else { - cpi_fatalf(_("Internal C-Pluff error: Unauthorized attempt at signaling a mutex.")); - } - unlock_mutex(mutex->os_mutex); -} - -#if !defined(NDEBUG) -CP_HIDDEN int cpi_is_mutex_locked(cpi_mutex_t *mutex) { - int locked; - - lock_mutex(mutex->os_mutex); - locked = (mutex->lock_count != 0); - unlock_mutex(mutex->os_mutex); - return locked; -} -#endif diff --git a/lib/cpluff/libcpluff/util.c b/lib/cpluff/libcpluff/util.c deleted file mode 100644 index e5ff7cfcfa..0000000000 --- a/lib/cpluff/libcpluff/util.c +++ /dev/null @@ -1,216 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Internal utility functions - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <assert.h> -#include "../kazlib/list.h" -#include "cpluff.h" -#include "defines.h" -#include "util.h" - - -/* ------------------------------------------------------------------------ - * Function definitions - * ----------------------------------------------------------------------*/ - -CP_HIDDEN int cpi_comp_ptr(const void *ptr1, const void *ptr2) { - return !(ptr1 == ptr2); -} - -CP_HIDDEN hash_val_t cpi_hashfunc_ptr(const void *ptr) { - return (hash_val_t) ptr; -} - -CP_HIDDEN int cpi_ptrset_add(list_t *set, void *ptr) { - - - // Only add the pointer if it is not already included - if (cpi_ptrset_contains(set, ptr)) { - return 1; - } else { - lnode_t *node; - - /* Add the pointer to the list */ - node = lnode_create(ptr); - if (node == NULL) { - return 0; - } - list_append(set, node); - return 1; - } - -} - -CP_HIDDEN int cpi_ptrset_remove(list_t *set, const void *ptr) { - lnode_t *node; - - // Find the pointer if it is in the set - node = list_find(set, ptr, cpi_comp_ptr); - if (node != NULL) { - list_delete(set, node); - lnode_destroy(node); - return 1; - } else { - return 0; - } -} - -CP_HIDDEN int cpi_ptrset_contains(list_t *set, const void *ptr) { - return list_find(set, ptr, cpi_comp_ptr) != NULL; -} - -CP_HIDDEN void cpi_process_free_ptr(list_t *list, lnode_t *node, void *dummy) { - void *ptr = lnode_get(node); - list_delete(list, node); - lnode_destroy(node); - free(ptr); -} - -static const char *vercmp_nondigit_end(const char *v) { - while (*v != '\0' && (*v < '0' || *v > '9')) { - v++; - } - return v; -} - -static const char *vercmp_digit_end(const char *v) { - while (*v >= '0' && *v <= '9') { - v++; - } - return v; -} - -static int vercmp_char_value(char c) { - if (c == '\0') { - return 0; - } else if (c >= 'A' && c <= 'Z') { - return 1 + (c - 'A'); - } else if (c >= 'a' && c <= 'z') { - return 1 + ('Z' - 'A' + 1) + (c - 'a'); - } else { - int i = 1 + ('Z' - 'A' + 1) + ('z' - 'a' + 1) + ((int) c - CHAR_MIN); - if (c > 'z') { - i -= 'z' - 'a' + 1; - } - if (c > 'Z') { - i -= 'Z' - 'A' + 1; - } - if (c > '\0') { - i--; - } - return i; - } -} - -static int vercmp_num_value(const char *v, const char *vn) { - - // Skip leading zeros - while (v < vn && *v == '0') { - v++; - } - - // Empty string equals to zero - if (v == vn) { - return 0; - } - - // Otherwise return the integer value - else { - char str[16]; - strncpy(str, v, vn - v < 16 ? vn - v : 16); - str[vn - v < 16 ? vn - v : 15] = '\0'; - return atoi(str); - } -} - -CP_HIDDEN int cpi_vercmp(const char *v1, const char *v2) { - const char *v1n; - const char *v2n; - int diff; - - // Check for NULL versions - if (v1 == NULL && v2 != NULL) { - return -1; - } else if (v1 == NULL && v2 == NULL) { - return 0; - } else if (v1 != NULL && v2 == NULL) { - return 1; - } - assert(v1 != NULL && v2 != NULL); - - // Component comparison loop - while (*v1 != '\0' || *v2 != '\0') { - - // Determine longest non-digit prefix - v1n = vercmp_nondigit_end(v1); - v2n = vercmp_nondigit_end(v2); - - // Compare the non-digit strings - while (v1 < v1n || v2 < v2n) { - char c1 = '\0'; - char c2 = '\0'; - - if (v1 < v1n) { - c1 = *v1++; - } - if (v2 < v2n) { - c2 = *v2++; - } - diff = vercmp_char_value(c1) - vercmp_char_value(c2); - if (diff != 0) { - return diff; - } - assert(v1 <= v1n && v2 <= v2n); - } - assert(v1 == v1n && v2 == v2n); - - // Determine the longest digit prefix - v1n = vercmp_digit_end(v1); - v2n = vercmp_digit_end(v2); - - // Compare the digit strings - { - int i1 = vercmp_num_value(v1, v1n); - int i2 = vercmp_num_value(v2, v2n); - int diff = i1 - i2; - if (diff != 0) { - return diff; - } - } - v1 = v1n; - v2 = v2n; - - } - return 0; -} diff --git a/lib/cpluff/libcpluff/util.h b/lib/cpluff/libcpluff/util.h deleted file mode 100644 index 837580a4cb..0000000000 --- a/lib/cpluff/libcpluff/util.h +++ /dev/null @@ -1,131 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Declarations for internal utility functions - */ - -#ifndef UTIL_H_ -#define UTIL_H_ - -#include "../kazlib/list.h" -#include "../kazlib/hash.h" -#include "cpluff.h" -#include "defines.h" - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -/* ------------------------------------------------------------------------ - * Function declarations - * ----------------------------------------------------------------------*/ - -// For operating on smallish pointer sets implemented as lists - -/** - * Compares pointers. - * - * @param ptr1 the first pointer - * @param ptr2 the second pointer - * @return zero if the pointers are equal, otherwise non-zero - */ -CP_HIDDEN int cpi_comp_ptr(const void *ptr1, const void *ptr2) CP_GCC_CONST; - -/** - * Returns a hash value for a pointer. - * - * @param ptr the pointer being hashed - * @return the corresponding hash value - */ -CP_HIDDEN hash_val_t cpi_hashfunc_ptr(const void *ptr) CP_GCC_CONST; - -/** - * Adds a new pointer to a list if the pointer is not yet included. - * - * @param set the set being operated on - * @param ptr the pointer being added - * @return non-zero if the operation was successful, zero if allocation failed - */ -CP_HIDDEN int cpi_ptrset_add(list_t *set, void *ptr); - -/** - * Removes a pointer from a pointer set, if it is included. - * - * @param set the set being operated on - * @param ptr the pointer being removed - * @return whether the pointer was contained in the set - */ -CP_HIDDEN int cpi_ptrset_remove(list_t *set, const void *ptr); - -/** - * Returns whether a pointer is included in a pointer set. - * - * @param set the set being operated on - * @param ptr the pointer - * @return non-zero if the pointer is included, zero otherwise - */ -CP_HIDDEN int cpi_ptrset_contains(list_t *set, const void *ptr) CP_GCC_PURE; - - -// Other list processing utility functions - -/** - * Processes a node of the list by freeing the associated pointer and - * deleting and destroying the node. - * - * @param list the list being processed - * @param node the list node being processed - * @param dummy a dummy argument to comply with prototype - */ -CP_HIDDEN void cpi_process_free_ptr(list_t *list, lnode_t *node, void *dummy); - - -// Version strings - -/** - * Compares two version strings. The comparison algorithm is derived from the - * way Debian package management system compares package versions. First the - * the longest prefix of each string composed entirely of non-digit characters - * is determined. These are compared lexically so that all the letters sort - * earlier than all the non-letters and otherwise the ordering is based on - * ASCII values. If there is a difference it is returned. Otherwise the longest - * prefix of remainder of each string composed entirely of digit characters - * is determined. These are compared numerically with empty string interpreted - * as zero. Again, if there is different it is returned. Otherwise the - * comparison continues with a non-digit component and so on. A NULL version - * is earlier than any non-NULL version. Two NULL versions are equal. - * - * @param v1 the first version string to compare or NULL - * @param v2 the second version string to compare or NULL - * @return less than, equal to or greater than zero when @a v1 < @a v2, @a v1 == @a v2 or @a v1 > @a v2, correspondingly - */ -CP_HIDDEN int cpi_vercmp(const char *v1, const char *v2) CP_GCC_PURE; - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //UTIL_H_ diff --git a/lib/cpluff/libcpluff/win32/cpluffdef.h b/lib/cpluff/libcpluff/win32/cpluffdef.h deleted file mode 100644 index 7e3d55f269..0000000000 --- a/lib/cpluff/libcpluff/win32/cpluffdef.h +++ /dev/null @@ -1,216 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2007 Johannes Lehtinen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -/** @file - * Common defines shared by C-Pluff C and C++ APIs. - * This file is automatically included by the top level C and C++ - * API header files. There should be no need to include it explicitly. - */ - -#ifndef CPLUFFDEF_H_ -#define CPLUFFDEF_H_ - - -/* ------------------------------------------------------------------------ - * Version information - * ----------------------------------------------------------------------*/ - -/** - * @defgroup versionInfo Version information - * @ingroup cDefines cxxDefines - * - * C-Pluff version information. Notice that this version information - * is static version information included in header files. The - * macros introduced here can be used for compile time checks. - */ -/*@{*/ - -/** - * The C-Pluff release version string. This string identifies a specific - * version of the C-Pluff distribution. Compile time software compatibility - * checks should use #CP_VERSION_MAJOR and #CP_VERSION_MINOR instead. - */ -#define CP_VERSION "0.1.4" - -/** - * The major version number component of the release version. This is an - * integer. - */ -#define CP_VERSION_MAJOR 0 - -/** - * The minor version number component of the release version. This is an - * integer. - */ -#define CP_VERSION_MINOR 1 - -/*@}*/ - - -/* ------------------------------------------------------------------------ - * Symbol visibility - * ----------------------------------------------------------------------*/ - -/** - * @defgroup symbolVisibility Symbol visibility - * @ingroup cDefines cxxDefines - * - * Macros for controlling inter-module symbol visibility and linkage. These - * macros have platform specific values. #CP_EXPORT, #CP_IMPORT and #CP_HIDDEN - * can be reused by plug-in implementations for better portability. The - * complexity is mostly due to Windows DLL exports and imports. - * - * @anchor symbolVisibilityExample - * Each module should usually define its own macro to declare API symbols with - * #CP_EXPORT and #CP_IMPORT as necessary. For example, a mobule could define - * a macro @c MY_API in the API header file as follows. - * - * @code - * #ifndef MY_API - * # define MY_API CP_IMPORT - * #endif - * @endcode - * - * By default the API symbols would then be marked for import which is correct - * when client modules are including the API header file. When compiling the - * module itself the option @c -DMY_API=CP_EXPORT would be passed to the compiler to - * override the API header file and to mark the API symbols for export. - * The overriding definition could also be included in module source files or - * in an internal header file before including the API header file. - */ -/*@{*/ - -/** - * @def CP_EXPORT - * - * Declares a symbol to be exported for inter-module usage. When compiling the - * module which defines the symbol this macro should be placed - * at the start of the symbol declaration to ensure that the symbol is exported - * to other modules. However, when compiling other modules the declaration of - * the symbol should start with #CP_IMPORT. - * See @ref symbolVisibilityExample "the example" of how to do this. - */ - -/** - * @def CP_IMPORT - * - * Declares a symbol to be imported from another module. When compiling a - * module which uses the symbol this macro should be placed at the start of - * the symbol declaration to ensure that the symbol is imported from the - * defining module. However, when compiling the defining module the declaration - * of the symbol should start with #CP_EXPORT. - * See @ref symbolVisibilityExample "the example" of how to do this. - */ - -/** - * @def CP_HIDDEN - * - * Declares a symbol hidden from other modules. This macro should be - * placed at the start of the symbol declaration to hide the symbol from other - * modules (if supported by the platform). This macro is not intended to be - * used with symbols declared as "static" which are already internal to the - * object file. Some platforms do not support hiding of symbols and therefore - * unique prefixes should be used for global symbols internal to the module - * even when they are declared using this macro. - */ - -#if defined(_WIN32) -# define CP_EXPORT __declspec(dllexport) -#if defined(_WINDLL) -# define CP_IMPORT extern __declspec(dllimport) -#else -# define CP_IMPORT -#endif -# define CP_HIDDEN -#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) -# define CP_EXPORT -# define CP_IMPORT extern -# define CP_HIDDEN __attribute__ ((visibility ("hidden"))) -#else -# define CP_EXPORT -# define CP_IMPORT extern -# define CP_HIDDEN -#endif - -/*@}*/ - - -/* ------------------------------------------------------------------------ - * GCC attributes - * ----------------------------------------------------------------------*/ - -/** - * @defgroup cDefinesGCCAttributes GCC attributes - * @ingroup cDefines cxxDefines - * - * These macros conditionally define GCC attributes for declarations. - * They are used in C-Pluff API declarations to enable better optimization - * and error checking when using GCC. In non-GCC platforms they have - * empty values. - */ -/*@{*/ - -/** - * @def CP_GCC_PURE - * - * Declares a function as pure function having no side effects. - * This attribute is supported in GCC since version 2.96. - * Such functions can be subject to common subexpression elimination - * and loop optimization. - */ - -/** - * @def CP_GCC_NONNULL - * - * Specifies that some pointer arguments to a function should have - * non-NULL values. Takes a variable length list of argument indexes as - * arguments. This attribute is supported in GCC since version 3.3. - * It can be used for enhanced error checking and some optimizations. - */ - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -#define CP_GCC_PURE __attribute__((pure)) -#else -#define CP_GCC_PURE -#endif -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) -#define CP_GCC_NONNULL(...) __attribute__((nonnull (__VA_ARGS__))) -#else -#define CP_GCC_NONNULL(...) -#endif - -/*@}*/ - -#ifdef _WIN32 -#ifndef __func__ -# define __func__ __FUNCTION__ -#endif -#ifndef snprintf -#define snprintf _snprintf -#endif -#define CP_HOST "win32" -#define CP_SHREXT ".dll" -#define CP_FNAMESEP_CHAR '\\' // If we switch back to special:// paths then this can be '/' instead -#define CP_THREADS -#endif -#endif /*CPLUFFDEF_H_*/ diff --git a/lib/cpluff/libcpluff/win32/dirent.c b/lib/cpluff/libcpluff/win32/dirent.c deleted file mode 100644 index ead41848f9..0000000000 --- a/lib/cpluff/libcpluff/win32/dirent.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - - Implementation of POSIX directory browsing functions and types for Win32. - - Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) - History: Created March 1997. Updated June 2003. - Rights: See end of file. - -*/ - -#include "dirent.h" -#include "win32_utils.h" -#include <errno.h> -#include <io.h> /* _findfirst and _findnext set errno iff they return -1 */ -#include <stdlib.h> -#include <string.h> - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct DIR -{ - HANDLE handle; /* -1 for failed rewind */ - struct dirent result; /* d_name null iff first time */ - wchar_t* name; - WIN32_FIND_DATAW info; -}; - -DIR *opendir(const char *name) -{ - DIR *dir = 0; - - if(name && name[0]) - { - if ((dir = (DIR *)malloc(sizeof *dir)) != 0) - { - dir->handle = INVALID_HANDLE_VALUE; - int len = strlen(name); - size_t newLength = len + 2; //add an extra for null and another for a * at the end - if (!(name[0] == '\\' && name[1] == '\\' && name[2] == '?' && name[3] == '\\')) - newLength += 4; - if (name[len - 1] != '\\') - newLength += 1; - - char* newDir = (char*)malloc(newLength); - strcpy_s(newDir, newLength, "\\\\?\\"); - strcat_s(newDir, newLength, name); - if (name[len - 1] != '\\') - strcat_s(newDir, newLength, "\\"); - strcat_s(newDir, newLength, "*"); - newDir[newLength - 1] = '\0'; - - dir->name = to_utf16(newDir, newLength); - free(newDir); - - dir->handle = FindFirstFileW(dir->name, &dir->info); - if (dir->handle != INVALID_HANDLE_VALUE) - { - dir->result.d_name = 0; - } - else /* rollback */ - { - free(dir->name); - free(dir); - dir = 0; - } - } - else /* rollback */ - { - free(dir->name); - free(dir); - dir = 0; - errno = ENOMEM; - } - } - else - { - errno = EINVAL; - } - - return dir; -} - -int closedir(DIR *dir) -{ - int result = -1; - - if(dir && dir->handle != INVALID_HANDLE_VALUE) - { - FindClose(dir->handle); - - free(dir->name); - free(dir); - } - - if(result == -1) /* map all errors to EBADF */ - { - errno = EBADF; - } - - return result; -} - -struct dirent *readdir(DIR *dir) -{ - struct dirent *result = 0; - - if(dir && dir->handle != INVALID_HANDLE_VALUE) - { - if (FindNextFileW(dir->handle, &dir->info)) - { - result = &dir->result; - result->d_name = to_utf8(dir->info.cFileName, 0); - } - } - else - { - errno = EBADF; - } - - return result; -} - -// helper for scandir below -static void scandir_free_dir_entries(struct dirent*** namelist, int entries) { - int i; - if (!*namelist) return; - for (i = 0; i < entries; ++i) { - free((*namelist)[i]); - } - free(*namelist); - *namelist = 0; -} - -// returns the number of directory entries select or -1 if an error occurs -int scandir( - const char* dir, - struct dirent*** namelist, - int(*filter)(const struct dirent*), - int(*compar)(const void*, const void*) -) { - int entries = 0; - int max_entries = 1024; // assume 2*512 = 1024 entries (used for allocation) - DIR* d; - - *namelist = 0; - - // open directory - d = opendir(dir); - if (!d) return -1; - - // iterate - while (1) { - struct dirent* ent = readdir(d); - if (!ent) break; - - // add if no filter or filter returns non-zero - if (filter && (0 == filter(ent))) continue; - - // resize our buffer if there is not enough room - if (!*namelist || entries >= max_entries) { - struct dirent** new_entries; - - max_entries *= 2; - new_entries = (struct dirent **)realloc(*namelist, max_entries); - if (!new_entries) { - scandir_free_dir_entries(namelist, entries); - closedir(d); - errno = ENOMEM; - return -1; - } - - *namelist = new_entries; - } - - // allocate new entry - (*namelist)[entries] = (struct dirent *)malloc(sizeof(struct dirent) + strlen(ent->d_name) + 1); - if (!(*namelist)[entries]) { - scandir_free_dir_entries(namelist, entries); - closedir(d); - errno = ENOMEM; - return -1; - } - - // copy entry info - *(*namelist)[entries] = *ent; - - // and then we tack the string onto the end - { - char* dest = (char*)((*namelist)[entries]) + sizeof(struct dirent); - strcpy(dest, ent->d_name); - (*namelist)[entries]->d_name = dest; - } - - ++entries; - } - - closedir(d); - - // sort - if (*namelist && compar) qsort(*namelist, entries, sizeof((*namelist)[0]), compar); - - return entries; -} - -int alphasort(const void* lhs, const void* rhs) { - const struct dirent* lhs_ent = *(struct dirent**)lhs; - const struct dirent* rhs_ent = *(struct dirent**)rhs; - return _strcmpi(lhs_ent->d_name, rhs_ent->d_name); -} - -#ifdef __cplusplus -} -#endif - -/* - - Copyright Kevlin Henney, 1997, 2003. All rights reserved. - - Permission to use, copy, modify, and distribute this software and its - documentation for any purpose is hereby granted without fee, provided - that this copyright and permissions notice appear in all copies and - derivatives. - - This software is supplied "as is" without express or implied warranty. - - But that said, if there are any problems please get in touch. - -*/ diff --git a/lib/cpluff/libcpluff/win32/dirent.h b/lib/cpluff/libcpluff/win32/dirent.h deleted file mode 100644 index c250bfdb28..0000000000 --- a/lib/cpluff/libcpluff/win32/dirent.h +++ /dev/null @@ -1,57 +0,0 @@ - -#ifndef DIRENT_INCLUDED -#define DIRENT_INCLUDED - -/* - - Declaration of POSIX directory browsing functions and types for Win32. - - Author: Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com) - History: Created March 1997. Updated June 2003. - Rights: See end of file. - -*/ - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef struct DIR DIR; - -struct dirent -{ - char *d_name; -}; - -DIR *opendir(const char *); -int closedir(DIR *); -struct dirent *readdir(DIR *); -void rewinddir(DIR *); -int scandir( - const char* dir, - struct dirent*** namelist, - int(*filter)(const struct dirent*), - int(*compar)(const void*, const void*) ); -int alphasort(const void* lhs, const void* rhs); - -/* - - Copyright Kevlin Henney, 1997, 2003. All rights reserved. - - Permission to use, copy, modify, and distribute this software and its - documentation for any purpose is hereby granted without fee, provided - that this copyright and permissions notice appear in all copies and - derivatives. - - This software is supplied "as is" without express or implied warranty. - - But that said, if there are any problems please get in touch. - -*/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/cpluff/libcpluff/win32/win32_utils.c b/lib/cpluff/libcpluff/win32/win32_utils.c deleted file mode 100644 index 52cf353c13..0000000000 --- a/lib/cpluff/libcpluff/win32/win32_utils.c +++ /dev/null @@ -1,73 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2016 Team Kodi - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -#include <stdlib.h> - -#include "win32_utils.h" - -wchar_t* to_utf16(const char* str, size_t length) -{ - if (length == 0) - length = strlen(str); - int result = MultiByteToWideChar(CP_UTF8, 0, str, length, NULL, 0); - if (result == 0) - { - return NULL; - } - - int newLen = result + 1; - wchar_t* dirPath = malloc(newLen * 2); - result = MultiByteToWideChar(CP_UTF8, 0, str, length, dirPath, newLen); - - if (result == 0) - { - free(dirPath); - return NULL; - } - - dirPath[newLen - 1] = L'\0'; - return dirPath; -} - -char* to_utf8(const wchar_t* str, size_t length) -{ - if (length == 0) - length = wcslen(str); - - int result = WideCharToMultiByte(CP_UTF8, 0, str, length, NULL, 0, NULL, NULL); - if (result == 0) - return NULL; - - int newLen = result + 1; - char *newStr = malloc(newLen); - result = WideCharToMultiByte(CP_UTF8, 0, str, length, newStr, result, NULL, NULL); - if (result == 0) - { - free(newStr); - return NULL; - } - - newStr[newLen - 1] = '\0'; - - return newStr; -} diff --git a/lib/cpluff/libcpluff/win32/win32_utils.h b/lib/cpluff/libcpluff/win32/win32_utils.h deleted file mode 100644 index f4074f3745..0000000000 --- a/lib/cpluff/libcpluff/win32/win32_utils.h +++ /dev/null @@ -1,30 +0,0 @@ -/*------------------------------------------------------------------------- - * C-Pluff, a plug-in framework for C - * Copyright 2016 Team Kodi - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - *-----------------------------------------------------------------------*/ - -#if !defined(WIN32_LEAN_AND_MEAN) - #define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> - -wchar_t* to_utf16(const char* str, size_t length); -char* to_utf8(const wchar_t* str, size_t length); |