parse.c revision 1573
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 for (ptr = argv[0]; *ptr && *ptr != ':'; ptr++) 101 continue; 102 103 if (*ptr == ':') { 104 *ptr = '\0'; 105 if (el_match(el->el_prog, ptr)) 106 return 0; 107 } 108 else 109 ptr = argv[0]; 110 111 for (i = 0; cmds[i].name != NULL; i++) 112 if (strcmp(cmds[i].name, ptr) == 0) { 113 i = (*cmds[i].func)(el, argc, argv); 114 return -i; 115 } 116 117 return -1; 118} 119 120 121/* parse__escape(): 122 * Parse a string of the form ^<char> \<odigit> \<char> and return 123 * the appropriate character or -1 if the escape is not valid 124 */ 125protected int 126parse__escape(ptr) 127 const char ** const ptr; 128{ 129 const char *p; 130 int c; 131 132 p = *ptr; 133 134 if (p[1] == 0) 135 return -1; 136 137 if (*p == '\\') { 138 p++; 139 switch (*p) { 140 case 'a': 141 c = '\007'; /* Bell */ 142 break; 143 case 'b': 144 c = '\010'; /* Backspace */ 145 break; 146 case 't': 147 c = '\011'; /* Horizontal Tab */ 148 break; 149 case 'n': 150 c = '\012'; /* New Line */ 151 break; 152 case 'v': 153 c = '\013'; /* Vertical Tab */ 154 break; 155 case 'f': 156 c = '\014'; /* Form Feed */ 157 break; 158 case 'r': 159 c = '\015'; /* Carriage Return */ 160 break; 161 case 'e': 162 c = '\033'; /* Escape */ 163 break; 164 case '0': 165 case '1': 166 case '2': 167 case '3': 168 case '4': 169 case '5': 170 case '6': 171 case '7': 172 { 173 int cnt, ch; 174 175 for (cnt = 0, c = 0; cnt < 3; cnt++) { 176 ch = *p++; 177 if (ch < '0' || ch > '7') { 178 p--; 179 break; 180 } 181 c = (c << 3) | (ch - '0'); 182 } 183 if ((c & 0xffffff00) != 0) 184 return -1; 185 --p; 186 } 187 break; 188 default: 189 c = *p; 190 break; 191 } 192 } 193 else if (*p == '^' && isalpha((unsigned char) *p)) { 194 p++; 195 c = (*p == '?') ? '\177' : (*p & 0237); 196 } 197 else 198 c = *p; 199 *ptr = ++p; 200 return c; 201} 202 203/* parse__string(): 204 * Parse the escapes from in and put the raw string out 205 */ 206protected char * 207parse__string(out, in) 208 char *out; 209 const char *in; 210{ 211 char *rv = out; 212 int n; 213 for (;;) 214 switch (*in) { 215 case '\0': 216 *out = '\0'; 217 return rv; 218 219 case '\\': 220 case '^': 221 if ((n = parse__escape(&in)) == -1) 222 return NULL; 223 *out++ = n; 224 break; 225 226 default: 227 *out++ = *in++; 228 break; 229 } 230} 231 232/* parse_cmd(): 233 * Return the command number for the command string given 234 * or -1 if one is not found 235 */ 236protected int 237parse_cmd(el, cmd) 238 EditLine *el; 239 const char *cmd; 240{ 241 el_bindings_t *b; 242 243 for (b = el->el_map.help; b->name != NULL; b++) 244 if (strcmp(b->name, cmd) == 0) 245 return b->func; 246 return -1; 247} 248