Accept multiple parameters to SM/RM/DECSET/DECRST, based on a diff from
[tmux-openbsd.git] / cmd-list.c
blob82ae7480c25c0329ef0662892d455df34806fc53
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 <stdlib.h>
22 #include <string.h>
24 #include "tmux.h"
26 struct cmd_list *
27 cmd_list_parse(int argc, char **argv, const char* file, u_int line,
28 char **cause)
30 struct cmd_list *cmdlist;
31 struct cmd *cmd;
32 int i, lastsplit;
33 size_t arglen, new_argc;
34 char **copy_argv, **new_argv;
36 copy_argv = cmd_copy_argv(argc, argv);
38 cmdlist = xcalloc(1, sizeof *cmdlist);
39 cmdlist->references = 1;
40 TAILQ_INIT(&cmdlist->list);
42 lastsplit = 0;
43 for (i = 0; i < argc; i++) {
44 arglen = strlen(copy_argv[i]);
45 if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
46 continue;
47 copy_argv[i][arglen - 1] = '\0';
49 if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
50 copy_argv[i][arglen - 2] = ';';
51 continue;
54 new_argc = i - lastsplit;
55 new_argv = copy_argv + lastsplit;
56 if (arglen != 1)
57 new_argc++;
59 cmd = cmd_parse(new_argc, new_argv, file, line, cause);
60 if (cmd == NULL)
61 goto bad;
62 TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
64 lastsplit = i + 1;
67 if (lastsplit != argc) {
68 cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit,
69 file, line, cause);
70 if (cmd == NULL)
71 goto bad;
72 TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
75 cmd_free_argv(argc, copy_argv);
76 return (cmdlist);
78 bad:
79 cmd_list_free(cmdlist);
80 cmd_free_argv(argc, copy_argv);
81 return (NULL);
84 void
85 cmd_list_free(struct cmd_list *cmdlist)
87 struct cmd *cmd, *cmd1;
89 if (--cmdlist->references != 0)
90 return;
92 TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) {
93 TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
94 args_free(cmd->args);
95 free(cmd->file);
96 free(cmd);
99 free(cmdlist);
102 size_t
103 cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
105 struct cmd *cmd;
106 size_t off;
108 off = 0;
109 TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
110 if (off >= len)
111 break;
112 off += cmd_print(cmd, buf + off, len - off);
113 if (off >= len)
114 break;
115 if (TAILQ_NEXT(cmd, qentry) != NULL)
116 off += xsnprintf(buf + off, len - off, " ; ");
118 return (off);