1 /* $NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Christos Zoulas of Cornell University.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #if !defined(lint) && !defined(SCCSID)
38 static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
40 __RCSID("$NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp $");
42 #endif /* not lint && not SCCSID */
45 * parse.c: parse an editline extended command
65 int (*func)(EditLine *, int, const wchar_t **);
67 { L"bind", map_bind },
68 { L"echotc", terminal_echotc },
69 { L"edit", el_editmode },
70 { L"history", hist_command },
71 { L"telltc", terminal_telltc },
72 { L"settc", terminal_settc },
73 { L"setty", tty_stty },
79 * Parse a line and dispatch it
82 parse_line(EditLine *el, const wchar_t *line)
88 tok = tok_winit(NULL);
89 tok_wstr(tok, line, &argc, &argv);
90 argc = el_wparse(el, argc, argv);
100 el_wparse(EditLine *el, int argc, const wchar_t *argv[])
107 ptr = wcschr(argv[0], L':');
114 l = (size_t)(ptr - argv[0]);
115 tprog = el_calloc(l + 1, sizeof(*tprog));
118 (void) wcsncpy(tprog, argv[0], l);
121 l = (size_t)el_match(el->el_prog, tprog);
128 for (i = 0; cmds[i].name != NULL; i++)
129 if (wcscmp(cmds[i].name, ptr) == 0) {
130 i = (*cmds[i].func) (el, argc, argv);
138 * Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
139 * the appropriate character or -1 if the escape is not valid
142 parse__escape(const wchar_t **ptr)
156 c = '\007'; /* Bell */
159 c = '\010'; /* Backspace */
162 c = '\011'; /* Horizontal Tab */
165 c = '\012'; /* New Line */
168 c = '\013'; /* Vertical Tab */
171 c = '\014'; /* Form Feed */
174 c = '\015'; /* Carriage Return */
177 c = '\033'; /* Escape */
179 case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
182 const wchar_t hex[] = L"0123456789ABCDEF";
188 for (i = 0; i < 5; ++i) {
189 h = wcschr(hex, *p++);
193 c = (c << 4) | ((int)(h - hex));
197 if (c > 0x10FFFF) /* outside valid character range */
212 for (cnt = 0, c = 0; cnt < 3; cnt++) {
214 if (ch < '0' || ch > '7') {
218 c = (c << 3) | (ch - '0');
220 if ((c & (wint_t)0xffffff00) != (wint_t)0)
229 } else if (*p == '^') {
231 c = (*p == '?') ? '\177' : (*p & 0237);
239 * Parse the escapes from in and put the raw string out
241 libedit_private wchar_t *
242 parse__string(wchar_t *out, const wchar_t *in)
255 if ((n = parse__escape(&in)) == -1)
261 if (in[1] == '-' && in[2] != '\0') {
276 * Return the command number for the command string given
277 * or -1 if one is not found
280 parse_cmd(EditLine *el, const wchar_t *cmd)
282 el_bindings_t *b = el->el_map.help;
285 for (i = 0; i < el->el_map.nfunc; i++)
286 if (wcscmp(b[i].name, cmd) == 0)