https://github.com/geany/geany/pull/3785.patch to make build of glfw deterministic From aa4e901807e8f0294f25d9f4ef3516b775ce0b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Techet?= Date: Wed, 6 Mar 2024 23:11:36 +0100 Subject: [PATCH] Rename both scope and var_type of anonymous types In addition to scope, anonymous type can appear also inside var_type which should be renamed as well. Thanks to Colomban Wendling for improving the original version of this patch. Fixes #3717. --- src/tagmanager/tm_ctags.c | 59 ++++++++++++++++++++-------------- tests/ctags/Makefile.am | 1 + tests/ctags/nested_anon.c | 5 +++ tests/ctags/nested_anon.c.tags | 6 ++++ tests/meson.build | 1 + 5 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 tests/ctags/nested_anon.c create mode 100644 tests/ctags/nested_anon.c.tags diff --git a/src/tagmanager/tm_ctags.c b/src/tagmanager/tm_ctags.c index 9a971b14fd..9cde83f317 100644 --- a/src/tagmanager/tm_ctags.c +++ b/src/tagmanager/tm_ctags.c @@ -241,6 +241,33 @@ void tm_ctags_clear_ignore_symbols(void) } +static gboolean replace_str(gchar **where, const gchar *what, guint what_len, + const gchar *replacement, guint replacement_len) +{ + if (where && *where) + { + gchar *pos = strstr(*where, what); + + if (pos) + { + gsize where_len = strlen(*where); + gchar *str = g_malloc(where_len + replacement_len - what_len + 1); + gsize prefix_len = (gsize) (pos - *where); + + strncpy(str, *where, prefix_len); + strcpy(str + prefix_len, replacement); + strcpy(str + prefix_len + replacement_len, pos + what_len); + g_free(*where); + *where = str; + + return TRUE; + } + } + + return FALSE; +} + + /* call after all tags have been collected so we don't have to handle reparses * with the counter (which gets complicated when also subparsers are involved) */ static void rename_anon_tags(TMSourceFile *source_file) @@ -336,7 +363,6 @@ static void rename_anon_tags(TMSourceFile *source_file) { TMTag *nested_tag = TM_TAG(source_file->tags_array->pdata[j]); guint nested_scope_len = nested_tag->scope ? strlen(nested_tag->scope) : 0; - gchar *pos; /* Tags can be interleaved with scopeless macros - skip those */ if (is_c && nested_tag->type & (tm_tag_macro_t | tm_tag_macro_with_arg_t)) @@ -361,22 +387,14 @@ static void rename_anon_tags(TMSourceFile *source_file) if (nested_scope_len <= scope_len) break; - pos = strstr(nested_tag->scope, orig_name); /* We found the parent name in the nested tag scope - replace it * with the new name. Note: anonymous tag names generated by * ctags are unique enough that we don't have to check for * scope separators here. */ - if (pos) - { - gchar *str = g_malloc(nested_scope_len + 50); - guint prefix_len = pos - nested_tag->scope; - - strncpy(str, nested_tag->scope, prefix_len); - strcpy(str + prefix_len, new_name); - strcpy(str + prefix_len + new_name_len, pos + orig_name_len); - g_free(nested_tag->scope); - nested_tag->scope = str; - } + replace_str(&nested_tag->scope, orig_name, orig_name_len, new_name, new_name_len); + + /* Do the same for var_type as well */ + replace_str(&nested_tag->var_type, orig_name, orig_name_len, new_name, new_name_len); } /* We are out of the nesting - the next tags could be variables @@ -385,22 +403,13 @@ static void rename_anon_tags(TMSourceFile *source_file) { TMTag *var_tag = TM_TAG(source_file->tags_array->pdata[j]); guint var_scope_len = var_tag->scope ? strlen(var_tag->scope) : 0; - gchar *pos; /* Should be at the same scope level as the anon tag */ - if (var_scope_len == scope_len && - var_tag->var_type && (pos = strstr(var_tag->var_type, orig_name))) + if (var_scope_len != scope_len || ! var_tag->var_type || + ! replace_str(&var_tag->var_type, orig_name, orig_name_len, new_name, new_name_len)) { - GString *str = g_string_new(var_tag->var_type); - gssize p = pos - var_tag->var_type; - g_string_erase(str, p, strlen(orig_name)); - g_string_insert(str, p, new_name); - g_free(var_tag->var_type); - var_tag->var_type = str->str; - g_string_free(str, FALSE); - } - else break; + } j++; } diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index a973eadd03..c30ac095fd 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -252,6 +252,7 @@ test_sources = \ namespace.cpp \ namespaces2.php \ namespaces.php \ + nested_anon.c \ no_terminator.js \ non-ascii-ident1.php \ numlib.f90 \ diff --git a/tests/ctags/nested_anon.c b/tests/ctags/nested_anon.c new file mode 100644 index 0000000000..0efb63f36a --- /dev/null +++ b/tests/ctags/nested_anon.c @@ -0,0 +1,5 @@ +typedef struct { + struct + { + } __value32; +} __atomic_wide_counter; diff --git a/tests/ctags/nested_anon.c.tags b/tests/ctags/nested_anon.c.tags new file mode 100644 index 0000000000..aef4a45c10 --- /dev/null +++ b/tests/ctags/nested_anon.c.tags @@ -0,0 +1,6 @@ +__atomic_wide_counterÌ2048Ö0 +struct: __atomic_wide_counter +__value32Ì64Î__atomic_wide_counterÖ0Ï__atomic_wide_counter::anon_struct_1 +member: __atomic_wide_counter::anon_struct_1 __atomic_wide_counter :: __value32 +anon_struct_1Ì2048Î__atomic_wide_counterÖ1 +struct: __atomic_wide_counter :: anon_struct_1 flags: 1