189 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* Copyright (c) 1985 Ceriel J.H. Jacobs */
 | |
| 
 | |
| # ifndef lint
 | |
| static char rcsid[] = "$Header$";
 | |
| # endif
 | |
| 
 | |
| # define _KEYS_
 | |
| 
 | |
| # include <ctype.h>
 | |
| # include "in_all.h"
 | |
| # include "machine.h"
 | |
| # include "keys.h"
 | |
| # include "commands.h"
 | |
| # include "prompt.h"
 | |
| # include "assert.h"
 | |
| 
 | |
| char defaultmap[] = "\
 | |
| bf=P:bl=k:bl=^K:bl=^[[A:bot=l:bot=$:bot=^[[Y:bp=-:bp=^[[V:bs=^B:bse=?:bsl=S:\
 | |
| bsp=F:chm=X:exg=x:ff=N:fl=^J:fl=^M:fl=j:fl=^[[B:fp= :fp=^[[U:fs=^D:fse=/:\
 | |
| fsl=s:fsp=f:hlp=h:nse=n:nsr=r:red=^L:rep=.:bps=Z:bss=b:fps=z:fss=d:shl=!:\
 | |
| tom=':top=\\^:top=^[[H:vis=e:wrf=w:qui=q:qui=Q:mar=m:pip=|";
 | |
| 
 | |
| char *strcpy();
 | |
| char *strcat();
 | |
| char *getenv();
 | |
| 
 | |
| /*
 | |
|  * Construct an error message and return it
 | |
|  */
 | |
| 
 | |
| STATIC char *
 | |
| kerror(key, emess) char *key, *emess; {
 | |
| 	static char ebuf[80];	/* Room for the error message */
 | |
| 
 | |
| 	(VOID) strcpy(ebuf, key);
 | |
| 	(VOID) strcat(ebuf, emess);
 | |
| 	return ebuf;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Compile a keymap into commtable. Returns an error message if there
 | |
|  * is one
 | |
|  */
 | |
| 
 | |
| STATIC char *
 | |
| compile(map, commtable)
 | |
|   register char *map; register struct keymap *commtable; {
 | |
| 	register char *mark;	/* Indicates start of mnemonic */
 | |
| 	register char *c;	/* Runs through buf */
 | |
| 	register int temp;
 | |
| 	char *escapes = commtable->k_esc;
 | |
| 	char buf[10];		/* Will hold key sequence */
 | |
| 
 | |
| 	(VOID) strcpy(commtable->k_help,"Illegal command");
 | |
| 	while (*map) {
 | |
| 		c = buf;
 | |
| 		mark = map;	/* Start of mnemonic */
 | |
| 		while (*map && *map != '=') {
 | |
| 			map++;
 | |
| 		}
 | |
| 		if (!*map) {
 | |
| 			/*
 | |
| 			 * Mnemonic should end with '='
 | |
| 			 */
 | |
| 			return kerror(mark, ": Syntax error");
 | |
| 		}
 | |
| 		*map++ = 0;
 | |
| 		while (*map) {
 | |
| 			/*
 | |
| 			 * Get key sequence
 | |
| 			 */
 | |
| 			if (*map == ':') {
 | |
| 				/*
 | |
| 				 * end of key sequence
 | |
| 				 */
 | |
| 				map++;
 | |
| 				break;
 | |
| 			}
 | |
| 			*c = *map++ & 0177;
 | |
| 			if (*c == '^' || *c == '\\') {
 | |
| 				if (!(temp = *map++)) {
 | |
| 					/*
 | |
| 					 * Escape not followed by a character
 | |
| 					 */
 | |
| 					return kerror(mark, ": Syntax error");
 | |
| 				}
 | |
| 				if (*c == '^') {
 | |
| 					if (temp == '?') *c = 0177;
 | |
| 					else *c = temp & 037;
 | |
| 				}
 | |
| 				else *c = temp & 0177;
 | |
| 			}
 | |
| 			setused(*c);
 | |
| 			c++;
 | |
| 			if (c >= &buf[9]) {
 | |
| 				return kerror(mark,": Key sequence too long");
 | |
| 			}
 | |
| 		}
 | |
| 		*c = 0;
 | |
| 		if (!(temp = lookup(mark))) {
 | |
| 			return kerror(mark,": Nonexistent function");
 | |
| 		}
 | |
| 		if (c == &buf[1] && (commands[temp].c_flags & ESC) &&
 | |
| 		    escapes < &(commtable->k_esc[sizeof(commtable->k_esc)-1])) {
 | |
| 			*escapes++ = buf[0] & 0177;
 | |
| 		}
 | |
| 		temp = addstring(buf, temp, &(commtable->k_mach));
 | |
| 		if (temp == FSM_ISPREFIX) {
 | |
| 			return kerror(mark,": Prefix of other key sequence");
 | |
| 		}
 | |
| 		if (temp == FSM_HASPREFIX) {
 | |
| 			return kerror(mark,": Other key sequence is prefix");
 | |
| 		}
 | |
| 		assert(temp == FSM_OKE);
 | |
| 		if (!strcmp(mark, "hlp")) {
 | |
| 			/*
 | |
| 			 * Create an error message to be given when the user
 | |
| 			 * types an illegal command
 | |
| 			 */
 | |
| 			(VOID) strcpy(commtable->k_help, "Type ");
 | |
| 			(VOID) strcat(commtable->k_help, buf);
 | |
| 			(VOID) strcat(commtable->k_help, " for help");
 | |
| 		}
 | |
| 	}
 | |
| 	*escapes = 0;
 | |
| 	return (char *) 0;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Initialize the keymaps
 | |
|  */
 | |
| 
 | |
| VOID
 | |
| initkeys() {
 | |
| 	register char *p;
 | |
| 	static struct keymap xx[2];
 | |
| 
 | |
| 	currmap = &xx[0];
 | |
| 	othermap = &xx[1];
 | |
| 	p = compile(defaultmap, currmap);	/* Compile default map */
 | |
| 	assert(p == (char *) 0);
 | |
| 	p = getenv("YAPKEYS");
 | |
| 	if (p) {
 | |
| 		if (!(p = compile(p, othermap))) {
 | |
| 			/*
 | |
| 			 * No errors in user defined keymap. So, use it
 | |
| 			 */
 | |
| 			do_chkm(0L);
 | |
| 			return;
 | |
| 		}
 | |
| 		error(p);
 | |
| 	}
 | |
| 	othermap = 0;		       /* No other keymap */
 | |
| }
 | |
| 
 | |
| int
 | |
| is_escape(c)
 | |
| {
 | |
| 	register char *p = currmap->k_esc;
 | |
| 
 | |
| 	while (*p) {
 | |
| 		if (c == *p++) return 1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static char keyset[16];		/* bitset indicating which keys are
 | |
| 				 * used
 | |
| 				 */
 | |
| /*
 | |
|  * Mark key "key" as used
 | |
|  */
 | |
| 
 | |
| VOID
 | |
| setused(key) int key; {
 | |
| 
 | |
| 	keyset[(key & 0177) >> 3] |= (1 << (key & 07));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return non-zero if key "key" is used in a keymap
 | |
|  */
 | |
| 
 | |
| int
 | |
| isused(key) int key; {
 | |
| 
 | |
| 	return keyset[(key & 0177) >> 3] & (1 << (key & 07));
 | |
| }
 | 
