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