r15230 - gnucash/branches/reshuffle-modules - Use GModule instead of libltdl.

Andreas Köhler andi5 at cvs.gnucash.org
Tue Dec 19 04:06:10 EST 2006


Author: andi5
Date: 2006-12-19 04:06:03 -0500 (Tue, 19 Dec 2006)
New Revision: 15230
Trac: http://svn.gnucash.org/trac/changeset/15230

Modified:
   gnucash/branches/reshuffle-modules/
   gnucash/branches/reshuffle-modules/src/gnc-module/gnc-module.c
Log:
Use GModule instead of libltdl.
* Load *.G_MODULE_SUFFIX, not *.la
* Use g_module_{open,symbol,close,error} for lt_dl{open,sym,close,error}
* Drop lt_dlinit




Property changes on: gnucash/branches/reshuffle-modules
___________________________________________________________________
Name: svk:merge
   - 3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/branches/reshuffle-modules:1002
3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/branches/swig-redo:802
3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/trunk:990
d2ab10a8-8a95-4986-baff-8d511d9f15b2:/local/gnucash/trunk:13714
d2ab10a8-8a95-4986-baff-8d511d9f15b2:/local/gnucash/trunk2:13366
   + 3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/branches/reshuffle-modules:1003
3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/branches/swig-redo:802
3889ce50-311e-0410-a464-f059747ec5d1:/local/gnucash/trunk:990
d2ab10a8-8a95-4986-baff-8d511d9f15b2:/local/gnucash/trunk:13714
d2ab10a8-8a95-4986-baff-8d511d9f15b2:/local/gnucash/trunk2:13366

Modified: gnucash/branches/reshuffle-modules/src/gnc-module/gnc-module.c
===================================================================
--- gnucash/branches/reshuffle-modules/src/gnc-module/gnc-module.c	2006-12-19 09:05:47 UTC (rev 15229)
+++ gnucash/branches/reshuffle-modules/src/gnc-module/gnc-module.c	2006-12-19 09:06:03 UTC (rev 15230)
@@ -8,22 +8,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <glib.h>
-#ifdef G_OS_WIN32
-# undef DLL_EXPORT /* Will cause warnings in ltdl.h if defined */
-# define LIBLTDL_DLL_IMPORT
-#endif
-#include <ltdl.h>
+#include <gmodule.h>
 #include <guile/gh.h>
 #include <sys/types.h>
 #include <dirent.h>
 
 #include "gnc-module.h"
 
-#ifndef lt_ptr
-# define lt_ptr lt_ptr_t
-#endif
-
 static GHashTable * loaded_modules = NULL;
 static GList      * module_info = NULL;
 
@@ -36,12 +27,12 @@
   int    module_revision;
 } GNCModuleInfo;
 
-typedef struct 
+typedef struct
 {
-  lt_dlhandle   handle;
+  GModule       * gmodule;
   gchar         * filename;
   int           load_count;
-  GNCModuleInfo * info;  
+  GNCModuleInfo * info;
   int           (* init_func)(int refcount);
 } GNCLoadedModule;
 
@@ -166,29 +157,21 @@
 
 /*************************************************************
  * gnc_module_system_init
- * initialize the module system 
+ * initialize the module system
  *************************************************************/
 
 void
-gnc_module_system_init(void) 
+gnc_module_system_init(void)
 {
-  if(loaded_modules == NULL) 
-  {
-    loaded_modules = g_hash_table_new(g_direct_hash, g_direct_equal);
-    
-    if(lt_dlinit() == 0)
-    {
-      gnc_module_system_setup_load_path();
-      
-      /* now crawl the GNC_MODULE_PATH to find likely libraries */
-      gnc_module_system_refresh();
-    }
-    else
-    {
-      /* FIXME: there's no way to report this error to the caller. */
-      g_warning ("gnc module system couldn't initialize libltdl");
-    }
-  }
+  if (loaded_modules)
+    return;
+
+  loaded_modules = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+  gnc_module_system_setup_load_path();
+
+  /* now crawl the GNC_MODULE_PATH to find likely libraries */
+  gnc_module_system_refresh();
 }
 
 
@@ -218,17 +201,14 @@
       DIR *d = opendir(current->data);
       struct dirent * dent = NULL;
       char * fullpath = NULL;
-      int namelen;
       GNCModuleInfo * info;
 
       if (!d) continue;
 
       while ((dent = readdir(d)) != NULL)
       {
-        namelen = strlen(dent->d_name);
-        
         /* is the file a .la shared lib? */
-        if((namelen > 3) && (!strncmp(dent->d_name + namelen - 3, ".la", 3)))
+        if (g_str_has_suffix(dent->d_name, "." G_MODULE_SUFFIX))
         {
           /* get the full path name, then dlopen the library and see
            * if it has the appropriate symbols to be a gnc_module */
@@ -279,68 +259,62 @@
  *************************************************************/
 
 static GNCModuleInfo *
-gnc_module_get_info(const char * fullpath) 
+gnc_module_get_info(const char * fullpath)
 {
-  lt_dlhandle handle;
-  lt_ptr modsysver;
+  GModule *gmodule;
+  gpointer modsysver;
+  GNCModuleInfo *info = NULL;
+  gpointer initfunc, pathfunc, descripfunc, iface, revision, age;
+  gchar * (* f_path)(void);
+  gchar * (* f_descrip)(void);
 
-  //printf("(init) dlopening %s\n", fullpath);
-  handle = lt_dlopen(fullpath);
-  if (handle == NULL) {
-      g_warning ("Failed to dlopen() '%s': %s\n", fullpath, lt_dlerror());
+/*   g_debug("(init) dlopening '%s'\n", fullpath); */
+  gmodule = g_module_open(fullpath, G_MODULE_BIND_MASK);
+  if (gmodule == NULL) {
+      g_warning("Failed to dlopen() '%s': %s\n", fullpath, g_module_error());
       return NULL;
   }
 
-  modsysver   = lt_dlsym(handle, "gnc_module_system_interface");
-    
   /* the modsysver tells us what the expected symbols and their
    * types are */
-  if (!modsysver) {
-      //printf("(init) closing %s\n", fullpath);
-      //lt_dlclose(handle);
-      return NULL;
+  if (!g_module_symbol(gmodule, "gnc_module_system_interface", &modsysver)) {
+/*       g_debug("Module '%s' does not contain 'gnc_module_system_interface'\n", */
+/*                 fullpath); */
+      goto get_info_close;
   }
 
   if (*(int *)modsysver != 0) {
-      /* unsupported module system interface version */
-      /* printf("\n** WARNING ** : module '%s' requires newer module system\n",
-         fullpath); */
-      //lt_dlclose(handle);
-      return NULL;
+      g_warning("Module '%s' requires newer module system\n", fullpath);
+      goto get_info_close;
   }
 
-  {
-      lt_ptr initfunc    = lt_dlsym(handle, "gnc_module_init");
-      lt_ptr pathfunc    = lt_dlsym(handle, "gnc_module_path");
-      lt_ptr descripfunc = lt_dlsym(handle, "gnc_module_description");
-      lt_ptr iface       = lt_dlsym(handle, "gnc_module_current");
-      lt_ptr revision    = lt_dlsym(handle, "gnc_module_revision");
-      lt_ptr age         = lt_dlsym(handle, "gnc_module_age");
-      
-      if (!(initfunc && pathfunc && descripfunc && iface &&
-            revision && age)) {
-          g_warning ("module '%s' does not match module signature\n",
-                     fullpath);
-          //lt_dlclose(handle);
-          return NULL;
-      }
-
-      {
-          /* we have found a gnc_module. */
-          GNCModuleInfo * info = g_new0(GNCModuleInfo, 1);
-          char * (* f_path)(void) = pathfunc;
-          char * (* f_descrip)(void) = descripfunc;
-          info->module_path        = f_path();
-          info->module_description = f_descrip();
-          info->module_filepath    = g_strdup(fullpath);
-          info->module_interface   = *(int *)iface;
-          info->module_age         = *(int *)age;
-          info->module_revision    = *(int *)revision;
-          //printf("(init) closing %s\n", fullpath);
-          //lt_dlclose(handle);
-          return info;
-      }
+  if (!g_module_symbol(gmodule, "gnc_module_init", &initfunc) ||
+      !g_module_symbol(gmodule, "gnc_module_path", &pathfunc) ||
+      !g_module_symbol(gmodule, "gnc_module_description", &descripfunc) ||
+      !g_module_symbol(gmodule, "gnc_module_current", &iface) ||
+      !g_module_symbol(gmodule, "gnc_module_revision", &revision) ||
+      !g_module_symbol(gmodule, "gnc_module_age", &age)) {
+    g_warning("Module '%s' does not match module signature\n", fullpath);
+    goto get_info_close;
   }
+
+  /* we have found a gnc_module. */
+  info = g_new0(GNCModuleInfo, 1);
+  f_path                   = pathfunc;
+  f_descrip                = descripfunc;
+  info->module_path        = f_path();
+  info->module_description = f_descrip();
+  info->module_filepath    = g_strdup(fullpath);
+  info->module_interface   = *(int *)iface;
+  info->module_age         = *(int *)age;
+  info->module_revision    = *(int *)revision;
+
+
+get_info_close:
+/*   g_debug("(init) closing '%s'\n", fullpath); */
+  g_module_close(gmodule);
+
+  return info;
 }
 
 
@@ -396,32 +370,32 @@
   *l = g_list_prepend(*l, v);
 }
 
-static GNCLoadedModule * 
-gnc_module_check_loaded(const char * module_name, gint iface) 
+static GNCLoadedModule *
+gnc_module_check_loaded(const char * module_name, gint iface)
 {
   GNCModuleInfo * modinfo = gnc_module_locate(module_name, iface);
   GList * modules = NULL;
   GList * p = NULL;
   GNCLoadedModule * rv = NULL;
 
-  if(modinfo == NULL) 
+  if (modinfo == NULL)
   {
     return NULL;
   }
-  
-  if(!loaded_modules) 
+
+  if (!loaded_modules)
   {
     gnc_module_system_init();
   }
-  
+
   /* turn the loaded-modules table into a list */
   g_hash_table_foreach(loaded_modules, list_loaded, &modules);
 
   /* walk the list to see if the file we want is already open */
-  for(p=modules; p; p=p->next) 
+  for (p=modules; p; p=p->next)
   {
     GNCLoadedModule * lm = p->data;
-    if(!strcmp(lm->filename, modinfo->module_filepath)) 
+    if (!strcmp(lm->filename, modinfo->module_filepath))
     {
       rv = lm;
       break;
@@ -434,33 +408,33 @@
 
 /*************************************************************
  * gnc_module_load
- * Ensure that the module named by "module_name" is loaded. 
+ * Ensure that the module named by "module_name" is loaded.
  *************************************************************/
 
-static GNCModule 
+static GNCModule
 gnc_module_load_common(char * module_name, gint iface, gboolean optional)
 {
 
   GNCLoadedModule * info;
-  
-  if(!loaded_modules) 
+
+  if(!loaded_modules)
   {
     gnc_module_system_init();
   }
-  
+
   info = gnc_module_check_loaded(module_name, iface);
-  
+
   /* if the module's already loaded, just increment its use count.
    * otherwise, load it and check for the initializer
    * "gnc_module_init".  if we find that, assume it's a gnucash module
    * and run the function. */
 
-  if(info) 
+  if (info)
   {
     /* module already loaded ... call the init thunk */
-    if(info->init_func) 
+    if (info->init_func)
     {
-      if(info->init_func(info->load_count)) 
+      if (info->init_func(info->load_count))
       {
         info->load_count++;
         return info;
@@ -476,44 +450,47 @@
       return NULL;
     }
   }
-  else 
+  else
   {
     GNCModuleInfo * modinfo = gnc_module_locate(module_name, iface);
-    lt_dlhandle   handle = NULL;
-    
-    //if(modinfo) 
-    //printf("(load) dlopening %s\n", modinfo->module_filepath);
+    GModule       * gmodule;
 
-    if(modinfo && ((handle = lt_dlopen(modinfo->module_filepath)) != NULL)) 
+/*     if (modinfo) */
+/*       g_debug("(init) loading '%s' from '%s'\n", module_name, */
+/*               modinfo->module_filepath); */
+
+    if (modinfo &&
+        ((gmodule = g_module_open(modinfo->module_filepath, 0))
+         != NULL))
     {
-      lt_ptr initfunc = lt_dlsym(handle, "gnc_module_init");
-      
-      if(initfunc) 
+      gpointer initfunc;
+
+      if (g_module_symbol(gmodule, "gnc_module_init", &initfunc))
       {
-        /* stick it in the hash table */ 
+        /* stick it in the hash table */
         info = g_new0(GNCLoadedModule, 1);
-        info->handle     = handle;
+        info->gmodule    = gmodule;
         info->filename   = g_strdup(modinfo->module_filepath);
         info->load_count = 1;
         info->init_func  = initfunc;
         g_hash_table_insert(loaded_modules, info, info);
-        
+
         /* now call its init function.  this should load any dependent
          * modules, too.  If it doesn't return TRUE unload the module. */
-        if(!info->init_func(0)) 
+        if (!info->init_func(0))
         {
           /* init failed. unload the module. */
           g_warning ("Initialization failed for module %s\n", module_name);
           g_hash_table_remove(loaded_modules, info);
           g_free(info->filename);
           g_free(info);
-          //lt_dlclose(handle);
+          /* g_module_close(module); */
           return NULL;
         }
 
         return info;
       }
-      else 
+      else
       {
         g_warning ("Module %s (%s) is not a gnc-module.\n", module_name,
                    modinfo->module_filepath);
@@ -524,7 +501,7 @@
     else if (!optional)
     {
       g_warning ("Failed to open module %s", module_name);
-      if(modinfo) printf(": %s\n", lt_dlerror());
+      if(modinfo) printf(": %s\n", g_module_error());
       else g_warning (": could not locate %s interface v.%d\n",
                       module_name, iface);
       return NULL;
@@ -551,40 +528,40 @@
  * unload a module (only actually unload it if the use count goes to 0)
  *************************************************************/
 
-int 
-gnc_module_unload(GNCModule module) 
+int
+gnc_module_unload(GNCModule module)
 {
   GNCLoadedModule * info;
- 
-  if(!loaded_modules) 
+
+  if(!loaded_modules)
   {
     gnc_module_system_init();
   }
-  
-  if((info = g_hash_table_lookup(loaded_modules, module)) != NULL) 
+
+  if ((info = g_hash_table_lookup(loaded_modules, module)) != NULL)
   {
-    lt_ptr unload_thunk = lt_dlsym(info->handle, "gnc_module_end");
-    int    unload_val = TRUE;
+    gpointer unload_thunk;
+    int unload_val = TRUE;
 
     info->load_count--;
-    if(unload_thunk) 
+    if (g_module_symbol(info->gmodule, "gnc_module_end", &unload_thunk))
     {
       int (* thunk)(int) = unload_thunk;
       unload_val = thunk(info->load_count);
     }
-    
+
     /* actually unload the module if necessary */
-    if(info->load_count == 0) 
+    if (info->load_count == 0)
     {
-      /* now close the module and free the struct */ 
-      //printf("(unload) closing %s\n", info->filename);
-      //lt_dlclose(info->handle);
+      /* now close the module and free the struct */
+      /* g_debug("(unload) closing %s\n", info->filename); */
+      /* g_module_close(info->gmodule); */
       g_hash_table_remove(loaded_modules, module);
       g_free(info);
     }
     return unload_val;
   }
-  else 
+  else
   {
     g_warning ("Failed to unload module %p (it is not loaded)\n", module);
     return 0;



More information about the gnucash-changes mailing list