diff options
author | nicm <nicm> | 2021-08-23 12:33:55 +0000 |
---|---|---|
committer | nicm <nicm> | 2021-08-23 12:33:55 +0000 |
commit | 210e71edf36198e3f22525e7f548a71a5681d25c (patch) | |
tree | 26ab4eab3dcd9bc89970b9c193085e44a3b10a4c /cmd-command-prompt.c | |
parent | 03b83a5a34a4257be9029e1f5195dcddcd531caa (diff) | |
download | rtmux-210e71edf36198e3f22525e7f548a71a5681d25c.tar.gz rtmux-210e71edf36198e3f22525e7f548a71a5681d25c.tar.bz2 rtmux-210e71edf36198e3f22525e7f548a71a5681d25c.zip |
Move command argument parsing common functions and don't bother to parse
again if given a command rather than a string.
Diffstat (limited to 'cmd-command-prompt.c')
-rw-r--r-- | cmd-command-prompt.c | 182 |
1 files changed, 88 insertions, 94 deletions
diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index f80760ce..a877897e 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -48,21 +48,24 @@ const struct cmd_entry cmd_command_prompt_entry = { .exec = cmd_command_prompt_exec }; -struct cmd_command_prompt_cdata { - struct cmdq_item *item; - struct cmd_parse_input pi; +struct cmd_command_prompt_prompt { + char *input; + char *prompt; +}; - int flags; - enum prompt_type prompt_type; +struct cmd_command_prompt_cdata { + struct cmdq_item *item; + struct args_command_state *state; - char *inputs; - char *next_input; + int flags; + enum prompt_type prompt_type; - char *prompts; - char *next_prompt; + struct cmd_command_prompt_prompt *prompts; + u_int count; + u_int current; - char *template; - int idx; + int argc; + char **argv; }; static enum cmd_retval @@ -71,12 +74,12 @@ 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 *inputs, *prompts, *type, *s; + const char *type, *s, *input; struct cmd_command_prompt_cdata *cdata; - char *prompt, *comma, *input = NULL; + char *tmp, *prompts, *prompt, *next_prompt; + char *inputs, *next_input; u_int count = args_count(args); - size_t n; - int wait = !args_has(args, 'b'); + int wait = !args_has(args, 'b'), space = 1; if (tc->prompt_string != NULL) return (CMD_RETURN_NORMAL); @@ -84,50 +87,49 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) wait = 0; cdata = xcalloc(1, sizeof *cdata); - cdata->idx = 1; - - cmd_get_source(self, &cdata->pi.file, &cdata->pi.line); - if (wait) - cdata->pi.item = item; - cdata->pi.c = tc; - cmd_find_copy_state(&cdata->pi.fs, target); - if (wait) cdata->item = item; - - if (count != 0) { - s = args_string(args, 0); - if (args_has(args, 'F')) - cdata->template = format_single_from_target(item, s); - else - cdata->template = xstrdup(s); - } else - cdata->template = xstrdup("%1"); - - if ((prompts = args_get(args, 'p')) != NULL) - cdata->prompts = xstrdup(prompts); - else if (count != 0) { - n = strcspn(cdata->template, " ,"); - xasprintf(&cdata->prompts, "(%.*s) ", (int)n, cdata->template); + cdata->state = args_make_commands_prepare(self, item, 0, "%1", wait, + args_has(args, 'F')); + + if ((s = args_get(args, 'p')) == NULL) { + if (count != 0) { + tmp = args_make_commands_get_command(cdata->state); + xasprintf(&prompts, "(%s)", tmp); + free(tmp); + } else { + prompts = xstrdup(":"); + space = 0; + } + next_prompt = prompts; } else - cdata->prompts = xstrdup(":"); - - /* Get first prompt. */ - cdata->next_prompt = cdata->prompts; - comma = strsep(&cdata->next_prompt, ","); - if (prompts == NULL) - prompt = xstrdup(comma); + next_prompt = prompts = xstrdup (s); + if ((s = args_get(args, 'I')) != NULL) + next_input = inputs = xstrdup(s); else - xasprintf(&prompt, "%s ", comma); - - /* Get initial prompt input. */ - if ((inputs = args_get(args, 'I')) != NULL) { - cdata->inputs = xstrdup(inputs); - cdata->next_input = cdata->inputs; - input = strsep(&cdata->next_input, ","); + next_input = NULL; + while ((prompt = strsep(&next_prompt, ",")) != NULL) { + cdata->prompts = xreallocarray(cdata->prompts, cdata->count + 1, + sizeof *cdata->prompts); + if (!space) + tmp = xstrdup(prompt); + else + xasprintf(&tmp, "%s ", prompt); + cdata->prompts[cdata->count].prompt = tmp; + + if (next_input != NULL) { + input = strsep(&next_input, ","); + if (input == NULL) + input = ""; + } else + input = ""; + cdata->prompts[cdata->count].input = xstrdup(input); + + cdata->count++; } + free(inputs); + free(prompts); - /* Get prompt type. */ if ((type = args_get(args, 'T')) != NULL) { cdata->prompt_type = status_prompt_type(type); if (cdata->prompt_type == PROMPT_TYPE_INVALID) { @@ -145,10 +147,9 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) cdata->flags |= PROMPT_INCREMENTAL; else if (args_has(args, 'k')) cdata->flags |= PROMPT_KEY; - status_prompt_set(tc, target, prompt, input, - cmd_command_prompt_callback, cmd_command_prompt_free, cdata, - cdata->flags, cdata->prompt_type); - free(prompt); + status_prompt_set(tc, target, cdata->prompts[0].prompt, + cdata->prompts[0].input, cmd_command_prompt_callback, + cmd_command_prompt_free, cdata, cdata->flags, cdata->prompt_type); if (!wait) return (CMD_RETURN_NORMAL); @@ -159,51 +160,39 @@ static int cmd_command_prompt_callback(struct client *c, void *data, const char *s, int done) { - struct cmd_command_prompt_cdata *cdata = data; - char *new_template, *prompt, *comma, *error; - char *input = NULL; - struct cmdq_item *item = cdata->item; - enum cmd_parse_status status; + struct cmd_command_prompt_cdata *cdata = data; + char *error; + struct cmdq_item *item = cdata->item, *new_item; + struct cmd_list *cmdlist; + struct cmd_command_prompt_prompt *prompt; if (s == NULL) goto out; - if (done && (cdata->flags & PROMPT_INCREMENTAL)) - goto out; - - new_template = cmd_template_replace(cdata->template, s, cdata->idx); if (done) { - free(cdata->template); - cdata->template = new_template; - } - - /* - * Check if there are more prompts; if so, get its respective input - * and update the prompt data. - */ - if (done && (comma = strsep(&cdata->next_prompt, ",")) != NULL) { - xasprintf(&prompt, "%s ", comma); - input = strsep(&cdata->next_input, ","); - status_prompt_update(c, prompt, input); - - free(prompt); - cdata->idx++; - return (1); + 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]; + status_prompt_update(c, prompt->prompt, prompt->input); + return (1); + } } - if (item != NULL) { - status = cmd_parse_and_insert(new_template, &cdata->pi, item, - cmdq_get_state(item), &error); - } else { - status = cmd_parse_and_append(new_template, &cdata->pi, c, NULL, - &error); - } - if (status == CMD_PARSE_ERROR) { + cmdlist = args_make_commands(cdata->state, cdata->argc, cdata->argv, + &error); + if (cmdlist == NULL) { cmdq_append(c, cmdq_get_error(error)); free(error); + } else if (item == NULL) { + new_item = cmdq_get_command(cmdlist, NULL); + cmdq_append(c, new_item); + } else { + new_item = cmdq_get_command(cmdlist, cmdq_get_state(item)); + cmdq_insert_after(item, new_item); } - if (!done) - free(new_template); if (c->prompt_inputcb != cmd_command_prompt_callback) return (1); @@ -217,9 +206,14 @@ static void cmd_command_prompt_free(void *data) { struct cmd_command_prompt_cdata *cdata = data; + u_int i; - free(cdata->inputs); + for (i = 0; i < cdata->count; i++) { + free(cdata->prompts[i].prompt); + free(cdata->prompts[i].input); + } free(cdata->prompts); - free(cdata->template); + cmd_free_argv(cdata->argc, cdata->argv); + args_make_commands_free(cdata->state); free(cdata); } |