00001 /* $NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $ */ 00002 00003 /*- 00004 * Copyright (c) 1992, 1993 00005 * The Regents of the University of California. All rights reserved. 00006 * 00007 * This code is derived from software contributed to Berkeley by 00008 * Christos Zoulas of Cornell University. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions 00012 * are met: 00013 * 1. Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * 3. Neither the name of the University nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00028 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00029 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00032 * SUCH DAMAGE. 00033 */ 00034 00035 #include <config.h> 00036 00037 /* 00038 * parse.c: parse an editline extended command 00039 * 00040 * commands are: 00041 * 00042 * bind 00043 * echotc 00044 * edit 00045 * gettc 00046 * history 00047 * settc 00048 * setty 00049 */ 00050 #include "el.h" 00051 #include <stdlib.h> 00052 00053 private const struct { 00054 const char *name; 00055 int (*func)(EditLine *, int, const char **); 00056 } cmds[] = { 00057 { "bind", map_bind }, 00058 { "echotc", term_echotc }, 00059 { "edit", el_editmode }, 00060 { "history", hist_command }, 00061 { "telltc", term_telltc }, 00062 { "settc", term_settc }, 00063 { "setty", tty_stty }, 00064 { NULL, NULL } 00065 }; 00066 00067 00068 /* parse_line(): 00069 * Parse a line and dispatch it 00070 */ 00071 protected int 00072 parse_line(EditLine *el, const char *line) 00073 { 00074 const char **argv; 00075 int argc; 00076 Tokenizer *tok; 00077 00078 tok = tok_init(NULL); 00079 tok_str(tok, line, &argc, &argv); 00080 argc = el_parse(el, argc, argv); 00081 tok_end(tok); 00082 return (argc); 00083 } 00084 00085 00086 /* el_parse(): 00087 * Command dispatcher 00088 */ 00089 public int 00090 el_parse(EditLine *el, int argc, const char *argv[]) 00091 { 00092 const char *ptr; 00093 int i; 00094 00095 if (argc < 1) 00096 return (-1); 00097 ptr = strchr(argv[0], ':'); 00098 if (ptr != NULL) { 00099 char *tprog; 00100 size_t l; 00101 00102 if (ptr == argv[0]) 00103 return (0); 00104 l = ptr - argv[0] - 1; 00105 tprog = (char *) el_malloc(l + 1); 00106 if (tprog == NULL) 00107 return (0); 00108 (void) strncpy(tprog, argv[0], l); 00109 tprog[l] = '\0'; 00110 ptr++; 00111 l = el_match(el->el_prog, tprog); 00112 el_free(tprog); 00113 if (!l) 00114 return (0); 00115 } else 00116 ptr = argv[0]; 00117 00118 for (i = 0; cmds[i].name != NULL; i++) 00119 if (strcmp(cmds[i].name, ptr) == 0) { 00120 i = (*cmds[i].func) (el, argc, argv); 00121 return (-i); 00122 } 00123 return (-1); 00124 } 00125 00126 00127 /* parse__escape(): 00128 * Parse a string of the form ^<char> <odigit> <char> and return 00129 * the appropriate character or -1 if the escape is not valid 00130 */ 00131 protected int 00132 parse__escape(const char **const ptr) 00133 { 00134 const char *p; 00135 int c; 00136 00137 p = *ptr; 00138 00139 if (p[1] == 0) 00140 return (-1); 00141 00142 if (*p == '\\') { 00143 p++; 00144 switch (*p) { 00145 case 'a': 00146 c = '\007'; /* Bell */ 00147 break; 00148 case 'b': 00149 c = '\010'; /* Backspace */ 00150 break; 00151 case 't': 00152 c = '\011'; /* Horizontal Tab */ 00153 break; 00154 case 'n': 00155 c = '\012'; /* New Line */ 00156 break; 00157 case 'v': 00158 c = '\013'; /* Vertical Tab */ 00159 break; 00160 case 'f': 00161 c = '\014'; /* Form Feed */ 00162 break; 00163 case 'r': 00164 c = '\015'; /* Carriage Return */ 00165 break; 00166 case 'e': 00167 c = '\033'; /* Escape */ 00168 break; 00169 case '0': 00170 case '1': 00171 case '2': 00172 case '3': 00173 case '4': 00174 case '5': 00175 case '6': 00176 case '7': 00177 { 00178 int cnt, ch; 00179 00180 for (cnt = 0, c = 0; cnt < 3; cnt++) { 00181 ch = *p++; 00182 if (ch < '0' || ch > '7') { 00183 p--; 00184 break; 00185 } 00186 c = (c << 3) | (ch - '0'); 00187 } 00188 if ((c & 0xffffff00) != 0) 00189 return (-1); 00190 --p; 00191 break; 00192 } 00193 default: 00194 c = *p; 00195 break; 00196 } 00197 } else if (*p == '^') { 00198 p++; 00199 c = (*p == '?') ? '\177' : (*p & 0237); 00200 } else 00201 c = *p; 00202 *ptr = ++p; 00203 return (c); 00204 } 00205 00206 /* parse__string(): 00207 * Parse the escapes from in and put the raw string out 00208 */ 00209 protected char * 00210 parse__string(char *out, const char *in) 00211 { 00212 char *rv = out; 00213 int n; 00214 00215 for (;;) 00216 switch (*in) { 00217 case '\0': 00218 *out = '\0'; 00219 return (rv); 00220 00221 case '\\': 00222 case '^': 00223 if ((n = parse__escape(&in)) == -1) 00224 return (NULL); 00225 *out++ = n; 00226 break; 00227 00228 case 'M': 00229 if (in[1] == '-' && in[2] != '\0') { 00230 *out++ = '\033'; 00231 in += 2; 00232 break; 00233 } 00234 /*FALLTHROUGH*/ 00235 00236 default: 00237 *out++ = *in++; 00238 break; 00239 } 00240 } 00241 00242 00243 /* parse_cmd(): 00244 * Return the command number for the command string given 00245 * or -1 if one is not found 00246 */ 00247 protected int 00248 parse_cmd(EditLine *el, const char *cmd) 00249 { 00250 el_bindings_t *b; 00251 00252 for (b = el->el_map.help; b->name != NULL; b++) 00253 if (strcmp(b->name, cmd) == 0) 00254 return (b->func); 00255 return (-1); 00256 }
1.4.7

