From e89d6d69ad1e3613640ae5afc591a6ce3ce89312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sat, 15 Feb 2025 20:31:11 +0100 Subject: [PATCH] api: add property `keep_spaces_right` in function hook_set to keep trailing spaces in command arguments --- CHANGELOG.md | 1 + doc/en/weechat_plugin_api.en.adoc | 4 ++ doc/fr/weechat_plugin_api.fr.adoc | 4 ++ doc/it/weechat_plugin_api.it.adoc | 6 +++ doc/ja/weechat_plugin_api.ja.adoc | 5 +++ doc/sr/weechat_plugin_api.sr.adoc | 5 +++ src/core/core-hook.c | 24 ++++++++++++ src/core/core-input.c | 9 ----- src/core/hook/hook-command-run.c | 40 +++++++++++++------ src/core/hook/hook-command-run.h | 4 ++ src/core/hook/hook-command.c | 65 +++++++++++++++++++------------ src/core/hook/hook-command.h | 5 +++ 12 files changed, 126 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7192b31e..5de03b77f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - core: add option `-v` to display upgrades in command `/version` +- api: add property `keep_spaces_right` in function hook_set to keep trailing spaces in command arguments ### Added diff --git a/doc/en/weechat_plugin_api.en.adoc b/doc/en/weechat_plugin_api.en.adoc index 75ac6a904..3a516979c 100644 --- a/doc/en/weechat_plugin_api.en.adoc +++ b/doc/en/weechat_plugin_api.en.adoc @@ -14014,6 +14014,10 @@ Properties: | Name of sub plugin (commonly script name, which is displayed in `/help command` for a hook of type _command_). +| keep_spaces_right | 4.6.0 | _command_, _command_run_ +| "0" or "1" +| Keep trailing spaces in command arguments when it is executed. + | stdin | 0.4.3 | _process_, _process_hashtable_ | any string | Send data on standard input (_stdin_) of child process. diff --git a/doc/fr/weechat_plugin_api.fr.adoc b/doc/fr/weechat_plugin_api.fr.adoc index b0e9af0b0..de56a97fe 100644 --- a/doc/fr/weechat_plugin_api.fr.adoc +++ b/doc/fr/weechat_plugin_api.fr.adoc @@ -14327,6 +14327,10 @@ Propriétés : | Nom de la sous-extension (couramment un nom de script, qui est affiché dans `/help commande` pour un hook de type _command_). +| keep_spaces_right | 4.6.0 | _command_, _command_run_ +| "0" ou "1" +| Garder les espaces à la fin des paramètres de la commande quand elle est exécutée. + | stdin | 0.4.3 | _process_, _process_hashtable_ | toute chaîne | Envoyer les données sur l'entrée standard (_stdin_) du processus fils. diff --git a/doc/it/weechat_plugin_api.it.adoc b/doc/it/weechat_plugin_api.it.adoc index 07c1542be..98e7b4a78 100644 --- a/doc/it/weechat_plugin_api.it.adoc +++ b/doc/it/weechat_plugin_api.it.adoc @@ -14667,11 +14667,17 @@ Properties: // TRANSLATION MISSING | subplugin | | any type + | qualsiasi stringa | // TRANSLATION MISSING Name of sub plugin (commonly script name, which is displayed in `/help command` for a hook of type _command_). +// TRANSLATION MISSING +| keep_spaces_right | 4.6.0 | _command_, _command_run_ +| "0" or "1" +| Keep trailing spaces in command arguments when it is executed. + | stdin | 0.4.3 | _process_, _process_hashtable_ | qualsiasi stringa | // TRANSLATION MISSING Send data on standard input (_stdin_) of child process. diff --git a/doc/ja/weechat_plugin_api.ja.adoc b/doc/ja/weechat_plugin_api.ja.adoc index e3b52af56..8fb64c0e4 100644 --- a/doc/ja/weechat_plugin_api.ja.adoc +++ b/doc/ja/weechat_plugin_api.ja.adoc @@ -14238,6 +14238,11 @@ void weechat_hook_set (struct t_hook *hook, const char *property, | サブプラグインの名前 (通常は `/help command` で _command_ をタイプした時のフックで表示されるスクリプト名) +// TRANSLATION MISSING +| keep_spaces_right | 4.6.0 | _command_, _command_run_ +| "0" or "1" +| Keep trailing spaces in command arguments when it is executed. + | stdin | 0.4.3 | _process_、_process_hashtable_ | 任意の文字列 | 子プロセスの標準入力 (_stdin_) にデータを送信 diff --git a/doc/sr/weechat_plugin_api.sr.adoc b/doc/sr/weechat_plugin_api.sr.adoc index 26aefc634..12b933b86 100644 --- a/doc/sr/weechat_plugin_api.sr.adoc +++ b/doc/sr/weechat_plugin_api.sr.adoc @@ -13621,6 +13621,11 @@ void weechat_hook_set (struct t_hook *hook, const char *property, | Име под додатка (обично је то име скрипте које се приказује у `/help команда` за куку типа _command_). +// TRANSLATION MISSING +| keep_spaces_right | 4.6.0 | _command_, _command_run_ +| "0" or "1" +| Keep trailing spaces in command arguments when it is executed. + | stdin | 0.4.3 | _process_, _process_hashtable_ | било који стринг | Шаље податке на стандардни улаз (_stdin_) дете процеса. diff --git a/src/core/core-hook.c b/src/core/core-hook.c index 94481e9f6..194daca61 100644 --- a/src/core/core-hook.c +++ b/src/core/core-hook.c @@ -624,6 +624,30 @@ hook_set (struct t_hook *hook, const char *property, const char *value) } } } + else if (strcmp (property, "keep_spaces_right") == 0) + { + if (!hook->deleted + && ((hook->type == HOOK_TYPE_COMMAND) + || (hook->type == HOOK_TYPE_COMMAND_RUN))) + { + error = NULL; + number = strtol (value, &error, 10); + if (error && !error[0]) + { + switch (hook->type) + { + case HOOK_TYPE_COMMAND: + HOOK_COMMAND(hook, keep_spaces_right) = (number) ? 1 : 0; + break; + case HOOK_TYPE_COMMAND_RUN: + HOOK_COMMAND_RUN(hook, keep_spaces_right) = (number) ? 1 : 0; + break; + default: + break; + } + } + } + } } /* diff --git a/src/core/core-input.c b/src/core/core-input.c index 8fe201d36..ac866c114 100644 --- a/src/core/core-input.c +++ b/src/core/core-input.c @@ -121,15 +121,6 @@ input_exec_command (struct t_gui_buffer *buffer, input_commands_allowed = new_commands_allowed; } - /* ignore spaces at the end of command */ - pos = &command[strlen (command) - 1]; - if (pos[0] == ' ') - { - while ((pos > command) && (pos[0] == ' ')) - pos--; - pos[1] = '\0'; - } - /* extract command name */ pos = strchr (command, ' '); command_name = (pos) ? diff --git a/src/core/hook/hook-command-run.c b/src/core/hook/hook-command-run.c index 1717c6892..1f0304864 100644 --- a/src/core/hook/hook-command-run.c +++ b/src/core/hook/hook-command-run.c @@ -87,6 +87,7 @@ hook_command_run (struct t_weechat_plugin *plugin, new_hook_command_run->callback = callback; new_hook_command_run->command = strdup ((ptr_command) ? ptr_command : ((command) ? command : "")); + new_hook_command_run->keep_spaces_right = 0; hook_add_to_list (new_hook); @@ -102,21 +103,22 @@ hook_command_run_exec (struct t_gui_buffer *buffer, const char *command) { struct t_hook *ptr_hook, *next_hook; struct t_hook_exec_cb hook_exec_cb; - int rc, hook_matching, length; + int rc, hook_matching, i, length; char *command2; - const char *ptr_string, *ptr_command; + const char *ptr_string; if (!weechat_hooks[HOOK_TYPE_COMMAND_RUN]) return WEECHAT_RC_OK; - ptr_command = command; - command2 = NULL; - if (command[0] != '/') { ptr_string = utf8_next_char (command); - if (string_asprintf (&command2, "/%s", ptr_string) >= 0) - ptr_command = command2; + if (string_asprintf (&command2, "/%s", ptr_string) < 0) + return WEECHAT_RC_ERROR; + } + else + { + command2 = strdup (command); } ptr_hook = weechat_hooks[HOOK_TYPE_COMMAND_RUN]; @@ -128,7 +130,7 @@ hook_command_run_exec (struct t_gui_buffer *buffer, const char *command) && !ptr_hook->running && HOOK_COMMAND_RUN(ptr_hook, command)) { - hook_matching = string_match (ptr_command, + hook_matching = string_match (command2, HOOK_COMMAND_RUN(ptr_hook, command), 1); @@ -136,21 +138,32 @@ hook_command_run_exec (struct t_gui_buffer *buffer, const char *command) && !strchr (HOOK_COMMAND_RUN(ptr_hook, command), ' ')) { length = strlen (HOOK_COMMAND_RUN(ptr_hook, command)); - hook_matching = ((string_strncmp (ptr_command, + hook_matching = ((string_strncmp (command2, HOOK_COMMAND_RUN(ptr_hook, command), utf8_strlen (HOOK_COMMAND_RUN(ptr_hook, command))) == 0) - && ((ptr_command[length] == ' ') - || (ptr_command[length] == '\0'))); + && ((command2[length] == ' ') + || (command2[length] == '\0'))); } if (hook_matching) { + /* remove trailing spaces */ + if (!HOOK_COMMAND_RUN(ptr_hook, keep_spaces_right)) + { + i = strlen (command2) - 1; + while ((i >= 0) && (command2[i] == ' ')) + { + command2[i] = '\0'; + i--; + } + } + /* execute the command_run hook */ hook_callback_start (ptr_hook, &hook_exec_cb); rc = (HOOK_COMMAND_RUN(ptr_hook, callback)) ( ptr_hook->callback_pointer, ptr_hook->callback_data, buffer, - ptr_command); + command2); hook_callback_end (ptr_hook, &hook_exec_cb); if (rc == WEECHAT_RC_OK_EAT) { @@ -207,6 +220,8 @@ hook_command_run_add_to_infolist (struct t_infolist_item *item, return 0; if (!infolist_new_var_string (item, "command", HOOK_COMMAND_RUN(hook, command))) return 0; + if (!infolist_new_var_integer (item, "keep_spaces_right", HOOK_COMMAND_RUN(hook, keep_spaces_right))) + return 0; return 1; } @@ -224,4 +239,5 @@ hook_command_run_print_log (struct t_hook *hook) log_printf (" command_run data:"); log_printf (" callback. . . . . . . : %p", HOOK_COMMAND_RUN(hook, callback)); log_printf (" command . . . . . . . : '%s'", HOOK_COMMAND_RUN(hook, command)); + log_printf (" keep_spaces_right . . : %d", HOOK_COMMAND_RUN(hook, keep_spaces_right)); } diff --git a/src/core/hook/hook-command-run.h b/src/core/hook/hook-command-run.h index be10621e2..912b21c92 100644 --- a/src/core/hook/hook-command-run.h +++ b/src/core/hook/hook-command-run.h @@ -34,6 +34,10 @@ struct t_hook_command_run { t_hook_callback_command_run *callback; /* command_run callback */ char *command; /* name of command (without '/') */ + + int keep_spaces_right; /* if set to 1: don't strip trailing */ + /* spaces in args when the command */ + /* is executed */ }; extern char *hook_command_run_get_description (struct t_hook *hook); diff --git a/src/core/hook/hook-command.c b/src/core/hook/hook-command.c index 8d7de8034..43ae4f9ca 100644 --- a/src/core/hook/hook-command.c +++ b/src/core/hook/hook-command.c @@ -565,6 +565,8 @@ hook_command (struct t_weechat_plugin *plugin, const char *command, new_hook_command->cplt_template_args_concat = NULL; hook_command_build_completion (new_hook_command); + new_hook_command->keep_spaces_right = 0; + hook_add_to_list (new_hook); return new_hook; @@ -592,10 +594,10 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin, struct t_hook *hook_plugin, *hook_other_plugin, *hook_other_plugin2; struct t_hook *hook_incomplete_command; struct t_hook_exec_cb hook_exec_cb; - char **argv, **argv_eol; - const char *ptr_command_name; + char **argv, **argv_eol, *command_name, *pos; + const char *ptr_string; int argc, rc, length_command_name, allow_incomplete_commands; - int count_other_plugin, count_incomplete_commands; + int count_other_plugin, count_incomplete_commands, flags; if (!buffer || !string || !string[0]) return HOOK_COMMAND_EXEC_NOT_FOUND; @@ -603,25 +605,13 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin, if (hook_command_run_exec (buffer, string) == WEECHAT_RC_OK_EAT) return HOOK_COMMAND_EXEC_OK; - argv = string_split (string, " ", NULL, - WEECHAT_STRING_SPLIT_STRIP_LEFT - | WEECHAT_STRING_SPLIT_STRIP_RIGHT - | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, - 0, &argc); - if (argc == 0) - { - string_free_split (argv); + ptr_string = utf8_next_char (string); + pos = strchr (ptr_string, ' '); + command_name = (pos) ? + string_strndup (ptr_string, pos - ptr_string) : strdup (ptr_string); + if (!command_name) return HOOK_COMMAND_EXEC_NOT_FOUND; - } - argv_eol = string_split (string, " ", NULL, - WEECHAT_STRING_SPLIT_STRIP_LEFT - | WEECHAT_STRING_SPLIT_STRIP_RIGHT - | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS - | WEECHAT_STRING_SPLIT_KEEP_EOL, - 0, NULL); - - ptr_command_name = utf8_next_char (argv[0]); - length_command_name = utf8_strlen (ptr_command_name); + length_command_name = utf8_strlen (command_name); hook_exec_start (); @@ -639,7 +629,7 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin, if (!ptr_hook->deleted) { - if (strcmp (ptr_command_name, HOOK_COMMAND(ptr_hook, command)) == 0) + if (strcmp (command_name, HOOK_COMMAND(ptr_hook, command)) == 0) { if (ptr_hook->plugin == plugin) { @@ -659,7 +649,7 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin, } } else if (allow_incomplete_commands - && (string_strncmp (ptr_command_name, + && (string_strncmp (command_name, HOOK_COMMAND(ptr_hook, command), length_command_name) == 0)) { @@ -727,6 +717,25 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin, } else { + /* split arguments */ + argv = string_split (string, " ", NULL, + WEECHAT_STRING_SPLIT_STRIP_LEFT + | WEECHAT_STRING_SPLIT_STRIP_RIGHT + | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, + 0, &argc); + if (argc == 0) + { + string_free_split (argv); + rc = HOOK_COMMAND_EXEC_NOT_FOUND; + goto end; + } + flags = WEECHAT_STRING_SPLIT_STRIP_LEFT + | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS + | WEECHAT_STRING_SPLIT_KEEP_EOL; + if (!HOOK_COMMAND(ptr_hook, keep_spaces_right)) + flags |= WEECHAT_STRING_SPLIT_STRIP_RIGHT; + argv_eol = string_split (string, " ", NULL, flags, 0, NULL); + /* execute the command! */ hook_callback_start (ptr_hook, &hook_exec_cb); rc = (int) (HOOK_COMMAND(ptr_hook, callback)) @@ -741,11 +750,14 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin, rc = HOOK_COMMAND_EXEC_ERROR; else rc = HOOK_COMMAND_EXEC_OK; + + string_free_split (argv); + string_free_split (argv_eol); } } - string_free_split (argv); - string_free_split (argv_eol); +end: + free (command_name); hook_exec_end (); @@ -1084,6 +1096,8 @@ hook_command_add_to_infolist (struct t_infolist_item *item, free (args_desc_nls); if (!infolist_new_var_string (item, "completion", HOOK_COMMAND(hook, completion))) return 0; + if (!infolist_new_var_integer (item, "keep_spaces_right", HOOK_COMMAND(hook, keep_spaces_right))) + return 0; return 1; } @@ -1128,4 +1142,5 @@ hook_command_print_log (struct t_hook *hook) log_printf (" args_concat[%04d] . . : '%s'", i, HOOK_COMMAND(hook, cplt_template_args_concat)[i]); } + log_printf (" keep_spaces_right . . : %d", HOOK_COMMAND(hook, keep_spaces_right)); } diff --git a/src/core/hook/hook-command.h b/src/core/hook/hook-command.h index 47f5638bf..6c242189f 100644 --- a/src/core/hook/hook-command.h +++ b/src/core/hook/hook-command.h @@ -66,6 +66,11 @@ struct t_hook_command /* concatenation of arg N for each template */ int cplt_template_num_args_concat; /* number of concatenated arguments */ char **cplt_template_args_concat; /* concatenated arguments */ + + /* other features */ + int keep_spaces_right; /* if set to 1: don't strip trailing */ + /* spaces in args when the command */ + /* is executed */ }; struct t_hook_command_similar