Annotation of embedaddon/tmux/cmd-command-prompt.c, revision 1.1
1.1 ! misho 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
! 15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
! 16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: #include <sys/types.h>
! 20:
! 21: #include <ctype.h>
! 22: #include <stdlib.h>
! 23: #include <string.h>
! 24: #include <time.h>
! 25:
! 26: #include "tmux.h"
! 27:
! 28: /*
! 29: * Prompt for command in client.
! 30: */
! 31:
! 32: static enum cmd_retval cmd_command_prompt_exec(struct cmd *,
! 33: struct cmdq_item *);
! 34:
! 35: static int cmd_command_prompt_callback(void *, const char *, int);
! 36: static void cmd_command_prompt_free(void *);
! 37:
! 38: const struct cmd_entry cmd_command_prompt_entry = {
! 39: .name = "command-prompt",
! 40: .alias = NULL,
! 41:
! 42: .args = { "1iI:Np:t:", 0, 1 },
! 43: .usage = "[-1Ni] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
! 44: "[template]",
! 45:
! 46: .tflag = CMD_CLIENT,
! 47:
! 48: .flags = 0,
! 49: .exec = cmd_command_prompt_exec
! 50: };
! 51:
! 52: struct cmd_command_prompt_cdata {
! 53: struct client *c;
! 54: int flags;
! 55:
! 56: char *inputs;
! 57: char *next_input;
! 58:
! 59: char *prompts;
! 60: char *next_prompt;
! 61:
! 62: char *template;
! 63: int idx;
! 64: };
! 65:
! 66: static enum cmd_retval
! 67: cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
! 68: {
! 69: struct args *args = self->args;
! 70: const char *inputs, *prompts;
! 71: struct cmd_command_prompt_cdata *cdata;
! 72: struct client *c = item->state.c;
! 73: char *prompt, *ptr, *input = NULL;
! 74: size_t n;
! 75:
! 76: if (c->prompt_string != NULL)
! 77: return (CMD_RETURN_NORMAL);
! 78:
! 79: cdata = xcalloc(1, sizeof *cdata);
! 80: cdata->c = c;
! 81:
! 82: cdata->inputs = NULL;
! 83: cdata->next_input = NULL;
! 84:
! 85: cdata->prompts = NULL;
! 86: cdata->next_prompt = NULL;
! 87:
! 88: cdata->template = NULL;
! 89: cdata->idx = 1;
! 90:
! 91: if (args->argc != 0)
! 92: cdata->template = xstrdup(args->argv[0]);
! 93: else
! 94: cdata->template = xstrdup("%1");
! 95:
! 96: if ((prompts = args_get(args, 'p')) != NULL)
! 97: cdata->prompts = xstrdup(prompts);
! 98: else if (args->argc != 0) {
! 99: n = strcspn(cdata->template, " ,");
! 100: xasprintf(&cdata->prompts, "(%.*s) ", (int) n, cdata->template);
! 101: } else
! 102: cdata->prompts = xstrdup(":");
! 103:
! 104: /* Get first prompt. */
! 105: cdata->next_prompt = cdata->prompts;
! 106: ptr = strsep(&cdata->next_prompt, ",");
! 107: if (prompts == NULL)
! 108: prompt = xstrdup(ptr);
! 109: else
! 110: xasprintf(&prompt, "%s ", ptr);
! 111:
! 112: /* Get initial prompt input. */
! 113: if ((inputs = args_get(args, 'I')) != NULL) {
! 114: cdata->inputs = xstrdup(inputs);
! 115: cdata->next_input = cdata->inputs;
! 116: input = strsep(&cdata->next_input, ",");
! 117: }
! 118:
! 119: if (args_has(args, '1'))
! 120: cdata->flags |= PROMPT_SINGLE;
! 121: else if (args_has(args, 'N'))
! 122: cdata->flags |= PROMPT_NUMERIC;
! 123: else if (args_has(args, 'i'))
! 124: cdata->flags |= PROMPT_INCREMENTAL;
! 125: status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
! 126: cmd_command_prompt_free, cdata, cdata->flags);
! 127: free(prompt);
! 128:
! 129: return (CMD_RETURN_NORMAL);
! 130: }
! 131:
! 132: static enum cmd_retval
! 133: cmd_command_prompt_error(struct cmdq_item *item, void *data)
! 134: {
! 135: char *error = data;
! 136:
! 137: cmdq_error(item, "%s", error);
! 138: free(error);
! 139:
! 140: return (CMD_RETURN_NORMAL);
! 141: }
! 142:
! 143: static int
! 144: cmd_command_prompt_callback(void *data, const char *s, int done)
! 145: {
! 146: struct cmd_command_prompt_cdata *cdata = data;
! 147: struct client *c = cdata->c;
! 148: struct cmd_list *cmdlist;
! 149: struct cmdq_item *new_item;
! 150: char *cause, *new_template, *prompt, *ptr;
! 151: char *input = NULL;
! 152:
! 153: if (s == NULL)
! 154: return (0);
! 155: if (done && (cdata->flags & PROMPT_INCREMENTAL))
! 156: return (0);
! 157:
! 158: new_template = cmd_template_replace(cdata->template, s, cdata->idx);
! 159: if (done) {
! 160: free(cdata->template);
! 161: cdata->template = new_template;
! 162: }
! 163:
! 164: /*
! 165: * Check if there are more prompts; if so, get its respective input
! 166: * and update the prompt data.
! 167: */
! 168: if (done && (ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
! 169: xasprintf(&prompt, "%s ", ptr);
! 170: input = strsep(&cdata->next_input, ",");
! 171: status_prompt_update(c, prompt, input);
! 172:
! 173: free(prompt);
! 174: cdata->idx++;
! 175: return (1);
! 176: }
! 177:
! 178: cmdlist = cmd_string_parse(new_template, NULL, 0, &cause);
! 179: if (cmdlist == NULL) {
! 180: if (cause != NULL) {
! 181: new_item = cmdq_get_callback(cmd_command_prompt_error,
! 182: cause);
! 183: } else
! 184: new_item = NULL;
! 185: } else {
! 186: new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
! 187: cmd_list_free(cmdlist);
! 188: }
! 189:
! 190: if (new_item != NULL)
! 191: cmdq_append(c, new_item);
! 192:
! 193: if (!done)
! 194: free(new_template);
! 195: if (c->prompt_callbackfn != (void *)&cmd_command_prompt_callback)
! 196: return (1);
! 197: return (0);
! 198: }
! 199:
! 200: static void
! 201: cmd_command_prompt_free(void *data)
! 202: {
! 203: struct cmd_command_prompt_cdata *cdata = data;
! 204:
! 205: free(cdata->inputs);
! 206: free(cdata->prompts);
! 207: free(cdata->template);
! 208: free(cdata);
! 209: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>