parse.c revision 8870
1174617Sdas/*- 2174617Sdas * Copyright (c) 1992, 1993 3174617Sdas * The Regents of the University of California. All rights reserved. 4174617Sdas * 5174617Sdas * This code is derived from software contributed to Berkeley by 6174617Sdas * Christos Zoulas of Cornell University. 7174617Sdas * 8174617Sdas * Redistribution and use in source and binary forms, with or without 9174617Sdas * modification, are permitted provided that the following conditions 10174617Sdas * are met: 11174617Sdas * 1. Redistributions of source code must retain the above copyright 12174617Sdas * notice, this list of conditions and the following disclaimer. 13174617Sdas * 2. Redistributions in binary form must reproduce the above copyright 14174617Sdas * notice, this list of conditions and the following disclaimer in the 15174617Sdas * documentation and/or other materials provided with the distribution. 16174617Sdas * 3. All advertising materials mentioning features or use of this software 17174617Sdas * must display the following acknowledgement: 18174617Sdas * This product includes software developed by the University of 19174617Sdas * California, Berkeley and its contributors. 20174617Sdas * 4. Neither the name of the University nor the names of its contributors 21174617Sdas * may be used to endorse or promote products derived from this software 22174617Sdas * without specific prior written permission. 23174617Sdas * 24174617Sdas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25174617Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26174617Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27174617Sdas * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28174617Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29174617Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30174617Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31174617Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32174617Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33174617Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34174617Sdas * SUCH DAMAGE. 35174617Sdas */ 36174617Sdas 37174617Sdas#if !defined(lint) && !defined(SCCSID) 38174617Sdasstatic char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; 39174617Sdas#endif /* not lint && not SCCSID */ 40174617Sdas 41174617Sdas/* 42181402Sdas * parse.c: parse an editline extended command 43174617Sdas * 44174617Sdas * commands are: 45174617Sdas * 46174617Sdas * bind 47174617Sdas * echotc 48174617Sdas * settc 49174617Sdas * gettc 50174617Sdas */ 51174617Sdas#include "sys.h" 52174617Sdas#include "el.h" 53174617Sdas#include "tokenizer.h" 54174617Sdas 55174617Sdasprivate struct { 56174617Sdas char *name; 57175225Sdas int (*func) __P((EditLine *, int, char **)); 58174617Sdas} cmds[] = { 59174617Sdas { "bind", map_bind }, 60174617Sdas { "echotc", term_echotc }, 61175225Sdas { "history", hist_list }, 62174617Sdas { "telltc", term_telltc }, 63175225Sdas { "settc", term_settc }, 64174617Sdas { "setty", tty_stty }, 65174617Sdas { NULL, NULL } 66174617Sdas}; 67174617Sdas 68174617Sdas 69174617Sdas/* parse_line(): 70174617Sdas * Parse a line and dispatch it 71174617Sdas */ 72174617Sdasprotected int 73174617Sdasparse_line(el, line) 74174617Sdas EditLine *el; 75174617Sdas const char *line; 76174617Sdas{ 77174617Sdas char **argv; 78174617Sdas int argc; 79174617Sdas Tokenizer *tok; 80174617Sdas 81174617Sdas tok = tok_init(NULL); 82174617Sdas tok_line(tok, line, &argc, &argv); 83174617Sdas argc = el_parse(el, argc, argv); 84174617Sdas tok_end(tok); 85174617Sdas return argc; 86174617Sdas} 87174617Sdas 88174617Sdas/* 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