main keys.c
  1/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  2
  3#include <ctype.h>
  4#include "in_all.h"
  5#include "machine.h"
  6#include "keys.h"
  7#include "commands.h"
  8#include "prompt.h"
  9#include "assert.h"
 10
 11struct keymap *currmap, *othermap;
 12
 13char defaultmap[] = "\
 14bf=P:bl=k:bl=^K:bl=^[[A:bot=l:bot=$:bp=-:bs=^B:bse=?:bsl=S:bsp=F:chm=X:exg=x:\
 15ff=N:fl=^J:fl=^M:fl=j:fl=^[[B:fp= :fs=^D:fse=/:fsl=s:fsp=f:hlp=h:nse=n:nsr=r:\
 16red=^L:rep=.:bps=Z:bss=b:fps=z:fss=d:shl=!:tom=':top=\\^:vis=e:\
 17wrf=w:qui=q:qui=Q:mar=m:pip=|";
 18
 19/*
 20 * Construct an error message and return it
 21 */
 22
 23static char *
 24kerror(char *key, char *emess)
 25{
 26	static char ebuf[80]; /* Room for the error message */
 27
 28	(void)strcpy(ebuf, key);
 29	(void)strcat(ebuf, emess);
 30	return ebuf;
 31}
 32
 33/*
 34 * Compile a keymap into commtable. Returns an error message if there
 35 * is one
 36 */
 37
 38static char *
 39compile(char *map, struct keymap *commtable)
 40{
 41	char *mark; /* Indicates start of mnemonic */
 42	char *c;    /* Runs through buf */
 43	int temp;
 44	char *escapes = commtable->k_esc;
 45	char buf[10]; /* Will hold key sequence */
 46
 47	(void)strcpy(commtable->k_help, "Illegal command");
 48	while (*map) {
 49		c = buf;
 50		mark = map; /* Start of mnemonic */
 51		while (*map && *map != '=') {
 52			map++;
 53		}
 54		if (!*map) {
 55			/*
 56			 * Mnemonic should end with '='
 57			 */
 58			return kerror(mark, ": Syntax error");
 59		}
 60		*map++ = 0;
 61		while (*map) {
 62			/*
 63			 * Get key sequence
 64			 */
 65			if (*map == ':') {
 66				/*
 67				 * end of key sequence
 68				 */
 69				map++;
 70				break;
 71			}
 72			*c = *map++ & 0x7f;
 73			if (*c == '^' || *c == '\\') {
 74				if (!(temp = *map++)) {
 75					/*
 76					 * Escape not followed by a character
 77					 */
 78					return kerror(mark, ": Syntax error");
 79				}
 80				if (*c == '^') {
 81					if (temp == '?')
 82						*c = 0x7f;
 83					else
 84						*c = temp & 0x1f;
 85				} else
 86					*c = temp & 0x7f;
 87			}
 88			setused(*c);
 89			c++;
 90			if (c >= &buf[9]) {
 91				return kerror(mark, ": Key sequence too long");
 92			}
 93		}
 94		*c = 0;
 95		if (!(temp = lookup(mark))) {
 96			return kerror(mark, ": Nonexistent function");
 97		}
 98		if (c == &buf[1] && (commands[temp].c_flags & ESC) &&
 99		    escapes < &(commtable->k_esc[sizeof(commtable->k_esc) - 1])) {
100			*escapes++ = buf[0] & 0x7f;
101		}
102		temp = addstring(buf, temp, &(commtable->k_mach));
103		if (temp == FSM_ISPREFIX) {
104			return kerror(mark, ": Prefix of other key sequence");
105		}
106		if (temp == FSM_HASPREFIX) {
107			return kerror(mark, ": Other key sequence is prefix");
108		}
109		assert(temp == FSM_OKE);
110		if (!strcmp(mark, "hlp")) {
111			/*
112			 * Create an error message to be given when the user
113			 * types an illegal command
114			 */
115			(void)strcpy(commtable->k_help, "Type ");
116			(void)strcat(commtable->k_help, buf);
117			(void)strcat(commtable->k_help, " for help");
118		}
119	}
120	*escapes = 0;
121	return (char *)0;
122}
123
124/*
125 * Initialize the keymaps
126 */
127
128void
129initkeys()
130{
131	char *p;
132	static struct keymap xx[2];
133
134	currmap = &xx[0];
135	othermap = &xx[1];
136	p = compile(defaultmap, currmap); /* Compile default map */
137	assert(p == (char *)0);
138	p = getenv("YAPKEYS");
139	if (p) {
140		if (!(p = compile(p, othermap))) {
141			/*
142			 * No errors in user defined keymap. So, use it
143			 */
144			do_chkm(0L);
145			return;
146		}
147		error(p);
148	}
149	othermap = 0; /* No other keymap */
150}
151
152int
153is_escape(int c)
154{
155	char *p = currmap->k_esc;
156
157	while (*p) {
158		if (c == *p++)
159			return 1;
160	}
161	return 0;
162}
163
164static char keyset[16]; /* bitset indicating which keys are
165                         * used
166                         */
167/*
168 * Mark key "key" as used
169 */
170
171void
172setused(int key)
173{
174
175	keyset[(key & 0x7f) >> 3] |= (1 << (key & 0x07));
176}
177
178/*
179 * return non-zero if key "key" is used in a keymap
180 */
181
182int
183isused(int key)
184{
185
186	return keyset[(key & 0x7f) >> 3] & (1 << (key & 0x07));
187}