From b1cf12700d6c928e0550d97a9c1da7b188f81dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Tue, 22 Jun 2021 20:38:13 +0200 Subject: [PATCH] irc: add keys/values with tags in output of irc_message_parse_to_hashtable (issue #1654) Key is "tag_xxx" (where "xxx" is the name of tag) and value is the unescaped tag value. --- ChangeLog.adoc | 1 + doc/de/weechat_scripting.de.adoc | 19 ++++--- doc/en/weechat_plugin_api.en.adoc | 14 ++--- doc/en/weechat_scripting.en.adoc | 18 ++++--- doc/fr/weechat_plugin_api.fr.adoc | 14 ++--- doc/fr/weechat_scripting.fr.adoc | 18 ++++--- doc/it/weechat_plugin_api.it.adoc | 14 ++--- doc/it/weechat_scripting.it.adoc | 19 ++++--- doc/ja/weechat_plugin_api.ja.adoc | 14 ++--- doc/ja/weechat_scripting.ja.adoc | 19 ++++--- doc/pl/weechat_scripting.pl.adoc | 19 ++++--- doc/sr/weechat_plugin_api.sr.adoc | 14 ++--- doc/sr/weechat_scripting.sr.adoc | 19 ++++--- src/plugins/irc/irc-info.c | 1 + src/plugins/irc/irc-message.c | 3 ++ src/plugins/irc/irc-protocol.c | 10 ++-- src/plugins/irc/irc-tag.c | 57 ++++++++++++--------- src/plugins/irc/irc-tag.h | 4 +- tests/unit/plugins/irc/test-irc-message.cpp | 22 ++++---- tests/unit/plugins/irc/test-irc-tag.cpp | 38 ++++++++++---- 20 files changed, 217 insertions(+), 120 deletions(-) diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 5e50bdac3..16bcc8b6a 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -21,6 +21,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes] New features:: * core: add option "certs" in command /debug + * api: add keys/values with tags in output of irc_message_parse_to_hashtable (issue #1654) * irc: add support of TAGMSG messages (issue #1654) * irc: enable all capabilities by default (if supported by server and WeeChat), change default value of option irc.server_default.capabilities to "*" (issue #320) * irc: add options irc.look.display_account_message and irc.look.display_extended_join (issue #320) diff --git a/doc/de/weechat_scripting.de.adoc b/doc/de/weechat_scripting.de.adoc index 8b339b8b7..e575c9b1e 100644 --- a/doc/de/weechat_scripting.de.adoc +++ b/doc/de/weechat_scripting.de.adoc @@ -1304,6 +1304,11 @@ Das Ergebnis ist eine Hashtabelle mit folgenden Schlüsseln Tags in der Nachricht (kann leer sein). | `+time=2015-06-27T16:40:35.000Z+` +// TRANSLATION MISSING +| tag_xxx | 3.3 | + Unescaped value of tag "xxx" (one key per tag). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | Die IRC Nachricht ohne Tags (wie eine Nachricht ohne Tags). | `+:nick!user@host PRIVMSG #weechat :hello!+` @@ -1360,10 +1365,12 @@ Das Ergebnis ist eine Hashtabelle mit folgenden Schlüsseln ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "user": "user", @@ -1372,10 +1379,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc index 3ce99dbcc..e2e089d0c 100644 --- a/doc/en/weechat_plugin_api.en.adoc +++ b/doc/en/weechat_plugin_api.en.adoc @@ -15581,12 +15581,14 @@ if (hashtable_in) weechat_hashtable_set ( hashtable_in, "message", - "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"); + "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"); hashtable_out = weechat_info_get_hashtable ("irc_message_parse", hashtable_in); /* * now hashtable_out has following keys/values: - * "tags" : "time=2015-06-27T16:40:35.000Z" + * "tags" : "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace" + * "tag_time" : "2015-06-27T16:40:35.000Z" + * "tag_tag2" : "value space" * "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!" * "nick" : "nick" * "user" : "user" @@ -15595,10 +15597,10 @@ if (hashtable_in) * "channel" : "#weechat" * "arguments" : "#weechat :hello!" * "text" : "hello!" - * "pos_command" : "47" - * "pos_arguments" : "55" - * "pos_channel" : "55" - * "pos_text" : "65" + * "pos_command" : "65" + * "pos_arguments" : "73" + * "pos_channel" : "73" + * "pos_text" : "83" */ weechat_hashtable_free (hashtable_in); weechat_hashtable_free (hashtable_out); diff --git a/doc/en/weechat_scripting.en.adoc b/doc/en/weechat_scripting.en.adoc index 7b1c5fb16..ffdf378de 100644 --- a/doc/en/weechat_scripting.en.adoc +++ b/doc/en/weechat_scripting.en.adoc @@ -1277,6 +1277,10 @@ The result is a hashtable with following keys The tags in message (can be empty). | `+time=2015-06-27T16:40:35.000Z+` +| tag_xxx | 3.3 | + Unescaped value of tag "xxx" (one key per tag). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | The message without the tags (the same as message if there are no tags). | `+:nick!user@host PRIVMSG #weechat :hello!+` @@ -1333,10 +1337,12 @@ The result is a hashtable with following keys ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "user": "user", @@ -1345,10 +1351,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/doc/fr/weechat_plugin_api.fr.adoc b/doc/fr/weechat_plugin_api.fr.adoc index 5bfe0b2b6..2dc757f35 100644 --- a/doc/fr/weechat_plugin_api.fr.adoc +++ b/doc/fr/weechat_plugin_api.fr.adoc @@ -15902,12 +15902,14 @@ if (hashtable_in) weechat_hashtable_set ( hashtable_in, "message", - "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"); + "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"); hashtable_out = weechat_info_get_hashtable ("irc_message_parse", hashtable_in); /* * maintenant hashtable_out a les clés/valeurs suivantes : - * "tags" : "time=2015-06-27T16:40:35.000Z" + * "tags" : "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace" + * "tag_time" : "2015-06-27T16:40:35.000Z" + * "tag_tag2" : "value space" * "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!" * "nick" : "nick" " "user" : "user" @@ -15916,10 +15918,10 @@ if (hashtable_in) * "channel" : "#weechat" * "arguments" : "#weechat :hello!" * "text" : "hello!" - * "pos_command" : "47" - * "pos_arguments" : "55" - * "pos_channel" : "55" - * "pos_text" : "65" + * "pos_command" : "65" + * "pos_arguments" : "73" + * "pos_channel" : "73" + * "pos_text" : "83" */ weechat_hashtable_free (hashtable_in); weechat_hashtable_free (hashtable_out); diff --git a/doc/fr/weechat_scripting.fr.adoc b/doc/fr/weechat_scripting.fr.adoc index 133e173e9..16b21902d 100644 --- a/doc/fr/weechat_scripting.fr.adoc +++ b/doc/fr/weechat_scripting.fr.adoc @@ -1314,6 +1314,10 @@ Le résultat est une table de hachage avec les clés suivantes Les étiquettes dans le message (peut être vide). | `+time=2015-06-27T16:40:35.000Z+` +| tag_xxx | 3.3 | + Valeur de l'étiquette "xxx" sans les échappements (une clé par étiquette). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | Le message sans les étiquettes (la même chose que le message s'il n'y a pas d'étiquettes). | @@ -1371,10 +1375,12 @@ Le résultat est une table de hachage avec les clés suivantes ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "user": "user", @@ -1383,10 +1389,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/doc/it/weechat_plugin_api.it.adoc b/doc/it/weechat_plugin_api.it.adoc index 5618bd8a2..f99fe73cf 100644 --- a/doc/it/weechat_plugin_api.it.adoc +++ b/doc/it/weechat_plugin_api.it.adoc @@ -16208,12 +16208,14 @@ if (hashtable_in) weechat_hashtable_set ( hashtable_in, "message", - "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"); + "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"); hashtable_out = weechat_info_get_hashtable ("irc_message_parse", hashtable_in); /* * now hashtable_out has following keys/values: - * "tags" : "time=2015-06-27T16:40:35.000Z" + * "tags" : "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace" + * "tag_time" : "2015-06-27T16:40:35.000Z" + * "tag_tag2" : "value space" * "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!" * "nick" : "nick" * "user" : "user" @@ -16222,10 +16224,10 @@ if (hashtable_in) * "channel" : "#weechat" * "arguments" : "#weechat :hello!" * "text" : "hello!" - * "pos_command" : "47" - * "pos_arguments" : "55" - * "pos_channel" : "55" - * "pos_text" : "65" + * "pos_command" : "65" + * "pos_arguments" : "73" + * "pos_channel" : "73" + * "pos_text" : "83" */ weechat_hashtable_free (hashtable_in); weechat_hashtable_free (hashtable_out); diff --git a/doc/it/weechat_scripting.it.adoc b/doc/it/weechat_scripting.it.adoc index 1922682a5..2a1b96a66 100644 --- a/doc/it/weechat_scripting.it.adoc +++ b/doc/it/weechat_scripting.it.adoc @@ -1340,6 +1340,11 @@ The result is a hashtable with following keys The tags in message (can be empty). | `+time=2015-06-27T16:40:35.000Z+` +// TRANSLATION MISSING +| tag_xxx | 3.3 | + Unescaped value of tag "xxx" (one key per tag). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | The message without the tags (the same as message if there are no tags). | `+:nick!user@host PRIVMSG #weechat :hello!+` @@ -1398,10 +1403,12 @@ The result is a hashtable with following keys ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "user": "user", @@ -1410,10 +1417,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/doc/ja/weechat_plugin_api.ja.adoc b/doc/ja/weechat_plugin_api.ja.adoc index 21bd45ec8..a833c0233 100644 --- a/doc/ja/weechat_plugin_api.ja.adoc +++ b/doc/ja/weechat_plugin_api.ja.adoc @@ -15616,12 +15616,14 @@ if (hashtable_in) weechat_hashtable_set ( hashtable_in, "message", - "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"); + "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"); hashtable_out = weechat_info_get_hashtable ("irc_message_parse", hashtable_in); /* * now hashtable_out has following keys/values: - * "tags" : "time=2015-06-27T16:40:35.000Z" + * "tags" : "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace" + * "tag_time" : "2015-06-27T16:40:35.000Z" + * "tag_tag2" : "value space" * "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!" * "nick" : "nick" * "user" : "user" @@ -15630,10 +15632,10 @@ if (hashtable_in) * "channel" : "#weechat" * "arguments" : "#weechat :hello!" * "text" : "hello!" - * "pos_command" : "47" - * "pos_arguments" : "55" - * "pos_channel" : "55" - * "pos_text" : "65" + * "pos_command" : "65" + * "pos_arguments" : "73" + * "pos_channel" : "73" + * "pos_text" : "83" */ weechat_hashtable_free (hashtable_in); weechat_hashtable_free (hashtable_out); diff --git a/doc/ja/weechat_scripting.ja.adoc b/doc/ja/weechat_scripting.ja.adoc index f078bbfe9..ef4a28172 100644 --- a/doc/ja/weechat_scripting.ja.adoc +++ b/doc/ja/weechat_scripting.ja.adoc @@ -1315,6 +1315,11 @@ _WeeChat バージョン 0.3.4 以上で利用可。_ メッセージに付けられたタグ (空にすることも可) | `+time=2015-06-27T16:40:35.000Z+` +// TRANSLATION MISSING +| tag_xxx | 3.3 | + Unescaped value of tag "xxx" (one key per tag). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | タグを除いたメッセージ (タグが付けられていなければメッセージと同じ) | `+:nick!user@host PRIVMSG #weechat :hello!+` @@ -1373,10 +1378,12 @@ _WeeChat バージョン 0.3.4 以上で利用可。_ ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "user": "user", @@ -1385,10 +1392,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/doc/pl/weechat_scripting.pl.adoc b/doc/pl/weechat_scripting.pl.adoc index cf041e3ad..e9b034028 100644 --- a/doc/pl/weechat_scripting.pl.adoc +++ b/doc/pl/weechat_scripting.pl.adoc @@ -1284,6 +1284,11 @@ Wynik jest tabela hashy z następującymi kluczami Tagi w wiadomości (mogą byc puste). | `+time=2015-06-27T16:40:35.000Z+` +// TRANSLATION MISSING +| tag_xxx | 3.3 | + Unescaped value of tag "xxx" (one key per tag). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | Wiadomość bez tagów (jeśli nie ma tagów jest to to samo co wiadomość). | `+:nick!user@host PRIVMSG #weechat :hello!+` @@ -1340,10 +1345,12 @@ Wynik jest tabela hashy z następującymi kluczami ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "user": "user", @@ -1352,10 +1359,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/doc/sr/weechat_plugin_api.sr.adoc b/doc/sr/weechat_plugin_api.sr.adoc index 829141662..12539794a 100644 --- a/doc/sr/weechat_plugin_api.sr.adoc +++ b/doc/sr/weechat_plugin_api.sr.adoc @@ -15034,12 +15034,14 @@ if (hashtable_in) weechat_hashtable_set ( hashtable_in, "message", - "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"); + "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :hello!"); hashtable_out = weechat_info_get_hashtable ("irc_message_parse", hashtable_in); /* * сада hashtable_out има следеће кључеве/вредности: - * "tags" : "time=2015-06-27T16:40:35.000Z" + * "tags" : "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace" + * "tag_time" : "2015-06-27T16:40:35.000Z" + * "tag_tag2" : "value space" * "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!" * "nick" : "nick" * "user" : "user" @@ -15048,10 +15050,10 @@ if (hashtable_in) * "channel" : "#weechat" * "arguments" : "#weechat :hello!" * "text" : "hello!" - * "pos_command" : "47" - * "pos_arguments" : "55" - * "pos_channel" : "55" - * "pos_text" : "65" + * "pos_command" : "65" + * "pos_arguments" : "73" + * "pos_channel" : "73" + * "pos_text" : "83" */ weechat_hashtable_free (hashtable_in); weechat_hashtable_free (hashtable_out); diff --git a/doc/sr/weechat_scripting.sr.adoc b/doc/sr/weechat_scripting.sr.adoc index 6dd4626a0..44259cb92 100644 --- a/doc/sr/weechat_scripting.sr.adoc +++ b/doc/sr/weechat_scripting.sr.adoc @@ -1206,6 +1206,11 @@ IRC поруку можете да парсирате са info_hashtable под Ознаке у поруци (може бити празно). | `+time=2015-06-27T16:40:35.000Z+` +// TRANSLATION MISSING +| tag_xxx | 3.3 | + Unescaped value of tag "xxx" (one key per tag). | + `+2015-06-27T16:40:35.000Z+` + | message_without_tags | 0.4.0 | Порука без ознака (иста као оригинална ако нема ознака у њој). | `+:nick!user@host PRIVMSG #weechat :здраво!+` @@ -1262,10 +1267,12 @@ IRC поруку можете да парсирате са info_hashtable под ---- dict = weechat.info_get_hashtable( "irc_message_parse", - {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :здраво!"}) + {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :здраво!"}) # dict == { -# "tags": "time=2015-06-27T16:40:35.000Z", +# "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", +# "tag_time": "2015-06-27T16:40:35.000Z", +# "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :здраво!", # "nick": "nick", # "user": "user", @@ -1274,10 +1281,10 @@ dict = weechat.info_get_hashtable( # "channel": "#weechat", # "arguments": "#weechat :здраво!", # "text": "hello!", -# "pos_command": "47", -# "pos_arguments": "55", -# "pos_channel": "55", -# "pos_text": "65", +# "pos_command": "65", +# "pos_arguments": "73", +# "pos_channel": "73", +# "pos_text": "83", # } ---- diff --git a/src/plugins/irc/irc-info.c b/src/plugins/irc/irc-info.c index 31f5cc412..892c1f3ed 100644 --- a/src/plugins/irc/irc-info.c +++ b/src/plugins/irc/irc-info.c @@ -1183,6 +1183,7 @@ irc_info_init () N_("\"message\": IRC message, \"server\": server name (optional)"), /* TRANSLATORS: please do not translate key names (enclosed by quotes) */ N_("\"tags\": tags, " + "\"tag_xxx\": unescaped value of tag \"xxx\" (one key per tag), " "\"message_without_tags\": message without the tags, " "\"nick\": nick, " "\"user\": user, " diff --git a/src/plugins/irc/irc-message.c b/src/plugins/irc/irc-message.c index 36341defd..eeaf91d6a 100644 --- a/src/plugins/irc/irc-message.c +++ b/src/plugins/irc/irc-message.c @@ -31,6 +31,7 @@ #include "irc-config.h" #include "irc-ignore.h" #include "irc-server.h" +#include "irc-tag.h" /* @@ -327,6 +328,7 @@ irc_message_parse (struct t_irc_server *server, const char *message, /* * Parses an IRC message and returns hashtable with keys: * - tags + * - tag_xxx (one key per tag, with unescaped value) * - message_without_tags * - nick * - host @@ -365,6 +367,7 @@ irc_message_parse_to_hashtable (struct t_irc_server *server, weechat_hashtable_set (hashtable, "tags", (tags) ? tags : empty_str); + irc_tag_parse (tags, hashtable, "tag_"); weechat_hashtable_set (hashtable, "message_without_tags", (message_without_tags) ? message_without_tags : empty_str); weechat_hashtable_set (hashtable, "nick", diff --git a/src/plugins/irc/irc-protocol.c b/src/plugins/irc/irc-protocol.c index 53631e1b2..140a662c0 100644 --- a/src/plugins/irc/irc-protocol.c +++ b/src/plugins/irc/irc-protocol.c @@ -6826,7 +6826,6 @@ irc_protocol_recv_command (struct t_irc_server *server, message_colors_decoded = NULL; argv = NULL; argv_eol = NULL; - hash_tags = NULL; date = 0; ptr_msg_after_tags = irc_message; @@ -6841,11 +6840,16 @@ irc_protocol_recv_command (struct t_irc_server *server, pos_space - (irc_message + 1)); if (tags) { - hash_tags = irc_tag_parse (tags); + hash_tags = weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, NULL); if (hash_tags) { + irc_tag_parse (tags, hash_tags, NULL); date = irc_protocol_parse_time ( weechat_hashtable_get (hash_tags, "time")); + weechat_hashtable_free (hash_tags); } free (tags); } @@ -7033,6 +7037,4 @@ end: weechat_string_free_split (argv); if (argv_eol) weechat_string_free_split (argv_eol); - if (hash_tags) - weechat_hashtable_free (hash_tags); } diff --git a/src/plugins/irc/irc-tag.c b/src/plugins/irc/irc-tag.c index a0534e0ad..05e4f3ff5 100644 --- a/src/plugins/irc/irc-tag.c +++ b/src/plugins/irc/irc-tag.c @@ -216,33 +216,34 @@ irc_tag_modifier_cb (const void *pointer, void *data, } /* - * Parses tags received in an IRC message. - * Returns a hashtable with tags and their unescaped values. + * Parses tags received in an IRC message and returns the number of tags + * set in the hasbtable "hashtable" (values are unescaped tag values). + * + * If prefix_key is not NULL, it is used as prefix before the name of keys. * * Example: - * if tags == "aaa=bbb;ccc;example.com/ddd=eee", - * hashtable will have following keys/values: - * "aaa" => "bbb" - * "ccc" => NULL - * "example.com/ddd" => "eee" + * + * input: + * tags == "aaa=bbb;ccc;example.com/ddd=value\swith\sspaces" + * prefix_key == "tag_" + * output: + * hashtable is completed with the following keys/values: + * "tag_aaa" => "bbb" + * "tag_ccc" => NULL + * "tag_example.com/ddd" => "value with spaces" */ -struct t_hashtable * -irc_tag_parse (const char *tags) +int +irc_tag_parse (const char *tags, + struct t_hashtable *hashtable, const char *prefix_key) { - struct t_hashtable *hashtable; - char **items, *pos, *key, *unescaped; - int num_items, i; + char **items, *pos, *key, str_key[4096], *unescaped; + int num_items, i, num_tags; - if (!tags || !tags[0]) - return NULL; + if (!tags || !tags[0] || !hashtable) + return 0; - hashtable = weechat_hashtable_new (32, - WEECHAT_HASHTABLE_STRING, - WEECHAT_HASHTABLE_STRING, - NULL, NULL); - if (!hashtable) - return NULL; + num_tags = 0; items = weechat_string_split (tags, ";", NULL, WEECHAT_STRING_SPLIT_STRIP_LEFT @@ -260,21 +261,31 @@ irc_tag_parse (const char *tags) key = weechat_strndup (items[i], pos - items[i]); if (key) { + snprintf (str_key, sizeof (str_key), + "%s%s", + (prefix_key) ? prefix_key : "", + key); unescaped = irc_tag_unescape_value (pos + 1); - weechat_hashtable_set (hashtable, key, unescaped); + weechat_hashtable_set (hashtable, str_key, unescaped); if (unescaped) free (unescaped); free (key); + num_tags++; } } else { /* format: "tag" */ - weechat_hashtable_set (hashtable, items[i], NULL); + snprintf (str_key, sizeof (str_key), + "%s%s", + (prefix_key) ? prefix_key : "", + items[i]); + weechat_hashtable_set (hashtable, str_key, NULL); + num_tags++; } } weechat_string_free_split (items); } - return hashtable; + return num_tags; } diff --git a/src/plugins/irc/irc-tag.h b/src/plugins/irc/irc-tag.h index 2e70668af..1fe0aeb8d 100644 --- a/src/plugins/irc/irc-tag.h +++ b/src/plugins/irc/irc-tag.h @@ -27,6 +27,8 @@ extern char *irc_tag_modifier_cb (const void *pointer, const char *modifier, const char *modifier_data, const char *string); -extern struct t_hashtable *irc_tag_parse (const char *tags); +extern int irc_tag_parse (const char *tags, + struct t_hashtable *hashtable, + const char *prefix_key); #endif /* WEECHAT_PLUGIN_IRC_TAG_H */ diff --git a/tests/unit/plugins/irc/test-irc-message.cpp b/tests/unit/plugins/irc/test-irc-message.cpp index d94d440c5..accd26186 100644 --- a/tests/unit/plugins/irc/test-irc-message.cpp +++ b/tests/unit/plugins/irc/test-irc-message.cpp @@ -521,12 +521,16 @@ TEST(IrcMessage, ParseToHashtable) hashtable = irc_message_parse_to_hashtable ( NULL, - "@time=2019-08-03T12:13:00.000Z :nick!user@host PRIVMSG #channel " - ":the message"); + "@time=2019-08-03T12:13:00.000Z;tag2=value\\sspace " + ":nick!user@host PRIVMSG #channel :the message"); CHECK(hashtable); - STRCMP_EQUAL("time=2019-08-03T12:13:00.000Z", + STRCMP_EQUAL("time=2019-08-03T12:13:00.000Z;tag2=value\\sspace", (const char *)hashtable_get (hashtable, "tags")); + STRCMP_EQUAL("2019-08-03T12:13:00.000Z", + (const char *)hashtable_get (hashtable, "tag_time")); + STRCMP_EQUAL("value space", + (const char *)hashtable_get (hashtable, "tag_tag2")); STRCMP_EQUAL(":nick!user@host PRIVMSG #channel :the message", (const char *)hashtable_get (hashtable, "message_without_tags")); STRCMP_EQUAL("nick", @@ -541,13 +545,13 @@ TEST(IrcMessage, ParseToHashtable) (const char *)hashtable_get (hashtable, "arguments")); STRCMP_EQUAL("the message", (const char *)hashtable_get (hashtable, "text")); - STRCMP_EQUAL("47", - (const char *)hashtable_get (hashtable, "pos_command")); - STRCMP_EQUAL("55", - (const char *)hashtable_get (hashtable, "pos_arguments")); - STRCMP_EQUAL("55", - (const char *)hashtable_get (hashtable, "pos_channel")); STRCMP_EQUAL("65", + (const char *)hashtable_get (hashtable, "pos_command")); + STRCMP_EQUAL("73", + (const char *)hashtable_get (hashtable, "pos_arguments")); + STRCMP_EQUAL("73", + (const char *)hashtable_get (hashtable, "pos_channel")); + STRCMP_EQUAL("83", (const char *)hashtable_get (hashtable, "pos_text")); hashtable_free (hashtable); diff --git a/tests/unit/plugins/irc/test-irc-tag.cpp b/tests/unit/plugins/irc/test-irc-tag.cpp index 50796ac37..2d00473e7 100644 --- a/tests/unit/plugins/irc/test-irc-tag.cpp +++ b/tests/unit/plugins/irc/test-irc-tag.cpp @@ -27,6 +27,7 @@ extern "C" #include "src/core/wee-hashtable.h" #include "src/core/wee-hook.h" #include "src/plugins/irc/irc-tag.h" +#include "src/plugins/plugin.h" } #define WEE_CHECK_ESCAPE_VALUE(__result, __string) \ @@ -122,26 +123,41 @@ TEST(IrcTag, Parse) { struct t_hashtable *hashtable; - POINTERS_EQUAL(NULL, irc_tag_parse (NULL)); - POINTERS_EQUAL(NULL, irc_tag_parse ("")); + hashtable = hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, NULL); - hashtable = irc_tag_parse ("abc"); - CHECK(hashtable); + LONGS_EQUAL(0, irc_tag_parse (NULL, hashtable, NULL)); + LONGS_EQUAL(0, irc_tag_parse ("", hashtable, NULL)); + + hashtable_remove_all (hashtable); + LONGS_EQUAL(1, irc_tag_parse ("abc", hashtable, NULL)); LONGS_EQUAL(1, hashtable->items_count); POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "abc")); - hashtable_free (hashtable); - hashtable = irc_tag_parse ("abc=def"); - CHECK(hashtable); + hashtable_remove_all (hashtable); + LONGS_EQUAL(1, irc_tag_parse ("abc=def", hashtable, NULL)); LONGS_EQUAL(1, hashtable->items_count); STRCMP_EQUAL("def", (const char *)hashtable_get (hashtable, "abc")); - hashtable_free (hashtable); - hashtable = irc_tag_parse ("aaa=bbb;ccc;example.com/ddd=eee"); - CHECK(hashtable); + hashtable_remove_all (hashtable); + LONGS_EQUAL(3, irc_tag_parse ("aaa=bbb;ccc;example.com/ddd=value\\sspace", + hashtable, NULL)); LONGS_EQUAL(3, hashtable->items_count); STRCMP_EQUAL("bbb", (const char *)hashtable_get (hashtable, "aaa")); POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "ccc")); - STRCMP_EQUAL("eee", (const char *)hashtable_get (hashtable, "example.com/ddd")); + STRCMP_EQUAL("value space", + (const char *)hashtable_get (hashtable, "example.com/ddd")); + + hashtable_remove_all (hashtable); + LONGS_EQUAL(3, irc_tag_parse ("aaa=bbb;ccc;example.com/ddd=value\\sspace", + hashtable, "tag_")); + LONGS_EQUAL(3, hashtable->items_count); + STRCMP_EQUAL("bbb", (const char *)hashtable_get (hashtable, "tag_aaa")); + POINTERS_EQUAL(NULL, (const char *)hashtable_get (hashtable, "tag_ccc")); + STRCMP_EQUAL("value space", + (const char *)hashtable_get (hashtable, "tag_example.com/ddd")); + hashtable_free (hashtable); }