1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Christos Zoulas of Cornell University.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #if !defined(lint) && !defined(SCCSID)
12 static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 06/04/93";
13 #endif /* not lint && not SCCSID */
14
15 /*
16 * parse.c: parse an editline extended command
17 *
18 * commands are:
19 *
20 * bind
21 * echotc
22 * settc
23 * gettc
24 */
25 #include "sys.h"
26 #include "el.h"
27 #include "tokenizer.h"
28
29 private struct {
30 char *name;
31 int (*func) __P((EditLine *, int, char **));
32 } cmds[] = {
33 { "bind", map_bind },
34 { "echotc", term_echotc },
35 { "history", hist_list },
36 { "telltc", term_telltc },
37 { "settc", term_settc },
38 { "setty", tty_stty },
39 { NULL, NULL }
40 };
41
42
43 /* parse_line():
44 * Parse a line and dispatch it
45 */
46 protected int
parse_line(el,line)47 parse_line(el, line)
48 EditLine *el;
49 const char *line;
50 {
51 char **argv;
52 int argc;
53 Tokenizer *tok;
54
55 tok = tok_init(NULL);
56 tok_line(tok, line, &argc, &argv);
57 argc = el_parse(el, argc, argv);
58 tok_end(tok);
59 return argc;
60 }
61
62 /* el_parse():
63 * Command dispatcher
64 */
65 public int
el_parse(el,argc,argv)66 el_parse(el, argc, argv)
67 EditLine *el;
68 int argc;
69 char *argv[];
70 {
71 char *ptr;
72 int i;
73
74 for (ptr = argv[0]; *ptr && *ptr != ':'; ptr++)
75 continue;
76
77 if (*ptr == ':') {
78 *ptr = '\0';
79 if (el_match(el->el_prog, ptr))
80 return 0;
81 }
82 else
83 ptr = argv[0];
84
85 for (i = 0; cmds[i].name != NULL; i++)
86 if (strcmp(cmds[i].name, ptr) == 0) {
87 i = (*cmds[i].func)(el, argc, argv);
88 return -i;
89 }
90
91 return -1;
92 }
93
94
95 /* parse__escape():
96 * Parse a string of the form ^<char> \<odigit> \<char> and return
97 * the appropriate character or -1 if the escape is not valid
98 */
99 protected int
parse__escape(ptr)100 parse__escape(ptr)
101 const char ** const ptr;
102 {
103 const char *p;
104 int c;
105
106 p = *ptr;
107
108 if (p[1] == 0)
109 return -1;
110
111 if (*p == '\\') {
112 p++;
113 switch (*p) {
114 case 'a':
115 c = '\007'; /* Bell */
116 break;
117 case 'b':
118 c = '\010'; /* Backspace */
119 break;
120 case 't':
121 c = '\011'; /* Horizontal Tab */
122 break;
123 case 'n':
124 c = '\012'; /* New Line */
125 break;
126 case 'v':
127 c = '\013'; /* Vertical Tab */
128 break;
129 case 'f':
130 c = '\014'; /* Form Feed */
131 break;
132 case 'r':
133 c = '\015'; /* Carriage Return */
134 break;
135 case 'e':
136 c = '\033'; /* Escape */
137 break;
138 case '0':
139 case '1':
140 case '2':
141 case '3':
142 case '4':
143 case '5':
144 case '6':
145 case '7':
146 {
147 int cnt, ch;
148
149 for (cnt = 0, c = 0; cnt < 3; cnt++) {
150 ch = *p++;
151 if (ch < '0' || ch > '7') {
152 p--;
153 break;
154 }
155 c = (c << 3) | (ch - '0');
156 }
157 if ((c & 0xffffff00) != 0)
158 return -1;
159 --p;
160 }
161 break;
162 default:
163 c = *p;
164 break;
165 }
166 }
167 else if (*p == '^' && isalpha((unsigned char) *p)) {
168 p++;
169 c = (*p == '?') ? '\177' : (*p & 0237);
170 }
171 else
172 c = *p;
173 *ptr = ++p;
174 return c;
175 }
176
177 /* parse__string():
178 * Parse the escapes from in and put the raw string out
179 */
180 protected char *
parse__string(out,in)181 parse__string(out, in)
182 char *out;
183 const char *in;
184 {
185 char *rv = out;
186 int n;
187 for (;;)
188 switch (*in) {
189 case '\0':
190 *out = '\0';
191 return rv;
192
193 case '\\':
194 case '^':
195 if ((n = parse__escape(&in)) == -1)
196 return NULL;
197 *out++ = n;
198 break;
199
200 default:
201 *out++ = *in++;
202 break;
203 }
204 }
205
206 /* parse_cmd():
207 * Return the command number for the command string given
208 * or -1 if one is not found
209 */
210 protected int
parse_cmd(el,cmd)211 parse_cmd(el, cmd)
212 EditLine *el;
213 const char *cmd;
214 {
215 el_bindings_t *b;
216
217 for (b = el->el_map.help; b->name != NULL; b++)
218 if (strcmp(b->name, cmd) == 0)
219 return b->func;
220 return -1;
221 }
222