gobject-introspection r541 - in trunk: docs gir girepository tests tools



Author: walters
Date: Sat Aug 30 20:31:07 2008
New Revision: 541
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=541&view=rev

Log:
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.


Removed:
   trunk/tests/gobject.gir
Modified:
   trunk/docs/typelib-format.txt
   trunk/gir/Makefile.am
   trunk/girepository/ginfo.c
   trunk/girepository/girepository.c
   trunk/girepository/girepository.h
   trunk/girepository/girmodule.c
   trunk/girepository/girmodule.h
   trunk/girepository/girparser.c
   trunk/girepository/gtypelib.c
   trunk/girepository/gtypelib.h
   trunk/tests/Makefile.am
   trunk/tests/object.gir
   trunk/tools/compiler.c
   trunk/tools/generate.c

Modified: trunk/docs/typelib-format.txt
==============================================================================
--- trunk/docs/typelib-format.txt	(original)
+++ trunk/docs/typelib-format.txt	Sat Aug 30 20:31:07 2008
@@ -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 @@
   guint32   directory;
   guint32   annotations;
 
+  guint32   dependencies;
+
   guint32   size;
   guint32   namespace;
   
@@ -152,6 +157,13 @@
 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:

Modified: trunk/gir/Makefile.am
==============================================================================
--- trunk/gir/Makefile.am	(original)
+++ trunk/gir/Makefile.am	Sat Aug 30 20:31:07 2008
@@ -14,8 +14,8 @@
 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 @@
 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 @@
 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 $@ \

Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c	(original)
+++ trunk/girepository/ginfo.c	Sat Aug 30 20:31:07 2008
@@ -174,18 +174,14 @@
       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 @@
       }
       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_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);
 }
 

Modified: trunk/girepository/girepository.c
==============================================================================
--- trunk/girepository/girepository.c	(original)
+++ trunk/girepository/girepository.c	Sat Aug 30 20:31:07 2008
@@ -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 @@
 {
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
 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 @@
 			   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 @@
 {
   IfaceData data;
 
+  repository = get_repository (repository);
+
   data.name = NULL;
   data.type = NULL;
   data.index = index + 1;
@@ -332,13 +384,13 @@
     {
       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 @@
 {
   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 @@
 {
   IfaceData data;
 
+  repository = get_repository (repository);
+
   data.name = name;
   data.type = NULL;
   data.index = -1;
@@ -386,13 +442,13 @@
     {
       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 @@
   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 @@
   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 @@
 {
   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 @@
  * 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 @@
   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 @@
 		       "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 @@
 		   "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; 
 }
 
 

Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h	(original)
+++ trunk/girepository/girepository.h	Sat Aug 30 20:31:07 2008
@@ -72,8 +72,10 @@
 
 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 @@
 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 @@
   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;
 
 

Modified: trunk/girepository/girmodule.c
==============================================================================
--- trunk/girepository/girmodule.c	(original)
+++ trunk/girepository/girmodule.c	Sat Aug 30 20:31:07 2008
@@ -33,13 +33,14 @@
 {
   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_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 @@
   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 @@
   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 @@
   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 @@
 
       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

Modified: trunk/girepository/girmodule.h
==============================================================================
--- trunk/girepository/girmodule.h	(original)
+++ trunk/girepository/girmodule.h	Sat Aug 30 20:31:07 2008
@@ -33,6 +33,7 @@
 { 
   gchar *name;
   gchar *shared_library;
+  GList *dependencies;
   GList *entries;
 };
 

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Sat Aug 30 20:31:07 2008
@@ -72,6 +72,7 @@
   
   GList *modules;
   gboolean prefix_aliases;
+  GList *dependencies;
   GHashTable *aliases;
 
   const char *namespace;
@@ -2188,6 +2189,9 @@
 	  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 @@
 	    {
 	      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 @@
   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);

Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c	(original)
+++ trunk/girepository/gtypelib.c	Sat Aug 30 20:31:07 2008
@@ -152,7 +152,7 @@
       size_check_ok = FALSE; \
     }
   
-  CHECK_SIZE (Header, 100);
+  CHECK_SIZE (Header, 104);
   CHECK_SIZE (DirEntry, 12);
   CHECK_SIZE (SimpleTypeBlob, 4);
   CHECK_SIZE (ArgBlob, 12);

Modified: trunk/girepository/gtypelib.h
==============================================================================
--- trunk/girepository/gtypelib.h	(original)
+++ trunk/girepository/gtypelib.h	Sat Aug 30 20:31:07 2008
@@ -57,6 +57,8 @@
   guint32 n_annotations;
   guint32 annotations;
 
+  guint32 dependencies;
+
   guint32 size;
   guint32 namespace;
   guint32 shared_library;

Modified: trunk/tests/Makefile.am
==============================================================================
--- trunk/tests/Makefile.am	(original)
+++ trunk/tests/Makefile.am	Sat Aug 30 20:31:07 2008
@@ -7,7 +7,6 @@
 	enum.gir	\
 	errors.gir	\
 	function.gir	\
-	gobject.gir	\
 	interface.gir	\
 	object.gir	\
 	struct.gir	\
@@ -20,15 +19,15 @@
 	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

Modified: trunk/tests/object.gir
==============================================================================
--- trunk/tests/object.gir	(original)
+++ trunk/tests/object.gir	Sat Aug 30 20:31:07 2008
@@ -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>

Modified: trunk/tools/compiler.c
==============================================================================
--- trunk/tools/compiler.c	(original)
+++ trunk/tools/compiler.c	Sat Aug 30 20:31:07 2008
@@ -41,6 +41,7 @@
 gchar *output = NULL;
 gchar *mname = NULL;
 gchar *shlib = NULL;
+gboolean include_cwd = FALSE;
 gboolean debug = FALSE;
 gboolean verbose = FALSE;
 
@@ -80,7 +81,7 @@
 			      "{\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 @@
   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++)
     {

Modified: trunk/tools/generate.c
==============================================================================
--- trunk/tools/generate.c	(original)
+++ trunk/tools/generate.c	Sat Aug 30 20:31:07 2008
@@ -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 @@
 	  
   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 @@
 }
 
 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 @@
       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 @@
 	     "            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 @@
       
   if (output != NULL)
     fclose (file);        
-
-  g_strfreev (namespaces);
 }
 
 static const guchar *
@@ -1167,10 +1178,13 @@
     {
       { "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 @@
       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 @@
         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)
 	{



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