From ac4bb89d4355a7a9bd2abe4cb27b31a445f7cd99 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 15 Mar 2023 08:15:39 +0000 Subject: [PATCH] Fix command prompt not to always append argument but only if there has actually been expansion. GitHub issue 3493. --- arguments.c | 22 ++++++++++++++++++++-- cmd-command-prompt.c | 7 +++++-- cmd-parse.y | 17 ++++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/arguments.c b/arguments.c index 326fad17..df05d328 100644 --- a/arguments.c +++ b/arguments.c @@ -98,6 +98,22 @@ args_copy_value(struct args_value *to, struct args_value *from) } } +/* Type to string. */ +static const char * +args_type_to_string (enum args_type type) +{ + switch (type) + { + case ARGS_NONE: + return "NONE"; + case ARGS_STRING: + return "STRING"; + case ARGS_COMMANDS: + return "COMMANDS"; + } + return "INVALID"; +} + /* Get value as string. */ static const char * args_value_as_string(struct args_value *value) @@ -250,8 +266,8 @@ args_parse(const struct args_parse *parse, struct args_value *values, value = &values[i]; s = args_value_as_string(value); - log_debug("%s: %u = %s (type %d)", __func__, i, s, - value->type); + log_debug("%s: %u = %s (type %s)", __func__, i, s, + args_type_to_string (value->type)); if (parse->cb != NULL) { type = parse->cb(args, args->count, cause); @@ -796,6 +812,8 @@ args_make_commands(struct args_command_state *state, int argc, char **argv, } cmd = xstrdup(state->cmd); + log_debug("%s: %s", __func__, cmd); + cmd_log_argv(argc, argv, __func__); for (i = 0; i < argc; i++) { new_cmd = cmd_template_replace(cmd, argv[i], i + 1); log_debug("%s: %%%u %s: %s", __func__, i + 1, argv[i], new_cmd); diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 4455856b..6010d0fd 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -179,10 +179,10 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, if (s == NULL) goto out; + if (done) { if (cdata->flags & PROMPT_INCREMENTAL) goto out; - cmd_append_argv(&cdata->argc, &cdata->argv, s); if (++cdata->current != cdata->count) { prompt = &cdata->prompts[cdata->current]; @@ -193,8 +193,11 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, argc = cdata->argc; argv = cmd_copy_argv(cdata->argc, cdata->argv); - cmd_append_argv(&argc, &argv, s); + if (!done) + cmd_append_argv(&argc, &argv, s); + if (done) { + cmd_free_argv(cdata->argc, cdata->argv); cdata->argc = argc; cdata->argv = cmd_copy_argv(argc, argv); } diff --git a/cmd-parse.y b/cmd-parse.y index cdf026f3..65ffad84 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -1615,13 +1615,24 @@ yylex_token(int ch) for (;;) { /* EOF or \n are always the end of the token. */ - if (ch == EOF || (state == NONE && ch == '\n')) + if (ch == EOF) { + log_debug("%s: end at EOF", __func__); break; + } + if (state == NONE && ch == '\n') { + log_debug("%s: end at EOL", __func__); + break; + } /* Whitespace or ; or } ends a token unless inside quotes. */ - if ((ch == ' ' || ch == '\t' || ch == ';' || ch == '}') && - state == NONE) + if (state == NONE && (ch == ' ' || ch == '\t')) { + log_debug("%s: end at WS", __func__); break; + } + if (state == NONE && (ch == ';' || ch == '}')) { + log_debug("%s: end at %c", __func__, ch); + break; + } /* * Spaces and comments inside quotes after \n are removed but