parse.c revision 9914
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 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#if !defined(lint) && !defined(SCCSID) 38static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; 39#endif /* not lint && not SCCSID */ 40 41/* 42 * parse.c: parse an editline extended command 43 * 44 * commands are: 45 * 46 * bind 47 * echotc 48 * settc 49 * gettc 50 */ 51#include "sys.h" 52#include "el.h" 53#include "tokenizer.h" 54 55private struct { 56 char *name; 57 int (*func) __P((EditLine *, int, char **)); 58} cmds[] = { 59 { "bind", map_bind }, 60 { "echotc", term_echotc }, 61 { "history", hist_list }, 62 { "telltc", term_telltc }, 63 { "settc", term_settc }, 64 { "setty", tty_stty }, 65 { NULL, NULL } 66}; 67 68 69/* parse_line(): 70 * Parse a line and dispatch it 71 */ 72protected int 73parse_line(el, line) 74 EditLine *el; 75 const char *line; 76{ 77 char **argv; 78 int argc; 79 Tokenizer *tok; 80 81 tok = tok_init(NULL); 82 tok_line(tok, line, &argc, &argv); 83 argc = el_parse(el, argc, argv); 84 tok_end(tok); 85 return argc; 86} 87 88/* el_parse(): 89 * Command dispatcher 90 */ 91public int 92el_parse(el, argc, argv) 93 EditLine *el; 94 int argc; 95 char *argv[]; 96{ 97 char *ptr; 98 int i; 99 100 if (argc < 1) 101 return argc; 102 103 for (ptr = argv[0]; *ptr && *ptr != ':'; ptr++) 104 continue; 105 106 if (*ptr == ':') { 107 *ptr = '\0'; 108 if (el_match(el->el_prog, ptr)) 109 return 0; 110 } 111 else 112 ptr = argv[0]; 113 114 for (i = 0; cmds[i].name != NULL; i++) 115 if (strcmp(cmds[i].name, ptr) == 0) { 116 i = (*cmds[i].func)(el, argc, argv); 117 return -i; 118 } 119 120 return -1; 121} 122 123 124/* parse__escape(): 125 * Parse a string of the form ^<char> \<odigit> \<char> and return 126 * the appropriate character or -1 if the escape is not valid 127 */ 128protected int 129parse__escape(ptr) 130 const char ** const ptr; 131{ 132 const char *p; 133 int c; 134 135 p = *ptr; 136 137 if (p[1] == 0) 138 return -1; 139 140 if (*p == '\\') { 141 p++; 142 switch (*p) { 143 case 'a': 144 c = '\007'; /* Bell */ 145 break; 146 case 'b': 147 c = '\010'; /* Backspace */ 148 break; 149 case 't': 150 c = '\011'; /* Horizontal Tab */ 151 break; 152 case 'n': 153 c = '\012'; /* New Line */ 154 break; 155 case 'v': 156 c = '\013'; /* Vertical Tab */ 157 break; 158 case 'f': 159 c = '\014'; /* Form Feed */ 160 break; 161 case 'r': 162 c = '\015'; /* Carriage Return */ 163 break; 164 case 'e': 165 c = '\033'; /* Escape */ 166 break; 167 case '0': 168 case '1': 169 case '2': 170 case '3': 171 case '4': 172 case '5': 173 case '6': 174 case '7': 175 { 176 int cnt, ch; 177 178 for (cnt = 0, c = 0; cnt < 3; cnt++) { 179 ch = *p++; 180 if (ch < '0' || ch > '7') { 181 p--; 182 break; 183 } 184 c = (c << 3) | (ch - '0'); 185 } 186 if ((c & 0xffffff00) != 0) 187 return -1; 188 --p; 189 } 190 break; 191 default: 192 c = *p; 193 break; 194 } 195 } 196 else if (*p == '^' && isalpha((unsigned char) *p)) { 197 p++; 198 c = (*p == '?') ? '\177' : (*p & 0237); 199 } 200 else 201 c = *p; 202 *ptr = ++p; 203 return c; 204} 205 206/* parse__string(): 207 * Parse the escapes from in and put the raw string out 208 */ 209protected char * 210parse__string(out, in) 211 char *out; 212 const char *in; 213{ 214 char *rv = out; 215 int n; 216 for (;;) 217 switch (*in) { 218 case '\0': 219 *out = '\0'; 220 return rv; 221 222 case '\\': 223 case '^': 224 if ((n = parse__escape(&in)) == -1) 225 return NULL; 226 *out++ = n; 227 break; 228 229 default: 230 *out++ = *in++; 231 break; 232 } 233} 234 235/* parse_cmd(): 236 * Return the command number for the command string given 237 * or -1 if one is not found 238 */ 239protected int 240parse_cmd(el, cmd) 241 EditLine *el; 242 const char *cmd; 243{ 244 el_bindings_t *b; 245 246 for (b = el->el_map.help; b->name != NULL; b++) 247 if (strcmp(b->name, cmd) == 0) 248 return b->func; 249 return -1; 250} 251