allow machine-specific libkern sources
[unix-history] / usr / src / lib / libedit / parse.c
CommitLineData
649300a1
KB
1/*-
2 * Copyright (c) 1992 The Regents of the University of California.
3 * 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
b6dd18ed
CZ
11#if !defined(lint) && !defined(SCCSID)
12static char sccsid[] = "@(#)parse.c 5.2 (Berkeley) %G%";
13#endif /* not lint && not SCCSID */
649300a1
KB
14
15/*
b6dd18ed 16 * parse.c: parse an editline extended command
649300a1
KB
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
29private 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 */
46protected int
47parse_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 */
65public int
66el_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';
b6dd18ed 79 if (el_match(el->el_prog, ptr))
649300a1
KB
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 */
99protected int
100parse__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 }
b6dd18ed 167 else if (*p == '^' && isalpha((unsigned char) *p)) {
649300a1
KB
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 */
180protected char *
181parse__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 */
210protected int
211parse_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}