summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2023-04-02 13:49:25 +0200
committerSébastien Helleu <flashcode@flashtux.org>2023-04-02 13:49:25 +0200
commitff85d00e7f565963c6cb7443ca763254fa6fe9cd (patch)
tree7f92ea16a9b499330195f21dfa9faeae0860b25f
parente15bd25f377f87a5f129e950b1d3dc5968cfbc31 (diff)
downloadweechat-ff85d00e7f565963c6cb7443ca763254fa6fe9cd.zip
irc: update autojoin option with redirected channels when autojoin_dynamic is enabled (closes #1898)
-rw-r--r--ChangeLog.adoc1
-rw-r--r--src/plugins/irc/irc-join.c117
-rw-r--r--src/plugins/irc/irc-join.h7
-rw-r--r--src/plugins/irc/irc-protocol.c7
-rw-r--r--tests/unit/plugins/irc/test-irc-join.cpp95
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);
}