parse.c revision 26982
1139804Simp/*- 240711Swollman * Copyright (c) 1992, 1993 340711Swollman * The Regents of the University of California. All rights reserved. 440711Swollman * 540711Swollman * This code is derived from software contributed to Berkeley by 640711Swollman * Christos Zoulas of Cornell University. 740711Swollman * 840711Swollman * Redistribution and use in source and binary forms, with or without 940711Swollman * modification, are permitted provided that the following conditions 1040711Swollman * are met: 1140711Swollman * 1. Redistributions of source code must retain the above copyright 1240711Swollman * notice, this list of conditions and the following disclaimer. 1340711Swollman * 2. Redistributions in binary form must reproduce the above copyright 1440711Swollman * notice, this list of conditions and the following disclaimer in the 15152543Syongari * documentation and/or other materials provided with the distribution. 1640711Swollman * 3. All advertising materials mentioning features or use of this software 1740711Swollman * must display the following acknowledgement: 1840711Swollman * This product includes software developed by the University of 1940711Swollman * California, Berkeley and its contributors. 2040711Swollman * 4. Neither the name of the University nor the names of its contributors 2140711Swollman * may be used to endorse or promote products derived from this software 2240711Swollman * without specific prior written permission. 2340711Swollman * 2440711Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2540711Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2640711Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2740711Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2840711Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2940711Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3040711Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3140711Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3240711Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3340711Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3440711Swollman * SUCH DAMAGE. 3540711Swollman */ 3640711Swollman 3740711Swollman#if !defined(lint) && !defined(SCCSID) 3840711Swollmanstatic char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; 3940711Swollman#endif /* not lint && not SCCSID */ 4040711Swollman 4140711Swollman/* 4240711Swollman * parse.c: parse an editline extended command 4340711Swollman * 4440711Swollman * commands are: 4540711Swollman * 4640711Swollman * bind 4740711Swollman * echotc 4840711Swollman * settc 4940711Swollman * gettc 5040711Swollman * history 5140711Swollman * settc 5240711Swollman * setty 5340711Swollman */ 5440711Swollman#include "sys.h" 5540711Swollman#include "el.h" 5640711Swollman#include "tokenizer.h" 5740711Swollman 58168791Sjhbprivate struct { 59168791Sjhb char *name; 60116182Sobrien int (*func) __P((EditLine *, int, char **)); 61116182Sobrien} cmds[] = { 62116182Sobrien { "bind", map_bind }, 6340711Swollman { "echotc", term_echotc }, 6440711Swollman { "history", hist_list }, 6541304Sbde { "telltc", term_telltc }, 66164881Sjhb { "settc", term_settc }, 6740711Swollman { "setty", tty_stty }, 6840711Swollman { NULL, NULL } 6971576Sjasone}; 7045720Speter 7145720Speter 7240711Swollman/* parse_line(): 73102962Siwasaki * Parse a line and dispatch it 7440711Swollman */ 75168791Sjhbprotected int 76168791Sjhbparse_line(el, line) 77168791Sjhb EditLine *el; 78168791Sjhb const char *line; 79151037Sphk{ 80151037Sphk char **argv; 81151037Sphk int argc; 82151037Sphk Tokenizer *tok; 83151037Sphk 84151037Sphk tok = tok_init(NULL); 85151037Sphk tok_line(tok, line, &argc, &argv); 86151037Sphk argc = el_parse(el, argc, argv); 87151037Sphk tok_end(tok); 88151037Sphk return argc; 89151037Sphk} 90151037Sphk 91151037Sphk/* el_parse(): 92151037Sphk * Command dispatcher 93151037Sphk */ 94151037Sphkpublic int 95151037Sphkel_parse(el, argc, argv) 96151037Sphk EditLine *el; 97151037Sphk int argc; 98151037Sphk char *argv[]; 99151037Sphk{ 100151037Sphk char *ptr; 101151037Sphk int i; 102102962Siwasaki 103102962Siwasaki if (argc < 1) 104102962Siwasaki return -1; 105102962Siwasaki ptr = strchr(argv[0], ':'); 10659910Spaul if (ptr != NULL) { 107102962Siwasaki *ptr++ = '\0'; 108102962Siwasaki if (! el_match(el->el_prog, argv[0])) 10945569Seivind return 0; 11040711Swollman } 11140711Swollman else 11271576Sjasone ptr = argv[0]; 113150523Sphk 114150523Sphk for (i = 0; cmds[i].name != NULL; i++) 115150523Sphk if (strcmp(cmds[i].name, ptr) == 0) { 116150523Sphk i = (*cmds[i].func)(el, argc, argv); 11740711Swollman return -i; 118150523Sphk } 119150523Sphk 120150523Sphk return -1; 121150523Sphk} 122150523Sphk 123150523Sphk 124150523Sphk/* parse__escape(): 125150523Sphk * Parse a string of the form ^<char> \<odigit> \<char> and return 126150523Sphk * the appropriate character or -1 if the escape is not valid 127150523Sphk */ 128150523Sphkprotected int 129150523Sphkparse__escape(ptr) 13040711Swollman const char ** const ptr; 13140711Swollman{ 13240711Swollman const char *p; 133152543Syongari int c; 13440711Swollman 13540711Swollman p = *ptr; 13640711Swollman 13740711Swollman if (p[1] == 0) 13893818Sjhb return -1; 13940711Swollman 14040711Swollman if (*p == '\\') { 14140711Swollman p++; 14240711Swollman switch (*p) { 14340711Swollman case 'a': 14440711Swollman c = '\007'; /* Bell */ 14540711Swollman break; 14668727Smckusick case 'b': 14784781Sjhb c = '\010'; /* Backspace */ 148152543Syongari break; 14940711Swollman case 't': 15093818Sjhb c = '\011'; /* Horizontal Tab */ 15140711Swollman break; 15272200Sbmilekic case 'n': 15340711Swollman c = '\012'; /* New Line */ 15472200Sbmilekic break; 15540711Swollman case 'v': 15640711Swollman c = '\013'; /* Vertical Tab */ 15740711Swollman break; 15840711Swollman case 'f': 15940711Swollman c = '\014'; /* Form Feed */ 16040711Swollman break; 161162224Sjhb case 'r': 16240711Swollman c = '\015'; /* Carriage Return */ 163134040Snjl break; 164134021Snjl case 'e': 165150523Sphk c = '\033'; /* Escape */ 166152543Syongari break; 16740711Swollman case '0': 16840711Swollman case '1': 16940711Swollman case '2': 17040711Swollman case '3': 17140711Swollman case '4': 17272200Sbmilekic case '5': 173162224Sjhb case '6': 174162224Sjhb case '7': 175164881Sjhb { 176164881Sjhb int cnt, ch; 177164881Sjhb 178164881Sjhb for (cnt = 0, c = 0; cnt < 3; cnt++) { 179164881Sjhb ch = *p++; 180164881Sjhb if (ch < '0' || ch > '7') { 18140711Swollman p--; 182162224Sjhb break; 18368727Smckusick } 18468727Smckusick c = (c << 3) | (ch - '0'); 18540711Swollman } 186162224Sjhb if ((c & 0xffffff00) != 0) 187162224Sjhb return -1; 188162224Sjhb --p; 189162224Sjhb } 190162224Sjhb break; 191162224Sjhb default: 192162224Sjhb c = *p; 193162224Sjhb break; 194162224Sjhb } 195162224Sjhb } 196162224Sjhb else if (*p == '^' && isascii(p[1]) && (p[1] == '?' || isalpha(p[1]))) { 197162224Sjhb p++; 198162224Sjhb c = (*p == '?') ? '\177' : (*p & 0237); 199162224Sjhb } 200162224Sjhb else 201162224Sjhb c = *p; 202162224Sjhb *ptr = ++p; 203162224Sjhb return (unsigned char)c; 204162224Sjhb} 205162224Sjhb 206162224Sjhb/* parse__string(): 207162224Sjhb * Parse the escapes from in and put the raw string out 208162224Sjhb */ 209162224Sjhbprotected char * 210162224Sjhbparse__string(out, in) 211162224Sjhb char *out; 212162224Sjhb const char *in; 213162224Sjhb{ 214166932Sscottl char *rv = out; 215166932Sscottl int n; 216166932Sscottl for (;;) 217166932Sscottl switch (*in) { 218166932Sscottl case '\0': 219166932Sscottl *out = '\0'; 220162224Sjhb return rv; 221166932Sscottl 222162224Sjhb case '\\': 22340711Swollman case '^': 22440711Swollman if ((n = parse__escape(&in)) == -1) 22572200Sbmilekic return NULL; 22640711Swollman *out++ = n; 22740711Swollman break; 22840711Swollman 22940711Swollman default: 230159536Simp *out++ = *in++; 231159536Simp break; 232159536Simp } 233159536Simp} 234159536Simp 235159536Simp/* parse_cmd(): 236159536Simp * Return the command number for the command string given 237159536Simp * or -1 if one is not found 238159536Simp */ 239159536Simpprotected int 24040711Swollmanparse_cmd(el, cmd) 24140711Swollman EditLine *el; 242150523Sphk const char *cmd; 24340711Swollman{ 24472200Sbmilekic el_bindings_t *b; 24568727Smckusick 24645720Speter for (b = el->el_map.help; b->name != NULL; b++) 24772200Sbmilekic if (strcmp(b->name, cmd) == 0) 24840711Swollman return b->func; 24945720Speter return -1; 25040711Swollman} 25140711Swollman