@b4n requested changes on this pull request.

Looks good, but impl can possibly be improved a tad (see nitpicks & useful 
comments inline).

Suggested changes (don't trust it blindly, esp. the part around L406):
```diff
diff --git a/src/tagmanager/tm_ctags.c b/src/tagmanager/tm_ctags.c
index ec795a31d..c7ed72fe0 100644
--- a/src/tagmanager/tm_ctags.c
+++ b/src/tagmanager/tm_ctags.c
@@ -241,26 +241,30 @@ void tm_ctags_clear_ignore_symbols(void)
 }
 
 
-static void replace_str(gchar **where, const gchar *what, guint what_len,
+static gboolean replace_str(gchar **where, const gchar *what, guint what_len,
        const gchar *replacement, guint replacement_len)
 {
        if (where && *where)
        {
-               guint where_len = strlen(*where);
                gchar *pos = strstr(*where, what);
 
                if (pos)
                {
-                       gchar *str = g_malloc(where_len + replacement_len);
-                       guint prefix_len = pos - *where;
+                       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;
 }
 
 
@@ -399,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++;
                        }
```

> @@ -241,6 +241,29 @@ void tm_ctags_clear_ignore_symbols(void)
 }
 
 
+static void replace_str(gchar **where, const gchar *what, guint what_len,
+       const gchar *replacement, guint replacement_len)
+{
+       if (where && *where)
+       {
+               guint where_len = strlen(*where);
+               gchar *pos = strstr(*where, what);
+
+               if (pos)
+               {
+                       gchar *str = g_malloc(where_len + replacement_len);

length should actually be `where_len + (replacement_len - what_len) + 1` 
shouldn't it?  The computation you have is simply gonna be a tiny bit wasteful 
in most (all) cases, but still wrong for `what=""`.
```suggestion
                        gchar *str = g_malloc(where_len + (replacement_len - 
what_len) + 1);
```

If we don't care about loosing a bit more space we could use GString that would 
make the code a bit simpler, but it seems to have like a minimal allocation of 
128 which might be a bit too much of a loss here.  Unless this is a temporary 
step?

> @@ -241,6 +241,29 @@ void tm_ctags_clear_ignore_symbols(void)
 }
 
 
+static void replace_str(gchar **where, const gchar *what, guint what_len,
+       const gchar *replacement, guint replacement_len)
+{
+       if (where && *where)
+       {
+               guint where_len = strlen(*where);

This should be moved inside the test below, it's only used there

> +static void replace_str(gchar **where, const gchar *what, guint what_len,
+       const gchar *replacement, guint replacement_len)

Just a remark, don't change anything for me here: this "API" is quite terrible 
(not all string args have a corresponding length, and they are still not 
allowed to lack a terminator anyway), but I guess it makes sense for how it's 
used (saves some `strlen()`s if the anon name is used more than once).

>                               /* 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);

Shouldn't this new helper be used around L406?

> @@ -241,6 +241,29 @@ void tm_ctags_clear_ignore_symbols(void)
 }
 
 
+static void replace_str(gchar **where, const gchar *what, guint what_len,
+       const gchar *replacement, guint replacement_len)
+{
+       if (where && *where)
+       {
+               guint where_len = strlen(*where);
+               gchar *pos = strstr(*where, what);
+
+               if (pos)
+               {
+                       gchar *str = g_malloc(where_len + replacement_len);
+                       guint prefix_len = pos - *where;

conversion: pointer difference yields signed (although we know it's `>= 0` in 
this case indeed), so we "need" an explicit cast

> @@ -241,6 +241,29 @@ void tm_ctags_clear_ignore_symbols(void)
 }
 
 
+static void replace_str(gchar **where, const gchar *what, guint what_len,
+       const gchar *replacement, guint replacement_len)
+{
+       if (where && *where)
+       {
+               guint where_len = strlen(*where);

Should also be `gsize` as that won't shrink `strlen()`'s return :)

-- 
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/3785#pullrequestreview-2010062333
You are receiving this because you are subscribed to this thread.

Message ID: <geany/geany/pull/3785/review/[email protected]>

Reply via email to