Annotation of src/usr.bin/tmux/cmd-list.c, Revision 1.10
1.10 ! nicm 1: /* $OpenBSD: cmd-list.c,v 1.9 2012/07/11 07:10:15 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:
1.9 nicm 82: enum cmd_retval
1.1 nicm 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.9 nicm 87: enum cmd_retval retval;
88: int guards, n;
1.7 nicm 89:
90: guards = 0;
91: if (c != NULL && c->session != NULL)
92: guards = c->flags & CLIENT_CONTROL;
1.1 nicm 93:
1.10 ! nicm 94: notify_disable();
! 95:
1.3 nicm 96: retval = 0;
1.5 nicm 97: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.7 nicm 98: if (guards)
99: ctx->print(ctx, "%%begin");
100: n = cmd_exec(cmd, ctx);
101: if (guards)
102: ctx->print(ctx, "%%end");
103:
1.9 nicm 104: switch (n)
105: {
106: case CMD_RETURN_ERROR:
107: return (CMD_RETURN_ERROR);
108: case CMD_RETURN_ATTACH:
109: /* Client is being attached (send MSG_READY). */
110: retval = CMD_RETURN_ATTACH;
1.3 nicm 111:
112: /*
1.9 nicm 113: * Mangle the context to treat any following commands
114: * as if they were called from inside.
1.3 nicm 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: }
1.9 nicm 124: break;
125: case CMD_RETURN_YIELD:
126: if (retval == CMD_RETURN_NORMAL)
127: retval = CMD_RETURN_YIELD;
128: break;
129: case CMD_RETURN_NORMAL:
130: break;
1.3 nicm 131: }
1.1 nicm 132: }
1.10 ! nicm 133:
! 134: notify_enable();
1.3 nicm 135: return (retval);
1.1 nicm 136: }
137:
138: void
139: cmd_list_free(struct cmd_list *cmdlist)
140: {
141: struct cmd *cmd;
142:
1.5 nicm 143: if (--cmdlist->references != 0)
144: return;
145:
146: while (!TAILQ_EMPTY(&cmdlist->list)) {
147: cmd = TAILQ_FIRST(&cmdlist->list);
148: TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
1.1 nicm 149: cmd_free(cmd);
150: }
1.8 nicm 151: free(cmdlist);
1.1 nicm 152: }
153:
154: size_t
155: cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
156: {
157: struct cmd *cmd;
158: size_t off;
159:
160: off = 0;
1.5 nicm 161: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.1 nicm 162: if (off >= len)
163: break;
164: off += cmd_print(cmd, buf + off, len - off);
165: if (off >= len)
166: break;
167: if (TAILQ_NEXT(cmd, qentry) != NULL)
168: off += xsnprintf(buf + off, len - off, " ; ");
169: }
170: return (off);
171: }