summaryrefslogtreecommitdiff
path: root/girepository
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@src.gnome.org>2008-11-12 17:17:01 +0000
committerOwen Taylor <otaylor@src.gnome.org>2008-11-12 17:17:01 +0000
commit09423f25cd99f0999ff3e0b710d34461a5cfa54a (patch)
tree5559043ee3c55001728706979127a44d1a228a43 /girepository
parent755ec2cc858997dd87e41cc5b8114d136d2434f6 (diff)
downloadgobject-introspection-09423f25cd99f0999ff3e0b710d34461a5cfa54a.tar.gz
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. svn path=/trunk/; revision=904
Diffstat (limited to 'girepository')
-rw-r--r--girepository/girmodule.c44
-rw-r--r--girepository/girmodule.h12
-rw-r--r--girepository/girparser.c138
3 files changed, 123 insertions, 71 deletions
diff --git a/girepository/girmodule.c b/girepository/girmodule.c
index 91cc02d8..1b7c3048 100644
--- a/girepository/girmodule.c
+++ b/girepository/girmodule.c
@@ -46,6 +46,9 @@ g_ir_module_new (const gchar *name,
module->dependencies = NULL;
module->entries = NULL;
+ module->include_modules = NULL;
+ module->aliases = NULL;
+
return module;
}
@@ -62,13 +65,50 @@ g_ir_module_free (GIrModule *module)
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)
diff --git a/girepository/girmodule.h b/girepository/girmodule.h
index 5008c4e9..c658e179 100644
--- a/girepository/girmodule.h
+++ b/girepository/girmodule.h
@@ -36,7 +36,16 @@ struct _GIrModule
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 @@ GIrModule *g_ir_module_new (const gchar *name,
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);
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 6601fcca..fcd9dade 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -79,7 +79,6 @@ struct _ParseContext
GList *modules;
GList *include_modules;
- gboolean prefix_aliases;
GList *dependencies;
GHashTable *aliases;
GHashTable *disguised_structures;
@@ -189,15 +188,7 @@ firstpass_start_element_handler (GMarkupParseContext *context,
{
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 @@ resolve_aliases (ParseContext *ctx, const gchar *type)
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 @@ resolve_aliases (ParseContext *ctx, const gchar *type)
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 @@ start_alias (GMarkupParseContext *context,
}
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 @@ start_type (GMarkupParseContext *context,
* 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 @@ parse_include (GMarkupParseContext *context,
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 @@ parse_include (GMarkupParseContext *context,
}
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 @@ start_element_handler (GMarkupParseContext *context,
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 @@ start_element_handler (GMarkupParseContext *context,
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 @@ g_ir_parser_parse_string (GIrParser *parser,
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 @@ g_ir_parser_parse_string (GIrParser *parser,
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);