summaryrefslogtreecommitdiffstats
path: root/cmd-string.c
authornicm <nicm>2008-06-19 20:45:15 (GMT)
committer nicm <nicm>2008-06-19 20:45:15 (GMT)
commit5079d10bf45f1e490c173e6fff0db52fe3549e00 (patch) (unidiff)
treeaa3c7aba189e74ef5533a88bdd8a4386fc50253c /cmd-string.c
parent88b3709e4ef556b6ae6a69101344410e65b788e8 (diff)
downloadtmux-old-5079d10bf45f1e490c173e6fff0db52fe3549e00.zip
tmux-old-5079d10bf45f1e490c173e6fff0db52fe3549e00.tar.gz
tmux-old-5079d10bf45f1e490c173e6fff0db52fe3549e00.tar.bz2
Command prompt for interactive commands.
Diffstat (limited to 'cmd-string.c') (more/less context) (ignore whitespace changes)
-rw-r--r--cmd-string.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/cmd-string.c b/cmd-string.c
new file mode 100644
index 0000000..12add6a
--- a/dev/null
+++ b/cmd-string.c
@@ -0,0 +1,171 @@
1/* $Id$ */
2
3/*
4 * Copyright (c) 2008 Nicholas Marriott <[email protected]>
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 <errno.h>
22#include <stdio.h>
23#include <string.h>
24
25#include "tmux.h"
26
27/*
28 * Parse a command from a string.
29 */
30
31 intcmd_string_getc(const char *, size_t *);
32char *cmd_string_string(const char *, size_t *, char, int);
33
34int
35cmd_string_getc(const char *s, size_t *p)
36{
37 if (s[*p] == '\0')
38 return (EOF);
39 return (s[(*p)++]);
40}
41
42struct cmd *
43cmd_string_parse(const char *s, char **cause)
44{
45 size_tp;
46 int ch, argc;
47 char **argv, *buf, *t;
48 size_t len;
49 struct cmd *cmd;
50
51 argv = NULL;
52 argc = 0;
53
54 buf = NULL;
55 len = 0;
56
57 cmd = NULL;
58
59 p = 0;
60 for (;;) {
61 ch = cmd_string_getc(s, &p);
62 switch (ch) {
63 case '\'':
64 if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
65 goto error;
66 argv = xrealloc(argv, argc + 1, sizeof *argv);
67 argv[argc++] = t;
68 break;
69 case '"':
70 if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
71 goto error;
72 argv = xrealloc(argv, argc + 1, sizeof *argv);
73 argv[argc++] = t;
74 break;
75 case '#':
76 /* Comment: discard rest of line. */
77 while ((ch = cmd_string_getc(s, &p)) != EOF)
78 ;
79 /* FALLTHROUGH */
80 case EOF:
81 case ' ':
82 case '\t':
83 if (len != 0) {
84 buf = xrealloc(buf, 1, len + 1);
85 buf[len] = '\0';
86
87 argv = xrealloc(argv, argc + 1, sizeof *argv);
88 argv[argc++] = buf;
89
90 buf = NULL;
91 len = 0;
92 }
93
94 if (ch != EOF)
95 break;
96
97 cmd = cmd_parse(argc, argv, cause);
98 goto out;
99 default:
100 if (len >= SIZE_MAX - 2)
101 goto error;
102
103 buf = xrealloc(buf, 1, len + 1);
104 buf[len++] = ch;
105 break;
106 }
107 }
108
109error:
110 xasprintf(cause, "bad command: %s", s);
111
112out:
113 if (buf != NULL)
114 xfree(buf);
115
116 while (--argc >= 0)
117 xfree(argv[argc]);
118 if (argv != NULL)
119 xfree(argv);
120
121 return (cmd);
122}
123
124char *
125cmd_string_string(const char *s, size_t *p, char endch, int esc)
126{
127 intch;
128 char *buf;
129 size_tlen;
130
131 buf = NULL;
132 len = 0;
133
134 while ((ch = cmd_string_getc(s, p)) != endch) {
135 switch (ch) {
136 case EOF:
137 goto error;
138 case '\\':
139 if (!esc)
140 break;
141 switch (ch = cmd_string_getc(s, p)) {
142 case EOF:
143 goto error;
144 case 'r':
145 ch = '\r';
146 break;
147 case 'n':
148 ch = '\n';
149 break;
150 case 't':
151 ch = '\t';
152 break;
153 }
154 break;
155 }
156
157 if (len >= SIZE_MAX - 2)
158 goto error;
159 buf = xrealloc(buf, 1, len + 1);
160 buf[len++] = ch;
161 }
162
163 buf = xrealloc(buf, 1, len + 1);
164 buf[len] = '\0';
165 return (buf);
166
167error:
168 if (buf != NULL)
169 xfree(buf);
170 return (NULL);
171}