From 25d7192677f8a415cd9ba94229d86aecb9ca5797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Mon, 1 May 2023 21:47:44 +0200 Subject: [PATCH] api: don't split on newline by default in functions `command` and `command_options` when input_multiline is set to 0 The API functions `command` and `command_options` (when `split_newline` = 0, which is the default value) don't split on newline and then the first line is executed and the subsequent lines (after "\n") are ignored. There are no changes when the input has multiple lines filled by the user: the split is done and multiple commands are executed (for example if the user is pasting multiple commands to execute). --- ChangeLog.adoc | 1 + src/core/wee-command.c | 40 +++++++++++++-------------- src/core/wee-input.c | 25 ++++++++++++----- src/core/wee-input.h | 5 ++-- src/core/wee-signal.c | 2 +- src/gui/gui-input.c | 2 +- src/gui/gui-key.c | 4 +-- src/plugins/plugin-api.c | 12 ++++++-- tests/tests.cpp | 4 +-- tests/unit/core/test-core-command.cpp | 2 +- tests/unit/gui/test-gui-buffer.cpp | 6 ++-- tests/unit/gui/test-gui-key.cpp | 8 +++--- 12 files changed, 66 insertions(+), 45 deletions(-) diff --git a/ChangeLog.adoc b/ChangeLog.adoc index df4b801c8..9a677a181 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -36,6 +36,7 @@ New features:: * core: add item "mouse_status" in default status bar, change default color to lightgreen * core, trigger: add options weechat.color.chat_status_disabled and weechat.color.chat_status_enabled, remove options trigger.color.trigger and trigger.color.trigger_disabled, add enabled/disabled status color in output of `/filter list` (issue #1820) * api: add function config_set_version (issue #1238) + * api: don't split on newline by default in functions `command` and `command_options` when `input_multiline` is set to 0 * api: add optional argument with version in info "version_number" * alias: use lower case for default aliases, rename all aliases to lower case on upgrade (issue #1872) * irc: rename "ssl" options to "tls", connect with TLS and port 6697 by default diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 9a9644cac..921fb40d4 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -124,7 +124,7 @@ COMMAND_CALLBACK(allbuf) { ptr_buffer = (struct t_gui_buffer *)arraylist_get (all_buffers, i); if (gui_buffer_valid (ptr_buffer)) - (void) input_data (ptr_buffer, argv_eol[1], NULL); + (void) input_data (ptr_buffer, argv_eol[1], NULL, 0); } arraylist_free (all_buffers); @@ -1603,7 +1603,7 @@ COMMAND_CALLBACK(color) if (string_strcmp (argv[1], "-o") == 0) { gui_color_info_term_colors (str_color, sizeof (str_color)); - (void) input_data (buffer, str_color, NULL); + (void) input_data (buffer, str_color, NULL, 0); return WEECHAT_RC_OK; } @@ -2131,7 +2131,7 @@ COMMAND_CALLBACK(debug) { COMMAND_MIN_ARGS(3, "time"); gettimeofday (&time_start, NULL); - (void) input_data (buffer, argv_eol[2], NULL); + (void) input_data (buffer, argv_eol[2], NULL, 0); gettimeofday (&time_end, NULL); debug_display_time_elapsed (&time_start, &time_end, argv_eol[2], 1); return WEECHAT_RC_OK; @@ -2319,7 +2319,7 @@ COMMAND_CALLBACK(eval) options); if (result) { - (void) input_data (buffer, result, NULL); + (void) input_data (buffer, result, NULL, 0); free (result); } else @@ -2342,7 +2342,7 @@ COMMAND_CALLBACK(eval) result = eval_expression (ptr_args, pointers, NULL, options); if (result) { - (void) input_data (buffer, result, NULL); + (void) input_data (buffer, result, NULL, 0); free (result); } else @@ -3569,7 +3569,7 @@ COMMAND_CALLBACK(input) gui_input_insert (buffer, argv_eol[2]); } else if (string_strcmp (argv[1], "send") == 0) - (void) input_data (buffer, argv_eol[2], NULL); + (void) input_data (buffer, argv_eol[2], NULL, 0); else if (string_strcmp (argv[1], "undo") == 0) gui_input_undo (buffer); else if (string_strcmp (argv[1], "redo") == 0) @@ -3610,10 +3610,10 @@ COMMAND_CALLBACK(input) gui_hotlist_restore_all_buffers (); /* since WeeChat 3.8: "/buffer set unread" */ else if (string_strcmp (argv[1], "set_unread_current_buffer") == 0) - (void) input_data (buffer, "/buffer set unread", NULL); + (void) input_data (buffer, "/buffer set unread", NULL, 0); /* since WeeChat 3.8: "/allbuf /buffer set unread" */ else if (string_strcmp (argv[1], "set_unread") == 0) - (void) input_data (buffer, "/allbuf /buffer set unread", NULL); + (void) input_data (buffer, "/allbuf /buffer set unread", NULL, 0); /* since WeeChat 3.8: "/buffer switch" */ else if (string_strcmp (argv[1], "switch_active_buffer") == 0) gui_buffer_switch_active_buffer (buffer); @@ -4952,7 +4952,7 @@ command_plugin_list_input (struct t_gui_buffer *buffer, if (send_to_buffer) { - (void) input_data (buffer, *buf, NULL); + (void) input_data (buffer, *buf, NULL, 0); } else { @@ -5691,7 +5691,7 @@ command_repeat_timer_cb (const void *pointer, void *data, int remaining_calls) /* search buffer, fallback to core buffer if not found */ ptr_buffer = gui_buffer_search_by_full_name (repeat_args[0]); if (ptr_buffer) - (void) input_data (ptr_buffer, repeat_args[1], repeat_args[2]); + (void) input_data (ptr_buffer, repeat_args[1], repeat_args[2], 0); } if (remaining_calls == 0) @@ -5747,7 +5747,7 @@ COMMAND_CALLBACK(repeat) } /* first execute command now */ - (void) input_data (buffer, argv_eol[arg_count + 1], NULL); + (void) input_data (buffer, argv_eol[arg_count + 1], NULL, 0); /* repeat execution of command */ if (count > 1) @@ -5757,7 +5757,7 @@ COMMAND_CALLBACK(repeat) /* execute command multiple times now */ for (i = 0; i < count - 1; i++) { - (void) input_data (buffer, argv_eol[arg_count + 1], NULL); + (void) input_data (buffer, argv_eol[arg_count + 1], NULL, 0); } } else @@ -7038,7 +7038,7 @@ COMMAND_CALLBACK(uptime) minutes, seconds, str_first_start); - (void) input_data (buffer, string, NULL); + (void) input_data (buffer, string, NULL, 0); } else if ((argc >= 2) && (string_strcmp (argv[1], "-ol") == 0)) { @@ -7051,7 +7051,7 @@ COMMAND_CALLBACK(uptime) minutes, seconds, util_get_time_string (&weechat_first_start_time)); - (void) input_data (buffer, string, NULL); + (void) input_data (buffer, string, NULL, 0); } else { @@ -7130,7 +7130,7 @@ command_version_display (struct t_gui_buffer *buffer, _("compiled on"), version_get_compilation_date (), version_get_compilation_time ()); - (void) input_data (buffer, string, NULL); + (void) input_data (buffer, string, NULL, 0); if (weechat_upgrade_count > 0) { snprintf (string, sizeof (string), @@ -7140,7 +7140,7 @@ command_version_display (struct t_gui_buffer *buffer, NG_("time", "times", weechat_upgrade_count), str_first_start, str_last_start); - (void) input_data (buffer, string, NULL); + (void) input_data (buffer, string, NULL, 0); } } else @@ -7151,7 +7151,7 @@ command_version_display (struct t_gui_buffer *buffer, "compiled on", version_get_compilation_date (), version_get_compilation_time ()); - (void) input_data (buffer, string, NULL); + (void) input_data (buffer, string, NULL, 0); if (weechat_upgrade_count > 0) { snprintf (string, sizeof (string), @@ -7160,7 +7160,7 @@ command_version_display (struct t_gui_buffer *buffer, (weechat_upgrade_count > 1) ? "times" : "time", str_first_start, str_last_start); - (void) input_data (buffer, string, NULL); + (void) input_data (buffer, string, NULL, 0); } } } @@ -7239,7 +7239,7 @@ COMMAND_CALLBACK(wait) if (delay < 1) COMMAND_ERROR; - if (input_data_delayed (buffer, argv_eol[2], NULL, delay) != WEECHAT_RC_OK) + if (input_data_delayed (buffer, argv_eol[2], NULL, 0, delay) != WEECHAT_RC_OK) COMMAND_ERROR; return WEECHAT_RC_OK; @@ -9296,7 +9296,7 @@ command_exec_list (const char *command_list) if (command_eval) { (void) input_data (gui_buffer_search_main (), - command_eval, NULL); + command_eval, NULL, 0); free (command_eval); } } diff --git a/src/core/wee-input.c b/src/core/wee-input.c index a287d7152..703d8619a 100644 --- a/src/core/wee-input.c +++ b/src/core/wee-input.c @@ -236,6 +236,9 @@ end: /* * Sends data to a buffer's callback. * + * If split_newline = 1 and if buffer input_multiline = 0, the string + * is split on "\n" and multiple commands can then be executed. + * * Returns: * WEECHAT_RC_OK: data properly sent (or command executed successfully) * WEECHAT_RC_ERROR: error @@ -243,7 +246,7 @@ end: int input_data (struct t_gui_buffer *buffer, const char *data, - const char *commands_allowed) + const char *commands_allowed, int split_newline) { char *pos, *buf, str_buffer[128], *new_data, *buffer_full_name; const char *ptr_data, *ptr_data_for_buffer; @@ -336,7 +339,7 @@ input_data (struct t_gui_buffer *buffer, const char *data, if (pos) { pos[0] = '\n'; - ptr_data = pos + 1; + ptr_data = (split_newline) ? pos + 1 : NULL; } else ptr_data = NULL; @@ -377,10 +380,16 @@ input_data_timer_cb (const void *pointer, void *data, int remaining_calls) { ptr_buffer = gui_buffer_search_by_full_name (timer_args[0]); if (ptr_buffer) - (void) input_data (ptr_buffer, timer_args[1], timer_args[2]); + { + (void) input_data ( + ptr_buffer, + timer_args[1], + timer_args[2], + (string_strcmp (timer_args[3], "1") == 0) ? 1 : 0); + } } - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) { if (timer_args[i]) free (timer_args[i]); @@ -403,14 +412,15 @@ input_data_timer_cb (const void *pointer, void *data, int remaining_calls) int input_data_delayed (struct t_gui_buffer *buffer, const char *data, - const char *commands_allowed, long delay) + const char *commands_allowed, int split_newline, + long delay) { char **timer_args, *new_commands_allowed; if (delay < 1) - return input_data (buffer, data, commands_allowed); + return input_data (buffer, data, commands_allowed, split_newline); - timer_args = malloc (3 * sizeof (*timer_args)); + timer_args = malloc (4 * sizeof (*timer_args)); if (!timer_args) { gui_chat_printf (NULL, @@ -437,6 +447,7 @@ input_data_delayed (struct t_gui_buffer *buffer, const char *data, timer_args[0] = strdup (buffer->full_name); timer_args[1] = strdup (data); timer_args[2] = new_commands_allowed; + timer_args[3] = strdup ((split_newline) ? "1" : "0"); /* schedule command, execute it after "delay" milliseconds */ hook_timer (NULL, diff --git a/src/core/wee-input.h b/src/core/wee-input.h index 24ab2de74..a4f37a50d 100644 --- a/src/core/wee-input.h +++ b/src/core/wee-input.h @@ -31,8 +31,9 @@ extern int input_exec_command (struct t_gui_buffer *buffer, const char *string, const char *commands_allowed); extern int input_data (struct t_gui_buffer *buffer, const char *data, - const char *commands_allowed); + const char *commands_allowed, int split_newline); extern int input_data_delayed (struct t_gui_buffer *buffer, const char *data, - const char *commands_allowed, long delay); + const char *commands_allowed, int split_newline, + long delay); #endif /* WEECHAT_INPUT_H */ diff --git a/src/core/wee-signal.c b/src/core/wee-signal.c index af88b674f..54c7019e5 100644 --- a/src/core/wee-signal.c +++ b/src/core/wee-signal.c @@ -226,7 +226,7 @@ signal_exec_command (int signal_index, const char *command) if (signal_upper) free (signal_upper); (void) input_data (gui_buffer_search_main (), - command_eval, NULL); + command_eval, NULL, 0); free (command_eval); } } diff --git a/src/gui/gui-input.c b/src/gui/gui-input.c index 02fc5cab6..38be95fdf 100644 --- a/src/gui/gui-input.c +++ b/src/gui/gui-input.c @@ -335,7 +335,7 @@ gui_input_send_data_to_buffer (struct t_gui_buffer *buffer, char *data) gui_input_text_changed_modifier_and_signal (buffer, 0, /* save undo */ 1); /* stop completion */ - (void) input_data (buffer, data, NULL); + (void) input_data (buffer, data, NULL, 1); } /* diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c index d185a818d..1737d2bad 100644 --- a/src/gui/gui-key.c +++ b/src/gui/gui-key.c @@ -2146,7 +2146,7 @@ gui_key_focus_command (const char *key, int context, command, ptr_buffer->full_name); } - (void) input_data (ptr_buffer, command, NULL); + (void) input_data (ptr_buffer, command, NULL, 0); free (command); } } @@ -2491,7 +2491,7 @@ gui_key_pressed (const char *key_str) for (i = 0; commands[i]; i++) { (void) input_data (gui_current_window->buffer, - commands[i], NULL); + commands[i], NULL, 0); } string_free_split (commands); } diff --git a/src/plugins/plugin-api.c b/src/plugins/plugin-api.c index 22ddc5374..2d7aedb8f 100644 --- a/src/plugins/plugin-api.c +++ b/src/plugins/plugin-api.c @@ -395,15 +395,16 @@ plugin_api_command_options (struct t_weechat_plugin *plugin, struct t_hashtable *options) { char *command2, *error; - const char *ptr_commands_allowed, *ptr_delay; + const char *ptr_commands_allowed, *ptr_delay, *ptr_split_newline; long delay; - int rc; + int rc, split_newline; if (!plugin || !command) return WEECHAT_RC_ERROR; ptr_commands_allowed = NULL; delay = 0; + split_newline = 0; if (options) { @@ -416,6 +417,12 @@ plugin_api_command_options (struct t_weechat_plugin *plugin, if (!error || error[0]) delay = 0; } + ptr_split_newline = hashtable_get (options, "split_newline"); + if (ptr_split_newline) + { + split_newline = (string_strcmp (ptr_split_newline, "1") == 0) ? + 1 : 0; + } } command2 = string_iconv_to_internal (plugin->charset, command); @@ -423,6 +430,7 @@ plugin_api_command_options (struct t_weechat_plugin *plugin, rc = input_data_delayed ((buffer) ? buffer : gui_current_window->buffer, (command2) ? command2 : command, ptr_commands_allowed, + split_newline, delay); if (command2) diff --git a/tests/tests.cpp b/tests/tests.cpp index 36c78d0a0..fa0a6b5b2 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -297,7 +297,7 @@ void run_cmd (const char *command) { printf (">>> Running command: %s\n", command); - input_data (ptr_core_buffer, command, NULL); + input_data (ptr_core_buffer, command, NULL, 0); } /* @@ -307,7 +307,7 @@ run_cmd (const char *command) void run_cmd_quiet (const char *command) { - input_data (ptr_core_buffer, command, NULL); + input_data (ptr_core_buffer, command, NULL, 0); } /* diff --git a/tests/unit/core/test-core-command.cpp b/tests/unit/core/test-core-command.cpp index e547edd9e..5fda4539a 100644 --- a/tests/unit/core/test-core-command.cpp +++ b/tests/unit/core/test-core-command.cpp @@ -70,7 +70,7 @@ TEST_GROUP(CoreCommand) FAIL("Buffer not found"); } record_start (); - input_data (buffer, command, NULL); + input_data (buffer, command, NULL, 0); record_stop (); } diff --git a/tests/unit/gui/test-gui-buffer.cpp b/tests/unit/gui/test-gui-buffer.cpp index 847452860..66309b9c7 100644 --- a/tests/unit/gui/test-gui-buffer.cpp +++ b/tests/unit/gui/test-gui-buffer.cpp @@ -534,7 +534,7 @@ TEST(GuiBuffer, NewUser) /* test signal "buffer_user_input_test" */ signal_buffer_user_input[0] = '\0'; - input_data (buffer, "something", NULL); + input_data (buffer, "something", NULL, 0); STRCMP_EQUAL("something", signal_buffer_user_input); /* test signal "buffer_user_closing_test" */ @@ -549,7 +549,7 @@ TEST(GuiBuffer, NewUser) /* close the buffer by sending "q" */ signal_buffer_user_input[0] = '\0'; signal_buffer_user_closing = 0; - input_data (buffer, "q", NULL); + input_data (buffer, "q", NULL, 0); STRCMP_EQUAL("q", signal_buffer_user_input); LONGS_EQUAL(1, signal_buffer_user_closing); @@ -569,7 +569,7 @@ TEST(GuiBuffer, NewUser) */ signal_buffer_user_input[0] = '\0'; signal_buffer_user_closing = 0; - input_data (buffer, "q", NULL); + input_data (buffer, "q", NULL, 0); STRCMP_EQUAL("q", signal_buffer_user_input); LONGS_EQUAL(0, signal_buffer_user_closing); diff --git a/tests/unit/gui/test-gui-key.cpp b/tests/unit/gui/test-gui-key.cpp index b69780619..02149d8c7 100644 --- a/tests/unit/gui/test-gui-key.cpp +++ b/tests/unit/gui/test-gui-key.cpp @@ -113,16 +113,16 @@ TEST(GuiKey, GetCurrentContext) { LONGS_EQUAL(GUI_KEY_CONTEXT_DEFAULT, gui_key_get_current_context ()); - input_data (gui_buffers, "/cursor", NULL); + input_data (gui_buffers, "/cursor", NULL, 0); LONGS_EQUAL(GUI_KEY_CONTEXT_CURSOR, gui_key_get_current_context ()); - input_data (gui_buffers, "/cursor stop", NULL); + input_data (gui_buffers, "/cursor stop", NULL, 0); LONGS_EQUAL(GUI_KEY_CONTEXT_DEFAULT, gui_key_get_current_context ()); - input_data (gui_buffers, "/input search_text_here", NULL); + input_data (gui_buffers, "/input search_text_here", NULL, 0); LONGS_EQUAL(GUI_KEY_CONTEXT_SEARCH, gui_key_get_current_context ()); - input_data (gui_buffers, "/input search_stop", NULL); + input_data (gui_buffers, "/input search_stop", NULL, 0); LONGS_EQUAL(GUI_KEY_CONTEXT_DEFAULT, gui_key_get_current_context ()); }