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}