diff --git a/arguments.c b/arguments.c index 5c53b3cf5..7852655ab 100644 --- a/arguments.c +++ b/arguments.c @@ -51,15 +51,6 @@ struct args { struct args_value *values; }; -/* Prepared command state. */ -struct args_command_state { - struct cmd_parse_tree *tree; - char *cmd; - struct cmd_parse_input pi; - char *error; - int parse_input; -}; - static struct args_entry *args_find(struct args *, u_char); static int args_cmp(struct args_entry *, struct args_entry *); @@ -748,151 +739,53 @@ args_string(struct args *args, u_int idx) return (args_value_as_string(&args->values[idx])); } -/* Make a command now. */ -struct cmdq_item * -args_command_now(struct cmd *self, struct cmdq_item *item, u_int idx, - int expand) +/* + * Convert one command argument into a parse tree. A string value is parsed; + * existing commands are referenced. + */ +struct cmd_parse_tree * +args_to_commands(struct cmd *self, struct cmdq_item *item, u_int idx, + const char *default_command, int expand, char **cause) { - struct args_command_state *state; - struct cmdq_item *new_item; - struct cmdq_state *cs = cmdq_get_state(item); - char *error; + struct args *args = cmd_get_args(self); + struct args_value *value; + struct cmd_parse_input pi = { 0 }; + const char *cmd = NULL, *file; + char *expanded; + struct cmd_parse_tree *tree; - state = args_command_prepare(self, item, idx, NULL, expand); - new_item = args_command_get(state, 0, NULL, cs, &error); - if (new_item == NULL) { - cmdq_error(item, "%s", error); - free(error); - } - args_command_free(state); - return (new_item); -} + *cause = NULL; -/* Save bits to make a command later. */ -struct args_command_state * -args_command_prepare(struct cmd *self, struct cmdq_item *item, u_int idx, - const char *default_command, int expand) -{ - struct args *args = cmd_get_args(self); - struct args_value *value; - struct args_command_state *state; - const char *cmd = NULL; - const char *file; - - state = xcalloc(1, sizeof *state); - state->pi.flags = cmd_get_parse_flags(self); - - cmd_get_source(self, &file, &state->pi.line); - if (file != NULL) - state->pi.file = xstrdup(file); - - if (idx < args->count) { - value = &args->values[idx]; - if (value->type == ARGS_COMMANDS) { - state->tree = cmd_parse_add_ref(value->cmd); - return (state); - } - if (value->type != ARGS_STRING) - fatalx("argument not string or commands"); - cmd = value->string; - } else { - if (default_command == NULL) - fatalx("argument out of range"); + if (idx >= args->count) cmd = default_command; + else { + value = &args->values[idx]; + switch (value->type) { + case ARGS_COMMANDS: + return (cmd_parse_add_ref(value->cmd)); + case ARGS_STRING: + cmd = value->string; + break; + case ARGS_NONE: + break; + } } - + if (cmd == NULL) + fatalx("argument out of range"); if (expand) - state->cmd = format_single_from_target(item, cmd); + expanded = format_single_from_target(item, cmd); else - state->cmd = xstrdup(cmd); - log_debug("%s: %s", __func__, state->cmd); + expanded = xstrdup(cmd); + log_debug("%s: %s", __func__, expanded); - if (strcmp(state->cmd, "%1") == 0) - state->parse_input = 1; - else { - state->tree = cmd_parse_from_string(state->cmd, &state->pi, - &state->error); - } - - return (state); -} - -/* Return argument as command queue item. */ -struct cmdq_item * -args_command_get(struct args_command_state *state, int argc, char **argv, - struct cmdq_state *qstate, char **error) -{ - struct cmd_invoke_input ci = { 0 }; - struct cmd_parse_tree *tree; - struct cmdq_item *item; - int free_tree = 0; - - if (state->error != NULL) { - *error = xstrdup(state->error); - return (NULL); - } - - ci.file = state->pi.file; - ci.flags = state->pi.flags; - - if (state->parse_input) { - if (argc == 0 || argv[0] == NULL) { - *error = xstrdup("missing command"); - return (NULL); - } - tree = cmd_parse_from_string(argv[0], &state->pi, error); - if (tree == NULL) - return (NULL); - free_tree = 1; - } else { - if (state->tree == NULL) - fatalx("no command tree"); - tree = state->tree; - ci.argc = argc; - ci.argv = argv; - } - - item = cmd_invoke_get(tree, qstate, &ci); - if (free_tree) - cmd_parse_free(tree); - return (item); -} - -/* Free commands state. */ -void -args_command_free(struct args_command_state *state) -{ - if (state->tree != NULL) - cmd_parse_free(state->tree); - free((void *)state->pi.file); - free(state->cmd); - free(state->error); - free(state); -} - -/* Get prepared command. */ -char * -args_command_get_command(struct args_command_state *state) -{ - int n; - char *s, *tmp; - - if (state->parse_input) - return (xstrdup("")); - if (state->cmd == NULL && state->tree != NULL) { - tmp = cmd_parse_print(state->tree); - n = strcspn(tmp, " ,"); - xasprintf(&s, "%.*s", n, tmp); - free(tmp); - return (s); - } - if (state->cmd != NULL) { - n = strcspn(state->cmd, " ,"); - xasprintf(&s, "%.*s", n, state->cmd); - return (s); - } - return (xstrdup("")); + cmd_get_source(self, &file, &pi.line); + if (file != NULL) + pi.file = file; + pi.flags = cmd_get_parse_flags(self); + tree = cmd_parse_from_string(expanded, &pi, cause); + free(expanded); + return (tree); } /* Get first value in argument. */ diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 617cc4514..845985239 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -57,7 +57,7 @@ struct cmd_command_prompt_prompt { struct cmd_command_prompt_cdata { struct cmdq_item *item; - struct args_command_state *state; + struct cmd_parse_tree *tree; int flags; enum prompt_type prompt_type; @@ -85,13 +85,13 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); struct client *tc = cmdq_get_target_client(item); struct cmd_find_state *target = cmdq_get_target(item); - const char *type, *s, *input; + const char *type, *s, *input, *cmd; struct cmd_command_prompt_cdata *cdata; char *tmp, *prompts, *prompt, *next_prompt; - char *inputs = NULL, *next_input; + char *inputs = NULL, *next_input, *cause = NULL; struct window_pane *wp = target->wp; u_int count = args_count(args); - int wait = !args_has(args, 'b'), space = 1; + int wait = !args_has(args, 'b'), space = 1, n; int pane = args_has(args, 'P'); if (pane) { @@ -107,14 +107,22 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) cdata->item = item; if (pane) cdata->wp = wp; - cdata->state = args_command_prepare(self, item, 0, "%1", - args_has(args, 'F')); + if (count != 0) { + cdata->tree = args_to_commands(self, item, 0, NULL, + args_has(args, 'F'), &cause); + if (cdata->tree == NULL) { + cmdq_error(item, "%s", cause); + free(cause); + free(cdata); + return (CMD_RETURN_ERROR); + } + } if ((s = args_get(args, 'p')) == NULL) { if (count != 0) { - tmp = args_command_get_command(cdata->state); - xasprintf(&prompts, "(%s)", tmp); - free(tmp); + cmd = args_string(args, 0); + n = strcspn(cmd, " ,"); + xasprintf(&prompts, "(%.*s)", n, cmd); } else { prompts = xstrdup(":"); space = 0; @@ -203,6 +211,9 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, struct cmdq_item *item = cdata->item, *new_item; struct cmdq_state *cs = NULL; struct cmd_command_prompt_prompt *prompt; + struct cmd_invoke_input ci = { 0 }; + struct cmd_parse_tree *tree; + struct cmd_parse_input pi = { 0 }; int argc = 0; char **argv = NULL; @@ -237,14 +248,33 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, if (item != NULL) cs = cmdq_get_state(item); - new_item = args_command_get(cdata->state, argc, argv, cs, &error); - if (new_item == NULL) { - cmdq_append(c, cmdq_get_error(error)); - free(error); - } else if (item == NULL) { - cmdq_append(c, new_item); + + if (cdata->tree != NULL) { + /* Explicit body: prompt inputs become the template argv. */ + ci.argc = argc; + ci.argv = argv; + new_item = cmd_invoke_get(cdata->tree, cs, &ci); + if (item == NULL) + cmdq_append(c, new_item); + else + cmdq_insert_after(item, new_item); } else { - cmdq_insert_after(item, new_item); + /* No body: parse the submitted text as command language. */ + tree = cmd_parse_from_string(s, &pi, &error); + if (tree == NULL) { + if (item == NULL) + cmdq_append(c, cmdq_get_error(error)); + else + cmdq_error(item, "%s", error); + free(error); + } else { + new_item = cmd_invoke_get(tree, cs, NULL); + cmd_parse_free(tree); + if (item == NULL) + cmdq_append(c, new_item); + else + cmdq_insert_after(item, new_item); + } } cmd_free_argv(argc, argv); @@ -281,6 +311,6 @@ cmd_command_prompt_free(void *data) } free(cdata->prompts); cmd_free_argv(cdata->argc, cdata->argv); - args_command_free(cdata->state); + cmd_parse_free(cdata->tree); free(cdata); } diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index 9c6326947..0109b8292 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -50,10 +50,10 @@ const struct cmd_entry cmd_confirm_before_entry = { }; struct cmd_confirm_before_data { - struct cmdq_item *item; - struct args_command_state *state; - u_char confirm_key; - int default_yes; + struct cmdq_item *item; + struct cmd_parse_tree *tree; + u_char confirm_key; + int default_yes; }; static enum args_parse_type @@ -70,13 +70,18 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item) struct cmd_confirm_before_data *cdata; struct client *tc = cmdq_get_target_client(item); struct cmd_find_state *target = cmdq_get_target(item); - char *new_prompt; - const char *confirm_key, *prompt; - char *cmd; - int wait = !args_has(args, 'b'); + char *new_prompt, *cause = NULL; + const char *confirm_key, *prompt, *cmd; + int wait = !args_has(args, 'b'), n; cdata = xcalloc(1, sizeof *cdata); - cdata->state = args_command_prepare(self, item, 0, NULL, 1); + cdata->tree = args_to_commands(self, item, 0, NULL, 1, &cause); + if (cdata->tree == NULL) { + cmdq_error(item, "%s", cause); + free(cause); + free(cdata); + return (CMD_RETURN_ERROR); + } if (wait) cdata->item = item; @@ -89,7 +94,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item) cdata->confirm_key = confirm_key[0]; else { cmdq_error(item, "invalid confirm key"); - args_command_free(cdata->state); + cmd_parse_free(cdata->tree); free(cdata); return (CMD_RETURN_ERROR); } @@ -100,10 +105,10 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item) if ((prompt = args_get(args, 'p')) != NULL) xasprintf(&new_prompt, "%s ", prompt); else { - cmd = args_command_get_command(cdata->state); - xasprintf(&new_prompt, "Confirm '%s'? (%c/n) ", cmd, + cmd = args_string(args, 0); + n = strcspn(cmd, " ,"); + xasprintf(&new_prompt, "Confirm '%.*s'? (%c/n) ", n, cmd, cdata->confirm_key); - free(cmd); } status_prompt_set(tc, target, new_prompt, NULL, @@ -122,7 +127,6 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s, { struct cmd_confirm_before_data *cdata = data; struct cmdq_item *item = cdata->item, *new_item; - char *error; int retcode = 1; if (c->flags & CLIENT_DEAD) @@ -135,22 +139,11 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s, retcode = 0; if (item == NULL) { - new_item = args_command_get(cdata->state, 0, NULL, NULL, - &error); - if (new_item == NULL) { - cmdq_append(c, cmdq_get_error(error)); - free(error); - goto out; - } + new_item = cmd_invoke_get(cdata->tree, NULL, NULL); cmdq_append(c, new_item); } else { - new_item = args_command_get(cdata->state, 0, NULL, - cmdq_get_state(item), &error); - if (new_item == NULL) { - cmdq_error(item, "%s", error); - free(error); - goto out; - } + new_item = cmd_invoke_get(cdata->tree, cmdq_get_state(item), + NULL); cmdq_insert_after(item, new_item); } @@ -169,6 +162,6 @@ cmd_confirm_before_free(void *data) { struct cmd_confirm_before_data *cdata = data; - args_command_free(cdata->state); + cmd_parse_free(cdata->tree); free(cdata); } diff --git a/cmd-display-panes.c b/cmd-display-panes.c index b2f56c488..db7a87fbe 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -44,8 +44,8 @@ const struct cmd_entry cmd_display_panes_entry = { }; struct cmd_display_panes_data { - struct cmdq_item *item; - struct args_command_state *state; + struct cmdq_item *item; + struct cmd_parse_tree *tree; }; struct cmd_display_panes_ctx { @@ -297,7 +297,7 @@ cmd_display_panes_free(__unused struct client *c, void *data) if (cdata->item != NULL) cmdq_continue(cdata->item); - args_command_free(cdata->state); + cmd_parse_free(cdata->tree); free(cdata); } @@ -305,9 +305,9 @@ static int cmd_display_panes_key(struct client *c, void *data, struct key_event *event) { struct cmd_display_panes_data *cdata = data; - char *expanded, *error; + char *expanded; + struct cmd_invoke_input ci = { 0 }; struct cmdq_item *item = cdata->item, *new_item; - struct cmdq_state *cs = NULL; struct window *w = c->session->curw->window; struct window_pane *wp; u_int index; @@ -330,20 +330,14 @@ cmd_display_panes_key(struct client *c, void *data, struct key_event *event) window_unzoom(w, 1); xasprintf(&expanded, "%%%u", wp->id); + ci.argc = 1; + ci.argv = &expanded; - if (item != NULL) - cs = cmdq_get_state(item); - new_item = args_command_get(cdata->state, 1, &expanded, cs, - &error); - if (new_item == NULL) { - cmdq_append(c, cmdq_get_error(error)); - free(error); - } else { - if (item == NULL) - cmdq_append(c, new_item); - else - cmdq_insert_after(item, new_item); - } + new_item = cmd_invoke_get(cdata->tree, cmdq_get_state(item), &ci); + if (item == NULL) + cmdq_append(c, new_item); + else + cmdq_insert_after(item, new_item); free(expanded); return (1); @@ -363,21 +357,28 @@ cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item) if (tc->overlay_draw != NULL) return (CMD_RETURN_NORMAL); - if (args_has(args, 'd')) { + if (!args_has(args, 'd')) + delay = options_get_number(s->options, "display-panes-time"); + else { delay = args_strtonum(args, 'd', 0, UINT_MAX, &cause); if (cause != NULL) { cmdq_error(item, "delay %s", cause); free(cause); return (CMD_RETURN_ERROR); } - } else - delay = options_get_number(s->options, "display-panes-time"); + } cdata = xcalloc(1, sizeof *cdata); if (wait) cdata->item = item; - cdata->state = args_command_prepare(self, item, 0, - "select-pane -t \"%%%\"", 0); + cdata->tree = args_to_commands(self, item, 0, "select-pane -t \"%%%\"", + 0, &cause); + if (cdata->tree == NULL) { + cmdq_error(item, "%s", cause); + free(cause); + free(cdata); + return (CMD_RETURN_ERROR); + } if (args_has(args, 'N')) { server_client_set_overlay(tc, delay, NULL, NULL, diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 3cd9829ad..216bca55b 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -53,11 +53,11 @@ const struct cmd_entry cmd_if_shell_entry = { }; struct cmd_if_shell_data { - struct args_command_state *cmd_if; - struct args_command_state *cmd_else; + struct cmd_parse_tree *cmd_if; + struct cmd_parse_tree *cmd_else; - struct client *client; - struct cmdq_item *item; + struct client *client; + struct cmdq_item *item; }; static enum args_parse_type @@ -76,42 +76,58 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *target = cmdq_get_target(item); struct cmd_if_shell_data *cdata; struct cmdq_item *new_item; - char *shellcmd; + struct cmd_parse_tree *tree; + char *shellcmd, *cause = NULL; struct client *tc = cmdq_get_target_client(item); struct session *s = target->s; - u_int count = args_count(args); + u_int count = args_count(args), idx; int wait = !args_has(args, 'b'); shellcmd = format_single_from_target(item, args_string(args, 0)); if (args_has(args, 'F')) { if (*shellcmd != '0' && *shellcmd != '\0') - new_item = args_command_now(self, item, 1, 0); + idx = 1; else if (count == 3) - new_item = args_command_now(self, item, 2, 0); + idx = 2; else { free(shellcmd); return (CMD_RETURN_NORMAL); } free(shellcmd); - if (new_item == NULL) + + tree = args_to_commands(self, item, idx, NULL, 0, &cause); + if (tree == NULL) { + cmdq_error(item, "%s", cause); + free(cause); return (CMD_RETURN_ERROR); + } + new_item = cmd_invoke_get(tree, cmdq_get_state(item), NULL); + cmd_parse_free(tree); cmdq_insert_after(item, new_item); return (CMD_RETURN_NORMAL); } cdata = xcalloc(1, sizeof *cdata); - - cdata->cmd_if = args_command_prepare(self, item, 1, NULL, 0); + cdata->cmd_if = args_to_commands(self, item, 1, NULL, 0, &cause); + if (cdata->cmd_if == NULL) { + cmdq_error(item, "%s", cause); + goto fail; + } if (count == 3) { - cdata->cmd_else = args_command_prepare(self, item, 2, - NULL, 0); + cdata->cmd_else = args_to_commands(self, item, 2, NULL, 0, + &cause); + if (cdata->cmd_else == NULL) { + cmdq_error(item, "%s", cause); + goto fail; + } } - if (wait) { + if (!wait) + cdata->client = tc; + else { cdata->client = cmdq_get_client(item); cdata->item = item; - } else - cdata->client = tc; + } if (cdata->client != NULL) cdata->client->references++; @@ -120,15 +136,19 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) cmd_if_shell_callback, cmd_if_shell_free, cdata, 0, -1, -1) == NULL) { cmdq_error(item, "failed to run command: %s", shellcmd); - free(shellcmd); - cmd_if_shell_free(cdata); - return (CMD_RETURN_ERROR); + goto fail; } free(shellcmd); if (!wait) return (CMD_RETURN_NORMAL); return (CMD_RETURN_WAIT); + +fail: + free(cause); + free(shellcmd); + cmd_if_shell_free(cdata); + return (CMD_RETURN_ERROR); } static void @@ -137,35 +157,23 @@ cmd_if_shell_callback(struct job *job) struct cmd_if_shell_data *cdata = job_get_data(job); struct client *c = cdata->client; struct cmdq_item *item = cdata->item, *new_item; - struct cmdq_state *cs = NULL; - struct args_command_state *state; - char *error; + struct cmd_parse_tree *tree; int status; status = job_get_status(job); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - state = cdata->cmd_else; + tree = cdata->cmd_else; else - state = cdata->cmd_if; - if (state == NULL) + tree = cdata->cmd_if; + if (tree == NULL) goto out; - if (item != NULL) - cs = cmdq_get_state(item); - new_item = args_command_get(state, 0, NULL, cs, &error); - if (new_item == NULL) { - if (cdata->item != NULL) - cmdq_error(cdata->item, "%s", error); - else { - *error = toupper((u_char)*error); - status_message_set(c, -1, 1, 0, 0, "%s", error); - } - free(error); + if (item == NULL) { + new_item = cmd_invoke_get(tree, NULL, NULL); + cmdq_append(c, new_item); } else { - if (item == NULL) - cmdq_append(c, new_item); - else - cmdq_insert_after(item, new_item); + new_item = cmd_invoke_get(tree, cmdq_get_state(item), NULL); + cmdq_insert_after(item, new_item); } out: @@ -182,8 +190,8 @@ cmd_if_shell_free(void *data) server_client_unref(cdata->client); if (cdata->cmd_else != NULL) - args_command_free(cdata->cmd_else); - args_command_free(cdata->cmd_if); - + cmd_parse_free(cdata->cmd_else); + if (cdata->cmd_if != NULL) + cmd_parse_free(cdata->cmd_if); free(cdata); } diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 547c44b95..e8328278e 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -55,15 +55,15 @@ const struct cmd_entry cmd_run_shell_entry = { }; struct cmd_run_shell_data { - struct client *client; - char *cmd; - struct args_command_state *state; - char *cwd; - struct cmdq_item *item; - struct session *s; - int wp_id; - struct event timer; - int flags; + struct client *client; + char *cmd; + struct cmd_parse_tree *tree; + char *cwd; + struct cmdq_item *item; + struct session *s; + int wp_id; + struct event timer; + int flags; }; static enum args_parse_type @@ -118,7 +118,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) struct format_tree *ft; double d; struct timeval tv; - char *end, key[16]; + char *end, key[16], *cause = NULL; u_int i; int wait = !args_has(args, 'b'); @@ -128,8 +128,10 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "invalid delay time: %s", delay); return (CMD_RETURN_ERROR); } - } else if (args_count(args) == 0) - return (CMD_RETURN_NORMAL); + } else { + if (args_count(args) == 0) + return (CMD_RETURN_NORMAL); + } cdata = xcalloc(1, sizeof *cdata); if (!args_has(args, 'C')) { @@ -144,8 +146,13 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) format_free(ft); } } else { - cdata->state = args_command_prepare(self, item, 0, NULL, - 1); + cdata->tree = args_to_commands(self, item, 0, NULL, 1, &cause); + if (cdata->tree == NULL) { + cmdq_error(item, "%s", cause); + free(cause); + cmd_run_shell_free(cdata); + return (CMD_RETURN_ERROR); + } } if (args_has(args, 't') && wp != NULL) @@ -162,6 +169,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) } if (cdata->client != NULL) cdata->client->references++; + if (args_has(args, 'c')) cdata->cwd = xstrdup(args_get(args, 'c')); else @@ -170,18 +178,20 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'E')) cdata->flags |= JOB_SHOWSTDERR; - cdata->s = s; - if (s != NULL) + if (s != NULL) { + cdata->s = s; session_add_ref(s, __func__); + } evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata); - if (delay != NULL) { + if (delay == NULL) + event_active(&cdata->timer, EV_TIMEOUT, 1); + else { timerclear(&tv); tv.tv_sec = (time_t)d; tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U; evtimer_add(&cdata->timer, &tv); - } else - event_active(&cdata->timer, EV_TIMEOUT, 1); + } if (!wait) return (CMD_RETURN_NORMAL); @@ -196,9 +206,8 @@ cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) const char *cmd = cdata->cmd; struct cmdq_item *item = cdata->item, *new_item; struct cmdq_state *cs = NULL; - char *error; - if (cdata->state == NULL) { + if (cdata->tree == NULL) { if (cmd == NULL) { if (cdata->item != NULL) cmdq_continue(cdata->item); @@ -223,21 +232,11 @@ cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) if (item != NULL) cs = cmdq_get_state(item); - new_item = args_command_get(cdata->state, 0, NULL, cs, &error); - if (new_item == NULL) { - if (cdata->item != NULL) - cmdq_error(cdata->item, "%s", error); - else { - *error = toupper((u_char)*error); - status_message_set(c, -1, 1, 0, 0, "%s", error); - } - free(error); - } else { - if (item == NULL) - cmdq_append(c, new_item); - else - cmdq_insert_after(item, new_item); - } + new_item = cmd_invoke_get(cdata->tree, cs, NULL); + if (item == NULL) + cmdq_append(c, new_item); + else + cmdq_insert_after(item, new_item); if (cdata->item != NULL) cmdq_continue(cdata->item); @@ -305,8 +304,7 @@ cmd_run_shell_free(void *data) session_remove_ref(cdata->s, __func__); if (cdata->client != NULL) server_client_unref(cdata->client); - if (cdata->state != NULL) - args_command_free(cdata->state); + cmd_parse_free(cdata->tree); free(cdata->cwd); free(cdata->cmd); free(cdata); diff --git a/tmux.h b/tmux.h index dd2dd60c0..bffda3a44 100644 --- a/tmux.h +++ b/tmux.h @@ -40,7 +40,6 @@ extern char **environ; struct args; -struct args_command_state; struct client; struct cmd; struct cmd_find_state; @@ -2898,14 +2897,8 @@ u_int args_count(struct args *); struct args_value *args_values(struct args *); struct args_value *args_value(struct args *, u_int); const char *args_string(struct args *, u_int); -struct cmdq_item *args_command_now(struct cmd *, struct cmdq_item *, - u_int, int); -struct args_command_state *args_command_prepare(struct cmd *, - struct cmdq_item *, u_int, const char *, int); -struct cmdq_item *args_command_get(struct args_command_state *, int, char **, - struct cmdq_state *, char **); -void args_command_free(struct args_command_state *); -char *args_command_get_command(struct args_command_state *); +struct cmd_parse_tree *args_to_commands(struct cmd *, struct cmdq_item *, + u_int, const char *, int, char **); struct args_value *args_first_value(struct args *, u_char); struct args_value *args_next_value(struct args_value *); long long args_strtonum(struct args *, u_char, long long, long long,