gobject-introspection r904 - in trunk: . girepository



Author: otaylor
Date: Wed Nov 12 17:17:01 2008
New Revision: 904
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=904&view=rev

Log:
Keep aliases and disguised_structures local to each module (#560419)

When parsing, keep keep a separate hash tables of aliases and
'disguised' flags for each module, and store that on the module.

After parsing an include merge the aliases/disguised flags to the
including module.

Remove 'prefix_aliases' flag and always prefix aliases/disguised
structure types when parsing; this simplifies the code considerably.

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

Modified: trunk/girepository/girmodule.c
==============================================================================
--- trunk/girepository/girmodule.c	(original)
+++ trunk/girepository/girmodule.c	Wed Nov 12 17:17:01 2008
@@ -46,6 +46,9 @@
   module->dependencies = NULL;
   module->entries = NULL;
 
+  module->include_modules = NULL;
+  module->aliases = NULL;
+
   return module;
 }
 
@@ -62,13 +65,50 @@
   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_hash_table_destroy (module->aliases);
+  g_hash_table_destroy (module->disguised_structures);
+
   g_free (module);
 }
 
+static void
+add_alias_foreach (gpointer key,
+		   gpointer value,
+		   gpointer data)
+{
+  GIrModule *module = data;
+
+  g_hash_table_replace (module->aliases, g_strdup (key), g_strdup (value));
+}
+
+static void
+add_disguised_structure_foreach (gpointer key,
+				 gpointer value,
+				 gpointer data)
+{
+  GIrModule *module = data;
+
+  g_hash_table_replace (module->disguised_structures, g_strdup (key), value);
+}
+
+void
+g_ir_module_add_include_module (GIrModule  *module,
+				GIrModule  *include_module)
+{
+  module->include_modules = g_list_prepend (module->include_modules,
+					    include_module);
+
+  g_hash_table_foreach (include_module->aliases,
+			add_alias_foreach,
+			module);
+
+  g_hash_table_foreach (include_module->disguised_structures,
+			add_disguised_structure_foreach,
+			module);
+}
+
 GTypelib *
 g_ir_module_build_typelib (GIrModule  *module,
 			     GList       *modules)

Modified: trunk/girepository/girmodule.h
==============================================================================
--- trunk/girepository/girmodule.h	(original)
+++ trunk/girepository/girmodule.h	Wed Nov 12 17:17:01 2008
@@ -36,7 +36,16 @@
   gchar *shared_library;
   GList *dependencies;
   GList *entries;
+
+  /* All modules that are included directly or indirectly */
   GList *include_modules;
+
+  /* Aliases defined in the module or in included modules */
+  GHashTable *aliases;
+
+  /* Structures with the 'disguised' flag (typedef struct _X *X)
+  * in the module or in included modules */
+  GHashTable *disguised_structures;
 };
 
 GIrModule *g_ir_module_new            (const gchar *name,
@@ -44,6 +53,9 @@
 				       const gchar *module_filename);
 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);
 

Modified: trunk/girepository/girparser.c
==============================================================================
--- trunk/girepository/girparser.c	(original)
+++ trunk/girepository/girparser.c	Wed Nov 12 17:17:01 2008
@@ -79,7 +79,6 @@
 
   GList *modules;
   GList *include_modules;
-  gboolean prefix_aliases;
   GList *dependencies;
   GHashTable *aliases;
   GHashTable *disguised_structures;
@@ -189,15 +188,7 @@
 	{
 	  char *key;
 
-	  if (ctx->prefix_aliases)
-	    {
-	      key = g_strdup_printf ("%s.%s", ctx->namespace, name);
-	    }
-	  else
-	    {
-	      key = g_strdup (name);
-	    }
-
+	  key = g_strdup_printf ("%s.%s", ctx->namespace, name);
 	  g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
 	}
     }
@@ -514,23 +505,22 @@
   gpointer orig;
   gpointer value;
   GSList *seen_values = NULL;
-  const char *lookup;
-  char *prefixed = NULL;
+  const gchar *lookup;
+  gchar *prefixed;
 
-  /* If we are in an included module, then we need to qualify the
-   * names of types before resolving them, since they will have
-   * been stored in the aliases qualified.
-   */
-  if (ctx->prefix_aliases && strchr (type, '.') == NULL)
+  if (strchr (type, '.') == NULL)
     {
       prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
       lookup = prefixed;
     }
   else
-    lookup = type;
+    {
+      lookup = type;
+      prefixed = NULL;
+    }
 
   seen_values = g_slist_prepend (seen_values, (char*)lookup);
-  while (g_hash_table_lookup_extended (ctx->aliases, lookup, &orig, &value))
+  while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
     {
       g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
       lookup = value;
@@ -543,12 +533,38 @@
 
   if (lookup == prefixed)
     lookup = type;
-  
+
   g_free (prefixed);
   
   return lookup;
 }
 
+static gboolean
+is_disguised_structure (ParseContext *ctx, const gchar *type)
+{
+  const gchar *lookup;
+  gchar *prefixed;
+  gboolean result;
+
+  if (strchr (type, '.') == NULL)
+    {
+      prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
+      lookup = prefixed;
+    }
+  else
+    {
+      lookup = type;
+      prefixed = NULL;
+    }
+
+  result = g_hash_table_lookup (ctx->current_module->disguised_structures,
+				lookup) != NULL;
+  
+  g_free (prefixed);
+  
+  return result;
+}
+
 static GIrNodeType *
 parse_type (ParseContext *ctx, const gchar *type)
 {
@@ -1062,25 +1078,18 @@
     }
 
   value = g_strdup (target);
-  if (ctx->prefix_aliases)
+  key = g_strdup_printf ("%s.%s", ctx->namespace, name);
+  if (!strchr (target, '.'))
     {
-      key = g_strdup_printf ("%s.%s", ctx->namespace, name);
-      if (!strchr (target, '.'))
+      const BasicTypeInfo *basic = parse_basic (target);
+      if (!basic)
 	{
-	  const BasicTypeInfo *basic = parse_basic (target);
-	  if (!basic)
-	    {
-	      g_free (value);
-	      /* For non-basic types, re-qualify the interface */
-	      value = g_strdup_printf ("%s.%s", ctx->namespace, target);
-	    }
+	  g_free (value);
+	  /* For non-basic types, re-qualify the interface */
+	  value = g_strdup_printf ("%s.%s", ctx->namespace, target);
 	}
     }
-  else
-    {
-      key = g_strdup (name);
-    }
-  g_hash_table_insert (ctx->aliases, key, value);
+  g_hash_table_replace (ctx->aliases, key, value);
 
   return TRUE;
 }
@@ -1660,7 +1669,7 @@
        * doesn't look like a pointer, but is internally.
        */
       if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
-	  g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL)
+	  is_disguised_structure (ctx, typenode->interface))
 	is_pointer = TRUE;
 
       if (is_pointer)
@@ -2190,11 +2199,11 @@
 	       const char          *version,
 	       GError             **error)
 {
-  ParseContext sub_ctx = { 0 };
   gchar *buffer;
   gsize length;
   char *girpath;
   gboolean success = FALSE;
+  GList *modules;
   GList *l;
 
   for (l = ctx->include_modules; l; l = l->next)
@@ -2240,38 +2249,12 @@
     }
   g_free (girpath);
 
-  sub_ctx.parser = ctx->parser;
-  sub_ctx.state = STATE_START;
-  sub_ctx.prefix_aliases = TRUE;
-  sub_ctx.namespace = name;
-  sub_ctx.aliases = ctx->aliases;
-  sub_ctx.disguised_structures = ctx->disguised_structures;
-  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))
-    goto out;
+  modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
+  success = error != NULL;
 
-  if (!g_markup_parse_context_end_parse (context, error))
-    goto out;
-
-  g_markup_parse_context_free (context);
-
-  context = g_markup_parse_context_new (&markup_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);
+					modules);
 
-  g_markup_parse_context_free (context);
   g_free (buffer);
 
   return success;
@@ -2477,6 +2460,8 @@
 	    MISSING_ATTRIBUTE (context, error, element_name, "version");
 	  else
 	    {
+	      GList *l;
+
 	      if (strcmp (name, ctx->namespace) != 0)
 		g_set_error (error,
 			     G_MARKUP_ERROR,
@@ -2485,6 +2470,15 @@
 			     name, ctx->namespace);
 
 	      ctx->current_module = g_ir_module_new (name, version, shared_library);
+
+	      ctx->current_module->aliases = ctx->aliases;
+	      ctx->aliases = NULL;
+	      ctx->current_module->disguised_structures = ctx->disguised_structures;
+	      ctx->disguised_structures = NULL;
+
+	      for (l = ctx->include_modules; l; l = l->next)
+		g_ir_module_add_include_module (ctx->current_module, l->data);
+
 	      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);
@@ -3033,7 +3027,6 @@
 
   ctx.parser = parser;
   ctx.state = STATE_START;
-  ctx.prefix_aliases = FALSE;
   ctx.namespace = namespace;
   ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
   ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -3060,8 +3053,15 @@
 
  out:
 
-  g_hash_table_destroy (ctx.aliases);
-  g_hash_table_destroy (ctx.disguised_structures);
+  if (ctx.modules == NULL)
+    {
+      /* If we have a module, then ownership is transferred to the module */
+
+      if (ctx.aliases != NULL)
+	g_hash_table_destroy (ctx.aliases);
+      if (ctx.disguised_structures != NULL)
+	g_hash_table_destroy (ctx.disguised_structures);
+    }
   
   g_markup_parse_context_free (context);
   



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