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