gobject-introspection r874 - trunk/girepository



Author: otaylor
Date: Tue Nov 11 00:48:17 2008
New Revision: 874
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=874&view=rev

Log:
Bug 560250 - Fully parse included modules

For some things, like computing structure offsets to put into the typelib
we need more than just the aliases from included modules. Do a completel
parse of included modules and store in module->included_modules.

Also add g_ir_find_node() to find node information from within the
active set of modules and their includes.

Modified:
   trunk/girepository/girmodule.c
   trunk/girepository/girmodule.h
   trunk/girepository/girnode.c
   trunk/girepository/girnode.h
   trunk/girepository/girparser.c

Modified: trunk/girepository/girmodule.c
==============================================================================
--- trunk/girepository/girmodule.c	(original)
+++ trunk/girepository/girmodule.c	Tue Nov 11 00:48:17 2008
@@ -62,6 +62,10 @@
   g_list_free (module->entries);
   /* Don't free dependencies, we inherit that from the parser */
 
+  /* FIXME: we leak the included modules themelves; they may be shared
+   * between multiple modules, so we would need refcounting */
+  g_list_free (module->include_modules);
+
   g_free (module);
 }
 

Modified: trunk/girepository/girmodule.h
==============================================================================
--- trunk/girepository/girmodule.h	(original)
+++ trunk/girepository/girmodule.h	Tue Nov 11 00:48:17 2008
@@ -36,6 +36,7 @@
   gchar *shared_library;
   GList *dependencies;
   GList *entries;
+  GList *include_modules;
 };
 
 GIrModule *g_ir_module_new            (const gchar *name,

Modified: trunk/girepository/girnode.c
==============================================================================
--- trunk/girepository/girnode.c	(original)
+++ trunk/girepository/girnode.c	Tue Nov 11 00:48:17 2008
@@ -1070,6 +1070,92 @@
   return idx;
 }
 
+static GIrNode *
+find_name_in_module (GIrModule   *module,
+		     const gchar *name)
+{
+  GList *l;
+
+  for (l = module->entries; l; l = l->next)
+    {
+      GIrNode *node = (GIrNode *)l->data;
+
+      if (strcmp (node->name, name) == 0)
+	return node;
+    }
+
+  return NULL;
+}
+
+gboolean
+g_ir_find_node (GIrModule  *module,
+		GList      *modules,
+		const char *name,
+		GIrNode   **node_out,
+		GIrModule **module_out)
+{
+  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;
+    }
+
+  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]);
+    }
+  else
+    {
+      for (l = module->include_modules; l; l = l->next)
+	{
+	  GIrModule *m = l->data;
+
+	  if (strcmp (names[0], m->name) == 0)
+	    {
+	      *module_out = m;
+	      node = find_name_in_module (m, names[1]);
+	      goto out;
+	    }
+	}
+
+      for (l = modules; l; l = l->next)
+	{
+	  GIrModule *m = l->data;
+
+	  if (strcmp (names[0], m->name) == 0)
+	    {
+	      *module_out = m;
+	      node = find_name_in_module (m, names[1]);
+	      goto out;
+	    }
+	}
+    }
+
+ out:
+  g_strfreev (names);
+
+  *node_out = node;
+
+  return node != NULL;
+}
+
 static void
 serialize_type (GIrModule    *module, 
 		GList        *modules,

Modified: trunk/girepository/girnode.h
==============================================================================
--- trunk/girepository/girnode.h	(original)
+++ trunk/girepository/girnode.h	Tue Nov 11 00:48:17 2008
@@ -23,6 +23,8 @@
 
 #include <glib.h>
 
+#include "girmodule.h"
+
 G_BEGIN_DECLS
 
 typedef struct _GIrNode GIrNode; 
@@ -340,6 +342,12 @@
 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);
+
 G_END_DECLS
 
 #endif  /* __G_IR_NODE_H__ */

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Tue Nov 11 00:48:17 2008
@@ -72,6 +72,7 @@
   const char * const*includes;
   
   GList *modules;
+  GList *include_modules;
   gboolean prefix_aliases;
   GList *dependencies;
   GHashTable *aliases;
@@ -87,6 +88,34 @@
   int type_depth;
 };
 
+static void start_element_handler (GMarkupParseContext *context,
+				   const gchar         *element_name,
+				   const gchar        **attribute_names,
+				   const gchar        **attribute_values,
+				   gpointer             user_data,
+				   GError             **error);
+static void end_element_handler   (GMarkupParseContext *context,
+				   const gchar         *element_name,
+				   gpointer             user_data,
+				   GError             **error);
+static void text_handler          (GMarkupParseContext *context,
+				   const gchar         *text,
+				   gsize                text_len,
+				   gpointer             user_data,
+				   GError             **error);
+static void cleanup               (GMarkupParseContext *context,
+				   GError              *error,
+				   gpointer             user_data);
+
+static GMarkupParser parser = 
+{
+  start_element_handler,
+  end_element_handler,
+  text_handler,
+  NULL,
+  cleanup
+};
+
 static gboolean
 start_alias (GMarkupParseContext *context,
 	     const gchar         *element_name,
@@ -2116,7 +2145,31 @@
   gchar *buffer;
   gsize length;
   char *girpath;
-  
+  gboolean success = FALSE;
+  GList *l;
+
+  for (l = ctx->include_modules; l; l = l->next)
+    {
+      GIrModule *m = l->data;
+
+      if (strcmp (m->name, name) == 0)
+	{
+	  if (strcmp (m->version, version) == 0)
+	    {
+	      return TRUE;
+	    }
+	  else
+	    {
+	      g_set_error (error,
+			   G_MARKUP_ERROR,
+			   G_MARKUP_ERROR_INVALID_CONTENT,
+			   "Module '%s' imported with conflicting versions '%s' and '%s'",
+			   name, m->version, version);
+	      return FALSE;
+	    }
+	}
+    }
+
   girpath = locate_gir (name, version, ctx->includes);
 
   if (girpath == NULL)
@@ -2147,21 +2200,32 @@
   sub_ctx.type_depth = 0;
 
   context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
-	  
+
   if (!g_markup_parse_context_parse (context, buffer, length, error))
-    {
-      g_free (buffer);
-      return FALSE;
-    }
-	  
+    goto out;
+
   if (!g_markup_parse_context_end_parse (context, error))
-    {
-      g_free (buffer);
-      return FALSE;
-    }
-	  
+    goto out;
+
   g_markup_parse_context_free (context);
-  return TRUE;
+
+  context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL);
+  if (!g_markup_parse_context_parse (context, buffer, length, error))
+    goto out;
+
+  if (!g_markup_parse_context_end_parse (context, error))
+    goto out;
+
+  success = TRUE;
+
+ out:
+  ctx->include_modules = g_list_concat (ctx->include_modules,
+					sub_ctx.modules);
+
+  g_markup_parse_context_free (context);
+  g_free (buffer);
+
+  return success;
 }
   
 extern GLogLevelFlags logged_levels;
@@ -2358,6 +2422,7 @@
 	      ctx->current_module = g_ir_module_new (name, version, shared_library);
 	      ctx->modules = g_list_append (ctx->modules, ctx->current_module);
 	      ctx->current_module->dependencies = ctx->dependencies;
+	      ctx->current_module->include_modules = g_list_copy (ctx->include_modules);
 
 	      state_switch (ctx, STATE_NAMESPACE);
 	      goto out;
@@ -2819,15 +2884,6 @@
   ctx->current_module = NULL;
 }
 
-static GMarkupParser parser = 
-{
-  start_element_handler,
-  end_element_handler,
-  text_handler,
-  NULL,
-  cleanup
-};
-
 static GList *
 post_filter_varargs_functions (GList *list)
 {



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