From 12e2b6fb1c9d89f173c599d17427ed8b57eeef3b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 13 Jul 2022 13:26:44 +0100 Subject: Use the pointer attribute in libgirepository The "disguised" attribute is there only for backward compatibility; we use the "pointer" attribute as the authoritative way to indicate a typedef to a struct pointer. --- girepository/girmodule.c | 14 ++++++++++ girepository/girmodule.h | 9 +++++-- girepository/girnode.h | 2 ++ girepository/girparser.c | 70 +++++++++++++++++++++++++++++++++++------------- 4 files changed, 75 insertions(+), 20 deletions(-) (limited to 'girepository') diff --git a/girepository/girmodule.c b/girepository/girmodule.c index 66b33fa1..943db971 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -74,6 +74,7 @@ _g_ir_module_free (GIrModule *module) g_list_free (module->include_modules); g_hash_table_destroy (module->aliases); + g_hash_table_destroy (module->pointer_structures); g_hash_table_destroy (module->disguised_structures); g_slice_free (GIrModule, module); @@ -141,6 +142,16 @@ add_alias_foreach (gpointer key, g_hash_table_replace (module->aliases, g_strdup (key), g_strdup (value)); } +static void +add_pointer_structure_foreach (gpointer key, + gpointer value, + gpointer data) +{ + GIrModule *module = data; + + g_hash_table_replace (module->pointer_structures, g_strdup (key), value); +} + static void add_disguised_structure_foreach (gpointer key, gpointer value, @@ -162,6 +173,9 @@ _g_ir_module_add_include_module (GIrModule *module, add_alias_foreach, module); + g_hash_table_foreach (include_module->pointer_structures, + add_pointer_structure_foreach, + module); g_hash_table_foreach (include_module->disguised_structures, add_disguised_structure_foreach, module); diff --git a/girepository/girmodule.h b/girepository/girmodule.h index 7837f2cf..fca7ebbf 100644 --- a/girepository/girmodule.h +++ b/girepository/girmodule.h @@ -55,8 +55,13 @@ struct _GIrModule /* 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 */ + /* Structures with the 'pointer' flag (typedef struct _X *X) + * in the module or in included modules + */ + GHashTable *pointer_structures; + /* Same as 'pointer' structures, but with the deprecated + * 'disguised' flag + */ GHashTable *disguised_structures; }; diff --git a/girepository/girnode.h b/girepository/girnode.h index 45a81477..a3583433 100644 --- a/girepository/girnode.h +++ b/girepository/girnode.h @@ -322,6 +322,8 @@ struct _GIrNodeStruct gboolean deprecated; gboolean disguised; + gboolean opaque; + gboolean pointer; gboolean is_gtype_struct; gboolean foreign; diff --git a/girepository/girparser.c b/girepository/girparser.c index 5ac4aefe..3edeac34 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -114,6 +114,7 @@ struct _ParseContext GList *dependencies; GHashTable *aliases; GHashTable *disguised_structures; + GHashTable *pointer_structures; const char *file_path; const char *namespace; @@ -235,11 +236,20 @@ firstpass_start_element_handler (GMarkupParseContext *context, { const gchar *name; const gchar *disguised; + const gchar *pointer; name = find_attribute ("name", attribute_names, attribute_values); disguised = find_attribute ("disguised", attribute_names, attribute_values); + pointer = find_attribute ("pointer", attribute_names, attribute_values); - if (disguised && strcmp (disguised, "1") == 0) + if (g_strcmp0 (pointer, "1") == 0) + { + char *key; + + key = g_strdup_printf ("%s.%s", ctx->namespace, name); + g_hash_table_replace (ctx->pointer_structures, key, GINT_TO_POINTER (1)); + } + else if (g_strcmp0 (disguised, "1") == 0) { char *key; @@ -660,12 +670,14 @@ resolve_aliases (ParseContext *ctx, const gchar *type) return lookup; } -static gboolean -is_disguised_structure (ParseContext *ctx, const gchar *type) +static void +is_pointer_or_disguised_structure (ParseContext *ctx, + const gchar *type, + gboolean *is_pointer, + gboolean *is_disguised) { const gchar *lookup; gchar *prefixed; - gboolean result; if (strchr (type, '.') == NULL) { @@ -678,12 +690,12 @@ is_disguised_structure (ParseContext *ctx, const gchar *type) prefixed = NULL; } - result = g_hash_table_lookup (ctx->current_module->disguised_structures, - lookup) != NULL; + if (is_pointer != NULL) + *is_pointer = g_hash_table_lookup (ctx->current_module->pointer_structures, lookup) != NULL; + if (is_disguised != NULL) + *is_disguised = g_hash_table_lookup (ctx->current_module->disguised_structures, lookup) != NULL; g_free (prefixed); - - return result; } static GIrNodeType * @@ -2096,12 +2108,22 @@ start_type (GMarkupParseContext *context, typenode = parse_type (ctx, name); - /* A 'disguised' structure is one where the c:type is a typedef that - * doesn't look like a pointer, but is internally. + /* A "pointer" structure is one where the c:type is a typedef that + * to a pointer to a structure; we used to call them "disguised" + * structures as well. */ - if (typenode->tag == GI_TYPE_TAG_INTERFACE && - is_disguised_structure (ctx, typenode->giinterface)) - pointer_depth++; + if (typenode->tag == GI_TYPE_TAG_INTERFACE) + { + gboolean is_pointer = FALSE; + gboolean is_disguised = FALSE; + + is_pointer_or_disguised_structure (ctx, typenode->giinterface, + &is_pointer, + &is_disguised); + + if (is_pointer || is_disguised) + pointer_depth++; + } if (pointer_depth > 0) typenode->is_pointer = TRUE; @@ -2558,6 +2580,8 @@ start_struct (GMarkupParseContext *context, const gchar *name; const gchar *deprecated; const gchar *disguised; + const gchar *opaque; + const gchar *pointer; const gchar *gtype_name; const gchar *gtype_init; const gchar *gtype_struct; @@ -2579,6 +2603,8 @@ start_struct (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); disguised = find_attribute ("disguised", attribute_names, attribute_values); + pointer = find_attribute ("pointer", attribute_names, attribute_values); + opaque = find_attribute ("opaque", attribute_names, attribute_values); gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); @@ -2611,9 +2637,15 @@ start_struct (GMarkupParseContext *context, else struct_->deprecated = FALSE; - if (disguised && strcmp (disguised, "1") == 0) + if (g_strcmp0 (disguised, "1") == 0) struct_->disguised = TRUE; + if (g_strcmp0 (pointer, "1") == 0) + struct_->pointer = TRUE; + + if (g_strcmp0 (opaque, "1") == 0) + struct_->opaque = TRUE; + struct_->is_gtype_struct = gtype_struct != NULL; struct_->gtype_name = g_strdup (gtype_name); @@ -3033,7 +3065,9 @@ start_element_handler (GMarkupParseContext *context, ctx->current_module->aliases = ctx->aliases; ctx->aliases = NULL; ctx->current_module->disguised_structures = ctx->disguised_structures; + ctx->current_module->pointer_structures = ctx->pointer_structures; ctx->disguised_structures = NULL; + ctx->pointer_structures = NULL; for (l = ctx->include_modules; l; l = l->next) _g_ir_module_add_include_module (ctx->current_module, l->data); @@ -3622,6 +3656,7 @@ _g_ir_parser_parse_string (GIrParser *parser, ctx.include_modules = NULL; 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); + ctx.pointer_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ctx.type_depth = 0; ctx.dependencies = NULL; ctx.current_module = NULL; @@ -3654,10 +3689,9 @@ _g_ir_parser_parse_string (GIrParser *parser, /* An error occurred before we created a module, so we haven't * transferred ownership of these hash tables 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_clear_pointer (&ctx.aliases, g_hash_table_unref); + g_clear_pointer (&ctx.disguised_structures, g_hash_table_unref); + g_clear_pointer (&ctx.pointer_structures, g_hash_table_unref); g_list_free (ctx.include_modules); } -- cgit v1.2.1