File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / tmux / cmd-command-prompt.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:22:44 2017 UTC (6 years, 11 months ago) by misho
Branches: tmux, MAIN
CVS tags: v2_4p0, v2_4, HEAD
tmux 2.4

    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>