Annotation of src/usr.bin/tmux/cmd-list.c, Revision 1.19
1.19 ! nicm 1: /* $OpenBSD: cmd-list.c,v 1.18 2019/05/23 11:13:30 nicm Exp $ */
1.1 nicm 2:
3: /*
1.16 nicm 4: * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 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:
1.8 nicm 21: #include <stdlib.h>
1.1 nicm 22: #include <string.h>
23:
24: #include "tmux.h"
25:
1.18 nicm 26: static u_int cmd_list_next_group = 1;
27:
28: struct cmd_list *
1.17 nicm 29: cmd_list_new(void)
30: {
31: struct cmd_list *cmdlist;
32:
33: cmdlist = xcalloc(1, sizeof *cmdlist);
34: cmdlist->references = 1;
1.18 nicm 35: cmdlist->group = cmd_list_next_group++;
1.17 nicm 36: TAILQ_INIT(&cmdlist->list);
37: return (cmdlist);
38: }
39:
1.18 nicm 40: void
41: cmd_list_append(struct cmd_list *cmdlist, struct cmd *cmd)
42: {
43: cmd->group = cmdlist->group;
44: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
45: }
46:
47: void
48: cmd_list_move(struct cmd_list *cmdlist, struct cmd_list *from)
49: {
50: struct cmd *cmd, *cmd1;
51:
52: TAILQ_FOREACH_SAFE(cmd, &from->list, qentry, cmd1) {
53: TAILQ_REMOVE(&from->list, cmd, qentry);
54: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
55: }
56: cmdlist->group = cmd_list_next_group++;
57: }
58:
1.1 nicm 59: struct cmd_list *
1.14 nicm 60: cmd_list_parse(int argc, char **argv, const char *file, u_int line,
1.12 nicm 61: char **cause)
1.1 nicm 62: {
63: struct cmd_list *cmdlist;
64: struct cmd *cmd;
65: int i, lastsplit;
66: size_t arglen, new_argc;
1.6 nicm 67: char **copy_argv, **new_argv;
68:
69: copy_argv = cmd_copy_argv(argc, argv);
1.1 nicm 70:
1.17 nicm 71: cmdlist = cmd_list_new();
1.1 nicm 72:
73: lastsplit = 0;
74: for (i = 0; i < argc; i++) {
1.6 nicm 75: arglen = strlen(copy_argv[i]);
76: if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
1.1 nicm 77: continue;
1.6 nicm 78: copy_argv[i][arglen - 1] = '\0';
1.1 nicm 79:
1.6 nicm 80: if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
81: copy_argv[i][arglen - 2] = ';';
1.1 nicm 82: continue;
83: }
84:
85: new_argc = i - lastsplit;
1.6 nicm 86: new_argv = copy_argv + lastsplit;
1.1 nicm 87: if (arglen != 1)
88: new_argc++;
89:
1.12 nicm 90: cmd = cmd_parse(new_argc, new_argv, file, line, cause);
1.1 nicm 91: if (cmd == NULL)
92: goto bad;
1.5 nicm 93: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
1.1 nicm 94:
95: lastsplit = i + 1;
96: }
97:
98: if (lastsplit != argc) {
1.12 nicm 99: cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit,
100: file, line, cause);
1.1 nicm 101: if (cmd == NULL)
102: goto bad;
1.5 nicm 103: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
1.1 nicm 104: }
105:
1.6 nicm 106: cmd_free_argv(argc, copy_argv);
1.1 nicm 107: return (cmdlist);
108:
109: bad:
110: cmd_list_free(cmdlist);
1.6 nicm 111: cmd_free_argv(argc, copy_argv);
1.1 nicm 112: return (NULL);
113: }
114:
115: void
116: cmd_list_free(struct cmd_list *cmdlist)
117: {
1.12 nicm 118: struct cmd *cmd, *cmd1;
1.1 nicm 119:
1.5 nicm 120: if (--cmdlist->references != 0)
121: return;
122:
1.12 nicm 123: TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) {
1.5 nicm 124: TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
1.18 nicm 125: cmd_free(cmd);
1.1 nicm 126: }
1.12 nicm 127:
1.8 nicm 128: free(cmdlist);
1.1 nicm 129: }
130:
1.15 nicm 131: char *
1.19 ! nicm 132: cmd_list_print(struct cmd_list *cmdlist, int escaped)
1.1 nicm 133: {
134: struct cmd *cmd;
1.15 nicm 135: char *buf, *this;
136: size_t len;
137:
138: len = 1;
139: buf = xcalloc(1, len);
1.1 nicm 140:
1.5 nicm 141: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.15 nicm 142: this = cmd_print(cmd);
143:
1.19 ! nicm 144: len += strlen(this) + 4;
1.15 nicm 145: buf = xrealloc(buf, len);
146:
147: strlcat(buf, this, len);
1.19 ! nicm 148: if (TAILQ_NEXT(cmd, qentry) != NULL) {
! 149: if (escaped)
! 150: strlcat(buf, " \\; ", len);
! 151: else
! 152: strlcat(buf, " ; ", len);
! 153: }
1.15 nicm 154:
155: free(this);
1.1 nicm 156: }
1.15 nicm 157:
158: return (buf);
1.1 nicm 159: }