Re: Gmodule stuff.



Hi,
 
> Appended is a patch, that does this and a little more.

As usual I forgot to attach the patch. Sorry. Here we go.
 
Bye,
Sebastian
-- 
Sebastian Wilhelmi
mailto:wilhelmi ira uka de
http://goethe.ira.uka.de/~wilhelmi
Index: configure.in
===================================================================
RCS file: /cvs/gnome/glib/configure.in,v
retrieving revision 1.160
diff -u -b -B -r1.160 configure.in
--- configure.in	2000/11/21 15:27:44	1.160
+++ configure.in	2000/11/28 14:50:57
@@ -654,6 +654,21 @@
 if test -z "$G_MODULE_IMPL"; then
 	G_MODULE_IMPL=0
 fi
+
+AC_MSG_CHECKING(for the suffix of shared libraries)
+case "$host_os" in
+  hpux9* | hpux10* | hpux11*)  # taken from ltconfig
+    glib_gmodule_suffix='sl'
+    ;;
+  cygwin* | mingw*)
+    glib_gmodule_suffix='dll'
+    ;;
+  *)
+    glib_gmodule_suffix='so'    
+    ;;
+esac
+AC_MSG_RESULT(.$glib_gmodule_suffix)
+ 
 AC_SUBST(G_MODULE_IMPL)
 AC_SUBST(G_MODULE_LIBS)
 AC_SUBST(G_MODULE_LIBS_EXTRA)
@@ -1473,6 +1488,8 @@
 
 	cat >>$outfile <<_______EOF
 
+#define G_MODULE_SUFFIX "$g_module_suffix"
+
 G_END_DECLS
 
 #endif /* GLIBCONFIG_H */
@@ -1682,6 +1699,8 @@
 g_mutex_sizeof="$glib_cv_sizeof_gmutex"
 g_system_thread_sizeof="$glib_cv_sizeof_system_thread"
 g_mutex_contents="$glib_cv_byte_contents_gmutex"
+
+g_module_suffix="$glib_gmodule_suffix"
 
 case $host in
   *-*-beos*)
Index: gmodule/gmodule.c
===================================================================
RCS file: /cvs/gnome/glib/gmodule/gmodule.c,v
retrieving revision 1.28
diff -u -b -B -r1.28 gmodule.c
--- gmodule/gmodule.c	2000/07/26 11:02:01	1.28
+++ gmodule/gmodule.c	2000/11/28 14:50:58
@@ -28,12 +28,20 @@
  * MT safe
  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
 #include	"gmodule.h"
 #include	"gmoduleconf.h"
 #include	<errno.h>
 #include	<string.h>
+#include 	<sys/types.h>
+#include 	<sys/stat.h>
+#include 	<fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 
-
 /* We maintain a list of modules, so we can reference count them.
  * That's needed because some platforms don't support refernce counts on
  * modules e.g. the shl_* implementation of HP-UX
@@ -177,6 +185,101 @@
   return TRUE;
 }
 
+static gchar*
+parse_libtool_archive (const gchar* libtool_name)
+{
+  const gint TOKEN_DLNAME = G_TOKEN_LAST + 1;
+  const gint TOKEN_INSTALLED = G_TOKEN_LAST + 2;
+  const gint TOKEN_LIBDIR = G_TOKEN_LAST + 3;
+  gchar *lt_dlname = NULL;
+  gboolean lt_installed = TRUE;
+  gchar *lt_libdir = NULL;
+  gchar *name;
+  GTokenType token;
+  GScanner *scanner;
+  
+  int fd = open (libtool_name, O_RDONLY, 0);
+  if (fd < 0)
+    {
+      g_module_set_error ("couldn't open libtool archive");   
+      return NULL;
+    }
+  /* search libtool's dlname specification  */
+  scanner = g_scanner_new (NULL);
+  g_scanner_input_file (scanner, fd);
+  scanner->config->symbol_2_token = TRUE;
+  g_scanner_scope_add_symbol (scanner, 0, "dlname", 
+			      GUINT_TO_POINTER (TOKEN_DLNAME));
+  g_scanner_scope_add_symbol (scanner, 0, "installed", 
+			      GUINT_TO_POINTER (TOKEN_INSTALLED));
+  g_scanner_scope_add_symbol (scanner, 0, "libdir", 
+			      GUINT_TO_POINTER (TOKEN_LIBDIR));
+  while (!g_scanner_eof (scanner))
+    {
+      token = g_scanner_get_next_token (scanner);
+      if (token == TOKEN_DLNAME || token == TOKEN_INSTALLED || 
+	  token == TOKEN_LIBDIR)
+	{
+	  if (g_scanner_get_next_token (scanner) != '=' ||
+	      g_scanner_get_next_token (scanner) != 
+	      (token == TOKEN_INSTALLED ? 
+	       G_TOKEN_IDENTIFIER : G_TOKEN_STRING))
+	    {
+	      g_module_set_error ("libtool archive has wrong format"); 
+
+	      g_free (lt_dlname);
+	      g_free (lt_libdir);
+	      g_scanner_destroy (scanner);
+	      close (fd);
+
+	      return NULL;
+	    }
+	  else
+	    {
+	      if (token == TOKEN_DLNAME)
+		{
+		  g_free (lt_dlname);
+		  lt_dlname = g_strdup (scanner->value.v_string);
+		}
+	      else if (token == TOKEN_INSTALLED)
+		lt_installed = 
+		  strcmp (scanner->value.v_identifier, "yes") == 0;
+	      else /* token == TOKEN_LIBDIR */
+		{
+		  g_free (lt_libdir);
+		  lt_libdir = g_strdup (scanner->value.v_string);
+		}
+	    }
+	}      
+    }
+
+  if (!lt_installed)
+    {
+      gchar *dir = g_path_get_dirname (libtool_name);
+      g_free (lt_libdir);
+      lt_libdir = g_strconcat (dir, G_DIR_SEPARATOR_S ".libs", NULL);
+    }
+
+  name = g_module_build_path (lt_libdir, lt_dlname);
+  
+  g_free (lt_dlname);
+  g_free (lt_libdir);
+  g_scanner_destroy (scanner);
+  close (fd);
+
+  return name;
+}
+
+static inline gboolean
+g_str_check_suffix (const gchar* string, const gchar* suffix)
+{
+  guint string_len = strlen (string);
+  guint suffix_len = strlen (suffix);
+
+  return string_len >= suffix_len && 
+    strcmp (string + string_len - suffix_len, suffix) == 0;
+}
+
 GModule*
 g_module_open (const gchar    *file_name,
 	       GModuleFlags    flags)
@@ -217,8 +320,42 @@
       return module;
     }
   
-  /* open the module */
+  /* First we try to open the module as provided */
   handle = _g_module_open (file_name, (flags & G_MODULE_BIND_LAZY) != 0);
+
+  /* If not found, we check, if it is a libtool archive */
+  if (!handle && g_str_check_suffix (file_name, ".la"))
+    {
+      gchar *name = parse_libtool_archive (file_name);
+      if (name)
+	{
+	  handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
+	  g_free (name);
+	}
+    }
+
+  /* If still not found, we check, if it is a library name without suffix */
+  if (!handle && !g_str_check_suffix (file_name, "." G_MODULE_SUFFIX))
+    {
+      gchar *name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
+      handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
+      g_free (name);
+    }
+
+  /* If still not found, we check, if it is a libtool archive name
+   * without suffix */
+  if (!handle && !g_str_check_suffix (file_name, ".la"))
+    {
+      gchar *la_name = g_strconcat (file_name, ".la", NULL);
+      gchar *name = parse_libtool_archive (la_name);
+      if (name)
+	{
+	  handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
+	  g_free (name);
+	}
+      g_free (la_name);
+    }
+
   if (handle)
     {
       gchar *saved_error;
Index: gmodule/testgmodule.c
===================================================================
RCS file: /cvs/gnome/glib/gmodule/testgmodule.c,v
retrieving revision 1.11
diff -u -b -B -r1.11 testgmodule.c
--- gmodule/testgmodule.c	2000/07/26 11:02:01	1.11
+++ gmodule/testgmodule.c	2000/11/28 14:50:58
@@ -54,16 +54,9 @@
   string = g_get_current_dir ();
   g_print ("testgmodule (%s):\n", string);
 
-#if (G_MODULE_IMPL == G_MODULE_IMPL_WIN32)
-  plugin_a = g_strconcat (string, "\\libgplugin_a.dll", NULL);
-  plugin_b = g_strconcat (string, "\\libgplugin_b.dll", NULL);
-#elif (G_MODULE_IMPL == G_MODULE_IMPL_DLD)
-  plugin_a = g_strconcat (string, "/.libs/", "libgplugin_a.sl", NULL);
-  plugin_b = g_strconcat (string, "/.libs/", "libgplugin_b.sl", NULL);
-#else /* neither DLD nor WIN32 */
-  plugin_a = g_strconcat (string, "/.libs/", "libgplugin_a.so", NULL);
-  plugin_b = g_strconcat (string, "/.libs/", "libgplugin_b.so", NULL);
-#endif
+  plugin_a = g_strconcat (string, G_DIR_SEPARATOR_S "libgplugin_a", NULL);
+  plugin_b = g_strconcat (string, G_DIR_SEPARATOR_S "libgplugin_b", NULL);
+
   g_free (string);
 
   /* module handles


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]