Annotation of src/usr.bin/tmux/cmd-list.c, Revision 1.7
1.7 ! nicm 1: /* $OpenBSD: cmd-list.c,v 1.6 2010/10/29 20:11:57 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: {
1.7 ! nicm 84: struct client *c = ctx->curclient;
1.1 nicm 85: struct cmd *cmd;
1.7 ! nicm 86: int n, retval, guards;
! 87:
! 88: guards = 0;
! 89: if (c != NULL && c->session != NULL)
! 90: guards = c->flags & CLIENT_CONTROL;
1.1 nicm 91:
1.3 nicm 92: retval = 0;
1.5 nicm 93: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.7 ! nicm 94: if (guards)
! 95: ctx->print(ctx, "%%begin");
! 96: n = cmd_exec(cmd, ctx);
! 97: if (guards)
! 98: ctx->print(ctx, "%%end");
! 99:
! 100: /* Return of -1 is an error. */
! 101: if (n == -1)
1.3 nicm 102: return (-1);
103:
104: /*
105: * A 1 return value means the command client is being attached
106: * (sent MSG_READY).
107: */
108: if (n == 1) {
109: retval = 1;
110:
111: /*
112: * The command client has been attached, so mangle the
113: * context to treat any following commands as if they
114: * were called from inside.
115: */
116: if (ctx->curclient == NULL) {
117: ctx->curclient = ctx->cmdclient;
118: ctx->cmdclient = NULL;
1.4 nicm 119:
120: ctx->error = key_bindings_error;
121: ctx->print = key_bindings_print;
122: ctx->info = key_bindings_info;
1.3 nicm 123: }
124: }
1.1 nicm 125: }
1.3 nicm 126: return (retval);
1.1 nicm 127: }
128:
129: void
130: cmd_list_free(struct cmd_list *cmdlist)
131: {
132: struct cmd *cmd;
133:
1.5 nicm 134: if (--cmdlist->references != 0)
135: return;
136:
137: while (!TAILQ_EMPTY(&cmdlist->list)) {
138: cmd = TAILQ_FIRST(&cmdlist->list);
139: TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
1.1 nicm 140: cmd_free(cmd);
141: }
142: xfree(cmdlist);
143: }
144:
145: size_t
146: cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
147: {
148: struct cmd *cmd;
149: size_t off;
150:
151: off = 0;
1.5 nicm 152: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.1 nicm 153: if (off >= len)
154: break;
155: off += cmd_print(cmd, buf + off, len - off);
156: if (off >= len)
157: break;
158: if (TAILQ_NEXT(cmd, qentry) != NULL)
159: off += xsnprintf(buf + off, len - off, " ; ");
160: }
161: return (off);
162: }