summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/cmd-parse.y
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2021-08-27 17:25:56 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2021-08-27 17:25:56 +0000
commit916b1961091211ea4a58e0a54a72053e2fadc855 (patch)
tree790d0f70ac27e17d69a55b11050d43af98c0c534 /usr.bin/tmux/cmd-parse.y
parentb9b52f488ddb6092e0930ae75f736ff92ab99f35 (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.y126
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);