summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2008-08-30 20:31:07 +0000
committerColin Walters <walters@src.gnome.org>2008-08-30 20:31:07 +0000
commit8e9b9ce60747b262e3e9c4be4ae85ee1319ae3f4 (patch)
tree1ddd59b84d74350c3b3afbf7df2092bfc001f053
parent3be5f52707d68d0fb02f4415dc90450aa64ffea1 (diff)
downloadgobject-introspection-8e9b9ce60747b262e3e9c4be4ae85ee1319ae3f4.tar.gz
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
-rw-r--r--docs/typelib-format.txt14
-rw-r--r--gir/Makefile.am12
-rw-r--r--girepository/ginfo.c33
-rw-r--r--girepository/girepository.c221
-rw-r--r--girepository/girepository.h13
-rw-r--r--girepository/girmodule.c40
-rw-r--r--girepository/girmodule.h1
-rw-r--r--girepository/girparser.c6
-rw-r--r--girepository/gtypelib.c2
-rw-r--r--girepository/gtypelib.h2
-rw-r--r--tests/Makefile.am11
-rw-r--r--tests/gobject.gir10
-rw-r--r--tests/object.gir3
-rw-r--r--tools/compiler.c9
-rw-r--r--tools/generate.c51
15 files changed, 275 insertions, 153 deletions
diff --git a/docs/typelib-format.txt b/docs/typelib-format.txt
index d281cf02..4951a3cc 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 acd4c9de..6747641d 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 4625e850..e7d07dbb 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 e87df1c3..be8ddca3 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, "<builtin>", 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, "<builtin>", 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 4c680169..f3b1f484 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 1077a487..65ee392d 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 67c6ef7a..a4511e3b 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 77a2b60d..267092c3 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 e889d699..3940a329 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 9213bbbb..31c484db 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 57e07873..2d806b22 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 33de9625..00000000
--- a/tests/gobject.gir
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-<repository version="1.0"
- 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">
- <namespace name="GObject">
- <class name="GObject" glib:type-name="GObject" glib:get-type="g_object_get_type">
- </class>
- </namespace>
-</repository>
diff --git a/tests/object.gir b/tests/object.gir
index 8ef9594c..13c37c79 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">
+ <include name="GObject"/>
<namespace name="Foo">
<interface name="IFace1" glib:type-name="IFace1" glib:get-type="iface1_get_type">
</interface>
@@ -57,7 +58,7 @@
</constant>
<interface name="Iface1" glib:type-name="Iface1" glib:get-type="iface1_get_type">
</interface>
- <class name="Object2" parent="GObject.GObject" glib:type-name="Object2" glib:get-type="object2_get_type">
+ <class name="Object2" glib:type-name="Object2" glib:get-type="object2_get_type">
</class>
</namespace>
</repository>
diff --git a/tools/compiler.c b/tools/compiler.c
index 68568b60..c2d22482 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 40c497b2..26ac8478 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</%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, " <include name=\"%s\"/>\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, " <namespace name=\"%s\" shared-library=\"%s\">\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)
{