diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2021-08-27 17:25:56 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2021-08-27 17:25:56 +0000 |
commit | 916b1961091211ea4a58e0a54a72053e2fadc855 (patch) | |
tree | 790d0f70ac27e17d69a55b11050d43af98c0c534 /usr.bin/tmux/cmd-parse.y | |
parent | b9b52f488ddb6092e0930ae75f736ff92ab99f35 (diff) |
Replace %% in command lists (by copying them) for template arguments ,
this means they can be used with {} as well. Also make argument
processing from an existing vector preserve commands. GitHub issue 2858.
Diffstat (limited to 'usr.bin/tmux/cmd-parse.y')
-rw-r--r-- | usr.bin/tmux/cmd-parse.y | 126 |
1 files changed, 66 insertions, 60 deletions
diff --git a/usr.bin/tmux/cmd-parse.y b/usr.bin/tmux/cmd-parse.y index 6d7c7730c82..8f4cbc131fd 100644 --- a/usr.bin/tmux/cmd-parse.y +++ b/usr.bin/tmux/cmd-parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-parse.y,v 1.45 2021/08/23 11:48:21 nicm Exp $ */ +/* $OpenBSD: cmd-parse.y,v 1.46 2021/08/27 17:25:55 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -44,13 +44,15 @@ struct cmd_parse_scope { enum cmd_parse_argument_type { CMD_PARSE_STRING, - CMD_PARSE_COMMANDS + CMD_PARSE_COMMANDS, + CMD_PARSE_PARSED_COMMANDS }; struct cmd_parse_argument { enum cmd_parse_argument_type type; char *string; struct cmd_parse_commands *commands; + struct cmd_list *cmdlist; TAILQ_ENTRY(cmd_parse_argument) entry; }; @@ -608,6 +610,9 @@ cmd_parse_free_argument(struct cmd_parse_argument *arg) case CMD_PARSE_COMMANDS: cmd_parse_free_commands(arg->commands); break; + case CMD_PARSE_PARSED_COMMANDS: + cmd_list_free(arg->cmdlist); + break; } free(arg); } @@ -723,6 +728,11 @@ cmd_parse_log_commands(struct cmd_parse_commands *cmds, const char *prefix) cmd_parse_log_commands(arg->commands, s); free(s); break; + case CMD_PARSE_PARSED_COMMANDS: + s = cmd_list_print(arg->cmdlist, 0); + log_debug("%s %u:%u: %s", prefix, i, j, s); + free(s); + break; } j++; } @@ -818,6 +828,11 @@ cmd_parse_build_command(struct cmd_parse_command *cmd, values[count].type = ARGS_COMMANDS; values[count].cmdlist = pr->cmdlist; break; + case CMD_PARSE_PARSED_COMMANDS: + values[count].type = ARGS_COMMANDS; + values[count].cmdlist = arg->cmdlist; + values[count].cmdlist->references++; + break; } count++; } @@ -1023,39 +1038,19 @@ cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi) return (&pr); } -static void -cmd_parse_add_command(struct cmd_parse_commands *cmds, - struct cmd_parse_input *pi, int argc, char **argv) +struct cmd_parse_result * +cmd_parse_from_arguments(struct args_value *values, u_int count, + struct cmd_parse_input *pi) { + static struct cmd_parse_result pr; + struct cmd_parse_input input; + struct cmd_parse_commands *cmds; struct cmd_parse_command *cmd; struct cmd_parse_argument *arg; - int i; - - cmd_log_argv(argc, argv, "%s", __func__); - - cmd = xcalloc(1, sizeof *cmd); - cmd->line = pi->line; - - TAILQ_INIT(&cmd->arguments); - for (i = 0; i < argc; i++) { - arg = xcalloc(1, sizeof *arg); - arg->type = CMD_PARSE_STRING; - arg->string = xstrdup(argv[i]); - TAILQ_INSERT_TAIL(&cmd->arguments, arg, entry); - } - - TAILQ_INSERT_TAIL(cmds, cmd, entry); -} - -struct cmd_parse_result * -cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi) -{ - static struct cmd_parse_result pr; - struct cmd_parse_input input; - struct cmd_parse_commands *cmds; - char **copy, **new_argv; - size_t size; - int i, last, new_argc; + u_int i; + char *copy; + size_t size; + int end; /* * The commands are already split up into arguments, so just separate @@ -1066,40 +1061,51 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi) memset(&input, 0, sizeof input); pi = &input; } - cmd_log_argv(argc, argv, "%s", __func__); cmds = cmd_parse_new_commands(); - copy = cmd_copy_argv(argc, argv); - - last = 0; - for (i = 0; i < argc; i++) { - size = strlen(copy[i]); - if (size == 0 || copy[i][size - 1] != ';') - continue; - copy[i][--size] = '\0'; - if (size > 0 && copy[i][size - 1] == '\\') { - copy[i][size - 1] = ';'; - continue; - } - - new_argc = i - last; - new_argv = copy + last; - if (size != 0) - new_argc++; - if (new_argc != 0) - cmd_parse_add_command(cmds, pi, new_argc, new_argv); - last = i + 1; - } - if (last != argc) { - new_argv = copy + last; - new_argc = argc - last; + cmd = xcalloc(1, sizeof *cmd); + cmd->line = pi->line; + TAILQ_INIT(&cmd->arguments); - if (new_argc != 0) - cmd_parse_add_command(cmds, pi, new_argc, new_argv); + for (i = 0; i < count; i++) { + end = 0; + if (values[i].type == ARGS_STRING) { + copy = xstrdup(values[i].string); + size = strlen(copy); + if (size != 0 && copy[size - 1] == ';') { + copy[--size] = '\0'; + if (size > 0 && copy[size - 1] == '\\') + copy[size - 1] = ';'; + else + end = 1; + } + if (!end || size != 0) { + arg = xcalloc(1, sizeof *arg); + arg->type = CMD_PARSE_STRING; + arg->string = copy; + TAILQ_INSERT_TAIL(&cmd->arguments, arg, entry); + } + } else if (values[i].type == ARGS_COMMANDS) { + arg = xcalloc(1, sizeof *arg); + arg->type = CMD_PARSE_PARSED_COMMANDS; + arg->cmdlist = values[i].cmdlist; + arg->cmdlist->references++; + TAILQ_INSERT_TAIL(&cmd->arguments, arg, entry); + } else + fatalx("unknown argument type"); + if (end) { + TAILQ_INSERT_TAIL(cmds, cmd, entry); + cmd = xcalloc(1, sizeof *cmd); + cmd->line = pi->line; + TAILQ_INIT(&cmd->arguments); + } } + if (!TAILQ_EMPTY(&cmd->arguments)) + TAILQ_INSERT_TAIL(cmds, cmd, entry); + else + free(cmd); - cmd_free_argv(argc, copy); cmd_parse_build_commands(cmds, pi, &pr); cmd_parse_free_commands(cmds); return (&pr); |