master xplshn/aruu / cmd / extra / yap / keys.c
  1/* Copyright (c) 1985 Ceriel J.H. Jacobs */
  2
  3#include "keys.h"
  4#include "assert.h"
  5#include "commands.h"
  6#include "in_all.h"
  7#include "machine.h"
  8#include "prompt.h"
  9#include <ctype.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  keyset[(key & 0x7f) >> 3] |= (1 << (key & 0x07));
175}
176
177/*
178 * return non-zero if key "key" is used in a keymap
179 */
180
181int
182isused(int key)
183{
184  return keyset[(key & 0x7f) >> 3] & (1 << (key & 0x07));
185}