From b27fbf503b5fb6b9b5f6ff6f1c0a91a9b2d5fe0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 10 May 2024 18:35:04 +0200 Subject: [PATCH] girepository/girparser,girmodule: Use a GPtrArray to hold the dependencies It's just better than a list of strings for various reasons, but mostly here it allows also to avoid copying the lists but making the ownership clearer through references --- girepository/girmodule-private.h | 2 +- girepository/girmodule.c | 48 +++++++++++++++++--------------- girepository/girparser.c | 20 +++++++------ 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/girepository/girmodule-private.h b/girepository/girmodule-private.h index fba781d5e..c6b9f413c 100644 --- a/girepository/girmodule-private.h +++ b/girepository/girmodule-private.h @@ -47,7 +47,7 @@ struct _GIIrModule char *version; char *shared_library; char *c_prefix; - GList *dependencies; /* (owned) */ + GPtrArray *dependencies; /* (owned) */ GList *entries; /* All modules that are included directly or indirectly */ diff --git a/girepository/girmodule.c b/girepository/girmodule.c index c3309cdc2..87bb13ad3 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -83,7 +83,7 @@ gi_ir_module_free (GIIrModule *module) gi_ir_node_free ((GIIrNode *)e->data); g_list_free (module->entries); - g_clear_list (&module->dependencies, g_free); + g_clear_pointer (&module->dependencies, g_ptr_array_unref); g_list_free (module->include_modules); @@ -351,25 +351,29 @@ gi_ir_module_build_typelib (GIIrModule *module) /* Serialize dependencies into one string; this is convenient * and not a major change to the typelib format. */ - { - GString *dependencies_str = g_string_new (""); - GList *link; - for (link = module->dependencies; link; link = link->next) - { - const char *dependency = link->data; - if (!strcmp (dependency, module->name)) - continue; - g_string_append (dependencies_str, dependency); - if (link->next) - g_string_append_c (dependencies_str, '|'); - } - dependencies = g_string_free (dependencies_str, FALSE); - if (!dependencies[0]) - { - g_free (dependencies); - dependencies = NULL; - } - } + if (module->dependencies->len) + { + GString *dependencies_str = g_string_new (NULL); + for (guint i = module->dependencies->len; i > 0; --i) + { + const char *dependency = g_ptr_array_index (module->dependencies, i-1); + if (!strcmp (dependency, module->name)) + continue; + g_string_append (dependencies_str, dependency); + if (i > 1) + g_string_append_c (dependencies_str, '|'); + } + dependencies = g_string_free (dependencies_str, FALSE); + if (dependencies && !dependencies[0]) + { + g_free (dependencies); + dependencies = NULL; + } + } + else + { + dependencies = NULL; + } restart: gi_ir_node_init_stats (); @@ -378,8 +382,8 @@ gi_ir_module_build_typelib (GIIrModule *module) nodes_with_attributes = NULL; n_entries = g_list_length (module->entries); - g_message ("%d entries (%d local), %d dependencies", n_entries, n_local_entries, - g_list_length (module->dependencies)); + g_message ("%d entries (%d local), %u dependencies", n_entries, n_local_entries, + module->dependencies ? module->dependencies->len : 0); dir_size = n_entries * sizeof (DirEntry); size = header_size + dir_size; diff --git a/girepository/girparser.c b/girepository/girparser.c index 091b947c6..a469d3dd2 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -120,7 +120,7 @@ struct _ParseContext GList *modules; GList *include_modules; - GList *dependencies; + GPtrArray *dependencies; GHashTable *aliases; GHashTable *disguised_structures; GHashTable *pointer_structures; @@ -3101,9 +3101,8 @@ start_element_handler (GMarkupParseContext *context, return; } - ctx->dependencies = g_list_prepend (ctx->dependencies, - g_strdup_printf ("%s-%s", name, version)); - + g_ptr_array_insert (ctx->dependencies, 0, + g_strdup_printf ("%s-%s", name, version)); state_switch (ctx, STATE_INCLUDE); goto out; @@ -3191,9 +3190,12 @@ start_element_handler (GMarkupParseContext *context, ctx->include_modules = NULL; ctx->modules = g_list_append (ctx->modules, ctx->current_module); - g_clear_list (&ctx->current_module->dependencies, g_free); - ctx->current_module->dependencies = - g_list_copy_deep (ctx->dependencies, (GCopyFunc) g_strdup, NULL); + + if (ctx->current_module->dependencies != ctx->dependencies) + { + g_clear_pointer (&ctx->current_module->dependencies, g_ptr_array_unref); + ctx->current_module->dependencies = g_ptr_array_ref (ctx->dependencies); + } state_switch (ctx, STATE_NAMESPACE); goto out; @@ -3786,7 +3788,7 @@ gi_ir_parser_parse_string (GIIrParser *parser, 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.dependencies = g_ptr_array_new_with_free_func (g_free); ctx.current_module = NULL; context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL); @@ -3828,7 +3830,7 @@ gi_ir_parser_parse_string (GIIrParser *parser, } g_clear_slist (&ctx.node_stack, NULL); - g_clear_list (&ctx.dependencies, g_free); + g_clear_pointer (&ctx.dependencies, g_ptr_array_unref); g_markup_parse_context_free (context); if (module)