From 22c09a76dce4a349436d1fb9ac06d3f55c8fbd31 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Aug 2008 23:56:40 +0000 Subject: [PATCH] Remove g_irepository_register_file in favor of g_irepository_require. 2008-08-20 Colin Walters * girepository/girepository.c: Remove g_irepository_register_file in favor of g_irepository_require. There are two possible deployment scenarios for typelibs: First, separate in $DATADIR/gitypelibs/. Second, they may be embedded in shlibs. However since the first is now the normal case, the API is optimized around it. Refactor internals to look up typelibs for namespaces just-in-time, but we expect consumers to call g_irepository_require. Also, add some docs. No one has died from that before. * gir/Makefile.am: Need --library for glib. * giscanner/girwriter.py: Write out shared-library. * tools/g-ir-writer: Take the first --library argument as the target of shared-library. In the future we should make this nicer with pkg-config probably. svn path=/trunk/; revision=426 --- ChangeLog | 24 +++++++++ gir/Makefile.am | 1 + girepository/girepository.c | 124 +++++++++++++++++++++++++++++++------------- girepository/girepository.h | 6 +-- giscanner/girwriter.py | 14 ++--- tools/g-ir-scanner | 6 ++- 6 files changed, 128 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 86b456f..3e06cfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,29 @@ 2008-08-20 Colin Walters + * girepository/girepository.c: Remove + g_irepository_register_file in favor of + g_irepository_require. There are two + possible deployment scenarios for typelibs: + First, separate in $DATADIR/gitypelibs/. Second, + they may be embedded in shlibs. However since + the first is now the normal case, the API is + optimized around it. + + Refactor internals to look up typelibs for + namespaces just-in-time, but we expect + consumers to call g_irepository_require. + + Also, add some docs. No one has died from that + before. + * gir/Makefile.am: Need --library for glib. + * giscanner/girwriter.py: Write out shared-library. + * tools/g-ir-writer: Take the first --library + argument as the target of shared-library. In + the future we should make this nicer with pkg-config + probably. + +2008-08-20 Colin Walters + * girepository/girparser.py: And parse them. 2008-08-20 Johan Dahlin diff --git a/gir/Makefile.am b/gir/Makefile.am index c01b6a5..f48c77d 100644 --- a/gir/Makefile.am +++ b/gir/Makefile.am @@ -12,6 +12,7 @@ GLib.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) --noclosure \ --output $@ \ --strip-prefix=g \ + --library=$(GOBJECT_LIBDIR)/libglib-2.0.so \ -I$(GLIB_INCLUDEDIR) \ -I$(GLIB_LIBDIR)/glib-2.0/include \ -DGETTEXT_PACKAGE=Dummy \ diff --git a/girepository/girepository.c b/girepository/girepository.c index a1759f6..0fcc987 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -28,6 +28,7 @@ #include "girepository.h" #include "gtypelib.h" +static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; static GHashTable *default_typelib = NULL; static GSList *search_path = NULL; @@ -68,6 +69,39 @@ g_irepository_class_init (GIRepositoryClass *class) g_type_class_add_private (class, sizeof (GIRepositoryPrivate)); } +static void +init_globals () +{ + g_static_mutex_lock (&globals_lock); + + if (default_repository == NULL) + { + default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); + if (default_typelib == NULL) + default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_typelib_free); + default_repository->priv->typelib = default_typelib; + } + + if (search_path == NULL) + { + const gchar *const *datadirs; + const gchar *const *dir; + + datadirs = g_get_system_data_dirs (); + + search_path = NULL; + for (dir = datadirs; *dir; dir++) { + char *path = g_build_filename (*dir, "gitypelibs", NULL); + search_path = g_slist_prepend (search_path, path); + } + search_path = g_slist_reverse (search_path); + } + + g_static_mutex_unlock (&globals_lock); +} + const gchar * g_irepository_register (GIRepository *repository, GTypelib *typelib) @@ -93,10 +127,7 @@ g_irepository_register (GIRepository *repository, } else { - if (default_typelib == NULL) - default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); + init_globals (); table = default_typelib; } @@ -126,8 +157,11 @@ g_irepository_unregister (GIRepository *repository, if (repository != NULL) table = repository->priv->typelib; - else - table = default_typelib; + else + { + init_globals (); + table = default_typelib; + } if (!g_hash_table_remove (table, namespace)) { @@ -144,7 +178,10 @@ g_irepository_is_registered (GIRepository *repository, if (repository != NULL) table = repository->priv->typelib; else - table = default_typelib; + { + init_globals (); + table = default_typelib; + } return g_hash_table_lookup (table, namespace) != NULL; } @@ -152,16 +189,7 @@ g_irepository_is_registered (GIRepository *repository, GIRepository * g_irepository_get_default (void) { - if (default_repository == NULL) - { - default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - if (default_typelib == NULL) - default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); - default_repository->priv->typelib = default_typelib; - } - + init_globals (); return default_repository; } @@ -315,6 +343,17 @@ g_irepository_find_by_gtype (GIRepository *repository, return data.iface; } +/** + * g_irepository_find_by_name + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to search in, may be %NULL for all + * @name: Name to find + * + * Searches for a particular name in one or all namespaces. + * See #g_irepository_require to load metadata for namespaces. + + * Returns: #GIBaseInfo representing metadata about @name, or %NULL + */ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, @@ -352,6 +391,16 @@ collect_namespaces (gpointer key, *list = g_list_append (*list, key); } +/** + * g_irepository_get_namespaces + * @repository: A #GIRepository, may be %NULL for the default + * + * Return the list of currently known namespaces. Normally + * if you want a particular namespace, you should call + * #g_irepository_require to load it in. + + * Returns: List of namespaces + */ gchar ** g_irepository_get_namespaces (GIRepository *repository) { @@ -390,23 +439,25 @@ g_irepository_get_shared_library (GIRepository *repository, static inline void g_irepository_build_search_path (void) { - const gchar *const *datadirs; - const gchar *const *dir; - - datadirs = g_get_system_data_dirs (); - - search_path = NULL; - for (dir = datadirs; *dir; dir++) { - char *path = g_build_filename (*dir, "gitypelibs", NULL); - search_path = g_slist_prepend (search_path, path); - } - search_path = g_slist_reverse (search_path); } +/** + * g_irepository_require + * @repository: Repository, may be null for the default + * @namespace: GI namespace to use, e.g. "Gtk" + * @error: a #GError. + * + * Force the namespace @namespace to be loaded if it isn't + * already. If @namespace is not loaded, this function will + * search for a ".typelib" file using the repository search + * path. + * + * Returns: Namespace if successful, NULL otherwise + */ const gchar * -g_irepository_register_file (GIRepository *repository, - const gchar *namespace, - GError **error) +g_irepository_require (GIRepository *repository, + const gchar *namespace, + GError **error) { GSList *ldir; const char *dir; @@ -422,14 +473,14 @@ g_irepository_register_file (GIRepository *repository, if (repository != NULL) table = repository->priv->typelib; else - table = default_typelib; + { + init_globals (); + table = default_typelib; + } /* don't bother loading a namespace if already registered */ if (g_hash_table_lookup (table, namespace)) - return NULL; - - if (search_path == NULL) - g_irepository_build_search_path (); + return namespace; fname = g_strconcat (namespace, ".typelib", NULL); @@ -438,7 +489,6 @@ g_irepository_register_file (GIRepository *repository, full_path = g_build_filename (dir, fname, NULL); mfile = g_mapped_file_new (full_path, FALSE, &error1); if (error1) { - g_debug ("Failed to mmap \"%s\": %s", full_path, error1->message); g_clear_error (&error1); g_free (full_path); continue; diff --git a/girepository/girepository.h b/girepository/girepository.h index 58d0aee..c3b804a 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -76,14 +76,14 @@ const gchar * g_irepository_register (GIRepository *repository, GTypelib *typelib); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); -const gchar * g_irepository_register_file (GIRepository *repository, - const gchar *filename, - GError **error); gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace); GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name); +const char * g_irepository_require (GIRepository *repository, + const char *namespace, + GError **error); gchar ** g_irepository_get_namespaces (GIRepository *repository); GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py index a5e8ffc..9b2a34e 100644 --- a/giscanner/girwriter.py +++ b/giscanner/girwriter.py @@ -20,6 +20,8 @@ from __future__ import with_statement +import os + from .ast import (Callback, Class, Enum, Function, Interface, Member, Sequence, Struct, Alias, Union) from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, @@ -29,11 +31,11 @@ from .xmlwriter import XMLWriter class GIRWriter(XMLWriter): - def __init__(self, namespace): + def __init__(self, namespace, shlib): super(GIRWriter, self).__init__() - self._write_repository(namespace) + self._write_repository(namespace, shlib) - def _write_repository(self, namespace): + def _write_repository(self, namespace, shlib): attrs = [ ('version', '1.0'), ('xmlns', 'http://www.gtk.org/introspection/core/1.0'), @@ -41,10 +43,10 @@ class GIRWriter(XMLWriter): ('xmlns:glib', 'http://www.gtk.org/introspection/glib/1.0'), ] with self.tagcontext('repository', attrs): - self._write_namespace(namespace) + self._write_namespace(namespace, shlib) - def _write_namespace(self, namespace): - attrs = [('name', namespace.name)] + def _write_namespace(self, namespace, shlib): + attrs = [('name', namespace.name),('shared-library', os.path.basename(shlib))] with self.tagcontext('namespace', attrs): for node in namespace.nodes: self._write_node(node) diff --git a/tools/g-ir-scanner b/tools/g-ir-scanner index 31c7129..d909658 100755 --- a/tools/g-ir-scanner +++ b/tools/g-ir-scanner @@ -109,6 +109,10 @@ def main(args): else: _error("Unknown format: %s" % (options.format, )) + if not options.libraries: + _error("Must specify --library for primary library") + primary_library = options.libraries[0] + for package in options.packages: output = commands.getoutput('pkg-config --cflags %s' % (package, )) pkg_options, unused = parser.parse_args(output.split()) @@ -149,7 +153,7 @@ def main(args): namespace = glibtransformer.parse() # Write out AST - writer = Writer(namespace) + writer = Writer(namespace, primary_library) data = writer.get_xml() if options.output: fd = open(options.output, "w") -- 2.7.4