[gobject-introspection] [gircompiler] Clean up parsing



commit 8942500c99de223eff6f91677a5dff206e09b3a7
Author: Colin Walters <walters verbum org>
Date:   Mon Jul 26 16:26:46 2010 -0400

    [gircompiler] Clean up parsing
    
    We never actually include multiple modules in the compiler,
    so just nuke that.  Also rather than passing around GIrModule
    consistently pass around a GIrTypelibBuild structure which
    has various things.
    
    This lets us maintain a stack there which we can walk for
    better error messages.
    
    Also, fix up the node lookup in giroffsets.c; previously
    it didn't really handle includes correctly.  We really need to
    switch to always using Foo.Bar (i.e. GIName) names internally...

 girepository/girmodule.c  |   36 ++++++++---
 girepository/girmodule.h  |   17 ++++-
 girepository/girnode.c    |  161 +++++++++++++++++++++------------------------
 girepository/girnode.h    |   28 ++------
 girepository/giroffsets.c |   96 +++++++++++++-------------
 girepository/girparser.c  |   97 +++++++++++++++++----------
 girepository/girparser.h  |   20 +++---
 tools/compiler.c          |   50 +++-----------
 8 files changed, 251 insertions(+), 254 deletions(-)
---
diff --git a/girepository/girmodule.c b/girepository/girmodule.c
index 066d516..70b1d2a 100644
--- a/girepository/girmodule.c
+++ b/girepository/girmodule.c
@@ -78,7 +78,7 @@ g_ir_module_free (GIrModule *module)
 
 /**
  * g_ir_module_fatal:
- * @module: Current module
+ * @build: Current build
  * @line: Origin line number, or 0 if unknown
  * @msg: printf-format string
  * @args: Remaining arguments
@@ -86,12 +86,14 @@ g_ir_module_free (GIrModule *module)
  * Report a fatal error, then exit.
  */
 void
-g_ir_module_fatal (GIrModule  *module,
+g_ir_module_fatal (GIrTypelibBuild  *build,
                    guint       line,
                    const char *msg,
                    ...)
 {
+  GString *context;
   char *formatted;
+  GList *link;
 
   va_list args;
 
@@ -99,10 +101,27 @@ g_ir_module_fatal (GIrModule  *module,
 
   formatted = g_strdup_vprintf (msg, args);
 
-  if (line)
-    g_printerr ("%s-%s.gir:%d: error: %s\n", module->name, module->version, line, formatted);
-  else
-    g_printerr ("%s-%s.gir: error: %s\n", module->name, module->version, formatted);
+  context = g_string_new ("");
+  if (line > 0)
+    g_string_append_printf (context, "%d: ", line);
+  if (build->stack)
+    g_string_append (context, "In ");
+  for (link = g_list_last (build->stack); link; link = link->prev)
+    {
+      GIrNode *node = link->data;
+      const char *name = node->name;
+      if (name)
+	g_string_append (context, name);
+      if (link->prev)
+	g_string_append (context, ".");
+    }
+  if (build->stack)
+    g_string_append (context, ": ");
+
+  g_printerr ("%s-%s.gir:%serror: %s\n", build->module->name, 
+	      build->module->version,
+	      context->str, formatted);
+  g_string_free (context, TRUE);
 
   exit (1);
 
@@ -203,8 +222,7 @@ node_cmp_offset_func (gconstpointer a,
 
 
 GTypelib *
-g_ir_module_build_typelib (GIrModule  *module,
-			     GList       *modules)
+g_ir_module_build_typelib (GIrModule  *module)
 {
   GError *error = NULL;
   GTypelib *typelib;
@@ -393,8 +411,8 @@ g_ir_module_build_typelib (GIrModule  *module,
 	  entry->offset = offset;
 	  entry->name = write_string (node->name, strings, data, &offset2);
 
+	  memset (&build, 0, sizeof (build));
 	  build.module = module;
-	  build.modules = modules;
 	  build.strings = strings;
 	  build.types = types;
 	  build.nodes_with_attributes = nodes_with_attributes;
diff --git a/girepository/girmodule.h b/girepository/girmodule.h
index bd3fbf2..e8d7ad1 100644
--- a/girepository/girmodule.h
+++ b/girepository/girmodule.h
@@ -26,9 +26,19 @@
 
 G_BEGIN_DECLS
 
-
+typedef struct _GIrTypelibBuild GIrTypelibBuild;
 typedef struct _GIrModule GIrModule;
 
+struct _GIrTypelibBuild {
+  GIrModule  *module;
+  GHashTable  *strings;
+  GHashTable  *types;
+  GList       *nodes_with_attributes;
+  guint32      n_attributes;
+  guchar      *data;
+  GList       *stack; 
+};
+
 struct _GIrModule
 {
   gchar *name;
@@ -58,10 +68,9 @@ void       g_ir_module_free           (GIrModule  *module);
 void       g_ir_module_add_include_module (GIrModule  *module,
 					   GIrModule  *include_module);
 
-GTypelib * g_ir_module_build_typelib  (GIrModule  *module,
-				       GList       *modules);
+GTypelib * g_ir_module_build_typelib  (GIrModule  *module);
 
-void       g_ir_module_fatal (GIrModule  *module, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN;
+void       g_ir_module_fatal (GIrTypelibBuild  *build, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN;
 
 void _g_irnode_init_stats (void);
 void _g_irnode_dump_stats (void);
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 17b739e..b35c745 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -113,7 +113,8 @@ g_ir_node_type_to_string (GIrNodeTypeId type)
 }
 
 GIrNode *
-g_ir_node_new (GIrNodeTypeId type)
+g_ir_node_new (GIrNodeTypeId  type,
+	       GIrModule     *module)
 {
   GIrNode *node = NULL;
 
@@ -192,6 +193,7 @@ g_ir_node_new (GIrNodeTypeId type)
     }
 
   node->type = type;
+  node->module = module;
   node->offset = 0;
   node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
                                             g_free, g_free);
@@ -1040,12 +1042,12 @@ parse_boolean_value (const gchar *str)
 }
 
 static GIrNode *
-find_entry_node (GIrModule   *module,
-		 GList       *modules,
+find_entry_node (GIrTypelibBuild   *build,
 		 const gchar *name,
 		 guint16     *idx)
 
 {
+  GIrModule *module = build->module;
   GList *l;
   gint i;
   gchar **names;
@@ -1086,7 +1088,7 @@ find_entry_node (GIrModule   *module,
 
   if (n_names > 1)
     {
-      GIrNode *node = g_ir_node_new (G_IR_NODE_XREF);
+      GIrNode *node = g_ir_node_new (G_IR_NODE_XREF, module);
 
       ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]);
       node->name = g_strdup (names[1]);
@@ -1103,8 +1105,9 @@ find_entry_node (GIrModule   *module,
       goto out;
     }
 
-  g_ir_module_fatal (module, 0, "Type reference '%s' not found", name);
-
+  
+  g_ir_module_fatal (build, -1, "type reference '%s' not found", 
+		     name);
  out:
 
   g_strfreev (names);
@@ -1113,101 +1116,77 @@ find_entry_node (GIrModule   *module,
 }
 
 static guint16
-find_entry (GIrModule   *module,
-	    GList       *modules,
+find_entry (GIrTypelibBuild   *build,
 	    const gchar *name)
 {
   guint16 idx = 0;
 
-  find_entry_node (module, modules, name, &idx);
+  find_entry_node (build, name, &idx);
 
   return idx;
 }
 
-static GIrNode *
-find_name_in_module (GIrModule   *module,
-		     const gchar *name)
+static GIrModule *
+find_namespace (GIrModule  *module,
+		const char *name)
 {
+  GIrModule *target;
   GList *l;
+  
+  if (strcmp (module->name, name) == 0)
+    return module;
 
-  for (l = module->entries; l; l = l->next)
+  for (l = module->include_modules; l; l = l->next)
     {
-      GIrNode *node = (GIrNode *)l->data;
+      GIrModule *submodule = l->data;
 
-      if (strcmp (node->name, name) == 0)
-	return node;
-    }
+     if (strcmp (submodule->name, name) == 0)
+       return submodule;
 
+      target = find_namespace (submodule, name);
+      if (target)
+       return target;
+    }
   return NULL;
 }
 
-gboolean
-g_ir_find_node (GIrModule  *module,
-		GList      *modules,
-		const char *name,
-		GIrNode   **node_out,
-		GIrModule **module_out)
+GIrNode *
+g_ir_find_node (GIrTypelibBuild  *build,
+		GIrModule        *src_module,
+		const char       *name)
 {
+  GList *l;
+  GIrNode *return_node = NULL;
   char **names = g_strsplit (name, ".", 0);
   gint n_names = g_strv_length (names);
-  GIrNode *node = NULL;
-  GList *l;
-
-  if (n_names == 0)
-    {
-      g_warning ("Name can't be empty");
-      goto out;
-    }
-
-  if (n_names > 2)
-    {
-      g_warning ("Too many name parts in '%s'", name);
-      goto out;
-    }
+  const char *target_name;
+  GIrModule *target_module;
 
   if (n_names == 1)
     {
-      *module_out = module;
-      node = find_name_in_module (module, names[0]);
-    }
-  else if (strcmp (names[0], module->name) == 0)
-    {
-      *module_out = module;
-      node = find_name_in_module (module, names[1]);
+      target_module = src_module;
+      target_name = name;
     }
   else
     {
-      for (l = module->include_modules; l; l = l->next)
-	{
-	  GIrModule *m = l->data;
+      target_module = find_namespace (build->module, names[0]);
+      target_name = names[1];
+    }
 
-	  if (strcmp (names[0], m->name) == 0)
-	    {
-	      *module_out = m;
-	      node = find_name_in_module (m, names[1]);
-	      goto out;
-	    }
-	}
+  for (l = target_module->entries; l; l = l->next)
+    {
+      GIrNode *node = (GIrNode *)l->data;
 
-      for (l = modules; l; l = l->next)
+      if (strcmp (node->name, target_name) == 0)
 	{
-	  GIrModule *m = l->data;
-
-	  if (strcmp (names[0], m->name) == 0)
-	    {
-	      *module_out = m;
-	      node = find_name_in_module (m, names[1]);
-	      goto out;
-	    }
+	  return_node = node;
+	  break;
 	}
     }
 
- out:
   g_strfreev (names);
 
-  *node_out = node;
-
-  return node != NULL;
+  return return_node;
 }
 
 static int
@@ -1235,8 +1214,7 @@ get_index_of_member_type (GIrNodeInterface *node,
 }
 
 static void
-serialize_type (GIrModule    *module,
-		GList        *modules,
+serialize_type (GIrTypelibBuild    *build,
 		GIrNodeType  *node,
 		GString      *str)
 {
@@ -1275,7 +1253,7 @@ serialize_type (GIrModule    *module,
     }
   else if (node->tag == GI_TYPE_TAG_ARRAY)
     {
-      serialize_type (module, modules, node->parameter_type1, str);
+      serialize_type (build, node->parameter_type1, str);
       g_string_append (str, "[");
 
       if (node->has_length)
@@ -1294,7 +1272,7 @@ serialize_type (GIrModule    *module,
       GIrNode *iface;
       gchar *name;
 
-      iface = find_entry_node (module, modules, node->interface, NULL);
+      iface = find_entry_node (build, node->interface, NULL);
       if (iface)
         {
           if (iface->type == G_IR_NODE_XREF)
@@ -1316,7 +1294,7 @@ serialize_type (GIrModule    *module,
       if (node->parameter_type1)
 	{
 	  g_string_append (str, "<");
-	  serialize_type (module, modules, node->parameter_type1, str);
+	  serialize_type (build, node->parameter_type1, str);
 	  g_string_append (str, ">");
 	}
     }
@@ -1326,7 +1304,7 @@ serialize_type (GIrModule    *module,
       if (node->parameter_type1)
 	{
 	  g_string_append (str, "<");
-	  serialize_type (module, modules, node->parameter_type1, str);
+	  serialize_type (build, node->parameter_type1, str);
 	  g_string_append (str, ">");
 	}
     }
@@ -1336,9 +1314,9 @@ serialize_type (GIrModule    *module,
       if (node->parameter_type1)
 	{
 	  g_string_append (str, "<");
-	  serialize_type (module, modules, node->parameter_type1, str);
+	  serialize_type (build, node->parameter_type1, str);
 	  g_string_append (str, ",");
-	  serialize_type (module, modules, node->parameter_type2, str);
+	  serialize_type (build, node->parameter_type2, str);
 	  g_string_append (str, ">");
 	}
     }
@@ -1421,8 +1399,7 @@ g_ir_node_build_typelib (GIrNode         *node,
                          guint32         *offset,
                          guint32         *offset2)
 {
-  GIrModule *module = build->module;
-  GList *modules = build->modules;
+  gboolean appended_stack;
   GHashTable *strings = build->strings;
   GHashTable *types = build->types;
   guchar *data = build->data;
@@ -1437,7 +1414,14 @@ g_ir_node_build_typelib (GIrNode         *node,
 	   node->name ? " " : "",
 	   g_ir_node_type_to_string (node->type));
 
-  g_ir_node_compute_offsets (node, module, modules);
+  if (build->stack)
+    appended_stack = node != (GIrNode*)build->stack->data; 
+  else
+    appended_stack = TRUE;
+  if (appended_stack)
+    build->stack = g_list_prepend (build->stack, node);
+  
+  g_ir_node_compute_offsets (build, node);
 
   /* We should only be building each node once.  If we do a typelib expansion, we also
    * reset the offset in girmodule.c.
@@ -1474,7 +1458,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 	    gpointer value;
 
 	    str = g_string_new (0);
-	    serialize_type (module, modules, type, str);
+	    serialize_type (build, type, str);
 	    s = g_string_free (str, FALSE);
 
 	    types_count += 1;
@@ -1529,7 +1513,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 		      iface->reserved = 0;
 		      iface->tag = type->tag;
 		      iface->reserved2 = 0;
-		      iface->interface = find_entry (module, modules, type->interface);
+		      iface->interface = find_entry (build, type->interface);
 
 		    }
 		    break;
@@ -1592,7 +1576,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 		      *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains)
 		                              + 2 * blob->n_domains, 4);
 		      for (i = 0; i < blob->n_domains; i++)
-			blob->domains[i] = find_entry (module, modules, type->errors[i]);
+			blob->domains[i] = find_entry (build, type->errors[i]);
 		    }
 		    break;
 
@@ -2121,11 +2105,11 @@ g_ir_node_build_typelib (GIrNode         *node,
         if (object->get_value_func)
           blob->get_value_func = write_string (object->get_value_func, strings, data, offset2);
 	if (object->parent)
-	  blob->parent = find_entry (module, modules, object->parent);
+	  blob->parent = find_entry (build, object->parent);
 	else
 	  blob->parent = 0;
 	if (object->glib_type_struct)
-	  blob->gtype_struct = find_entry (module, modules, object->glib_type_struct);
+	  blob->gtype_struct = find_entry (build, object->glib_type_struct);
 	else
 	  blob->gtype_struct = 0;
 
@@ -2141,7 +2125,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 	for (l = object->interfaces; l; l = l->next)
 	  {
 	    blob->n_interfaces++;
-	    *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
+	    *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data);
 	    *offset += 2;
 	  }
 
@@ -2190,7 +2174,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 	blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
 	blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
 	if (iface->glib_type_struct)
-	  blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct);
+	  blob->gtype_struct = find_entry (build, iface->glib_type_struct);
 	else
 	  blob->gtype_struct = 0;
 	blob->n_prerequisites = 0;
@@ -2204,7 +2188,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 	for (l = iface->prerequisites; l; l = l->next)
 	  {
 	    blob->n_prerequisites++;
-	    *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
+	    *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data);
 	    *offset += 2;
 	  }
 
@@ -2261,7 +2245,7 @@ g_ir_node_build_typelib (GIrNode         *node,
 	blob->reserved = 0;
 	blob->name = write_string (node->name, strings, data, offset2);
 	blob->get_quark = write_string (domain->getquark, strings, data, offset2);
-	blob->error_codes = find_entry (module, modules, domain->codes);
+	blob->error_codes = find_entry (build, domain->codes);
 	blob->reserved2 = 0;
       }
       break;
@@ -2352,6 +2336,9 @@ g_ir_node_build_typelib (GIrNode         *node,
   if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
     g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
              *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node));
+
+  if (appended_stack)
+    build->stack = g_list_delete_link (build->stack, build->stack);
 }
 
 /* if str is already in the pool, return previous location, otherwise write str
diff --git a/girepository/girnode.h b/girepository/girnode.h
index dcd8fa4..edb9400 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -27,7 +27,6 @@
 
 G_BEGIN_DECLS
 
-typedef struct _GIrTypelibBuild GIrTypelibBuild;
 typedef struct _GIrNode GIrNode;
 typedef struct _GIrNodeFunction GIrNodeFunction;
 typedef struct _GIrNodeParam GIrNodeParam;
@@ -46,16 +45,6 @@ typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain;
 typedef struct _GIrNodeXRef GIrNodeXRef;
 typedef struct _GIrNodeUnion GIrNodeUnion;
 
-struct _GIrTypelibBuild {
-  GIrModule  *module;
-  GList       *modules;
-  GHashTable  *strings;
-  GHashTable  *types;
-  GList       *nodes_with_attributes;
-  guint32      n_attributes;
-  guchar      *data;
-};
-
 typedef enum
 {
   G_IR_NODE_INVALID      =  0,
@@ -84,6 +73,7 @@ struct _GIrNode
 {
   GIrNodeTypeId type;
   gchar *name;
+  GIrModule *module;
 
   guint32 offset; /* Assigned as we build the typelib */
 
@@ -364,7 +354,8 @@ struct _GIrNodeErrorDomain
 };
 
 
-GIrNode * g_ir_node_new             (GIrNodeTypeId type);
+GIrNode * g_ir_node_new             (GIrNodeTypeId type,
+				     GIrModule     *module);
 void      g_ir_node_free            (GIrNode    *node);
 guint32   g_ir_node_get_size        (GIrNode    *node);
 guint32   g_ir_node_get_full_size   (GIrNode    *node);
@@ -386,17 +377,14 @@ guint32   write_string              (const gchar *str,
 const gchar * g_ir_node_param_direction_string (GIrNodeParam * node);
 const gchar * g_ir_node_type_to_string         (GIrNodeTypeId type);
 
-gboolean g_ir_find_node (GIrModule  *module,
-			 GList      *modules,
-			 const char *name,
-			 GIrNode   **node_out,
-			 GIrModule **module_out);
+GIrNode *g_ir_find_node (GIrTypelibBuild  *build,
+			 GIrModule        *module,
+			 const char       *name);
 
 /* In giroffsets.c */
 
-void g_ir_node_compute_offsets (GIrNode   *node,
-			        GIrModule *module,
-			        GList     *modules);
+void g_ir_node_compute_offsets (GIrTypelibBuild *build, 
+				GIrNode         *node);
 
 
 G_END_DECLS
diff --git a/girepository/giroffsets.c b/girepository/giroffsets.c
index 5d481da..bcac716 100644
--- a/girepository/giroffsets.c
+++ b/girepository/giroffsets.c
@@ -20,6 +20,7 @@
 
 #include "girepository-private.h"
 #include "girnode.h"
+#include <string.h>
 
 /* The C standard specifies that an enumeration can be any char or any signed
  * or unsigned integer type capable of resresenting all the values of the
@@ -144,26 +145,24 @@ get_enum_size_alignment (GIrNodeEnum *enum_node,
 }
 
 static gboolean
-get_interface_size_alignment (GIrNodeType *type,
-                              GIrModule   *module,
-			      GList       *modules,
+get_interface_size_alignment (GIrTypelibBuild   *build,
+			      GIrNodeType *type,
 			      gint        *size,
 			      gint        *alignment,
                               const char  *who)
 {
   GIrNode *iface;
-  GIrModule *iface_module;
 
-  if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module))
+  iface = g_ir_find_node (build, ((GIrNode*)type)->module, type->interface);
+  if (!iface)
     {
-      g_ir_module_fatal (module, 0, "Can't resolve type '%s' for %s", type->interface, who);
+      g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->interface, who);
       *size = -1;
       *alignment = -1;
       return FALSE;
     }
 
-  g_ir_node_compute_offsets (iface, iface_module,
-			     iface_module == module ? modules : NULL);
+  g_ir_node_compute_offsets (build, iface);
 
   switch (iface->type)
     {
@@ -223,9 +222,8 @@ get_interface_size_alignment (GIrNodeType *type,
 }
 
 static gboolean
-get_type_size_alignment (GIrNodeType *type,
-                         GIrModule   *module,
-                         GList       *modules,
+get_type_size_alignment (GIrTypelibBuild   *build,
+			 GIrNodeType *type,
                          gint        *size,
                          gint        *alignment,
                          const char  *who)
@@ -241,7 +239,7 @@ get_type_size_alignment (GIrNodeType *type,
       gint elt_size, elt_alignment;
 
       if (!type->has_size
-          || !get_type_size_alignment(type->parameter_type1, module, modules,
+          || !get_type_size_alignment(build, type->parameter_type1,
                                       &elt_size, &elt_alignment, who))
         {
           *size = -1;
@@ -258,7 +256,7 @@ get_type_size_alignment (GIrNodeType *type,
     {
       if (type->tag == GI_TYPE_TAG_INTERFACE)
 	{
-	  return get_interface_size_alignment (type, module, modules, size, alignment, who);
+	  return get_interface_size_alignment (build, type, size, alignment, who);
 	}
       else
 	{
@@ -291,13 +289,13 @@ get_type_size_alignment (GIrNodeType *type,
 }
 
 static gboolean
-get_field_size_alignment (GIrNodeField *field,
+get_field_size_alignment (GIrTypelibBuild    *build,
+			  GIrNodeField *field,
 			  GIrNode      *parent_node,
-			  GIrModule    *module,
-			  GList        *modules,
 			  gint         *size,
 			  gint         *alignment)
 {
+  GIrModule *module = build->module;
   gchar *who;
   gboolean success;
 
@@ -310,7 +308,7 @@ get_field_size_alignment (GIrNodeField *field,
       success = TRUE;
     }
   else
-    success = get_type_size_alignment (field->type, module, modules, size, alignment, who);
+    success = get_type_size_alignment (build, field->type, size, alignment, who);
   g_free (who);
 
   return success;
@@ -319,10 +317,9 @@ get_field_size_alignment (GIrNodeField *field,
 #define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1))
 
 static gboolean
-compute_struct_field_offsets (GIrNode     *node,
+compute_struct_field_offsets (GIrTypelibBuild   *build,
+			      GIrNode     *node,
 			      GList       *members,
-			      GIrModule   *module,
-			      GList       *modules,
 			      gint        *size_out,
 			      gint        *alignment_out)
 {
@@ -346,8 +343,7 @@ compute_struct_field_offsets (GIrNode     *node,
 	      int member_size;
 	      int member_alignment;
 
-	      if (get_field_size_alignment (field, node,
-					    module, modules,
+	      if (get_field_size_alignment (build, field, node,
 					    &member_size, &member_alignment))
 		{
 		  size = ALIGN (size, member_alignment);
@@ -388,10 +384,9 @@ compute_struct_field_offsets (GIrNode     *node,
 }
 
 static gboolean
-compute_union_field_offsets (GIrNode     *node,
+compute_union_field_offsets (GIrTypelibBuild *build,
+			     GIrNode     *node,
 			     GList       *members,
-			     GIrModule   *module,
-			     GList       *modules,
 			     gint        *size_out,
 			     gint        *alignment_out)
 {
@@ -415,8 +410,7 @@ compute_union_field_offsets (GIrNode     *node,
 	      int member_size;
 	      int member_alignment;
 
-	      if (get_field_size_alignment (field, node,
-					    module, modules,
+	      if (get_field_size_alignment (build,field, node,
 					    &member_size, &member_alignment))
 		{
 		  size = MAX (size, member_size);
@@ -446,10 +440,11 @@ compute_union_field_offsets (GIrNode     *node,
 }
 
 static gboolean
-check_needs_computation (GIrNode   *node,
-			 GIrModule *module,
+check_needs_computation (GIrTypelibBuild *build,
+			 GIrNode   *node,
 			 gint       alignment)
 {
+  GIrModule *module = build->module;
   /*
    *  0: Not yet computed
    * >0: Previously succeeded
@@ -467,30 +462,36 @@ check_needs_computation (GIrNode   *node,
 
 /**
  * g_ir_node_compute_offsets:
+ * @build: Current typelib build
  * @node: a #GIrNode
- * @module: Current module being processed
- * @modules: all currently loaded modules
  *
  * If a node is a a structure or union, makes sure that the field
  * offsets have been computed, and also computes the overall size and
  * alignment for the type.
  */
 void
-g_ir_node_compute_offsets (GIrNode   *node,
-			   GIrModule *module,
-			   GList     *modules)
+g_ir_node_compute_offsets (GIrTypelibBuild *build,
+			   GIrNode         *node)
 {
+  gboolean appended_stack;
+
+  if (build->stack)
+    appended_stack = node != (GIrNode*)build->stack->data; 
+  else
+    appended_stack = TRUE;
+  if (appended_stack)
+    build->stack = g_list_prepend (build->stack, node);
+
   switch (node->type)
     {
     case G_IR_NODE_BOXED:
       {
 	GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
 
-	if (!check_needs_computation (node, module, boxed->alignment))
+	if (!check_needs_computation (build, node, boxed->alignment))
 	  return;
 
-	compute_struct_field_offsets (node, boxed->members,
-				      module, modules,
+	compute_struct_field_offsets (build, node, boxed->members,
 				      &boxed->size, &boxed->alignment);
 	break;
       }
@@ -498,11 +499,10 @@ g_ir_node_compute_offsets (GIrNode   *node,
       {
 	GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
-	if (!check_needs_computation (node, module, struct_->alignment))
+	if (!check_needs_computation (build, node, struct_->alignment))
 	  return;
 
-	compute_struct_field_offsets (node, struct_->members,
-				      module, modules,
+	compute_struct_field_offsets (build, node, struct_->members,
 				      &struct_->size, &struct_->alignment);
 	break;
       }
@@ -511,11 +511,10 @@ g_ir_node_compute_offsets (GIrNode   *node,
       {
 	GIrNodeInterface *iface = (GIrNodeInterface *)node;
 
-	if (!check_needs_computation (node, module, iface->alignment))
+	if (!check_needs_computation (build, node, iface->alignment))
 	  return;
 
-	compute_struct_field_offsets (node, iface->members,
-				      module, modules,
+	compute_struct_field_offsets (build, node, iface->members,
 				      &iface->size, &iface->alignment);
 	break;
       }
@@ -523,11 +522,10 @@ g_ir_node_compute_offsets (GIrNode   *node,
       {
 	GIrNodeUnion *union_ = (GIrNodeUnion *)node;
 
-	if (!check_needs_computation (node, module, union_->alignment))
+	if (!check_needs_computation (build, node, union_->alignment))
 	  return;
 
-	compute_union_field_offsets (node, union_->members,
-				     module, modules,
+	compute_union_field_offsets (build, (GIrNode*)union_, union_->members,
 				     &union_->size, &union_->alignment);
 	break;
       }
@@ -544,7 +542,9 @@ g_ir_node_compute_offsets (GIrNode   *node,
 	break;
       }
     default:
-      /* Nothing to do */
-      return;
+      break;
     }
+  
+  if (appended_stack)
+    build->stack = g_list_delete_link (build->stack, build->stack);
 }
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 11576e9..ae1e625 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -324,7 +324,8 @@ push_node (ParseContext *ctx, GIrNode *node)
   ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
 }
 
-static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
+static GIrNodeType * parse_type_internal (GIrModule *module,
+					  const gchar *str, gchar **next, gboolean in_glib,
 					  gboolean in_gobject);
 
 typedef struct {
@@ -423,14 +424,15 @@ parse_basic (const char *str)
 }
 
 static GIrNodeType *
-parse_type_internal (const gchar *str, char **next, gboolean in_glib,
+parse_type_internal (GIrModule *module,
+		     const gchar *str, char **next, gboolean in_glib,
 		     gboolean in_gobject)
 {
   const BasicTypeInfo *basic;
   GIrNodeType *type;
   char *temporary_type = NULL;
 
-  type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
+  type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE, module);
 
   type->unparsed = g_strdup (str);
 
@@ -644,7 +646,7 @@ parse_type (ParseContext *ctx, const gchar *type)
   if (basic == NULL)
     type = resolve_aliases (ctx, type);
 
-  node = parse_type_internal (type, NULL, in_glib, in_gobject);
+  node = parse_type_internal (ctx->current_module, type, NULL, in_glib, in_gobject);
   if (node)
     g_debug ("Parsed type: %s => %d", type, node->tag);
   else
@@ -721,7 +723,8 @@ start_glib_boxed (GMarkupParseContext *context,
       return FALSE;
     }
 
-  boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
+  boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED,
+					  ctx->current_module);
 
   ((GIrNode *)boxed)->name = g_strdup (name);
   boxed->gtype_name = g_strdup (typename);
@@ -804,7 +807,8 @@ start_function (GMarkupParseContext *context,
       return FALSE;
     }
 
-  function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
+  function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION,
+						ctx->current_module);
 
   ((GIrNode *)function)->name = g_strdup (name);
   function->symbol = g_strdup (symbol);
@@ -1005,7 +1009,8 @@ start_parameter (GMarkupParseContext *context,
   if (name == NULL)
     name = "unknown";
 
-  param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
+  param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM,
+					 ctx->current_module);
 
   ctx->current_typed = (GIrNode*) param;
   ctx->current_typed->name = g_strdup (name);
@@ -1141,7 +1146,8 @@ start_field (GMarkupParseContext *context,
       return FALSE;
     }
 
-  field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
+  field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD,
+					 ctx->current_module);
   ctx->current_typed = (GIrNode*) field;
   ((GIrNode *)field)->name = g_strdup (name);
   /* Fields are assumed to be read-only.
@@ -1203,7 +1209,8 @@ start_field (GMarkupParseContext *context,
 	  {
 	    GIrNodeConstant *constant;
 
-	    constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
+	    constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT,
+							  ctx->current_module);
 	    ((GIrNode *)constant)->name = g_strdup (name);
 	    constant->value = g_strdup (branch);
 	    constant->type = union_->discriminator_type;
@@ -1298,9 +1305,11 @@ start_enum (GMarkupParseContext *context,
     }
 
   if (strcmp (element_name, "enumeration") == 0)
-    enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
+    enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM,
+					   ctx->current_module);
   else
-    enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
+    enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS,
+					   ctx->current_module);
   ((GIrNode *)enum_)->name = g_strdup (name);
   enum_->gtype_name = g_strdup (typename);
   enum_->gtype_init = g_strdup (typeinit);
@@ -1363,7 +1372,8 @@ start_property (GMarkupParseContext *context,
       return FALSE;
     }
 
-  property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
+  property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY,
+						ctx->current_module);
   ctx->current_typed = (GIrNode*) property;
 
   ((GIrNode *)property)->name = g_strdup (name);
@@ -1445,7 +1455,8 @@ start_member (GMarkupParseContext *context,
       return FALSE;
     }
 
-  value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
+  value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE,
+					   ctx->current_module);
 
   ((GIrNode *)value_)->name = g_strdup (name);
 
@@ -1518,7 +1529,8 @@ start_constant (GMarkupParseContext *context,
       return FALSE;
     }
 
-  constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
+  constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT,
+						ctx->current_module);
 
   ((GIrNode *)constant)->name = g_strdup (name);
   constant->value = g_strdup (value);
@@ -1590,7 +1602,8 @@ start_errordomain (GMarkupParseContext *context,
       return FALSE;
     }
 
-  domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
+  domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN,
+						 ctx->current_module);
 
   ((GIrNode *)domain)->name = g_strdup (name);
   domain->getquark = g_strdup (getquark);
@@ -1652,7 +1665,8 @@ start_interface (GMarkupParseContext *context,
       return FALSE;
     }
 
-  iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
+  iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE,
+					      ctx->current_module);
   ((GIrNode *)iface)->name = g_strdup (name);
   iface->gtype_name = g_strdup (typename);
   iface->gtype_init = g_strdup (typeinit);
@@ -1727,7 +1741,8 @@ start_class (GMarkupParseContext *context,
       return FALSE;
     }
 
-  iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
+  iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT,
+					      ctx->current_module);
   ((GIrNode *)iface)->name = g_strdup (name);
   iface->gtype_name = g_strdup (typename);
   iface->gtype_init = g_strdup (typeinit);
@@ -1820,7 +1835,8 @@ start_type (GMarkupParseContext *context,
       const char *len;
       const char *size;
 
-      typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
+      typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE,
+					       ctx->current_module);
 
       typenode->tag = GI_TYPE_TAG_ARRAY;
       typenode->is_pointer = TRUE;
@@ -1870,7 +1886,10 @@ start_type (GMarkupParseContext *context,
       name = find_attribute ("name", attribute_names, attribute_values);
 
       if (name == NULL)
-	MISSING_ATTRIBUTE (context, error, element_name, "name");
+	{
+	  MISSING_ATTRIBUTE (context, error, element_name, "name");
+	  return FALSE;
+	}
 
       pointer_depth = 0;
       ctype = find_attribute ("c:type", attribute_names, attribute_values);
@@ -2097,7 +2116,8 @@ start_return_value (GMarkupParseContext *context,
 	ctx->state == STATE_FUNCTION))
     return FALSE;
 
-  param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
+  param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM,
+					 ctx->current_module);
   param->in = FALSE;
   param->out = FALSE;
   param->retval = TRUE;
@@ -2206,7 +2226,8 @@ start_glib_signal (GMarkupParseContext *context,
       MISSING_ATTRIBUTE (context, error, element_name, "name");
       return FALSE;
     }
-  signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
+  signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL,
+					   ctx->current_module);
 
   ((GIrNode *)signal)->name = g_strdup (name);
 
@@ -2287,7 +2308,8 @@ start_vfunc (GMarkupParseContext *context,
       return FALSE;
     }
 
-  vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
+  vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC,
+					 ctx->current_module);
 
   ((GIrNode *)vfunc)->name = g_strdup (name);
 
@@ -2383,7 +2405,8 @@ start_struct (GMarkupParseContext *context,
       return FALSE;
     }
 
-  struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
+  struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT,
+					     ctx->current_module);
 
   ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
   if (deprecated)
@@ -2443,7 +2466,8 @@ start_union (GMarkupParseContext *context,
       return FALSE;
     }
 
-  union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
+  union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION,
+					   ctx->current_module);
 
   ((GIrNode *)union_)->name = g_strdup (name ? name : "");
   union_->gtype_name = g_strdup (typename);
@@ -2505,7 +2529,7 @@ parse_include (GMarkupParseContext *context,
   gchar *buffer;
   gsize length;
   gchar *girpath, *girname;
-  GList *modules;
+  GIrModule *module;
   GList *l;
 
   for (l = ctx->parser->parsed_modules; l; l = l->next)
@@ -2541,7 +2565,7 @@ parse_include (GMarkupParseContext *context,
     }
   g_free (girname);
 
-  g_debug ("Parsing include %s", girpath);
+  g_debug ("Parsing include %s\n", girpath);
 
   if (!g_file_get_contents (girpath, &buffer, &length, &error))
     {
@@ -2551,7 +2575,7 @@ parse_include (GMarkupParseContext *context,
       return FALSE;
     }
 
-  modules = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error);
+  module = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error);
   g_free (buffer);
   if (error != NULL)
     {
@@ -2564,8 +2588,8 @@ parse_include (GMarkupParseContext *context,
     }
   g_free (girpath);
 
-  ctx->include_modules = g_list_concat (ctx->include_modules,
-					modules);
+  ctx->include_modules = g_list_append (ctx->include_modules,
+					module);
 
   return TRUE;
 }
@@ -3357,10 +3381,9 @@ cleanup (GMarkupParseContext *context,
  * Parse a string that holds a complete GIR XML file, and return a list of a
  * a #GirModule for each &lt;namespace/&gt; element within the file.
  *
- * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves
- *  are owned by the #GIrParser and will be freed along with the parser.
+ * Returns: (transfer none): a new #GirModule
  */
-GList *
+GIrModule *
 g_ir_parser_parse_string (GIrParser           *parser,
 			  const gchar         *namespace,
 			  const gchar         *filename,
@@ -3418,7 +3441,7 @@ g_ir_parser_parse_string (GIrParser           *parser,
 
   g_markup_parse_context_free (context);
 
-  return ctx.modules;
+  return ctx.modules->data;
 }
 
 /**
@@ -3433,14 +3456,14 @@ g_ir_parser_parse_string (GIrParser           *parser,
  * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves
  *  are owned by the #GIrParser and will be freed along with the parser.
  */
-GList *
+GIrModule *
 g_ir_parser_parse_file (GIrParser   *parser,
 			const gchar *filename,
 			GError     **error)
 {
   gchar *buffer;
   gsize length;
-  GList *modules;
+  GIrModule *module;
   const char *slash;
   char *dash;
   char *namespace;
@@ -3471,13 +3494,13 @@ g_ir_parser_parse_file (GIrParser   *parser,
   if (!g_file_get_contents (filename, &buffer, &length, error))
     return NULL;
 
-  modules = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error);
+  module = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error);
 
   g_free (namespace);
 
   g_free (buffer);
 
-  return modules;
+  return module;
 }
 
 
diff --git a/girepository/girparser.h b/girepository/girparser.h
index 6fca1b3..076c981 100644
--- a/girepository/girparser.h
+++ b/girepository/girparser.h
@@ -25,6 +25,8 @@
 
 G_BEGIN_DECLS
 
+#include "girmodule.h"
+
 typedef struct _GIrParser GIrParser;
 
 GIrParser *g_ir_parser_new          (void);
@@ -32,15 +34,15 @@ void       g_ir_parser_free         (GIrParser          *parser);
 void       g_ir_parser_set_includes (GIrParser          *parser,
 				     const gchar *const *includes);
 
-GList *g_ir_parser_parse_string (GIrParser    *parser,
-				 const gchar  *namespace,
-				 const gchar  *filename,
-				 const gchar  *buffer,
-				 gssize        length,
-				 GError      **error);
-GList *g_ir_parser_parse_file   (GIrParser    *parser,
-				 const gchar  *filename,
-				 GError      **error);
+GIrModule *g_ir_parser_parse_string (GIrParser    *parser,
+				     const gchar  *namespace,
+				     const gchar  *filename,
+				     const gchar  *buffer,
+				     gssize        length,
+				     GError      **error);
+GIrModule *g_ir_parser_parse_file   (GIrParser    *parser,
+				     const gchar  *filename,
+				     GError      **error);
 
 G_END_DECLS
 
diff --git a/tools/compiler.c b/tools/compiler.c
index 62c0d34..1c68b0a 100644
--- a/tools/compiler.c
+++ b/tools/compiler.c
@@ -140,7 +140,7 @@ main (int argc, char ** argv)
   GOptionContext *context;
   GError *error = NULL;
   GIrParser *parser;
-  GList *m, *modules;
+  GIrModule *module;
   gint i;
   g_typelib_check_sanity ();
 
@@ -178,35 +178,22 @@ main (int argc, char ** argv)
 
   g_ir_parser_set_includes (parser, (const char*const*) includedirs);
 
-  modules = NULL;
-  for (i = 0; input[i]; i++)
+  module = g_ir_parser_parse_file (parser, input[0], &error);
+  if (module == NULL) 
     {
-      GList *mods;
-      mods = g_ir_parser_parse_file (parser, input[i], &error);
+      g_fprintf (stderr, "error parsing file %s: %s\n", 
+		 input[0], error->message);
       
-      if (mods == NULL) 
-	{
-	  g_fprintf (stderr, "error parsing file %s: %s\n", 
-		     input[i], error->message);
-      
-	  return 1;
-	}
-
-      modules = g_list_concat (modules, mods);
+      return 1;
     }
 
   g_debug ("[parsing] done");
 
   g_debug ("[building] start");
 
-  for (m = modules; m; m = m->next)
-    {
-      GIrModule *module = m->data;
-      gchar *prefix;
+  {
       GTypelib *typelib;
 
-      if (mname && strcmp (mname, module->name) != 0)
-	continue;
       if (shlib)
 	{
           if (module->shared_library)
@@ -216,33 +203,16 @@ main (int argc, char ** argv)
 
       g_debug ("[building] module %s", module->name);
 
-      typelib = g_ir_module_build_typelib (module, modules);
+      typelib = g_ir_module_build_typelib (module);
       if (typelib == NULL)
-	{
-	  g_error ("Failed to build typelib for module '%s'\n", module->name);
-
-	  continue;
-	}
+	g_error ("Failed to build typelib for module '%s'\n", module->name);
       if (!g_typelib_validate (typelib, &error))
 	g_error ("Invalid typelib for module '%s': %s", 
 		 module->name, error->message);
 
-      if (!mname && (m->next || m->prev) && output)
-	prefix = module->name;
-      else
-	prefix = NULL;
-
-      write_out_typelib (prefix, typelib);
+      write_out_typelib (NULL, typelib);
       g_typelib_free (typelib);
       typelib = NULL;
-
-      /* when writing to stdout, stop after the first module */
-      if (m->next && !output && !mname)
-	{
-	  g_warning ("%d modules omitted\n", g_list_length (modules) - 1);
-
-	  break;
-	}
     }
 
   g_debug ("[building] done");



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