1: /* $OpenBSD$ */
2:
3: /*
4: * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
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 <stdlib.h>
22: #include <string.h>
23:
24: #include "tmux.h"
25:
26: struct cmd_list *
27: cmd_list_parse(int argc, char **argv, const char *file, u_int line,
28: char **cause)
29: {
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;
35:
36: copy_argv = cmd_copy_argv(argc, argv);
37:
38: cmdlist = xcalloc(1, sizeof *cmdlist);
39: cmdlist->references = 1;
40: TAILQ_INIT(&cmdlist->list);
41:
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';
48:
49: if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
50: copy_argv[i][arglen - 2] = ';';
51: continue;
52: }
53:
54: new_argc = i - lastsplit;
55: new_argv = copy_argv + lastsplit;
56: if (arglen != 1)
57: new_argc++;
58:
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);
63:
64: lastsplit = i + 1;
65: }
66:
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);
73: }
74:
75: cmd_free_argv(argc, copy_argv);
76: return (cmdlist);
77:
78: bad:
79: cmd_list_free(cmdlist);
80: cmd_free_argv(argc, copy_argv);
81: return (NULL);
82: }
83:
84: void
85: cmd_list_free(struct cmd_list *cmdlist)
86: {
87: struct cmd *cmd, *cmd1;
88:
89: if (--cmdlist->references != 0)
90: return;
91:
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);
97: }
98:
99: free(cmdlist);
100: }
101:
102: char *
103: cmd_list_print(struct cmd_list *cmdlist)
104: {
105: struct cmd *cmd;
106: char *buf, *this;
107: size_t len;
108:
109: len = 1;
110: buf = xcalloc(1, len);
111:
112: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
113: this = cmd_print(cmd);
114:
115: len += strlen(this) + 3;
116: buf = xrealloc(buf, len);
117:
118: strlcat(buf, this, len);
119: if (TAILQ_NEXT(cmd, qentry) != NULL)
120: strlcat(buf, " ; ", len);
121:
122: free(this);
123: }
124:
125: return (buf);
126: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>