Annotation of src/usr.bin/tmux/cmd-list.c, Revision 1.17
1.17 ! nicm 1: /* $OpenBSD: cmd-list.c,v 1.16 2016/01/19 15:59:12 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.17 ! nicm 26: static struct cmd_list *
! 27: cmd_list_new(void)
! 28: {
! 29: struct cmd_list *cmdlist;
! 30:
! 31: cmdlist = xcalloc(1, sizeof *cmdlist);
! 32: cmdlist->references = 1;
! 33: TAILQ_INIT(&cmdlist->list);
! 34: return (cmdlist);
! 35: }
! 36:
1.1 nicm 37: struct cmd_list *
1.14 nicm 38: cmd_list_parse(int argc, char **argv, const char *file, u_int line,
1.12 nicm 39: char **cause)
1.1 nicm 40: {
41: struct cmd_list *cmdlist;
42: struct cmd *cmd;
43: int i, lastsplit;
44: size_t arglen, new_argc;
1.6 nicm 45: char **copy_argv, **new_argv;
46:
47: copy_argv = cmd_copy_argv(argc, argv);
1.1 nicm 48:
1.17 ! nicm 49: cmdlist = cmd_list_new();
1.1 nicm 50:
51: lastsplit = 0;
52: for (i = 0; i < argc; i++) {
1.6 nicm 53: arglen = strlen(copy_argv[i]);
54: if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
1.1 nicm 55: continue;
1.6 nicm 56: copy_argv[i][arglen - 1] = '\0';
1.1 nicm 57:
1.6 nicm 58: if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
59: copy_argv[i][arglen - 2] = ';';
1.1 nicm 60: continue;
61: }
62:
63: new_argc = i - lastsplit;
1.6 nicm 64: new_argv = copy_argv + lastsplit;
1.1 nicm 65: if (arglen != 1)
66: new_argc++;
67:
1.12 nicm 68: cmd = cmd_parse(new_argc, new_argv, file, line, cause);
1.1 nicm 69: if (cmd == NULL)
70: goto bad;
1.5 nicm 71: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
1.1 nicm 72:
73: lastsplit = i + 1;
74: }
75:
76: if (lastsplit != argc) {
1.12 nicm 77: cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit,
78: file, line, cause);
1.1 nicm 79: if (cmd == NULL)
80: goto bad;
1.5 nicm 81: TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
1.1 nicm 82: }
83:
1.6 nicm 84: cmd_free_argv(argc, copy_argv);
1.1 nicm 85: return (cmdlist);
86:
87: bad:
88: cmd_list_free(cmdlist);
1.6 nicm 89: cmd_free_argv(argc, copy_argv);
1.1 nicm 90: return (NULL);
91: }
92:
93: void
94: cmd_list_free(struct cmd_list *cmdlist)
95: {
1.12 nicm 96: struct cmd *cmd, *cmd1;
1.1 nicm 97:
1.5 nicm 98: if (--cmdlist->references != 0)
99: return;
100:
1.12 nicm 101: TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) {
1.5 nicm 102: TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
1.11 nicm 103: args_free(cmd->args);
1.12 nicm 104: free(cmd->file);
1.11 nicm 105: free(cmd);
1.1 nicm 106: }
1.12 nicm 107:
1.8 nicm 108: free(cmdlist);
1.1 nicm 109: }
110:
1.15 nicm 111: char *
112: cmd_list_print(struct cmd_list *cmdlist)
1.1 nicm 113: {
114: struct cmd *cmd;
1.15 nicm 115: char *buf, *this;
116: size_t len;
117:
118: len = 1;
119: buf = xcalloc(1, len);
1.1 nicm 120:
1.5 nicm 121: TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
1.15 nicm 122: this = cmd_print(cmd);
123:
124: len += strlen(this) + 3;
125: buf = xrealloc(buf, len);
126:
127: strlcat(buf, this, len);
128: if (TAILQ_NEXT(cmd, qentry) != NULL)
129: strlcat(buf, " ; ", len);
130:
131: free(this);
1.1 nicm 132: }
1.15 nicm 133:
134: return (buf);
1.1 nicm 135: }