diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2023-04-02 13:49:25 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2023-04-02 13:49:25 +0200 |
commit | ff85d00e7f565963c6cb7443ca763254fa6fe9cd (patch) | |
tree | 7f92ea16a9b499330195f21dfa9faeae0860b25f | |
parent | e15bd25f377f87a5f129e950b1d3dc5968cfbc31 (diff) | |
download | weechat-ff85d00e7f565963c6cb7443ca763254fa6fe9cd.zip |
irc: update autojoin option with redirected channels when autojoin_dynamic is enabled (closes #1898)
-rw-r--r-- | ChangeLog.adoc | 1 | ||||
-rw-r--r-- | src/plugins/irc/irc-join.c | 117 | ||||
-rw-r--r-- | src/plugins/irc/irc-join.h | 7 | ||||
-rw-r--r-- | src/plugins/irc/irc-protocol.c | 7 | ||||
-rw-r--r-- | tests/unit/plugins/irc/test-irc-join.cpp | 95 |
5 files changed, 227 insertions, 0 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 727ddaad3..53679499c 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -55,6 +55,7 @@ Bug fixes:: * buflist: do not display keys added in default context on first load * fset: remove scroll to top of fset buffer when options are added or removed (issue #1892) * irc: fix join of channels in "autojoin" server option on first connection to server if auto reconnection is performed (issue #1873) + * irc: update autojoin option with redirected channels when autojoin_dynamic is enabled (issue #1898) * irc: fix target buffer for commands 432/433 (erroneous nickname/nickname already in use) when the nickname looks like a channel * spell: check buffer pointer received in info "spell_dict" * typing: fix crash when pointer buffer is not received in callback for signal "input_text_changed" (issue #1869) diff --git a/src/plugins/irc/irc-join.c b/src/plugins/irc/irc-join.c index 609c2b50c..0312ee37b 100644 --- a/src/plugins/irc/irc-join.c +++ b/src/plugins/irc/irc-join.c @@ -597,6 +597,123 @@ irc_join_remove_channel_from_autojoin (struct t_irc_server *server, } /* + * Renames a channel in a join string: removes the channel then adds it (with + * its key, if set). + * + * Channels with a key are first in list, so for example: + * + * join = "#abc,#def,#ghi key_abc,key_def" + * channel_name = "#def" + * new_channel_name = "#zzz" + * + * => returned value: "#abc,#zzz,#ghi key_abc,key_def" + * + * If channel_name == new_channel_name (ignoring case), the function does + * nothing. + * + * If channel_name is not in the list, the function does nothing. + * + * If the new_channel_name is already in the list, the channel_name is just + * removed. + * + * Note: result must be freed after use. + */ + +char * +irc_join_rename_channel (struct t_irc_server *server, + const char *join, + const char *channel_name, + const char *new_channel_name) +{ + struct t_arraylist *arraylist; + struct t_irc_join_channel *ptr_join_chan; + char *new_join; + int i, to_remove; + + if (!channel_name || !new_channel_name) + return NULL; + + if (irc_server_strcasecmp (server, channel_name, new_channel_name) == 0) + return (join) ? strdup (join) : NULL; + + arraylist = irc_join_split (server, join, 0); + if (!arraylist) + return NULL; + + /* check if new channel name is already in the list */ + to_remove = 0; + for (i = 0; i < weechat_arraylist_size (arraylist); i++) + { + ptr_join_chan = (struct t_irc_join_channel *)weechat_arraylist_get ( + arraylist, i); + if (irc_server_strcasecmp (server, ptr_join_chan->name, + new_channel_name) == 0) + { + to_remove = 1; + break; + } + } + + i = 0; + while (i < weechat_arraylist_size (arraylist)) + { + ptr_join_chan = (struct t_irc_join_channel *)weechat_arraylist_get ( + arraylist, i); + if (irc_server_strcasecmp (server, ptr_join_chan->name, + channel_name) == 0) + { + if (to_remove) + { + weechat_arraylist_remove (arraylist, i); + } + else + { + free (ptr_join_chan->name); + ptr_join_chan->name = strdup (new_channel_name); + i++; + } + } + else + { + i++; + } + } + + new_join = irc_join_build_string (arraylist); + + weechat_arraylist_free (arraylist); + + return new_join; +} + +/* + * Renames a channel in a server autojoin option. + */ + +void +irc_join_rename_channel_in_autojoin (struct t_irc_server *server, + const char *channel_name, + const char *new_channel_name) +{ + char *new_autojoin; + + if (!channel_name || !new_channel_name) + return; + + new_autojoin = irc_join_rename_channel ( + server, + IRC_SERVER_OPTION_STRING(server, IRC_SERVER_OPTION_AUTOJOIN), + channel_name, + new_channel_name); + if (new_autojoin) + { + weechat_config_option_set (server->options[IRC_SERVER_OPTION_AUTOJOIN], + new_autojoin, 1); + free (new_autojoin); + } +} + +/* * Saves currently joined channels in the autojoin option of a server. */ diff --git a/src/plugins/irc/irc-join.h b/src/plugins/irc/irc-join.h index 16795b18b..87a656d62 100644 --- a/src/plugins/irc/irc-join.h +++ b/src/plugins/irc/irc-join.h @@ -47,6 +47,13 @@ extern char *irc_join_remove_channel (struct t_irc_server *server, const char *channel_name); extern void irc_join_remove_channel_from_autojoin (struct t_irc_server *server, const char *channel_name); +extern char *irc_join_rename_channel (struct t_irc_server *server, + const char *join, + const char *channel_name, + const char *new_channel_name); +extern void irc_join_rename_channel_in_autojoin (struct t_irc_server *server, + const char *channel_name, + const char *new_channel_name); extern void irc_join_save_channels_to_autojoin (struct t_irc_server *server); extern char *irc_join_sort_channels (struct t_irc_server *server, const char *join); diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 6ce3e7629..235b32bbe 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -48,6 +48,7 @@ #include "irc-config.h" #include "irc-ctcp.h" #include "irc-ignore.h" +#include "irc-join.h" #include "irc-message.h" #include "irc-mode.h" #include "irc-modelist.h" @@ -6789,6 +6790,12 @@ IRC_PROTOCOL_CALLBACK(470) WEECHAT_HOOK_SIGNAL_POINTER, ptr_buffer); } + if (IRC_SERVER_OPTION_BOOLEAN(server, + IRC_SERVER_OPTION_AUTOJOIN_DYNAMIC)) + { + irc_join_rename_channel_in_autojoin (server, params[1], + params[2]); + } } old_channel_lower = weechat_string_tolower (params[1]); diff --git a/tests/unit/plugins/irc/test-irc-join.cpp b/tests/unit/plugins/irc/test-irc-join.cpp index 5d189e9d4..b9a320964 100644 --- a/tests/unit/plugins/irc/test-irc-join.cpp +++ b/tests/unit/plugins/irc/test-irc-join.cpp @@ -78,6 +78,21 @@ extern int irc_join_compare_join_channel (struct t_irc_server *server, if (str) \ free (str); +#define WEE_CHECK_RENAME_CHANNEL(__result, __join, __channel, \ + __new_channel) \ + str = irc_join_rename_channel (NULL, __join, __channel, \ + __new_channel); \ + if (__result == NULL) \ + { \ + POINTERS_EQUAL(NULL, str); \ + } \ + else \ + { \ + STRCMP_EQUAL(__result, str); \ + } \ + if (str) \ + free (str); + #define WEE_CHECK_SORT_CHANNELS(__result, __join) \ str = irc_join_sort_channels (NULL, __join); \ if (__result == NULL) \ @@ -439,6 +454,49 @@ TEST(IrcJoin, RemoveChannel) /* * Tests functions: + * irc_join_rename_channel + */ + +TEST(IrcJoin, RenameChannel) +{ + char *str; + + WEE_CHECK_RENAME_CHANNEL(NULL, NULL, NULL, NULL); + WEE_CHECK_RENAME_CHANNEL(NULL, "", NULL, NULL); + WEE_CHECK_RENAME_CHANNEL(NULL, "", NULL, NULL); + WEE_CHECK_RENAME_CHANNEL(NULL, "", NULL, ""); + WEE_CHECK_RENAME_CHANNEL(NULL, "", "", NULL); + WEE_CHECK_RENAME_CHANNEL(NULL, NULL, "", ""); + WEE_CHECK_RENAME_CHANNEL("", NULL, "", "#xyz"); + WEE_CHECK_RENAME_CHANNEL("", NULL, "xyz",""); + + WEE_CHECK_RENAME_CHANNEL("", NULL, "#abc", "#xyz"); + WEE_CHECK_RENAME_CHANNEL("", "", "#abc", "#xyz"); + + WEE_CHECK_RENAME_CHANNEL("#abc", "#abc", "#xyz", "#xyz"); + WEE_CHECK_RENAME_CHANNEL("#xyz", "#abc", "#abc", "#xyz"); + WEE_CHECK_RENAME_CHANNEL("#xyz,#def", "#abc,#def", "#abc", "#xyz"); + + WEE_CHECK_RENAME_CHANNEL("#xyz,#def key_abc", + "#abc,#def key_abc", "#abc", "#xyz"); + WEE_CHECK_RENAME_CHANNEL("#xyz,#def key_abc,key_def", + "#abc,#def key_abc,key_def", "#abc", "#xyz"); + + /* channel not found */ + WEE_CHECK_RENAME_CHANNEL("#abc,#def key_abc,key_def", + "#abc,#def key_abc,key_def", "#xxx", "#yyy"); + + /* same name for the new channel */ + WEE_CHECK_RENAME_CHANNEL("#abc,#def key_abc,key_def", + "#abc,#def key_abc,key_def", "#abc", "#abc"); + + /* new name already exists */ + WEE_CHECK_RENAME_CHANNEL("#def key_def", + "#abc,#def key_abc,key_def", "#abc", "#def"); +} + +/* + * Tests functions: * irc_join_sort_channels */ @@ -465,6 +523,7 @@ TEST(IrcJoin, SortChannels) * irc_join_add_channel_to_autojoin * irc_join_add_channels_to_autojoin * irc_join_remove_channel_from_autojoin + * irc_join_rename_channel_in_autojoin */ TEST(IrcJoin, AddRemoveChannelsAutojoin) @@ -585,6 +644,42 @@ TEST(IrcJoin, AddRemoveChannelsAutojoin) "#abc,#xyz,#DEF,#GHI key_abc,key_xyz", CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + /* rename channel (not found) */ + irc_join_rename_channel_in_autojoin (server, "#yyy", "#zzz"); + STRCMP_EQUAL( + "#abc,#xyz,#DEF,#GHI key_abc,key_xyz", + CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + + /* rename channel */ + irc_join_rename_channel_in_autojoin (server, "#abc", "#aabbcc"); + STRCMP_EQUAL( + "#aabbcc,#xyz,#DEF,#GHI key_abc,key_xyz", + CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + + /* rename channel */ + irc_join_rename_channel_in_autojoin (server, "#aabbcc", "#abc"); + STRCMP_EQUAL( + "#abc,#xyz,#DEF,#GHI key_abc,key_xyz", + CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + + /* rename channel */ + irc_join_rename_channel_in_autojoin (server, "#DEF", "#def"); + STRCMP_EQUAL( + "#abc,#xyz,#DEF,#GHI key_abc,key_xyz", + CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + + /* rename channel (new channel already exists) */ + irc_join_rename_channel_in_autojoin (server, "#GHI", "#jkl"); + STRCMP_EQUAL( + "#abc,#xyz,#DEF,#jkl key_abc,key_xyz", + CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + + /* rename channel (new channel already exists) */ + irc_join_rename_channel_in_autojoin (server, "#abc", "#def"); + STRCMP_EQUAL( + "#xyz,#DEF,#jkl key_xyz", + CONFIG_STRING(server->options[IRC_SERVER_OPTION_AUTOJOIN])); + irc_server_free (server); } |