From 8e9b9ce60747b262e3e9c4be4ae85ee1319ae3f4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 20:31:07 +0000 Subject: [PATCH] Put dependencies in typelibs, resolve them when loading * gir/Makefile.am: Dep on Makefile * girepository/ginfo.c: Print out a nicer error message if we failed to load something. * girepository/girepository.c: Clean up default typelib handling; remove global default_typelib variable. Ensure we handle NULL repository in more places. Support dependency resolution. * tests/Makefile.am: Kill off gobject.gir, it conflicts with the real one. * tests/Object.gir: Depend on GObject. * tools/generate.c: Take --includedir argument to say which directories to search for typelibs. Print out dependencies. svn path=/trunk/; revision=541 --- docs/typelib-format.txt | 14 ++- gir/Makefile.am | 12 +-- girepository/ginfo.c | 33 ++----- girepository/girepository.c | 221 ++++++++++++++++++++++++++++---------------- girepository/girepository.h | 13 ++- girepository/girmodule.c | 40 +++++++- girepository/girmodule.h | 1 + girepository/girparser.c | 6 ++ girepository/gtypelib.c | 2 +- girepository/gtypelib.h | 2 + tests/Makefile.am | 11 +-- tests/gobject.gir | 10 -- tests/object.gir | 3 +- tools/compiler.c | 9 +- tools/generate.c | 51 +++++++--- 15 files changed, 275 insertions(+), 153 deletions(-) delete mode 100644 tests/gobject.gir diff --git a/docs/typelib-format.txt b/docs/typelib-format.txt index d281cf0..4951a3c 100644 --- a/docs/typelib-format.txt +++ b/docs/typelib-format.txt @@ -1,7 +1,10 @@ GObject binary typelib for introspection ----------------------------------------- -Version 0.7 +Version 0.8 + +Changes since 0.7: +- Add dependencies Changes since 0.6: - rename metadata to typelib, to follow xpcom terminology @@ -105,6 +108,8 @@ struct Header guint32 directory; guint32 annotations; + guint32 dependencies; + guint32 size; guint32 namespace; @@ -152,6 +157,13 @@ directory: annotations: Offset of the list of annotations in the typelib. +dependencies: + Offset of a single string, which is the list of + dependencies, separated by the '|' character. The + dependencies are required in order to avoid having programs + consuming a typelib check for an "Unresolved" type return + from every API call. + size: The size of the typelib. namespace: diff --git a/gir/Makefile.am b/gir/Makefile.am index acd4c9d..6747641 100644 --- a/gir/Makefile.am +++ b/gir/Makefile.am @@ -14,8 +14,8 @@ else GLIB_LIBRARY=glib-2.0 endif -GLib.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) - PYTHONPATH=$(top_builddir):$$PYTHONPATH $(G_IR_SCANNER) \ +GLib.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) Makefile + PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(G_IR_SCANNER) \ -v --namespace GLib \ --noclosure \ --output $@ \ @@ -40,8 +40,8 @@ else GOBJECT_LIBRARY=gobject-2.0 endif -GObject.gir: GLib.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) - PYTHONPATH=$(top_builddir):$$PYTHONPATH $(G_IR_SCANNER) \ +GObject.gir: GLib.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) Makefile + PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(G_IR_SCANNER) \ -v --namespace GObject \ --noclosure \ --output $@ \ @@ -65,8 +65,8 @@ else GIO_LIBRARY=gio-2.0 endif -Gio.gir: GObject.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) - PYTHONPATH=$(top_builddir):$$PYTHONPATH $(G_IR_SCANNER) \ +Gio.gir: GObject.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES) Makefile + PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(G_IR_SCANNER) \ -v --namespace Gio \ --noclosure \ --output $@ \ diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 4625e85..e7d07db 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -174,18 +174,14 @@ g_info_from_entry (GTypelib *typelib, result = g_irepository_find_by_name (repository, namespace, name); if (result == NULL) { - GIUnresolvedInfo *unresolved; - - unresolved = g_new0 (GIUnresolvedInfo, 1); - - unresolved->type = GI_INFO_TYPE_UNRESOLVED; - unresolved->ref_count = 1; - unresolved->container = NULL; - unresolved->name = name; - unresolved->namespace = namespace; - - result = (GIBaseInfo*)unresolved; + char **all_namespaces = g_irepository_get_namespaces (repository); + char *namespaces_str = g_strjoinv (", ", all_namespaces); + g_critical ("Failed to find namespace: %s name: %s (currently loaded namespaces: %s)", namespace, + name, namespaces_str); + g_strfreev (all_namespaces); + g_free (namespaces_str); } + return result; } return result; @@ -294,14 +290,6 @@ g_base_info_get_name (GIBaseInfo *info) } break; - case GI_INFO_TYPE_UNRESOLVED: - { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - - return unresolved->name; - } - break; - case GI_INFO_TYPE_TYPE: default: ; g_assert_not_reached (); @@ -318,13 +306,6 @@ g_base_info_get_namespace (GIBaseInfo *info) g_assert (info->ref_count > 0); - if (info->type == GI_INFO_TYPE_UNRESOLVED) - { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - - return unresolved->namespace; - } - return g_typelib_get_string (info->typelib, header->namespace); } diff --git a/girepository/girepository.c b/girepository/girepository.c index e87df1c..be8ddca 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -30,12 +30,11 @@ static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; -static GHashTable *default_typelib = NULL; static GSList *search_path = NULL; struct _GIRepositoryPrivate { - GHashTable *typelib; /* (string) namespace -> GTypelib */ + GHashTable *typelibs; /* (string) namespace -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -52,7 +51,7 @@ g_irepository_finalize (GObject *object) { GIRepository *repository = G_IREPOSITORY (object); - g_hash_table_destroy (repository->priv->typelib); + g_hash_table_destroy (repository->priv->typelibs); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -77,11 +76,10 @@ init_globals () 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; + default_repository->priv->typelibs + = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_typelib_free); } if (search_path == NULL) @@ -102,6 +100,13 @@ init_globals () g_static_mutex_unlock (&globals_lock); } +void +g_irepository_prepend_search_path (const char *directory) +{ + init_globals (); + search_path = g_slist_prepend (search_path, g_strdup (directory)); +} + static char * build_typelib_key (const char *name, const char *source) { @@ -111,46 +116,79 @@ build_typelib_key (const char *name, const char *source) return g_string_free (str, FALSE); } -static const gchar * -register_internal (GIRepository *repository, - const char *source, - GTypelib *typelib) +static char ** +get_typelib_dependencies (GTypelib *typelib) { Header *header; - const gchar *name; - GHashTable *table; - GError *error = NULL; - - g_return_val_if_fail (typelib != NULL, NULL); - + const char *dependencies_glob; + header = (Header *)typelib->data; - g_return_val_if_fail (header != NULL, NULL); + if (header->dependencies == 0) + return NULL; + + dependencies_glob = g_typelib_get_string (typelib, header->dependencies); + return g_strsplit (dependencies_glob, "|", 0); +} +static GIRepository * +get_repository (GIRepository *repository) +{ if (repository != NULL) { - if (repository->priv->typelib == NULL) - repository->priv->typelib = g_hash_table_new_full (g_str_hash, g_str_equal, + if (repository->priv->typelibs == NULL) + repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); - table = repository->priv->typelib; + return repository; } else { init_globals (); - table = default_typelib; + return default_repository; } +} + +static const char * +register_internal (GIRepository *repository, + const char *source, + GTypelib *typelib, + GError **error) +{ + Header *header; + const gchar *name; + const char *dependencies_glob; + char **dependencies; + + g_return_val_if_fail (typelib != NULL, FALSE); + + header = (Header *)typelib->data; + + g_return_val_if_fail (header != NULL, FALSE); name = g_typelib_get_string (typelib, header->namespace); - if (g_hash_table_lookup (table, name)) + dependencies = get_typelib_dependencies (typelib); + if (dependencies != NULL) { - g_printerr ("typelib (%p) for '%s' already registered\n", - typelib, name); - - return NULL; + int i; + + for (i = 0; dependencies[i]; i++) + { + char *dependency = dependencies[i]; + + if (!g_irepository_require (repository, dependency, error)) + { + g_strfreev (dependencies); + return NULL; + } + } + g_strfreev (dependencies); } - g_hash_table_insert (table, build_typelib_key (name, source), (void *)typelib); + + g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL); + g_hash_table_insert (repository->priv->typelibs, + build_typelib_key (name, source), (void *)typelib); if (typelib->module == NULL) typelib->module = g_module_open (NULL, 0); @@ -158,28 +196,47 @@ register_internal (GIRepository *repository, return name; } -const gchar * -g_irepository_register (GIRepository *repository, - GTypelib *typelib) +char ** +g_irepository_get_dependencies (GIRepository *repository, + const char *namespace) +{ + GTypelib *typelib; + + g_return_val_if_fail (namespace != NULL, NULL); + + repository = get_repository (repository); + + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + g_return_val_if_fail (typelib != NULL, NULL); + + return get_typelib_dependencies (typelib); +} + +const char * +g_irepository_load_typelib (GIRepository *repository, + GTypelib *typelib, + GError **error) { - return register_internal (repository, "", typelib); + Header *header; + const char *namespace; + + repository = get_repository (repository); + + header = (Header *) typelib->data; + namespace = g_typelib_get_string (typelib, header->namespace); + + if (g_hash_table_lookup (repository->priv->typelibs, namespace)) + return namespace; + return register_internal (repository, "", typelib, error); } void g_irepository_unregister (GIRepository *repository, const gchar *namespace) { - GHashTable *table; + repository = get_repository (repository); - if (repository != NULL) - table = repository->priv->typelib; - else - { - init_globals (); - table = default_typelib; - } - - if (!g_hash_table_remove (table, namespace)) + if (!g_hash_table_remove (repository->priv->typelibs, namespace)) { g_printerr ("namespace '%s' not registered\n", namespace); } @@ -189,24 +246,15 @@ gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace) { - GHashTable *table; - - if (repository != NULL) - table = repository->priv->typelib; - else - { - init_globals (); - table = default_typelib; - } + repository = get_repository (repository); - return g_hash_table_lookup (table, namespace) != NULL; + return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL; } GIRepository * g_irepository_get_default (void) { - init_globals (); - return default_repository; + return get_repository (NULL); } static void @@ -225,19 +273,21 @@ g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace) { gint n_interfaces = 0; + + repository = get_repository (repository); if (namespace) { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (typelib) n_interfaces = ((Header *)typelib->data)->n_local_entries; } else { - g_hash_table_foreach (repository->priv->typelib, + g_hash_table_foreach (repository->priv->typelibs, count_interfaces, &n_interfaces); } @@ -323,6 +373,8 @@ g_irepository_get_info (GIRepository *repository, { IfaceData data; + repository = get_repository (repository); + data.name = NULL; data.type = NULL; data.index = index + 1; @@ -332,13 +384,13 @@ g_irepository_get_info (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (typelib) find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->typelib, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); return data.iface; } @@ -349,12 +401,14 @@ g_irepository_find_by_gtype (GIRepository *repository, { IfaceData data; + repository = get_repository (repository); + data.name = NULL; data.type = g_type_name (type); data.index = -1; data.iface = NULL; - g_hash_table_foreach (repository->priv->typelib, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); return data.iface; } @@ -377,6 +431,8 @@ g_irepository_find_by_name (GIRepository *repository, { IfaceData data; + repository = get_repository (repository); + data.name = name; data.type = NULL; data.index = -1; @@ -386,13 +442,13 @@ g_irepository_find_by_name (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (typelib) find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->typelib, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); return data.iface; } @@ -424,7 +480,9 @@ g_irepository_get_namespaces (GIRepository *repository) gchar **names; gint i; - g_hash_table_foreach (repository->priv->typelib, collect_namespaces, &list); + repository = get_repository (repository); + + g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list); names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1)); i = 0; @@ -442,7 +500,9 @@ g_irepository_get_shared_library (GIRepository *repository, GTypelib *typelib; Header *header; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + repository = get_repository (repository); + + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (!typelib) return NULL; header = (Header *) typelib->data; @@ -471,7 +531,9 @@ g_irepository_get_typelib_path (GIRepository *repository, { gpointer orig_key, value; - if (!g_hash_table_lookup_extended (repository->priv->typelib, namespace, + repository = get_repository (repository); + + if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace, &orig_key, &value)) return NULL; return ((char*)orig_key) + strlen ((char *) orig_key) + 1; @@ -488,9 +550,9 @@ g_irepository_get_typelib_path (GIRepository *repository, * search for a ".typelib" file using the repository search * path. * - * Returns: Namespace if successful, NULL otherwise + * Returns: %TRUE if successful, %NULL otherwise */ -const gchar * +gboolean g_irepository_require (GIRepository *repository, const gchar *namespace, GError **error) @@ -506,17 +568,12 @@ g_irepository_require (GIRepository *repository, guint32 shlib; GHashTable *table; - if (repository != NULL) - table = repository->priv->typelib; - else - { - init_globals (); - table = default_typelib; - } + repository = get_repository (repository); + table = repository->priv->typelibs; /* don't bother loading a namespace if already registered */ if (g_hash_table_lookup (table, namespace)) - return namespace; + return TRUE; fname = g_strconcat (namespace, ".typelib", NULL); @@ -544,7 +601,7 @@ g_irepository_require (GIRepository *repository, "namespace '%s' which doesn't match the file name", full_path, namespace, typelib_namespace); g_free (full_path); - return NULL; + return FALSE; } break; } @@ -556,14 +613,18 @@ g_irepository_require (GIRepository *repository, "Typelib file for namespace '%s' was not found in search" " path or could not be openened", namespace); g_free (full_path); - return NULL; + return FALSE; } g_free (fname); - g_hash_table_remove (table, namespace); - register_internal (repository, full_path, typelib); + if (!register_internal (repository, full_path, typelib, error)) + { + g_typelib_free (typelib); + g_free (full_path); + return FALSE; + } g_free (full_path); - return namespace; + return TRUE; } diff --git a/girepository/girepository.h b/girepository/girepository.h index 4c68016..f3b1f48 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -72,8 +72,10 @@ struct _GIRepositoryClass GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); -const gchar * g_irepository_register (GIRepository *repository, - GTypelib *typelib); +void g_irepository_prepend_search_path (const char *directory); +const char * g_irepository_load_typelib (GIRepository *repository, + GTypelib *typelib, + GError **error); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); gboolean g_irepository_is_registered (GIRepository *repository, @@ -81,9 +83,11 @@ gboolean g_irepository_is_registered (GIRepository *repository, GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name); -const char * g_irepository_require (GIRepository *repository, +gboolean g_irepository_require (GIRepository *repository, const char *namespace, GError **error); +gchar ** g_irepository_get_dependencies (GIRepository *repository, + const char *namespace); gchar ** g_irepository_get_namespaces (GIRepository *repository); GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); @@ -142,8 +146,7 @@ typedef enum GI_INFO_TYPE_PROPERTY, GI_INFO_TYPE_FIELD, GI_INFO_TYPE_ARG, - GI_INFO_TYPE_TYPE, - GI_INFO_TYPE_UNRESOLVED + GI_INFO_TYPE_TYPE } GIInfoType; diff --git a/girepository/girmodule.c b/girepository/girmodule.c index 1077a48..65ee392 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -33,13 +33,14 @@ g_ir_module_new (const gchar *name, const gchar *shared_library) { GIrModule *module; - module = g_new (GIrModule, 1); + module = g_new0 (GIrModule, 1); module->name = g_strdup (name); if (shared_library) module->shared_library = g_strdup (shared_library); else module->shared_library = NULL; + module->dependencies = NULL; module->entries = NULL; return module; @@ -56,6 +57,7 @@ g_ir_module_free (GIrModule *module) g_ir_node_free ((GIrNode *)e->data); g_list_free (module->entries); + /* Don't free dependencies, we inherit that from the parser */ g_free (module); } @@ -77,18 +79,42 @@ g_ir_module_build_typelib (GIrModule *module, guint32 size, offset, offset2, old_offset; GHashTable *strings; GHashTable *types; + char *dependencies; guchar *data; header_size = ALIGN_VALUE (sizeof (Header), 4); n_local_entries = g_list_length (module->entries); + /* Serialize dependencies into one string; this is convenient + * and not a major change to the typelib format. */ + { + GString *dependencies_str = g_string_new (""); + GList *link; + for (link = module->dependencies; link; link = link->next) + { + const char *dependency = link->data; + if (!strcmp (dependency, module->name)) + continue; + g_string_append (dependencies_str, dependency); + if (link->next) + g_string_append_c (dependencies_str, '|'); + } + dependencies = g_string_free (dependencies_str, FALSE); + if (!dependencies[0]) + { + g_free (dependencies); + dependencies = NULL; + } + } + restart: init_stats (); strings = g_hash_table_new (g_str_hash, g_str_equal); types = g_hash_table_new (g_str_hash, g_str_equal); n_entries = g_list_length (module->entries); - g_message ("%d entries (%d local)\n", n_entries, n_local_entries); + g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, + g_list_length (module->dependencies)); dir_size = n_entries * 12; size = header_size + dir_size; @@ -106,6 +132,8 @@ g_ir_module_build_typelib (GIrModule *module, size += strlen (module->name); if (module->shared_library) size += strlen (module->shared_library); + if (dependencies != NULL) + size += strlen (dependencies); g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); @@ -122,6 +150,10 @@ g_ir_module_build_typelib (GIrModule *module, header->n_local_entries = n_local_entries; header->n_annotations = 0; header->annotations = 0; /* filled in later */ + if (dependencies != NULL) + header->dependencies = write_string (dependencies, strings, data, &header_size); + else + header->dependencies = 0; header->size = 0; /* filled in later */ header->namespace = write_string (module->name, strings, data, &header_size); header->shared_library = (module->shared_library? @@ -180,9 +212,11 @@ g_ir_module_build_typelib (GIrModule *module, if (node->type == G_IR_NODE_XREF) { + const char *namespace = ((GIrNodeXRef*)node)->namespace; + entry->blob_type = 0; entry->local = FALSE; - entry->offset = write_string (((GIrNodeXRef*)node)->namespace, strings, data, &offset2); + entry->offset = write_string (namespace, strings, data, &offset2); entry->name = write_string (node->name, strings, data, &offset2); } else diff --git a/girepository/girmodule.h b/girepository/girmodule.h index 67c6ef7..a4511e3 100644 --- a/girepository/girmodule.h +++ b/girepository/girmodule.h @@ -33,6 +33,7 @@ struct _GIrModule { gchar *name; gchar *shared_library; + GList *dependencies; GList *entries; }; diff --git a/girepository/girparser.c b/girepository/girparser.c index 77a2b60..267092c 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -72,6 +72,7 @@ struct _ParseContext GList *modules; gboolean prefix_aliases; + GList *dependencies; GHashTable *aliases; const char *namespace; @@ -2188,6 +2189,9 @@ start_element_handler (GMarkupParseContext *context, if (!parse_include (context, ctx, name, error)) break; + ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup (name)); + + state_switch (ctx, STATE_INCLUDE); goto out; } @@ -2226,6 +2230,7 @@ start_element_handler (GMarkupParseContext *context, { ctx->current_module = g_ir_module_new (name, shared_library); ctx->modules = g_list_append (ctx->modules, ctx->current_module); + ctx->current_module->dependencies = ctx->dependencies; state_switch (ctx, STATE_NAMESPACE); goto out; @@ -2704,6 +2709,7 @@ g_ir_parse_string (const gchar *namespace, ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.type_depth = 0; + ctx.dependencies = NULL; ctx.current_module = NULL; context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL); diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c index e889d69..3940a32 100644 --- a/girepository/gtypelib.c +++ b/girepository/gtypelib.c @@ -152,7 +152,7 @@ g_typelib_check_sanity (void) size_check_ok = FALSE; \ } - CHECK_SIZE (Header, 100); + CHECK_SIZE (Header, 104); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); CHECK_SIZE (ArgBlob, 12); diff --git a/girepository/gtypelib.h b/girepository/gtypelib.h index 9213bbb..31c484d 100644 --- a/girepository/gtypelib.h +++ b/girepository/gtypelib.h @@ -57,6 +57,8 @@ typedef struct guint32 n_annotations; guint32 annotations; + guint32 dependencies; + guint32 size; guint32 namespace; guint32 shared_library; diff --git a/tests/Makefile.am b/tests/Makefile.am index 57e0787..2d806b2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -7,7 +7,6 @@ EXTRA_DIST = \ enum.gir \ errors.gir \ function.gir \ - gobject.gir \ interface.gir \ object.gir \ struct.gir \ @@ -20,15 +19,15 @@ GIRTESTS = \ boxed.gir.test \ constant.gir.test \ enum.gir.test \ - gobject.gir.test \ object.gir.test \ struct.gir.test -%.gir.test: %.gir +%.gir.test: %.gir Makefile @echo Testing $<: - $(DEBUG) $(top_builddir)/tools/g-ir-compiler $< > $*.1; \ - $(DEBUG) $(top_builddir)/tools/g-ir-generate $*.1 > $*.2; \ - diff -u $< $*.2; rm $*.1 $*.2 + $(DEBUG) $(top_builddir)/tools/g-ir-compiler --includedir=$(top_builddir)/gir $< > $*.1; \ + $(DEBUG) $(top_builddir)/tools/g-ir-generate --includedir=$(top_builddir)/gir $*.1 > $*.2; \ + diff -u $*.1 $*.2; rm $*.1 $*.2 + check-local: $(GIRTESTS) @echo Running PEP8 on Python sources diff --git a/tests/gobject.gir b/tests/gobject.gir deleted file mode 100644 index 33de962..0000000 --- a/tests/gobject.gir +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/tests/object.gir b/tests/object.gir index 8ef9594..13c37c7 100644 --- a/tests/object.gir +++ b/tests/object.gir @@ -3,6 +3,7 @@ xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> + @@ -57,7 +58,7 @@ - + diff --git a/tools/compiler.c b/tools/compiler.c index 68568b6..c2d2248 100644 --- a/tools/compiler.c +++ b/tools/compiler.c @@ -41,6 +41,7 @@ gchar **input = NULL; gchar *output = NULL; gchar *mname = NULL; gchar *shlib = NULL; +gboolean include_cwd = FALSE; gboolean debug = FALSE; gboolean verbose = FALSE; @@ -80,7 +81,7 @@ format_output (GTypelib *typelib) "{\n" "\tGTypelib *typelib;\n" "\ttypelib = g_typelib_new_from_const_memory (_G_TYPELIB, _G_TYPELIB_SIZE);\n" - "\tg_irepository_register (NULL, typelib);\n" + "\tg_irepository_load_typelib (NULL, typelib, NULL);\n" "}\n\n"); g_string_append_printf (result, @@ -204,6 +205,12 @@ main (int argc, char ** argv) g_debug ("[parsing] start, %d includes", includedirs ? g_strv_length (includedirs) : 0); + g_type_init (); + + if (includedirs != NULL) + for (i = 0; includedirs[i]; i++) + g_irepository_prepend_search_path (includedirs[i]); + modules = NULL; for (i = 0; input[i]; i++) { diff --git a/tools/generate.c b/tools/generate.c index 40c497b..26ac847 100644 --- a/tools/generate.c +++ b/tools/generate.c @@ -31,6 +31,7 @@ /* FIXME: Avoid global */ static gchar *output = NULL; +gchar **includedirs = NULL; static void write_type_name (const gchar *namespace, @@ -371,7 +372,7 @@ write_function_info (const gchar *namespace, if (deprecated) g_fprintf (file, " deprecated=\"1\""); - + write_callable_info (namespace, (GICallableInfo*)info, file, indent); g_fprintf (file, "%*s\n", indent, "", tag); } @@ -1002,15 +1003,16 @@ write_union_info (const gchar *namespace, } static void -write_repository (GIRepository *repository, +write_repository (const char *namespace, gboolean needs_prefix) { FILE *file; - gchar **namespaces; gchar *ns; gint i, j; + char **dependencies; + GIRepository *repository; - namespaces = g_irepository_get_namespaces (repository); + repository = g_irepository_get_default (); if (output == NULL) file = stdout; @@ -1019,7 +1021,7 @@ write_repository (GIRepository *repository, gchar *filename; if (needs_prefix) - filename = g_strdup_printf ("%s-%s", namespaces[0], output); + filename = g_strdup_printf ("%s-%s", namespace, output); else filename = g_strdup (output); file = g_fopen (filename, "w"); @@ -1042,10 +1044,21 @@ write_repository (GIRepository *repository, " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n" " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\">\n"); - for (i = 0; namespaces[i]; i++) + dependencies = g_irepository_get_dependencies (repository, + namespace); + if (dependencies != NULL) + { + for (i = 0; dependencies[i]; i++) + { + g_fprintf (file, " \n", dependencies[i]); + } + } + + if (TRUE) { const gchar *shared_library; - ns = namespaces[i]; + const char *ns = namespace; + shared_library = g_irepository_get_shared_library (repository, ns); if (shared_library) g_fprintf (file, " \n", @@ -1110,8 +1123,6 @@ write_repository (GIRepository *repository, if (output != NULL) fclose (file); - - g_strfreev (namespaces); } static const guchar * @@ -1167,10 +1178,13 @@ main (int argc, char *argv[]) { { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL }, { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, + { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL }, { NULL, } }; + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); + g_type_init (); g_typelib_check_sanity (); @@ -1186,11 +1200,16 @@ main (int argc, char *argv[]) return 1; } + if (includedirs != NULL) + for (i = 0; includedirs[i]; i++) + g_irepository_prepend_search_path (includedirs[i]); + for (i = 0; input[i]; i++) { GModule *dlhandle = NULL; const guchar *typelib; gsize len; + const char *namespace; if (!shlib) { @@ -1224,12 +1243,18 @@ main (int argc, char *argv[]) if (!g_typelib_validate (data, &error)) { g_printerr ("typelib not valid: %s\n", error->message); g_clear_error (&error); + return 1; } } - g_irepository_register (g_irepository_get_default (), data); - write_repository (g_irepository_get_default (), needs_prefix); - g_irepository_unregister (g_irepository_get_default (), - g_typelib_get_namespace (data)); + namespace = g_irepository_load_typelib (g_irepository_get_default (), data, + &error); + if (namespace == NULL) + { + g_printerr ("failed to load typelib: %s\n", error->message); + return 1; + } + + write_repository (namespace, needs_prefix); if (dlhandle) { -- 2.7.4