Add dladdr and env code for eina_module from Vincent Torri.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 1 Nov 2008 15:39:53 +0000 (15:39 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 1 Nov 2008 15:39:53 +0000 (15:39 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@37374 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.ac
m4/ac_attribute.m4
src/include/eina_module.h
src/lib/Makefile.am
src/lib/eina_mempool.c
src/lib/eina_module.c
src/modules/mp/fixed_bitmap/Makefile.am
src/tests/eina_suite.c
src/tests/eina_test_mempool.c
src/tests/eina_test_module.c

index d13a3e8..3c5e5cc 100644 (file)
@@ -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
index 46c1a42..34bb4db 100644 (file)
@@ -1,14 +1,46 @@
+dnl Copyright (C) 2004-2008 Kim Woelders
+dnl Copyright (C) 2008 Vincent Torri <vtorri at univ-evry dot fr>
+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 <stdlib.h>],
-  [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 <stdlib.h>
+       ],
+       [
+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
+
+])
index a5cd867..d9379cd 100644 (file)
@@ -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);
index 91e9441..3391569 100644 (file)
@@ -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:
index c8faf2e..a796d2d 100644 (file)
@@ -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");
index 6021808..ee59e85 100644 (file)
 # include "config.h"
 #endif
 
+#ifdef HAVE_DLADDR
+#define _GNU_SOURCE
+#endif
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <string.h>
+
 #include <dlfcn.h>
 
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#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);
 }
-
index e37d843..b4bb05e 100644 (file)
@@ -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
 
index 13d00ad..da0bf14 100644 (file)
@@ -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);
 }
 
index cee9092..43b86ac 100644 (file)
@@ -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);
 }
 
index b209ea6..ba972bb 100644 (file)
@@ -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);