Annotation of src/usr.bin/tmux/cmd-list.c, Revision 1.6
1.6 ! nicm 1: /* $OpenBSD: cmd-list.c,v 1.5 2010/06/26 18:20:53 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
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 <string.h>
22:
23: #include "tmux.h"
24:
25: struct cmd_list *
26: cmd_list_parse(int argc, char **argv, char **cause)
27: {
28: struct cmd_list *cmdlist;
29: struct cmd *cmd;
30: int i, lastsplit;
31: size_t arglen, new_argc;
1.6 ! nicm 32: char **copy_argv, **new_argv;
! 33:
! 34: copy_argv = cmd_copy_argv(argc, argv);
1.1 nicm 35:
36: cmdlist = xmalloc(sizeof *cmdlist);
1.5 nicm 37: cmdlist->references = 1;
38: TAILQ_INIT(&cmdlist->list);
1.1 nicm 39:
40: lastsplit = 0;
41: for (i = 0; i < argc; i++) {
1.6 ! nicm 42: arglen = strlen(copy_argv[i]);
! 43: if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
1.1 nicm 44: continue;
1.6 ! nicm 45: copy_argv[i][arglen - 1] = '\0';
1.1 nicm 46:
1.6 ! nicm 47: if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
! 48: copy_argv[i][arglen - 2] = ';';
1.1 nicm 49: continue;
50: }
51:
52: new_argc = i - lastsplit;
1.6 ! nicm 53: new_argv = copy_argv + lastsplit;
1.1 nicm 54: if (arglen != 1)
55: new_argc++;
56:
57: cmd = cmd_parse(new_argc, new_argv, cause);
58: if (cmd == NULL)
59: goto bad;
1.5 nicm 60: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
1.1 nicm 61:
62: lastsplit = i + 1;
63: }
64:
65: if (lastsplit != argc) {
1.6 ! nicm 66: cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit, cause);
1.1 nicm 67: if (cmd == NULL)
68: goto bad;
1.5 nicm 69: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
1.1 nicm 70: }
71:
1.6 ! nicm 72: cmd_free_argv(argc, copy_argv);
1.1 nicm 73: return (cmdlist);
74:
75: bad:
76: cmd_list_free(cmdlist);
1.6 ! nicm 77: cmd_free_argv(argc, copy_argv);
1.1 nicm 78: return (NULL);
79: }
80:
81: int
82: cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
83: {
84: struct cmd *cmd;
1.3 nicm 85: int n, retval;
1.1 nicm 86:
1.3 nicm 87: retval = 0;
1.5 nicm 88: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.3 nicm 89: if ((n = cmd_exec(cmd, ctx)) == -1)
90: return (-1);
91:
92: /*
93: * A 1 return value means the command client is being attached
94: * (sent MSG_READY).
95: */
96: if (n == 1) {
97: retval = 1;
98:
99: /*
100: * The command client has been attached, so mangle the
101: * context to treat any following commands as if they
102: * were called from inside.
103: */
104: if (ctx->curclient == NULL) {
105: ctx->curclient = ctx->cmdclient;
106: ctx->cmdclient = NULL;
1.4 nicm 107:
108: ctx->error = key_bindings_error;
109: ctx->print = key_bindings_print;
110: ctx->info = key_bindings_info;
1.3 nicm 111: }
112: }
1.1 nicm 113: }
1.3 nicm 114: return (retval);
1.1 nicm 115: }
116:
117: void
118: cmd_list_free(struct cmd_list *cmdlist)
119: {
120: struct cmd *cmd;
121:
1.5 nicm 122: if (--cmdlist->references != 0)
123: return;
124:
125: while (!TAILQ_EMPTY(&cmdlist->list)) {
126: cmd = TAILQ_FIRST(&cmdlist->list);
127: TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
1.1 nicm 128: cmd_free(cmd);
129: }
130: xfree(cmdlist);
131: }
132:
133: size_t
134: cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
135: {
136: struct cmd *cmd;
137: size_t off;
138:
139: off = 0;
1.5 nicm 140: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.1 nicm 141: if (off >= len)
142: break;
143: off += cmd_print(cmd, buf + off, len - off);
144: if (off >= len)
145: break;
146: if (TAILQ_NEXT(cmd, qentry) != NULL)
147: off += xsnprintf(buf + off, len - off, " ; ");
148: }
149: return (off);
150: }