From d406e73ace6a3ae9d73fd76fcebce45a18bcc41d Mon Sep 17 00:00:00 2001 From: cedric Date: Sat, 1 Nov 2008 15:39:53 +0000 Subject: [PATCH] Add dladdr and env code for eina_module from Vincent Torri. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eina@37374 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- configure.ac | 27 +++++++++++ m4/ac_attribute.m4 | 52 +++++++++++++++++---- src/include/eina_module.h | 5 +- src/lib/Makefile.am | 2 +- src/lib/eina_mempool.c | 18 +++++++- src/lib/eina_module.c | 82 +++++++++++++++++++++++++++++++-- src/modules/mp/fixed_bitmap/Makefile.am | 1 - src/tests/eina_suite.c | 2 +- src/tests/eina_test_mempool.c | 2 +- src/tests/eina_test_module.c | 2 +- 10 files changed, 171 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index d13a3e8..3c5e5cc 100644 --- a/configure.ac +++ b/configure.ac @@ -288,6 +288,33 @@ AC_SUBST(lt_enable_auto_import) ### Checks for library functions AC_FUNC_ALLOCA +#dlopen and dladdr +dlopen_libs="" +case "$host_os" in + mingw32ce* | cegcc*) +# managed by evil + AC_DEFINE(HAVE_DLADDR) + ;; + mingw*) +dnl nothing on mingw platform + ;; + *) + AC_CHECK_FUNCS([dlopen], [res="yes"], [res="no"]) + if test "x${res}" = "xyes" ; then + AC_CHECK_FUNCS([dladdr], [AC_DEFINE(HAVE_DLADDR)]) + else + AC_CHECK_LIB([dl], [dlopen], [res="yes"], [res="no"]) + if test "x${res}" = "xyes" ; then + AC_CHECK_LIB([dl], [dladdr], [AC_DEFINE(HAVE_DLADDR)]) + dlopen_libs="-ldl" + else + AC_MSG_ERROR([Cannot find dlopen]) + fi + fi + ;; +esac +AC_SUBST(dlopen_libs) + ### Create the .pc.in file according to the major version #cat > ${srcdir}/eina-${VMAJ}.pc.in << EOF diff --git a/m4/ac_attribute.m4 b/m4/ac_attribute.m4 index 46c1a42..34bb4db 100644 --- a/m4/ac_attribute.m4 +++ b/m4/ac_attribute.m4 @@ -1,14 +1,46 @@ +dnl Copyright (C) 2004-2008 Kim Woelders +dnl Copyright (C) 2008 Vincent Torri +dnl That code is public domain and can be freely used or copied. +dnl Originally snatched from somewhere... + +dnl Macro for checking if the compiler supports __atribute__ + +dnl Usage: AC_C___ATTRIBUTE__ +dnl call AC_DEFINE for HAVE___ATTRIBUTE__ and __UNUSED__ +dnl if the compiler supports __attribute__, HAVE___ATTRIBUTE__ is +dnl defined to 1 and __UNUSED__ is defined to __attribute__((unused)) +dnl otherwise, HAVE___ATTRIBUTE__ is not defined and __UNUSED__ is +dnl defined to nothing. AC_DEFUN([AC_C___ATTRIBUTE__], [ - AC_MSG_CHECKING(for __attribute__) - AC_CACHE_VAL(ac_cv___attribute__, [ - AC_TRY_COMPILE([#include ], - [int func(int x); int foo(int x __attribute__ ((unused))) { exit(1); }], - ac_cv___attribute__=yes, ac_cv___attribute__=no)]) - if test "$ac_cv___attribute__" = "yes"; then - AC_DEFINE(HAVE___ATTRIBUTE__, 1, [Define to 1 if your compiler has __attribute__]) - fi - AC_MSG_RESULT($ac_cv___attribute__) -]) +AC_MSG_CHECKING([for __attribute__]) + +AC_CACHE_VAL([ac_cv___attribute__], + [AC_TRY_COMPILE( + [ +#include + ], + [ +int func(int x); +int foo(int x __attribute__ ((unused))) +{ + exit(1); +} + ], + [ac_cv___attribute__="yes"], + [ac_cv___attribute__="no"] + )] +) + +AC_MSG_RESULT($ac_cv___attribute__) + +if test "x${ac_cv___attribute__}" = "xyes" ; then + AC_DEFINE([HAVE___ATTRIBUTE__], [1], [Define to 1 if your compiler has __attribute__]) + AC_DEFINE([__UNUSED__], [__attribute__((unused))], [Macro declaring a function argument to be unused]) + else + AC_DEFINE([__UNUSED__], [], [Macro declaring a function argument to be unused]) +fi + +]) diff --git a/src/include/eina_module.h b/src/include/eina_module.h index a5cd867..d9379cd 100644 --- a/src/include/eina_module.h +++ b/src/include/eina_module.h @@ -50,7 +50,10 @@ EAPI Eina_Bool eina_module_unload(Eina_Module *m); EAPI void *eina_module_symbol_get(Eina_Module *module, const char *symbol); EAPI const char * eina_module_file_get(Eina_Module *m); -EAPI Eina_Array * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data); +EAPI char *eina_module_symbol_path_get(const void *symbol, const char *sub_dir); +EAPI char *eina_module_environment_path_get(const char *env, const char *sub_dir); + +EAPI Eina_Array * eina_module_list_get(Eina_Array *array, const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data); EAPI void eina_module_list_load(Eina_Array *list); EAPI void eina_module_list_unload(Eina_Array *list); EAPI void eina_module_list_delete(Eina_Array *list); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 91e9441..3391569 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -56,7 +56,7 @@ libeina_la_SOURCES += $(top_srcdir)/src/modules/mp/pass_through/pass_through.c endif -libeina_la_LIBADD = @EINA_LIBS@ +libeina_la_LIBADD = @EINA_LIBS@ @dlopen_libs@ libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ clean-local: diff --git a/src/lib/eina_mempool.c b/src/lib/eina_mempool.c index c8faf2e..a796d2d 100644 --- a/src/lib/eina_mempool.c +++ b/src/lib/eina_mempool.c @@ -117,13 +117,29 @@ eina_mempool_init(void) { if (!_init_count) { + char *path; + eina_hash_init(); eina_module_init(); EINA_ERROR_NOT_MEMPOOL_MODULE = eina_error_msg_register("Not a memory pool module."); _backends = eina_hash_string_superfast_new(NULL); + /* dynamic backends */ - _modules = eina_module_list_get(PACKAGE_LIB_DIR "/eina/mp/", 0, NULL, NULL); + _modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/eina/mp/", 0, NULL, NULL); + + path = eina_module_environment_path_get("HOME", "/.eina/mp/"); + _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); + if (path) free(path); + + path = eina_module_environment_path_get("EINA_MODULES_MEMPOOL_DIR", "/eina/mp/"); + _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); + if (path) free(path); + + path = eina_module_symbol_path_get(eina_mempool_init, "/eina/mp/"); + _modules = eina_module_list_get(_modules, path, 0, NULL, NULL); + if (path) free(path); + if (!_modules) { EINA_ERROR_PERR("ERROR: no mempool modules able to be loaded.\n"); diff --git a/src/lib/eina_module.c b/src/lib/eina_module.c index 6021808..ee59e85 100644 --- a/src/lib/eina_module.c +++ b/src/lib/eina_module.c @@ -20,12 +20,21 @@ # include "config.h" #endif +#ifdef HAVE_DLADDR +#define _GNU_SOURCE +#endif + #include #include #include #include + #include +#ifdef HAVE_EVIL +# include +#endif + #include "eina_error.h" #include "eina_module.h" #include "eina_file.h" @@ -265,24 +274,88 @@ EAPI const char * eina_module_file_get(Eina_Module *m) return m->file; } +EAPI char *eina_module_symbol_path_get(const void *symbol, const char *sub_dir) +{ +#ifdef HAVE_DLADDR + Dl_info eina_dl; + + if (dladdr(symbol, &eina_dl)) + { + if (strrchr(eina_dl.dli_fname, '/')) + { + char *path; + int l0; + int l1; + int l2 = 0; + + l0 = strlen(eina_dl.dli_fname); + l1 = strlen(strrchr(eina_dl.dli_fname, '/')); + if (sub_dir && (*sub_dir != '\0')) + l2 = strlen(sub_dir); + path = malloc(l0 - l1 + l2 + 1); + if (path) + { + memcpy(path, eina_dl.dli_fname, l0 - l1); + if (sub_dir && (*sub_dir != '\0')) + memcpy(path + l0 - l1, sub_dir, l2); + path[l0 - l1 + l2] = '\0'; + return path; + } + } + } +#endif /* ! HAVE_DLADDR */ + + return NULL; +} + +EAPI char *eina_module_environment_path_get(const char *env, const char *sub_dir) +{ + const char *env_dir; + + env_dir = getenv(env); + if (env_dir) + { + char *path; + int l1; + int l2 = 0; + + l1 = strlen(env_dir); + if (sub_dir && (*sub_dir != '\0')) + l2 = strlen(sub_dir); + + path = (char *)malloc(l1 + l2 + 1); + if (path) + { + memcpy(path, env_dir, l1); + if (sub_dir && (*sub_dir != '\0')) + memcpy(path + l1, sub_dir, l2); + path[l1 + l2] = '\0'; + + return path; + } + } + + return NULL; +} + /** * Gets a list of modules found on the directory path - * + * * @param path The directory's path to search for modules * @param recursive Iterate recursively on the path * @param cb Callback function to call, if the return value of the callback is zero * it won't be added to the list, if it is one, it will. * @param data Data passed to the callback function */ -EAPI Eina_Array * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data) +EAPI Eina_Array * eina_module_list_get(Eina_Array *array, const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data) { Dir_List_Get_Cb_Data list_get_cb_data; Dir_List_Cb_Data list_cb_data; if (!path) - return NULL; + return array; - list_get_cb_data.array = eina_array_new(4); + list_get_cb_data.array = array ? array : eina_array_new(4); list_get_cb_data.cb = cb; list_get_cb_data.data = data; @@ -332,4 +405,3 @@ EAPI void eina_module_list_delete(Eina_Array *array) EINA_ARRAY_ITER_NEXT(array, i, m, iterator) eina_module_delete(m); } - diff --git a/src/modules/mp/fixed_bitmap/Makefile.am b/src/modules/mp/fixed_bitmap/Makefile.am index e37d843..b4bb05e 100644 --- a/src/modules/mp/fixed_bitmap/Makefile.am +++ b/src/modules/mp/fixed_bitmap/Makefile.am @@ -17,7 +17,6 @@ eina_fixed_bitmap.c eina_fixed_bitmap_la_LIBADD = $(top_builddir)/src/lib/libeina.la @EINA_LIBS@ eina_fixed_bitmap_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version eina_fixed_bitmap_la_LIBTOOLFLAGS = --tag=disable-static -eina_fixed_bitmap_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la endif diff --git a/src/tests/eina_suite.c b/src/tests/eina_suite.c index 13d00ad..da0bf14 100644 --- a/src/tests/eina_suite.c +++ b/src/tests/eina_suite.c @@ -78,7 +78,7 @@ static void _mempool_init(void) { eina_mempool_init(); /* force modules to be loaded in case they are not installed */ - _modules = eina_module_list_get(PACKAGE_BUILD_DIR"/src/modules", 1, NULL, NULL); + _modules = eina_module_list_get(NULL, PACKAGE_BUILD_DIR"/src/modules", 1, NULL, NULL); eina_module_list_load(_modules); } diff --git a/src/tests/eina_test_mempool.c b/src/tests/eina_test_mempool.c index cee9092..43b86ac 100644 --- a/src/tests/eina_test_mempool.c +++ b/src/tests/eina_test_mempool.c @@ -30,7 +30,7 @@ _mempool_init(void) { eina_mempool_init(); /* force modules to be loaded in case they are not installed */ - _modules = eina_module_list_get(PACKAGE_BUILD_DIR"/src/modules", 1, NULL, NULL); + _modules = eina_module_list_get(NULL, PACKAGE_BUILD_DIR"/src/modules", 1, NULL, NULL); eina_module_list_load(_modules); } diff --git a/src/tests/eina_test_module.c b/src/tests/eina_test_module.c index b209ea6..ba972bb 100644 --- a/src/tests/eina_test_module.c +++ b/src/tests/eina_test_module.c @@ -66,7 +66,7 @@ START_TEST(eina_module_load_unload) Eina_Array *_modules; eina_module_init(); - _modules = eina_module_list_get(PACKAGE_BUILD_DIR"/src/tests/", 1, &list_cb, NULL); + _modules = eina_module_list_get(NULL, PACKAGE_BUILD_DIR"/src/tests/", 1, &list_cb, NULL); fail_if(!_modules); eina_module_list_load(_modules); eina_module_list_unload(_modules); -- 2.7.4