gobject-introspection r660 - in trunk: . girepository giscanner tools
- From: lucasr svn gnome org
- To: svn-commits-list gnome org
- Subject: gobject-introspection r660 - in trunk: . girepository giscanner tools
- Date: Tue, 7 Oct 2008 21:25:01 +0000 (UTC)
Author: lucasr
Date: Tue Oct 7 21:25:01 2008
New Revision: 660
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=660&view=rev
Log:
2008-10-06 Lucas Rocha <lucasr gnome org>
Bug 555294: Add support for multiple shared libraries per typelib.
* girepository/ginvoke.c (g_function_info_invoke),
girepository/ginfo.c(g_registered_type_info_get_g_type): use
g_typelib_symbol instead of g_module_symbol.
* girepository/girepository.h: remove g_typelib_set_module and add
g_typelib_symbol.
* girepository/gtypelib.[ch] (find_some_symbol, _g_typelib_init,
g_typelib_new_from_memory, g_typelib_new_from_const_memory,
g_typelib_free, g_typelib_symbol): chnage GTypeLib to hold a list of
modules instead of just one. The symbol lookup is now abstracted
behind g_typelib_symbol which tries to find the passed symbol name in
one of its modules.
* giscanner/girwriter.py, tools/g-ir-scanner: change scanner to read
and write shared_library attribute as a comma-separated list of libs.
Modified:
trunk/ChangeLog
trunk/girepository/ginfo.c
trunk/girepository/ginvoke.c
trunk/girepository/girepository.c
trunk/girepository/girepository.h
trunk/girepository/gtypelib.c
trunk/girepository/gtypelib.h
trunk/giscanner/girwriter.py
trunk/tools/g-ir-scanner
Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c (original)
+++ trunk/girepository/ginfo.c Tue Oct 7 21:25:01 2008
@@ -992,9 +992,9 @@
return G_TYPE_NONE;
get_type_func = NULL;
- if (!g_module_symbol (((GIBaseInfo*)info)->typelib->module,
- type_init,
- (void**) &get_type_func))
+ if (!g_typelib_symbol (((GIBaseInfo*)info)->typelib,
+ type_init,
+ (void**) &get_type_func))
return G_TYPE_NONE;
return (* get_type_func) ();
Modified: trunk/girepository/ginvoke.c
==============================================================================
--- trunk/girepository/ginvoke.c (original)
+++ trunk/girepository/ginvoke.c Tue Oct 7 21:25:01 2008
@@ -162,42 +162,18 @@
gint n_args, n_invoke_args, in_pos, out_pos, i;
gpointer *args;
gboolean success = FALSE;
-
+
symbol = g_function_info_get_symbol (info);
- if (!g_module_symbol (g_base_info_get_typelib((GIBaseInfo *) info)->module,
- symbol, &func))
+ if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info),
+ symbol, &func))
{
- GModule *entire_app;
+ g_set_error (error,
+ G_INVOKE_ERROR,
+ G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
+ "Could not locate %s: %s", symbol, g_module_error ());
- /*
- * We want to be able to add symbols to an app or an auxiliary
- * library to fill in gaps in an introspected library. However,
- * normally we would only look for symbols in the main library
- * (typelib->module).
- *
- * A more elaborate solution is probably possible, but as a
- * simple approach for now, if we fail to find a symbol we look
- * for it in the global module.
- *
- * This would not be very efficient if it happened often, since
- * we always do the failed lookup above first, but very few
- * symbols should be outside of typelib->module so it doesn't
- * matter.
- */
- entire_app = g_module_open (NULL, 0);
- if (!g_module_symbol (entire_app, symbol, &func))
- {
- g_set_error (error,
- G_INVOKE_ERROR,
- G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
- "Could not locate %s: %s", symbol, g_module_error ());
-
- g_module_close (entire_app);
-
- return FALSE;
- }
- g_module_close (entire_app);
+ return FALSE;
}
is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0
Modified: trunk/girepository/girepository.c
==============================================================================
--- trunk/girepository/girepository.c (original)
+++ trunk/girepository/girepository.c Tue Oct 7 21:25:01 2008
@@ -252,9 +252,6 @@
g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
}
- if (typelib->module == NULL)
- typelib->module = g_module_open (NULL, 0);
-
return namespace;
}
Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h (original)
+++ trunk/girepository/girepository.h Tue Oct 7 21:25:01 2008
@@ -112,8 +112,9 @@
gsize len);
GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile);
void g_typelib_free (GTypelib *typelib);
-void g_typelib_set_module (GTypelib *typelib,
- GModule *module);
+gboolean g_typelib_symbol (GTypelib *typelib,
+ const gchar *symbol_name,
+ gpointer *symbol);
const gchar * g_typelib_get_namespace (GTypelib *typelib);
typedef enum
Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c (original)
+++ trunk/girepository/gtypelib.c Tue Oct 7 21:25:01 2008
@@ -1886,44 +1886,6 @@
return quark;
}
-static const char*
-find_some_symbol (GTypelib *typelib)
-{
- Header *header = (Header *) typelib->data;
- gint i;
-
- for (i = 0; i < header->n_entries; i++)
- {
- DirEntry *entry;
-
- entry = g_typelib_get_dir_entry (typelib, i + 1);
-
- switch (entry->blob_type)
- {
- case BLOB_TYPE_FUNCTION:
- {
- FunctionBlob *blob = (FunctionBlob *) &typelib->data[entry->offset];
-
- if (blob->symbol)
- return g_typelib_get_string (typelib, blob->symbol);
- }
- break;
- case BLOB_TYPE_OBJECT:
- {
- RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &typelib->data[entry->offset];
-
- if (blob->gtype_init)
- return g_typelib_get_string (typelib, blob->gtype_init);
- }
- break;
- default:
- break;
- }
- }
-
- return NULL;
-}
-
static inline void
_g_typelib_init (GTypelib *typelib)
{
@@ -1932,76 +1894,75 @@
header = (Header *) typelib->data;
if (header->shared_library)
{
- const gchar *shlib;
+ const gchar *shlib_str;
+ GModule *app_module = NULL;
- shlib = g_typelib_get_string (typelib, header->shared_library);
+ shlib_str = g_typelib_get_string (typelib, header->shared_library);
/* note that NULL shlib means to open the main app, which is allowed */
- /* If we do have a shared lib, first be sure the main app isn't already linked to it */
- if (shlib != NULL)
+ if (shlib_str != NULL)
{
- const char *symbol_in_module;
-
- symbol_in_module = find_some_symbol (typelib);
- if (symbol_in_module != NULL)
+ gchar **shlibs;
+ gint i;
+
+ /* shared-library is a comma-separated list of libraries */
+ shlibs = g_strsplit (shlib_str, ",", 0);
+
+ /* We load all passed libs unconditionally as if the same library is loaded
+ * again with dlopen(), the same file handle will be returned. See bug:
+ * http://bugzilla.gnome.org/show_bug.cgi?id=555294
+ */
+ for (i = 0; shlibs[i]; i++)
{
- typelib->module = g_module_open (NULL, G_MODULE_BIND_LAZY);
- if (typelib->module == NULL)
+ GModule *module;
+
+ /* Glade's autoconnect feature and OpenGL's extension mechanism
+ * as used by Clutter rely on dlopen(NULL) to work as a means of
+ * accessing the app's symbols. This keeps us from using
+ * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
+ * in general libraries are not expecting multiple copies of
+ * themselves and are not expecting to be unloaded. So we just
+ * load modules globally for now.
+ */
+
+ module = g_module_open (shlibs[i], G_MODULE_BIND_LAZY);
+
+ if (module == NULL)
+ {
+ GString *shlib_full = g_string_new (shlibs[i]);
+
+ /* Prefix with "lib", try both .la and .so */
+ if (!g_str_has_prefix (shlib_full->str, "lib"))
+ g_string_prepend (shlib_full, "lib");
+ g_string_append (shlib_full, ".la");
+ module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY);
+ if (module == NULL)
+ g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX);
+ module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY);
+
+ g_string_free (shlib_full, TRUE);
+ }
+
+ if (module == NULL)
{
- g_warning ("Could not open main app as GModule: %s",
- g_module_error ());
+ g_warning ("Failed to load shared library '%s' referenced by the typelib: %s",
+ shlibs[i], g_module_error ());
}
else
{
- void *sym;
- if (!g_module_symbol (typelib->module, symbol_in_module, &sym))
- {
- /* we will try opening the shlib, symbol is not in app already */
- g_module_close (typelib->module);
- typelib->module = NULL;
- }
+ typelib->modules = g_list_append (typelib->modules, module);
}
- }
- else
- {
- g_warning ("Could not find any symbols in typelib");
- }
- }
-
- if (typelib->module == NULL && shlib != NULL)
- {
- GString *shlib_full;
-
- /* Glade's autoconnect feature and OpenGL's extension mechanism
- * as used by Clutter rely on dlopen(NULL) to work as a means of
- * accessing the app's symbols. This keeps us from using
- * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
- * in general libraries are not expecting multiple copies of
- * themselves and are not expecting to be unloaded. So we just
- * load modules globally for now.
- */
-
- typelib->module = g_module_open (shlib, G_MODULE_BIND_LAZY);
+ }
- if (typelib->module == NULL)
- {
- shlib_full = g_string_new (shlib);
-
- /* Prefix with "lib", try both .la and .so */
- if (!g_str_has_prefix (shlib_full->str, "lib"))
- g_string_prepend (shlib_full, "lib");
- g_string_append (shlib_full, ".la");
- typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY);
- if (typelib->module == NULL)
- g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX);
- typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY);
-
- g_string_free (shlib_full, TRUE);
- }
- if (typelib->module == NULL)
- g_warning ("Failed to load shared library '%s' referenced by the typelib: %s",
- shlib, g_module_error ());
+ g_strfreev (shlibs);
}
+
+ /* we should make sure the app_module in the end of list so that
+ * it's last symbol source when loading any symbols from modules.
+ * See comments in g_typelib_symbol */
+ app_module = g_module_open (NULL, G_MODULE_BIND_LAZY);
+ if (app_module)
+ typelib->modules = g_list_append (typelib->modules, app_module);
}
}
@@ -2025,6 +1986,7 @@
meta->data = memory;
meta->len = len;
meta->owns_memory = TRUE;
+ meta->modules = NULL;
_g_typelib_init (meta);
return meta;
}
@@ -2047,6 +2009,7 @@
meta->data = (guchar *) memory;
meta->len = len;
meta->owns_memory = FALSE;
+ meta->modules = NULL;
_g_typelib_init (meta);
return meta;
}
@@ -2087,28 +2050,56 @@
else
if (typelib->owns_memory)
g_free (typelib->data);
- if (typelib->module)
- g_module_close (typelib->module);
+ if (typelib->modules)
+ {
+ g_list_foreach (typelib->modules, (GFunc) g_module_close, NULL);
+ g_list_free (typelib->modules);
+ }
g_free (typelib);
}
-/**
- * g_typelib_set_module:
- * @typelib: a #GTypelib instance
- * @module: a #GModule; takes ownership of this module
- *
- * Sets the target module for all symbols referenced by the typelib.
- **/
-void
-g_typelib_set_module (GTypelib *typelib, GModule *module)
-{
- if (typelib->module)
- g_module_close (typelib->module);
- typelib->module = module;
-}
-
const gchar *
g_typelib_get_namespace(GTypelib *typelib)
{
return g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace);
}
+
+/**
+ * g_typelib_symbol:
+ * @symbol_name: name of symbol to be loaded
+ * @symbol: returns a pointer to the symbol value
+ *
+ * Loads a symbol from #GTypelib.
+ *
+ * Return value: #TRUE on success
+ **/
+gboolean
+g_typelib_symbol(GTypelib *typelib, const char *symbol_name, gpointer *symbol)
+{
+ GList *l;
+
+ /*
+ * We want to be able to add symbols to an app or an auxiliary
+ * library to fill in gaps in an introspected library. However,
+ * normally we would only look for symbols in the main library
+ * (the first items in typelib->modules).
+ *
+ * A more elaborate solution is probably possible, but as a
+ * simple approach for now, if we fail to find a symbol we look
+ * for it in the global module (the last item in type->modules).
+ *
+ * This would not be very efficient if it happened often, since
+ * we always do the failed lookup above first, but very few
+ * symbols should be outside of the main libraries in
+ * typelib->modules so it doesn't matter.
+ */
+ for (l = typelib->modules; l; l = l->next)
+ {
+ GModule *module = l->data;
+
+ if (g_module_symbol (module, symbol_name, symbol))
+ return TRUE;
+ }
+
+ return FALSE;
+}
Modified: trunk/girepository/gtypelib.h
==============================================================================
--- trunk/girepository/gtypelib.h (original)
+++ trunk/girepository/gtypelib.h Tue Oct 7 21:25:01 2008
@@ -484,7 +484,7 @@
gsize len;
gboolean owns_memory;
GMappedFile *mfile;
- GModule *module;
+ GList *modules;
};
DirEntry *g_typelib_get_dir_entry (GTypelib *typelib,
Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py (original)
+++ trunk/giscanner/girwriter.py Tue Oct 7 21:25:01 2008
@@ -31,11 +31,11 @@
class GIRWriter(XMLWriter):
- def __init__(self, namespace, shlib, includes):
+ def __init__(self, namespace, shlibs, includes):
super(GIRWriter, self).__init__()
- self._write_repository(namespace, shlib, includes)
+ self._write_repository(namespace, shlibs, includes)
- def _write_repository(self, namespace, shlib, includes=set()):
+ def _write_repository(self, namespace, shlibs, includes=set()):
attrs = [
('version', '1.0'),
('xmlns', 'http://www.gtk.org/introspection/core/1.0'),
@@ -45,15 +45,19 @@
with self.tagcontext('repository', attrs):
for include in includes:
self._write_include(include)
- self._write_namespace(namespace, shlib)
+ self._write_namespace(namespace, shlibs)
def _write_include(self, include):
attrs = [('name', include)]
self.write_tag('include', attrs)
- def _write_namespace(self, namespace, shlib):
+ def _write_namespace(self, namespace, shlibs):
+ libraries = []
+ for l in shlibs:
+ libraries.append(os.path.basename(l))
+
attrs = [('name', namespace.name),
- ('shared-library', os.path.basename(shlib))]
+ ('shared-library', ','.join(libraries))]
with self.tagcontext('namespace', attrs):
for node in namespace.nodes:
self._write_node(node)
Modified: trunk/tools/g-ir-scanner
==============================================================================
--- trunk/tools/g-ir-scanner (original)
+++ trunk/tools/g-ir-scanner Tue Oct 7 21:25:01 2008
@@ -175,8 +175,8 @@
_error("Unknown format: %s" % (options.format, ))
if not options.libraries:
- _error("Must specify --library for primary library")
- primary_library = options.libraries[0]
+ _error("Must specify --library at least one primary library")
+ libraries = options.libraries
for package in options.packages:
output = subprocess.Popen(['pkg-config', '--cflags', package],
@@ -236,7 +236,7 @@
namespace = glibtransformer.parse()
# Write out AST
- writer = Writer(namespace, primary_library, transformer.get_includes())
+ writer = Writer(namespace, libraries, transformer.get_includes())
data = writer.get_xml()
if options.output:
fd = open(options.output, "w")
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]