1 /* $OpenBSD: parse.c,v 1.20 2016/04/11 21:17:29 schwarze Exp $ */
2 /* $NetBSD: parse.c,v 1.38 2016/04/11 18:56:31 christos Exp $ */
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Christos Zoulas of Cornell University.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * parse.c: parse an editline extended command
59 int (*func
)(EditLine
*, int, const wchar_t **);
61 { L
"bind", map_bind
},
62 { L
"echotc", terminal_echotc
},
63 { L
"edit", el_editmode
},
64 { L
"history", hist_command
},
65 { L
"telltc", terminal_telltc
},
66 { L
"settc", terminal_settc
},
67 { L
"setty", tty_stty
},
73 * Parse a line and dispatch it
76 parse_line(EditLine
*el
, const wchar_t *line
)
82 tok
= tok_winit(NULL
);
83 tok_wstr(tok
, line
, &argc
, &argv
);
84 argc
= el_wparse(el
, argc
, argv
);
94 el_wparse(EditLine
*el
, int argc
, const wchar_t *argv
[])
101 ptr
= wcschr(argv
[0], L
':');
108 l
= ptr
- argv
[0] - 1;
109 tprog
= reallocarray(NULL
, l
+ 1, sizeof(*tprog
));
112 (void) wcsncpy(tprog
, argv
[0], l
);
115 l
= el_match(el
->el_prog
, tprog
);
122 for (i
= 0; cmds
[i
].name
!= NULL
; i
++)
123 if (wcscmp(cmds
[i
].name
, ptr
) == 0) {
124 i
= (*cmds
[i
].func
) (el
, argc
, argv
);
132 * Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
133 * the appropriate character or -1 if the escape is not valid
136 parse__escape(const wchar_t **ptr
)
150 c
= '\007'; /* Bell */
153 c
= '\010'; /* Backspace */
156 c
= '\011'; /* Horizontal Tab */
159 c
= '\012'; /* New Line */
162 c
= '\013'; /* Vertical Tab */
165 c
= '\014'; /* Form Feed */
168 c
= '\015'; /* Carriage Return */
171 c
= '\033'; /* Escape */
173 case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
176 const wchar_t hex
[] = L
"0123456789ABCDEF";
182 for (i
= 0; i
< 5; ++i
) {
183 h
= wcschr(hex
, *p
++);
187 c
= (c
<< 4) | ((int)(h
- hex
));
191 if (c
> 0x10FFFF) /* outside valid character range */
206 for (cnt
= 0, c
= 0; cnt
< 3; cnt
++) {
208 if (ch
< '0' || ch
> '7') {
212 c
= (c
<< 3) | (ch
- '0');
214 if ((c
& 0xffffff00) != 0)
223 } else if (*p
== '^') {
225 c
= (*p
== '?') ? '\177' : (*p
& 0237);
233 * Parse the escapes from in and put the raw string out
236 parse__string(wchar_t *out
, const wchar_t *in
)
249 if ((n
= parse__escape(&in
)) == -1)
255 if (in
[1] == '-' && in
[2] != '\0') {
270 * Return the command number for the command string given
271 * or -1 if one is not found
274 parse_cmd(EditLine
*el
, const wchar_t *cmd
)
279 for (b
= el
->el_map
.help
, i
= 0; i
< el
->el_map
.nfunc
; i
++)
280 if (wcscmp(b
[i
].name
, cmd
) == 0)