Put "or" on new line from command with .Ic.
[tmux-openbsd.git] / cmd-list.c
blob181127ae404b189cbf3af0b5723062ce0fc14a51
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
21 #include <string.h>
23 #include "tmux.h"
25 struct cmd_list *
26 cmd_list_parse(int argc, char **argv, char **cause)
28 struct cmd_list *cmdlist;
29 struct cmd *cmd;
30 int i, lastsplit;
31 size_t arglen, new_argc;
32 char **new_argv;
34 cmdlist = xmalloc(sizeof *cmdlist);
35 cmdlist->references = 1;
36 TAILQ_INIT(&cmdlist->list);
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';
45 if (arglen > 1 && argv[i][arglen - 2] == '\\') {
46 argv[i][arglen - 2] = ';';
47 continue;
50 new_argc = i - lastsplit;
51 new_argv = argv + lastsplit;
52 if (arglen != 1)
53 new_argc++;
55 cmd = cmd_parse(new_argc, new_argv, cause);
56 if (cmd == NULL)
57 goto bad;
58 TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
60 lastsplit = i + 1;
63 if (lastsplit != argc) {
64 cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
65 if (cmd == NULL)
66 goto bad;
67 TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
70 return (cmdlist);
72 bad:
73 cmd_list_free(cmdlist);
74 return (NULL);
77 int
78 cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
80 struct cmd *cmd;
81 int n, retval;
83 retval = 0;
84 TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
85 if ((n = cmd_exec(cmd, ctx)) == -1)
86 return (-1);
89 * A 1 return value means the command client is being attached
90 * (sent MSG_READY).
92 if (n == 1) {
93 retval = 1;
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.
100 if (ctx->curclient == NULL) {
101 ctx->curclient = ctx->cmdclient;
102 ctx->cmdclient = NULL;
104 ctx->error = key_bindings_error;
105 ctx->print = key_bindings_print;
106 ctx->info = key_bindings_info;
110 return (retval);
113 void
114 cmd_list_free(struct cmd_list *cmdlist)
116 struct cmd *cmd;
118 if (--cmdlist->references != 0)
119 return;
121 while (!TAILQ_EMPTY(&cmdlist->list)) {
122 cmd = TAILQ_FIRST(&cmdlist->list);
123 TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
124 cmd_free(cmd);
126 xfree(cmdlist);
129 size_t
130 cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
132 struct cmd *cmd;
133 size_t off;
135 off = 0;
136 TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
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, " ; ");
145 return (off);