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 * %sccs.include.redist.c% 9 */ 10 11 #if !defined(lint) && !defined(SCCSID) 12 static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* not lint && not SCCSID */ 14 15 /* 16 * parse.c: parse an editline extended command 17 * 18 * commands are: 19 * 20 * bind 21 * echotc 22 * settc 23 * gettc 24 */ 25 #include "sys.h" 26 #include "el.h" 27 #include "tokenizer.h" 28 29 private struct { 30 char *name; 31 int (*func) __P((EditLine *, int, char **)); 32 } cmds[] = { 33 { "bind", map_bind }, 34 { "echotc", term_echotc }, 35 { "history", hist_list }, 36 { "telltc", term_telltc }, 37 { "settc", term_settc }, 38 { "setty", tty_stty }, 39 { NULL, NULL } 40 }; 41 42 43 /* parse_line(): 44 * Parse a line and dispatch it 45 */ 46 protected int 47 parse_line(el, line) 48 EditLine *el; 49 const char *line; 50 { 51 char **argv; 52 int argc; 53 Tokenizer *tok; 54 55 tok = tok_init(NULL); 56 tok_line(tok, line, &argc, &argv); 57 argc = el_parse(el, argc, argv); 58 tok_end(tok); 59 return argc; 60 } 61 62 /* el_parse(): 63 * Command dispatcher 64 */ 65 public int 66 el_parse(el, argc, argv) 67 EditLine *el; 68 int argc; 69 char *argv[]; 70 { 71 char *ptr; 72 int i; 73 74 for (ptr = argv[0]; *ptr && *ptr != ':'; ptr++) 75 continue; 76 77 if (*ptr == ':') { 78 *ptr = '\0'; 79 if (el_match(el->el_prog, ptr)) 80 return 0; 81 } 82 else 83 ptr = argv[0]; 84 85 for (i = 0; cmds[i].name != NULL; i++) 86 if (strcmp(cmds[i].name, ptr) == 0) { 87 i = (*cmds[i].func)(el, argc, argv); 88 return -i; 89 } 90 91 return -1; 92 } 93 94 95 /* parse__escape(): 96 * Parse a string of the form ^<char> \<odigit> \<char> and return 97 * the appropriate character or -1 if the escape is not valid 98 */ 99 protected int 100 parse__escape(ptr) 101 const char ** const ptr; 102 { 103 const char *p; 104 int c; 105 106 p = *ptr; 107 108 if (p[1] == 0) 109 return -1; 110 111 if (*p == '\\') { 112 p++; 113 switch (*p) { 114 case 'a': 115 c = '\007'; /* Bell */ 116 break; 117 case 'b': 118 c = '\010'; /* Backspace */ 119 break; 120 case 't': 121 c = '\011'; /* Horizontal Tab */ 122 break; 123 case 'n': 124 c = '\012'; /* New Line */ 125 break; 126 case 'v': 127 c = '\013'; /* Vertical Tab */ 128 break; 129 case 'f': 130 c = '\014'; /* Form Feed */ 131 break; 132 case 'r': 133 c = '\015'; /* Carriage Return */ 134 break; 135 case 'e': 136 c = '\033'; /* Escape */ 137 break; 138 case '0': 139 case '1': 140 case '2': 141 case '3': 142 case '4': 143 case '5': 144 case '6': 145 case '7': 146 { 147 int cnt, ch; 148 149 for (cnt = 0, c = 0; cnt < 3; cnt++) { 150 ch = *p++; 151 if (ch < '0' || ch > '7') { 152 p--; 153 break; 154 } 155 c = (c << 3) | (ch - '0'); 156 } 157 if ((c & 0xffffff00) != 0) 158 return -1; 159 --p; 160 } 161 break; 162 default: 163 c = *p; 164 break; 165 } 166 } 167 else if (*p == '^' && isalpha((unsigned char) *p)) { 168 p++; 169 c = (*p == '?') ? '\177' : (*p & 0237); 170 } 171 else 172 c = *p; 173 *ptr = ++p; 174 return c; 175 } 176 177 /* parse__string(): 178 * Parse the escapes from in and put the raw string out 179 */ 180 protected char * 181 parse__string(out, in) 182 char *out; 183 const char *in; 184 { 185 char *rv = out; 186 int n; 187 for (;;) 188 switch (*in) { 189 case '\0': 190 *out = '\0'; 191 return rv; 192 193 case '\\': 194 case '^': 195 if ((n = parse__escape(&in)) == -1) 196 return NULL; 197 *out++ = n; 198 break; 199 200 default: 201 *out++ = *in++; 202 break; 203 } 204 } 205 206 /* parse_cmd(): 207 * Return the command number for the command string given 208 * or -1 if one is not found 209 */ 210 protected int 211 parse_cmd(el, cmd) 212 EditLine *el; 213 const char *cmd; 214 { 215 el_bindings_t *b; 216 217 for (b = el->el_map.help; b->name != NULL; b++) 218 if (strcmp(b->name, cmd) == 0) 219 return b->func; 220 return -1; 221 } 222