mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
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
This commit is contained in:
parent
102e08428b
commit
b1c6e64049
44
girmodule.c
44
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)
|
||||
|
12
girmodule.h
12
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);
|
||||
|
||||
|
138
girparser.c
138
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;
|
||||
modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
|
||||
success = error != NULL;
|
||||
|
||||
context = g_markup_parse_context_new (&firstpass_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;
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user