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