xref: /freebsd/contrib/tcsh/tc.bind.c (revision c80476e4c3e6730697b9424f88dfa74d1907cabd)
1c80476e4SDavid E. O'Brien /* $Header: /src/pub/tcsh/tc.bind.c,v 3.33 1998/11/24 18:17:40 christos Exp $ */
2c80476e4SDavid E. O'Brien /*
3c80476e4SDavid E. O'Brien  * tc.bind.c: Key binding functions
4c80476e4SDavid E. O'Brien  */
5c80476e4SDavid E. O'Brien /*-
6c80476e4SDavid E. O'Brien  * Copyright (c) 1980, 1991 The Regents of the University of California.
7c80476e4SDavid E. O'Brien  * All rights reserved.
8c80476e4SDavid E. O'Brien  *
9c80476e4SDavid E. O'Brien  * Redistribution and use in source and binary forms, with or without
10c80476e4SDavid E. O'Brien  * modification, are permitted provided that the following conditions
11c80476e4SDavid E. O'Brien  * are met:
12c80476e4SDavid E. O'Brien  * 1. Redistributions of source code must retain the above copyright
13c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer.
14c80476e4SDavid E. O'Brien  * 2. Redistributions in binary form must reproduce the above copyright
15c80476e4SDavid E. O'Brien  *    notice, this list of conditions and the following disclaimer in the
16c80476e4SDavid E. O'Brien  *    documentation and/or other materials provided with the distribution.
17c80476e4SDavid E. O'Brien  * 3. All advertising materials mentioning features or use of this software
18c80476e4SDavid E. O'Brien  *    must display the following acknowledgement:
19c80476e4SDavid E. O'Brien  *	This product includes software developed by the University of
20c80476e4SDavid E. O'Brien  *	California, Berkeley and its contributors.
21c80476e4SDavid E. O'Brien  * 4. Neither the name of the University nor the names of its contributors
22c80476e4SDavid E. O'Brien  *    may be used to endorse or promote products derived from this software
23c80476e4SDavid E. O'Brien  *    without specific prior written permission.
24c80476e4SDavid E. O'Brien  *
25c80476e4SDavid E. O'Brien  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26c80476e4SDavid E. O'Brien  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27c80476e4SDavid E. O'Brien  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28c80476e4SDavid E. O'Brien  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29c80476e4SDavid E. O'Brien  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30c80476e4SDavid E. O'Brien  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31c80476e4SDavid E. O'Brien  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32c80476e4SDavid E. O'Brien  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33c80476e4SDavid E. O'Brien  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34c80476e4SDavid E. O'Brien  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35c80476e4SDavid E. O'Brien  * SUCH DAMAGE.
36c80476e4SDavid E. O'Brien  */
37c80476e4SDavid E. O'Brien #include "sh.h"
38c80476e4SDavid E. O'Brien 
39c80476e4SDavid E. O'Brien RCSID("$Id: tc.bind.c,v 3.33 1998/11/24 18:17:40 christos Exp $")
40c80476e4SDavid E. O'Brien 
41c80476e4SDavid E. O'Brien #include "ed.h"
42c80476e4SDavid E. O'Brien #include "ed.defns.h"
43c80476e4SDavid E. O'Brien 
44c80476e4SDavid E. O'Brien #ifdef OBSOLETE
45c80476e4SDavid E. O'Brien static	int    tocontrol	__P((int));
46c80476e4SDavid E. O'Brien static	char  *unparsekey	__P((int));
47c80476e4SDavid E. O'Brien static	KEYCMD getkeycmd	__P((Char **));
48c80476e4SDavid E. O'Brien static	int    parsekey		__P((Char **));
49c80476e4SDavid E. O'Brien static	void   pkeys		__P((int, int));
50c80476e4SDavid E. O'Brien #endif /* OBSOLETE */
51c80476e4SDavid E. O'Brien 
52c80476e4SDavid E. O'Brien static	void   printkey		__P((KEYCMD *, CStr *));
53c80476e4SDavid E. O'Brien static	KEYCMD parsecmd		__P((Char *));
54c80476e4SDavid E. O'Brien static  void   bad_spec		__P((Char *));
55c80476e4SDavid E. O'Brien static	CStr  *parsestring	__P((Char *, CStr *));
56c80476e4SDavid E. O'Brien static	CStr  *parsebind	__P((Char *, CStr *));
57c80476e4SDavid E. O'Brien static	void   print_all_keys	__P((void));
58c80476e4SDavid E. O'Brien static	void   printkeys	__P((KEYCMD *, int, int));
59c80476e4SDavid E. O'Brien static	void   bindkey_usage	__P((void));
60c80476e4SDavid E. O'Brien static	void   list_functions	__P((void));
61c80476e4SDavid E. O'Brien 
62c80476e4SDavid E. O'Brien extern int MapsAreInited;
63c80476e4SDavid E. O'Brien 
64c80476e4SDavid E. O'Brien 
65c80476e4SDavid E. O'Brien 
66c80476e4SDavid E. O'Brien 
67c80476e4SDavid E. O'Brien /*ARGSUSED*/
68c80476e4SDavid E. O'Brien void
69c80476e4SDavid E. O'Brien dobindkey(v, c)
70c80476e4SDavid E. O'Brien     Char  **v;
71c80476e4SDavid E. O'Brien     struct command *c;
72c80476e4SDavid E. O'Brien {
73c80476e4SDavid E. O'Brien     KEYCMD *map;
74c80476e4SDavid E. O'Brien     int     ntype, no, remove, key, bind;
75c80476e4SDavid E. O'Brien     Char   *par;
76c80476e4SDavid E. O'Brien     Char    p;
77c80476e4SDavid E. O'Brien     KEYCMD  cmd;
78c80476e4SDavid E. O'Brien     CStr    in;
79c80476e4SDavid E. O'Brien     CStr    out;
80c80476e4SDavid E. O'Brien     Char    inbuf[200];
81c80476e4SDavid E. O'Brien     Char    outbuf[200];
82c80476e4SDavid E. O'Brien     uChar   ch;
83c80476e4SDavid E. O'Brien     in.buf = inbuf;
84c80476e4SDavid E. O'Brien     out.buf = outbuf;
85c80476e4SDavid E. O'Brien     in.len = 0;
86c80476e4SDavid E. O'Brien     out.len = 0;
87c80476e4SDavid E. O'Brien 
88c80476e4SDavid E. O'Brien     USE(c);
89c80476e4SDavid E. O'Brien     if (!MapsAreInited)
90c80476e4SDavid E. O'Brien 	ed_InitMaps();
91c80476e4SDavid E. O'Brien 
92c80476e4SDavid E. O'Brien     map = CcKeyMap;
93c80476e4SDavid E. O'Brien     ntype = XK_CMD;
94c80476e4SDavid E. O'Brien     key = remove = bind = 0;
95c80476e4SDavid E. O'Brien     for (no = 1, par = v[no];
96c80476e4SDavid E. O'Brien 	 par != NULL && (*par++ & CHAR) == '-'; no++, par = v[no]) {
97c80476e4SDavid E. O'Brien 	if ((p = (*par & CHAR)) == '-') {
98c80476e4SDavid E. O'Brien 	    no++;
99c80476e4SDavid E. O'Brien 	    break;
100c80476e4SDavid E. O'Brien 	}
101c80476e4SDavid E. O'Brien 	else
102c80476e4SDavid E. O'Brien 	    switch (p) {
103c80476e4SDavid E. O'Brien 	    case 'b':
104c80476e4SDavid E. O'Brien 		bind = 1;
105c80476e4SDavid E. O'Brien 		break;
106c80476e4SDavid E. O'Brien 	    case 'k':
107c80476e4SDavid E. O'Brien 		key = 1;
108c80476e4SDavid E. O'Brien 		break;
109c80476e4SDavid E. O'Brien 	    case 'a':
110c80476e4SDavid E. O'Brien 		map = CcAltMap;
111c80476e4SDavid E. O'Brien 		break;
112c80476e4SDavid E. O'Brien 	    case 's':
113c80476e4SDavid E. O'Brien 		ntype = XK_STR;
114c80476e4SDavid E. O'Brien 		break;
115c80476e4SDavid E. O'Brien 	    case 'c':
116c80476e4SDavid E. O'Brien 		ntype = XK_EXE;
117c80476e4SDavid E. O'Brien 		break;
118c80476e4SDavid E. O'Brien 	    case 'r':
119c80476e4SDavid E. O'Brien 		remove = 1;
120c80476e4SDavid E. O'Brien 		break;
121c80476e4SDavid E. O'Brien 	    case 'v':
122c80476e4SDavid E. O'Brien 		ed_InitVIMaps();
123c80476e4SDavid E. O'Brien 		return;
124c80476e4SDavid E. O'Brien 	    case 'e':
125c80476e4SDavid E. O'Brien 		ed_InitEmacsMaps();
126c80476e4SDavid E. O'Brien 		return;
127c80476e4SDavid E. O'Brien 	    case 'd':
128c80476e4SDavid E. O'Brien #ifdef VIDEFAULT
129c80476e4SDavid E. O'Brien 		ed_InitVIMaps();
130c80476e4SDavid E. O'Brien #else /* EMACSDEFAULT */
131c80476e4SDavid E. O'Brien 		ed_InitEmacsMaps();
132c80476e4SDavid E. O'Brien #endif /* VIDEFAULT */
133c80476e4SDavid E. O'Brien 		return;
134c80476e4SDavid E. O'Brien 	    case 'l':
135c80476e4SDavid E. O'Brien 		list_functions();
136c80476e4SDavid E. O'Brien 		return;
137c80476e4SDavid E. O'Brien 	    default:
138c80476e4SDavid E. O'Brien 		bindkey_usage();
139c80476e4SDavid E. O'Brien 		return;
140c80476e4SDavid E. O'Brien 	    }
141c80476e4SDavid E. O'Brien     }
142c80476e4SDavid E. O'Brien 
143c80476e4SDavid E. O'Brien     if (!v[no]) {
144c80476e4SDavid E. O'Brien 	print_all_keys();
145c80476e4SDavid E. O'Brien 	return;
146c80476e4SDavid E. O'Brien     }
147c80476e4SDavid E. O'Brien 
148c80476e4SDavid E. O'Brien     if (key) {
149c80476e4SDavid E. O'Brien 	if (!IsArrowKey(v[no]))
150c80476e4SDavid E. O'Brien 	    xprintf(CGETS(20, 1, "Invalid key name `%S'\n"), v[no]);
151c80476e4SDavid E. O'Brien 	in.buf = v[no++];
152c80476e4SDavid E. O'Brien 	in.len = Strlen(in.buf);
153c80476e4SDavid E. O'Brien     }
154c80476e4SDavid E. O'Brien     else {
155c80476e4SDavid E. O'Brien 	if (bind) {
156c80476e4SDavid E. O'Brien 	    if (parsebind(v[no++], &in) == NULL)
157c80476e4SDavid E. O'Brien 		return;
158c80476e4SDavid E. O'Brien 	}
159c80476e4SDavid E. O'Brien 	else {
160c80476e4SDavid E. O'Brien 	    if (parsestring(v[no++], &in) == NULL)
161c80476e4SDavid E. O'Brien 		return;
162c80476e4SDavid E. O'Brien 	}
163c80476e4SDavid E. O'Brien     }
164c80476e4SDavid E. O'Brien 
165c80476e4SDavid E. O'Brien     ch = (uChar) in.buf[0];
166c80476e4SDavid E. O'Brien 
167c80476e4SDavid E. O'Brien     if (remove) {
168c80476e4SDavid E. O'Brien 	if (key) {
169c80476e4SDavid E. O'Brien 	    (void) ClearArrowKeys(&in);
170c80476e4SDavid E. O'Brien 	    return;
171c80476e4SDavid E. O'Brien 	}
172c80476e4SDavid E. O'Brien 	if (in.len > 1) {
173c80476e4SDavid E. O'Brien 	    (void) DeleteXkey(&in);
174c80476e4SDavid E. O'Brien 	}
175c80476e4SDavid E. O'Brien 	else if (map[ch] == F_XKEY) {
176c80476e4SDavid E. O'Brien 	    (void) DeleteXkey(&in);
177c80476e4SDavid E. O'Brien 	    map[ch] = F_UNASSIGNED;
178c80476e4SDavid E. O'Brien 	}
179c80476e4SDavid E. O'Brien 	else {
180c80476e4SDavid E. O'Brien 	    map[ch] = F_UNASSIGNED;
181c80476e4SDavid E. O'Brien 	}
182c80476e4SDavid E. O'Brien 	return;
183c80476e4SDavid E. O'Brien     }
184c80476e4SDavid E. O'Brien     if (!v[no]) {
185c80476e4SDavid E. O'Brien 	if (key)
186c80476e4SDavid E. O'Brien 	    PrintArrowKeys(&in);
187c80476e4SDavid E. O'Brien 	else
188c80476e4SDavid E. O'Brien 	    printkey(map, &in);
189c80476e4SDavid E. O'Brien 	return;
190c80476e4SDavid E. O'Brien     }
191c80476e4SDavid E. O'Brien     if (v[no + 1]) {
192c80476e4SDavid E. O'Brien 	bindkey_usage();
193c80476e4SDavid E. O'Brien 	return;
194c80476e4SDavid E. O'Brien     }
195c80476e4SDavid E. O'Brien     switch (ntype) {
196c80476e4SDavid E. O'Brien     case XK_STR:
197c80476e4SDavid E. O'Brien     case XK_EXE:
198c80476e4SDavid E. O'Brien 	if (parsestring(v[no], &out) == NULL)
199c80476e4SDavid E. O'Brien 	    return;
200c80476e4SDavid E. O'Brien 	if (key) {
201c80476e4SDavid E. O'Brien 	    if (SetArrowKeys(&in, XmapStr(&out), ntype) == -1)
202c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 2, "Bad key name: %S\n"), in);
203c80476e4SDavid E. O'Brien 	}
204c80476e4SDavid E. O'Brien 	else
205c80476e4SDavid E. O'Brien 	    AddXkey(&in, XmapStr(&out), ntype);
206c80476e4SDavid E. O'Brien 	map[ch] = F_XKEY;
207c80476e4SDavid E. O'Brien 	break;
208c80476e4SDavid E. O'Brien     case XK_CMD:
209c80476e4SDavid E. O'Brien 	if ((cmd = parsecmd(v[no])) == 0)
210c80476e4SDavid E. O'Brien 	    return;
211c80476e4SDavid E. O'Brien 	if (key)
212c80476e4SDavid E. O'Brien 	    (void) SetArrowKeys(&in, XmapCmd((int) cmd), ntype);
213c80476e4SDavid E. O'Brien 	else {
214c80476e4SDavid E. O'Brien 	    if (in.len > 1) {
215c80476e4SDavid E. O'Brien 		AddXkey(&in, XmapCmd((int) cmd), ntype);
216c80476e4SDavid E. O'Brien 		map[ch] = F_XKEY;
217c80476e4SDavid E. O'Brien 	    }
218c80476e4SDavid E. O'Brien 	    else {
219c80476e4SDavid E. O'Brien 		ClearXkey(map, &in);
220c80476e4SDavid E. O'Brien 		map[ch] = cmd;
221c80476e4SDavid E. O'Brien 	    }
222c80476e4SDavid E. O'Brien 	}
223c80476e4SDavid E. O'Brien 	break;
224c80476e4SDavid E. O'Brien     default:
225c80476e4SDavid E. O'Brien 	abort();
226c80476e4SDavid E. O'Brien 	break;
227c80476e4SDavid E. O'Brien     }
228c80476e4SDavid E. O'Brien     if (key)
229c80476e4SDavid E. O'Brien 	BindArrowKeys();
230c80476e4SDavid E. O'Brien }
231c80476e4SDavid E. O'Brien 
232c80476e4SDavid E. O'Brien static void
233c80476e4SDavid E. O'Brien printkey(map, in)
234c80476e4SDavid E. O'Brien     KEYCMD *map;
235c80476e4SDavid E. O'Brien     CStr   *in;
236c80476e4SDavid E. O'Brien {
237c80476e4SDavid E. O'Brien     unsigned char outbuf[100];
238c80476e4SDavid E. O'Brien     register struct KeyFuncs *fp;
239c80476e4SDavid E. O'Brien 
240c80476e4SDavid E. O'Brien     if (in->len < 2) {
241c80476e4SDavid E. O'Brien 	(void) unparsestring(in, outbuf, STRQQ);
242c80476e4SDavid E. O'Brien 	for (fp = FuncNames; fp->name; fp++) {
243c80476e4SDavid E. O'Brien 	    if (fp->func == map[(uChar) *(in->buf)]) {
244c80476e4SDavid E. O'Brien 		xprintf("%s\t->\t%s\n", outbuf, fp->name);
245c80476e4SDavid E. O'Brien 	    }
246c80476e4SDavid E. O'Brien 	}
247c80476e4SDavid E. O'Brien     }
248c80476e4SDavid E. O'Brien     else
249c80476e4SDavid E. O'Brien 	PrintXkey(in);
250c80476e4SDavid E. O'Brien }
251c80476e4SDavid E. O'Brien 
252c80476e4SDavid E. O'Brien static  KEYCMD
253c80476e4SDavid E. O'Brien parsecmd(str)
254c80476e4SDavid E. O'Brien     Char   *str;
255c80476e4SDavid E. O'Brien {
256c80476e4SDavid E. O'Brien     register struct KeyFuncs *fp;
257c80476e4SDavid E. O'Brien 
258c80476e4SDavid E. O'Brien     for (fp = FuncNames; fp->name; fp++) {
259c80476e4SDavid E. O'Brien 	if (strcmp(short2str(str), fp->name) == 0) {
260c80476e4SDavid E. O'Brien 	    return (KEYCMD) fp->func;
261c80476e4SDavid E. O'Brien 	}
262c80476e4SDavid E. O'Brien     }
263c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 3, "Bad command name: %S\n"), str);
264c80476e4SDavid E. O'Brien     return 0;
265c80476e4SDavid E. O'Brien }
266c80476e4SDavid E. O'Brien 
267c80476e4SDavid E. O'Brien 
268c80476e4SDavid E. O'Brien static void
269c80476e4SDavid E. O'Brien bad_spec(str)
270c80476e4SDavid E. O'Brien     Char *str;
271c80476e4SDavid E. O'Brien {
272c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 4, "Bad key spec %S\n"), str);
273c80476e4SDavid E. O'Brien }
274c80476e4SDavid E. O'Brien 
275c80476e4SDavid E. O'Brien static CStr *
276c80476e4SDavid E. O'Brien parsebind(s, str)
277c80476e4SDavid E. O'Brien     Char *s;
278c80476e4SDavid E. O'Brien     CStr *str;
279c80476e4SDavid E. O'Brien {
280c80476e4SDavid E. O'Brien #ifdef DSPMBYTE
281c80476e4SDavid E. O'Brien     extern bool NoNLSRebind;
282c80476e4SDavid E. O'Brien #endif /* DSPMBYTE */
283c80476e4SDavid E. O'Brien     Char *b = str->buf;
284c80476e4SDavid E. O'Brien 
285c80476e4SDavid E. O'Brien     if (Iscntrl(*s)) {
286c80476e4SDavid E. O'Brien 	*b++ = *s;
287c80476e4SDavid E. O'Brien 	*b = '\0';
288c80476e4SDavid E. O'Brien 	str->len = (int) (b - str->buf);
289c80476e4SDavid E. O'Brien 	return str;
290c80476e4SDavid E. O'Brien     }
291c80476e4SDavid E. O'Brien 
292c80476e4SDavid E. O'Brien     switch (*s) {
293c80476e4SDavid E. O'Brien     case '^':
294c80476e4SDavid E. O'Brien 	s++;
295c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX
296c80476e4SDavid E. O'Brien 	*b++ = (*s == '?') ? '\177' : ((*s & CHAR) & 0237);
297c80476e4SDavid E. O'Brien #else /*_OSD_POSIX*/
298c80476e4SDavid E. O'Brien 	*b++ = (*s == '?') ? CTL_ESC('\177') : _toebcdic[_toascii[*s & CHAR] & 0237];
299c80476e4SDavid E. O'Brien #endif /*_OSD_POSIX*/
300c80476e4SDavid E. O'Brien 	*b = '\0';
301c80476e4SDavid E. O'Brien 	break;
302c80476e4SDavid E. O'Brien 
303c80476e4SDavid E. O'Brien     case 'F':
304c80476e4SDavid E. O'Brien     case 'M':
305c80476e4SDavid E. O'Brien     case 'X':
306c80476e4SDavid E. O'Brien     case 'C':
307c80476e4SDavid E. O'Brien #ifdef WINNT
308c80476e4SDavid E. O'Brien     case 'N':
309c80476e4SDavid E. O'Brien #endif /* WINNT */
310c80476e4SDavid E. O'Brien 	if (s[1] != '-' || s[2] == '\0') {
311c80476e4SDavid E. O'Brien 	    bad_spec(s);
312c80476e4SDavid E. O'Brien 	    return NULL;
313c80476e4SDavid E. O'Brien 	}
314c80476e4SDavid E. O'Brien 	s += 2;
315c80476e4SDavid E. O'Brien 	switch (s[-2]) {
316c80476e4SDavid E. O'Brien 	case 'F': case 'f':	/* Turn into ^[str */
317c80476e4SDavid E. O'Brien 	    *b++ = CTL_ESC('\033');
318c80476e4SDavid E. O'Brien 	    while ((*b++ = *s++) != '\0')
319c80476e4SDavid E. O'Brien 		continue;
320c80476e4SDavid E. O'Brien 	    b--;
321c80476e4SDavid E. O'Brien 	    break;
322c80476e4SDavid E. O'Brien 
323c80476e4SDavid E. O'Brien 	case 'C': case 'c':	/* Turn into ^c */
324c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX
325c80476e4SDavid E. O'Brien 	    *b++ = (*s == '?') ? '\177' : ((*s & CHAR) & 0237);
326c80476e4SDavid E. O'Brien #else /*_OSD_POSIX*/
327c80476e4SDavid E. O'Brien 	    *b++ = (*s == '?') ? CTL_ESC('\177') : _toebcdic[_toascii[*s & CHAR] & 0237];
328c80476e4SDavid E. O'Brien #endif /*_OSD_POSIX*/
329c80476e4SDavid E. O'Brien 	    *b = '\0';
330c80476e4SDavid E. O'Brien 	    break;
331c80476e4SDavid E. O'Brien 
332c80476e4SDavid E. O'Brien 	case 'X' : case 'x':	/* Turn into ^Xc */
333c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX
334c80476e4SDavid E. O'Brien 	    *b++ = 'X' & 0237;
335c80476e4SDavid E. O'Brien #else /*_OSD_POSIX*/
336c80476e4SDavid E. O'Brien 	    *b++ = _toebcdic[_toascii['X'] & 0237];
337c80476e4SDavid E. O'Brien #endif /*_OSD_POSIX*/
338c80476e4SDavid E. O'Brien 	    *b++ = *s;
339c80476e4SDavid E. O'Brien 	    *b = '\0';
340c80476e4SDavid E. O'Brien 	    break;
341c80476e4SDavid E. O'Brien 
342c80476e4SDavid E. O'Brien 	case 'M' : case 'm':	/* Turn into 0x80|c */
343c80476e4SDavid E. O'Brien #ifdef DSPMBYTE
344c80476e4SDavid E. O'Brien 	    if (!NoNLSRebind) {
345c80476e4SDavid E. O'Brien 	    	*b++ = CTL_ESC('\033');
346c80476e4SDavid E. O'Brien 	    	*b++ = *s;
347c80476e4SDavid E. O'Brien 	    } else {
348c80476e4SDavid E. O'Brien #endif /* DSPMBYTE */
349c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX
350c80476e4SDavid E. O'Brien 	    *b++ = *s | 0x80;
351c80476e4SDavid E. O'Brien #else /*_OSD_POSIX*/
352c80476e4SDavid E. O'Brien 	    *b++ = _toebcdic[_toascii[*s] | 0x80];
353c80476e4SDavid E. O'Brien #endif /*_OSD_POSIX*/
354c80476e4SDavid E. O'Brien #ifdef DSPMBYTE
355c80476e4SDavid E. O'Brien 	    }
356c80476e4SDavid E. O'Brien #endif /* DSPMBYTE */
357c80476e4SDavid E. O'Brien 	    *b = '\0';
358c80476e4SDavid E. O'Brien 	    break;
359c80476e4SDavid E. O'Brien #ifdef WINNT
360c80476e4SDavid E. O'Brien 	case 'N' : case 'n':	/* NT */
361c80476e4SDavid E. O'Brien 		{
362c80476e4SDavid E. O'Brien 			Char bnt;
363c80476e4SDavid E. O'Brien 
364c80476e4SDavid E. O'Brien 			bnt = nt_translate_bindkey(s);
365c80476e4SDavid E. O'Brien 			if (bnt != 0)
366c80476e4SDavid E. O'Brien 				*b++ = bnt;
367c80476e4SDavid E. O'Brien 			else
368c80476e4SDavid E. O'Brien 				bad_spec(s);
369c80476e4SDavid E. O'Brien 		}
370c80476e4SDavid E. O'Brien 	    break;
371c80476e4SDavid E. O'Brien #endif /* WINNT */
372c80476e4SDavid E. O'Brien 
373c80476e4SDavid E. O'Brien 	default:
374c80476e4SDavid E. O'Brien 	    abort();
375c80476e4SDavid E. O'Brien 	    /*NOTREACHED*/
376c80476e4SDavid E. O'Brien 	    return NULL;
377c80476e4SDavid E. O'Brien 	}
378c80476e4SDavid E. O'Brien 	break;
379c80476e4SDavid E. O'Brien 
380c80476e4SDavid E. O'Brien     default:
381c80476e4SDavid E. O'Brien 	bad_spec(s);
382c80476e4SDavid E. O'Brien 	return NULL;
383c80476e4SDavid E. O'Brien     }
384c80476e4SDavid E. O'Brien 
385c80476e4SDavid E. O'Brien     str->len = (int) (b - str->buf);
386c80476e4SDavid E. O'Brien     return str;
387c80476e4SDavid E. O'Brien }
388c80476e4SDavid E. O'Brien 
389c80476e4SDavid E. O'Brien 
390c80476e4SDavid E. O'Brien static CStr *
391c80476e4SDavid E. O'Brien parsestring(str, buf)
392c80476e4SDavid E. O'Brien     Char   *str;
393c80476e4SDavid E. O'Brien     CStr   *buf;
394c80476e4SDavid E. O'Brien {
395c80476e4SDavid E. O'Brien     Char   *b;
396c80476e4SDavid E. O'Brien     const Char   *p;
397c80476e4SDavid E. O'Brien     int    es;
398c80476e4SDavid E. O'Brien 
399c80476e4SDavid E. O'Brien     b = buf->buf;
400c80476e4SDavid E. O'Brien     if (*str == 0) {
401c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 5, "Null string specification\n"));
402c80476e4SDavid E. O'Brien 	return NULL;
403c80476e4SDavid E. O'Brien     }
404c80476e4SDavid E. O'Brien 
405c80476e4SDavid E. O'Brien     for (p = str; *p != 0; p++) {
406c80476e4SDavid E. O'Brien 	if ((*p & CHAR) == '\\' || (*p & CHAR) == '^') {
407c80476e4SDavid E. O'Brien 	    if ((es = parseescape(&p)) == -1)
408c80476e4SDavid E. O'Brien 		return 0;
409c80476e4SDavid E. O'Brien 	    else
410c80476e4SDavid E. O'Brien 		*b++ = (Char) es;
411c80476e4SDavid E. O'Brien 	}
412c80476e4SDavid E. O'Brien 	else
413c80476e4SDavid E. O'Brien 	    *b++ = *p & CHAR;
414c80476e4SDavid E. O'Brien     }
415c80476e4SDavid E. O'Brien     *b = 0;
416c80476e4SDavid E. O'Brien     buf->len = (int) (b - buf->buf);
417c80476e4SDavid E. O'Brien     return buf;
418c80476e4SDavid E. O'Brien }
419c80476e4SDavid E. O'Brien 
420c80476e4SDavid E. O'Brien static void
421c80476e4SDavid E. O'Brien print_all_keys()
422c80476e4SDavid E. O'Brien {
423c80476e4SDavid E. O'Brien     int     prev, i;
424c80476e4SDavid E. O'Brien     CStr nilstr;
425c80476e4SDavid E. O'Brien     nilstr.buf = NULL;
426c80476e4SDavid E. O'Brien     nilstr.len = 0;
427c80476e4SDavid E. O'Brien 
428c80476e4SDavid E. O'Brien 
429c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 6, "Standard key bindings\n"));
430c80476e4SDavid E. O'Brien     prev = 0;
431c80476e4SDavid E. O'Brien     for (i = 0; i < 256; i++) {
432c80476e4SDavid E. O'Brien 	if (CcKeyMap[prev] == CcKeyMap[i])
433c80476e4SDavid E. O'Brien 	    continue;
434c80476e4SDavid E. O'Brien 	printkeys(CcKeyMap, prev, i - 1);
435c80476e4SDavid E. O'Brien 	prev = i;
436c80476e4SDavid E. O'Brien     }
437c80476e4SDavid E. O'Brien     printkeys(CcKeyMap, prev, i - 1);
438c80476e4SDavid E. O'Brien 
439c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 7, "Alternative key bindings\n"));
440c80476e4SDavid E. O'Brien     prev = 0;
441c80476e4SDavid E. O'Brien     for (i = 0; i < 256; i++) {
442c80476e4SDavid E. O'Brien 	if (CcAltMap[prev] == CcAltMap[i])
443c80476e4SDavid E. O'Brien 	    continue;
444c80476e4SDavid E. O'Brien 	printkeys(CcAltMap, prev, i - 1);
445c80476e4SDavid E. O'Brien 	prev = i;
446c80476e4SDavid E. O'Brien     }
447c80476e4SDavid E. O'Brien     printkeys(CcAltMap, prev, i - 1);
448c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 8, "Multi-character bindings\n"));
449c80476e4SDavid E. O'Brien     PrintXkey(NULL);	/* print all Xkey bindings */
450c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 9, "Arrow key bindings\n"));
451c80476e4SDavid E. O'Brien     PrintArrowKeys(&nilstr);
452c80476e4SDavid E. O'Brien }
453c80476e4SDavid E. O'Brien 
454c80476e4SDavid E. O'Brien static void
455c80476e4SDavid E. O'Brien printkeys(map, first, last)
456c80476e4SDavid E. O'Brien     KEYCMD *map;
457c80476e4SDavid E. O'Brien     int     first, last;
458c80476e4SDavid E. O'Brien {
459c80476e4SDavid E. O'Brien     register struct KeyFuncs *fp;
460c80476e4SDavid E. O'Brien     Char    firstbuf[2], lastbuf[2];
461c80476e4SDavid E. O'Brien     CStr fb, lb;
462c80476e4SDavid E. O'Brien     unsigned char unparsbuf[10], extrabuf[10];
463c80476e4SDavid E. O'Brien     fb.buf = firstbuf;
464c80476e4SDavid E. O'Brien     lb.buf = lastbuf;
465c80476e4SDavid E. O'Brien 
466c80476e4SDavid E. O'Brien     firstbuf[0] = (Char) first;
467c80476e4SDavid E. O'Brien     firstbuf[1] = 0;
468c80476e4SDavid E. O'Brien     lastbuf[0] = (Char) last;
469c80476e4SDavid E. O'Brien     lastbuf[1] = 0;
470c80476e4SDavid E. O'Brien     fb.len = 1;
471c80476e4SDavid E. O'Brien     lb.len = 1;
472c80476e4SDavid E. O'Brien 
473c80476e4SDavid E. O'Brien     if (map[first] == F_UNASSIGNED) {
474c80476e4SDavid E. O'Brien 	if (first == last)
475c80476e4SDavid E. O'Brien 	    xprintf(CGETS(20, 10, "%-15s->  is undefined\n"),
476c80476e4SDavid E. O'Brien 		    unparsestring(&fb, unparsbuf, STRQQ));
477c80476e4SDavid E. O'Brien 	return;
478c80476e4SDavid E. O'Brien     }
479c80476e4SDavid E. O'Brien 
480c80476e4SDavid E. O'Brien     for (fp = FuncNames; fp->name; fp++) {
481c80476e4SDavid E. O'Brien 	if (fp->func == map[first]) {
482c80476e4SDavid E. O'Brien 	    if (first == last) {
483c80476e4SDavid E. O'Brien 		xprintf("%-15s->  %s\n",
484c80476e4SDavid E. O'Brien 			unparsestring(&fb, unparsbuf, STRQQ), fp->name);
485c80476e4SDavid E. O'Brien 	    }
486c80476e4SDavid E. O'Brien 	    else {
487c80476e4SDavid E. O'Brien 		xprintf("%-4s to %-7s->  %s\n",
488c80476e4SDavid E. O'Brien 			unparsestring(&fb, unparsbuf, STRQQ),
489c80476e4SDavid E. O'Brien 			unparsestring(&lb, extrabuf, STRQQ), fp->name);
490c80476e4SDavid E. O'Brien 	    }
491c80476e4SDavid E. O'Brien 	    return;
492c80476e4SDavid E. O'Brien 	}
493c80476e4SDavid E. O'Brien     }
494c80476e4SDavid E. O'Brien     if (map == CcKeyMap) {
495c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"),
496c80476e4SDavid E. O'Brien 		unparsestring(&fb, unparsbuf, STRQQ));
497c80476e4SDavid E. O'Brien 	xprintf("CcKeyMap[%d] == %d\n", first, CcKeyMap[first]);
498c80476e4SDavid E. O'Brien     }
499c80476e4SDavid E. O'Brien     else {
500c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"),
501c80476e4SDavid E. O'Brien 		unparsestring(&fb, unparsbuf, STRQQ));
502c80476e4SDavid E. O'Brien 	xprintf("CcAltMap[%d] == %d\n", first, CcAltMap[first]);
503c80476e4SDavid E. O'Brien     }
504c80476e4SDavid E. O'Brien }
505c80476e4SDavid E. O'Brien 
506c80476e4SDavid E. O'Brien static void
507c80476e4SDavid E. O'Brien bindkey_usage()
508c80476e4SDavid E. O'Brien {
509c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 12,
510c80476e4SDavid E. O'Brien 	    "Usage: bindkey [options] [--] [KEY [COMMAND]]\n"));
511c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 13,
512c80476e4SDavid E. O'Brien     	    "    -a   list or bind KEY in alternative key map\n"));
513c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 14,
514c80476e4SDavid E. O'Brien 	    "    -b   interpret KEY as a C-, M-, F- or X- key name\n"));
515c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 15,
516c80476e4SDavid E. O'Brien             "    -s   interpret COMMAND as a literal string to be output\n"));
517c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 16,
518c80476e4SDavid E. O'Brien             "    -c   interpret COMMAND as a builtin or external command\n"));
519c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 17,
520c80476e4SDavid E. O'Brien 	    "    -v   bind all keys to vi bindings\n"));
521c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 18,
522c80476e4SDavid E. O'Brien 	    "    -e   bind all keys to emacs bindings\n"));
523c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 19,
524c80476e4SDavid E. O'Brien 	    "    -d   bind all keys to default editor's bindings\n"));
525c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 20,
526c80476e4SDavid E. O'Brien 	    "    -l   list editor commands with descriptions\n"));
527c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 21,
528c80476e4SDavid E. O'Brien 	    "    -r   remove KEY's binding\n"));
529c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 22,
530c80476e4SDavid E. O'Brien 	    "    -k   interpret KEY as a symbolic arrow-key name\n"));
531c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 23,
532c80476e4SDavid E. O'Brien 	    "    --   force a break from option processing\n"));
533c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 24,
534c80476e4SDavid E. O'Brien 	    "    -u   (or any invalid option) this message\n"));
535c80476e4SDavid E. O'Brien     xprintf("\n");
536c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 25,
537c80476e4SDavid E. O'Brien 	    "Without KEY or COMMAND, prints all bindings\n"));
538c80476e4SDavid E. O'Brien     xprintf(CGETS(20, 26,
539c80476e4SDavid E. O'Brien 	    "Without COMMAND, prints the binding for KEY.\n"));
540c80476e4SDavid E. O'Brien }
541c80476e4SDavid E. O'Brien 
542c80476e4SDavid E. O'Brien static void
543c80476e4SDavid E. O'Brien list_functions()
544c80476e4SDavid E. O'Brien {
545c80476e4SDavid E. O'Brien     register struct KeyFuncs *fp;
546c80476e4SDavid E. O'Brien 
547c80476e4SDavid E. O'Brien     for (fp = FuncNames; fp->name; fp++) {
548c80476e4SDavid E. O'Brien 	xprintf("%s\n          %s\n", fp->name, fp->desc);
549c80476e4SDavid E. O'Brien     }
550c80476e4SDavid E. O'Brien }
551c80476e4SDavid E. O'Brien 
552c80476e4SDavid E. O'Brien #ifdef OBSOLETE
553c80476e4SDavid E. O'Brien 
554c80476e4SDavid E. O'Brien /*
555c80476e4SDavid E. O'Brien  * Unfortunately the apollo optimizer does not like & operations
556c80476e4SDavid E. O'Brien  * with 0377, and produces illegal instructions. So we make it
557c80476e4SDavid E. O'Brien  * an unsigned char, and hope for the best.
558c80476e4SDavid E. O'Brien  * Of-course the compiler is smart enough to produce bad assembly
559c80476e4SDavid E. O'Brien  * language instructions, but dumb when it comes to fold the constant :-)
560c80476e4SDavid E. O'Brien  */
561c80476e4SDavid E. O'Brien #ifdef apollo
562c80476e4SDavid E. O'Brien static unsigned char APOLLO_0377 = 0377;
563c80476e4SDavid E. O'Brien #else /* sane */
564c80476e4SDavid E. O'Brien # define APOLLO_0377    0377
565c80476e4SDavid E. O'Brien #endif /* apollo */
566c80476e4SDavid E. O'Brien 
567c80476e4SDavid E. O'Brien static int
568c80476e4SDavid E. O'Brien tocontrol(c)
569c80476e4SDavid E. O'Brien     int    c;
570c80476e4SDavid E. O'Brien {
571c80476e4SDavid E. O'Brien     c &= CHAR;
572c80476e4SDavid E. O'Brien     if (Islower(c))
573c80476e4SDavid E. O'Brien 	c = Toupper(c);
574c80476e4SDavid E. O'Brien     else if (c == ' ')
575c80476e4SDavid E. O'Brien 	c = '@';
576c80476e4SDavid E. O'Brien     if (c == '?')
577c80476e4SDavid E. O'Brien 	c = CTL_ESC('\177');
578c80476e4SDavid E. O'Brien     else
579c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX
580c80476e4SDavid E. O'Brien 	c &= 037;
581c80476e4SDavid E. O'Brien #else /* EBCDIC: simulate ASCII-behavior by transforming to ASCII and back */
582c80476e4SDavid E. O'Brien 	c  = _toebcdic[_toascii[c] & 037];
583c80476e4SDavid E. O'Brien #endif
584c80476e4SDavid E. O'Brien     return (c);
585c80476e4SDavid E. O'Brien }
586c80476e4SDavid E. O'Brien 
587c80476e4SDavid E. O'Brien static char *
588c80476e4SDavid E. O'Brien unparsekey(c)			/* 'c' -> "c", '^C' -> "^" + "C" */
589c80476e4SDavid E. O'Brien     register int c;
590c80476e4SDavid E. O'Brien {
591c80476e4SDavid E. O'Brien     register char *cp;
592c80476e4SDavid E. O'Brien     static char tmp[10];
593c80476e4SDavid E. O'Brien 
594c80476e4SDavid E. O'Brien     cp = tmp;
595c80476e4SDavid E. O'Brien 
596c80476e4SDavid E. O'Brien     if (c & 0400) {
597c80476e4SDavid E. O'Brien 	*cp++ = 'A';
598c80476e4SDavid E. O'Brien 	*cp++ = '-';
599c80476e4SDavid E. O'Brien 	c &= APOLLO_0377;
600c80476e4SDavid E. O'Brien     }
601c80476e4SDavid E. O'Brien     if ((c & META) && !(Isprint(c) || (Iscntrl(c) && Isprint(c | 0100)))) {
602c80476e4SDavid E. O'Brien 	*cp++ = 'M';
603c80476e4SDavid E. O'Brien 	*cp++ = '-';
604c80476e4SDavid E. O'Brien 	c &= ASCII;
605c80476e4SDavid E. O'Brien     }
606c80476e4SDavid E. O'Brien     if (Isprint(c)) {
607c80476e4SDavid E. O'Brien 	*cp++ = (char) c;
608c80476e4SDavid E. O'Brien 	*cp = '\0';
609c80476e4SDavid E. O'Brien 	return (tmp);
610c80476e4SDavid E. O'Brien     }
611c80476e4SDavid E. O'Brien     switch (c) {
612c80476e4SDavid E. O'Brien     case ' ':
613c80476e4SDavid E. O'Brien 	(void) strcpy(cp, "Spc");
614c80476e4SDavid E. O'Brien 	return (tmp);
615c80476e4SDavid E. O'Brien     case '\n':
616c80476e4SDavid E. O'Brien 	(void) strcpy(cp, "Lfd");
617c80476e4SDavid E. O'Brien 	return (tmp);
618c80476e4SDavid E. O'Brien     case '\r':
619c80476e4SDavid E. O'Brien 	(void) strcpy(cp, "Ret");
620c80476e4SDavid E. O'Brien 	return (tmp);
621c80476e4SDavid E. O'Brien     case '\t':
622c80476e4SDavid E. O'Brien 	(void) strcpy(cp, "Tab");
623c80476e4SDavid E. O'Brien 	return (tmp);
624c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX
625c80476e4SDavid E. O'Brien     case '\033':
626c80476e4SDavid E. O'Brien 	(void) strcpy(cp, "Esc");
627c80476e4SDavid E. O'Brien 	return (tmp);
628c80476e4SDavid E. O'Brien     case '\177':
629c80476e4SDavid E. O'Brien 	(void) strcpy(cp, "Del");
630c80476e4SDavid E. O'Brien 	return (tmp);
631c80476e4SDavid E. O'Brien     default:
632c80476e4SDavid E. O'Brien 	*cp++ = '^';
633c80476e4SDavid E. O'Brien 	if (c == '\177') {
634c80476e4SDavid E. O'Brien 	    *cp++ = '?';
635c80476e4SDavid E. O'Brien 	}
636c80476e4SDavid E. O'Brien 	else {
637c80476e4SDavid E. O'Brien 	    *cp++ = c | 0100;
638c80476e4SDavid E. O'Brien 	}
639c80476e4SDavid E. O'Brien 	*cp = '\0';
640c80476e4SDavid E. O'Brien 	return (tmp);
641c80476e4SDavid E. O'Brien #else /*_OSD_POSIX*/
642c80476e4SDavid E. O'Brien     default:
643c80476e4SDavid E. O'Brien         if (*cp == CTL_ESC('\033')) {
644c80476e4SDavid E. O'Brien 	    (void) strcpy(cp, "Esc");
645c80476e4SDavid E. O'Brien 	    return (tmp);
646c80476e4SDavid E. O'Brien 	}
647c80476e4SDavid E. O'Brien 	else if (*cp == CTL_ESC('\177')) {
648c80476e4SDavid E. O'Brien 	    (void) strcpy(cp, "Del");
649c80476e4SDavid E. O'Brien 	    return (tmp);
650c80476e4SDavid E. O'Brien 	}
651c80476e4SDavid E. O'Brien 	else if (Isupper(_toebcdic[_toascii[c]|0100])
652c80476e4SDavid E. O'Brien 		|| strchr("@[\\]^_", _toebcdic[_toascii[c]|0100]) != NULL) {
653c80476e4SDavid E. O'Brien 	    *cp++ = '^';
654c80476e4SDavid E. O'Brien 	    *cp++ = _toebcdic[_toascii[c]|0100]
655c80476e4SDavid E. O'Brien 	}
656c80476e4SDavid E. O'Brien 	else {
657c80476e4SDavid E. O'Brien 	    xsnprintf(cp, 3, "\\%3.3o", c);
658c80476e4SDavid E. O'Brien 	    cp += 4;
659c80476e4SDavid E. O'Brien 	}
660c80476e4SDavid E. O'Brien #endif /*_OSD_POSIX*/
661c80476e4SDavid E. O'Brien     }
662c80476e4SDavid E. O'Brien }
663c80476e4SDavid E. O'Brien 
664c80476e4SDavid E. O'Brien static  KEYCMD
665c80476e4SDavid E. O'Brien getkeycmd(sp)
666c80476e4SDavid E. O'Brien     Char  **sp;
667c80476e4SDavid E. O'Brien {
668c80476e4SDavid E. O'Brien     register Char *s = *sp;
669c80476e4SDavid E. O'Brien     register char c;
670c80476e4SDavid E. O'Brien     register KEYCMD keycmd = F_UNASSIGNED;
671c80476e4SDavid E. O'Brien     KEYCMD *map;
672c80476e4SDavid E. O'Brien     int     meta = 0;
673c80476e4SDavid E. O'Brien     Char   *ret_sp = s;
674c80476e4SDavid E. O'Brien 
675c80476e4SDavid E. O'Brien     map = CcKeyMap;
676c80476e4SDavid E. O'Brien 
677c80476e4SDavid E. O'Brien     while (*s) {
678c80476e4SDavid E. O'Brien 	if (*s == '^' && s[1]) {
679c80476e4SDavid E. O'Brien 	    s++;
680c80476e4SDavid E. O'Brien 	    c = tocontrol(*s++);
681c80476e4SDavid E. O'Brien 	}
682c80476e4SDavid E. O'Brien 	else
683c80476e4SDavid E. O'Brien 	    c = *s++;
684c80476e4SDavid E. O'Brien 
685c80476e4SDavid E. O'Brien 	if (*s == '\0')
686c80476e4SDavid E. O'Brien 	    break;
687c80476e4SDavid E. O'Brien 
688c80476e4SDavid E. O'Brien 	switch (map[c | meta]) {
689c80476e4SDavid E. O'Brien 	case F_METANEXT:
690c80476e4SDavid E. O'Brien 	    meta = META;
691c80476e4SDavid E. O'Brien 	    keycmd = F_METANEXT;
692c80476e4SDavid E. O'Brien 	    ret_sp = s;
693c80476e4SDavid E. O'Brien 	    break;
694c80476e4SDavid E. O'Brien 
695c80476e4SDavid E. O'Brien 	case F_XKEY:
696c80476e4SDavid E. O'Brien 	    keycmd = F_XKEY;
697c80476e4SDavid E. O'Brien 	    ret_sp = s;
698c80476e4SDavid E. O'Brien 	    /* FALLTHROUGH */
699c80476e4SDavid E. O'Brien 
700c80476e4SDavid E. O'Brien 	default:
701c80476e4SDavid E. O'Brien 	    *sp = ret_sp;
702c80476e4SDavid E. O'Brien 	    return (keycmd);
703c80476e4SDavid E. O'Brien 
704c80476e4SDavid E. O'Brien 	}
705c80476e4SDavid E. O'Brien     }
706c80476e4SDavid E. O'Brien     *sp = ret_sp;
707c80476e4SDavid E. O'Brien     return (keycmd);
708c80476e4SDavid E. O'Brien }
709c80476e4SDavid E. O'Brien 
710c80476e4SDavid E. O'Brien static int
711c80476e4SDavid E. O'Brien parsekey(sp)
712c80476e4SDavid E. O'Brien     Char  **sp;			/* Return position of first unparsed character
713c80476e4SDavid E. O'Brien 				 * for return value -2 (xkeynext) */
714c80476e4SDavid E. O'Brien {
715c80476e4SDavid E. O'Brien     register int c, meta = 0, control = 0, ctrlx = 0;
716c80476e4SDavid E. O'Brien     Char   *s = *sp;
717c80476e4SDavid E. O'Brien     KEYCMD  keycmd;
718c80476e4SDavid E. O'Brien 
719c80476e4SDavid E. O'Brien     if (s == NULL) {
720c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 27, "bad key specification -- null string\n"));
721c80476e4SDavid E. O'Brien 	return -1;
722c80476e4SDavid E. O'Brien     }
723c80476e4SDavid E. O'Brien     if (*s == 0) {
724c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 28, "bad key specification -- empty string\n"));
725c80476e4SDavid E. O'Brien 	return -1;
726c80476e4SDavid E. O'Brien     }
727c80476e4SDavid E. O'Brien 
728c80476e4SDavid E. O'Brien     (void) strip(s);		/* trim to 7 bits. */
729c80476e4SDavid E. O'Brien 
730c80476e4SDavid E. O'Brien     if (s[1] == 0)		/* single char */
731c80476e4SDavid E. O'Brien 	return (s[0] & APOLLO_0377);
732c80476e4SDavid E. O'Brien 
733c80476e4SDavid E. O'Brien     if ((s[0] == 'F' || s[0] == 'f') && s[1] == '-') {
734c80476e4SDavid E. O'Brien 	if (s[2] == 0) {
735c80476e4SDavid E. O'Brien 	    xprintf(CGETS(20, 29,
736c80476e4SDavid E. O'Brien 		   "Bad function-key specification.  Null key not allowed\n"));
737c80476e4SDavid E. O'Brien 	    return (-1);
738c80476e4SDavid E. O'Brien 	}
739c80476e4SDavid E. O'Brien 	*sp = s + 2;
740c80476e4SDavid E. O'Brien 	return (-2);
741c80476e4SDavid E. O'Brien     }
742c80476e4SDavid E. O'Brien 
743c80476e4SDavid E. O'Brien     if (s[0] == '0' && s[1] == 'x') {	/* if 0xn, then assume number */
744c80476e4SDavid E. O'Brien 	c = 0;
745c80476e4SDavid E. O'Brien 	for (s += 2; *s; s++) {	/* convert to hex; skip the first 0 */
746c80476e4SDavid E. O'Brien 	    c *= 16;
747c80476e4SDavid E. O'Brien 	    if (!Isxdigit(*s)) {
748c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 30,
749c80476e4SDavid E. O'Brien 			"bad key specification -- malformed hex number\n"));
750c80476e4SDavid E. O'Brien 		return -1;	/* error */
751c80476e4SDavid E. O'Brien 	    }
752c80476e4SDavid E. O'Brien 	    if (Isdigit(*s))
753c80476e4SDavid E. O'Brien 		c += *s - '0';
754c80476e4SDavid E. O'Brien 	    else if (*s >= 'a' && *s <= 'f')
755c80476e4SDavid E. O'Brien 		c += *s - 'a' + 0xA;
756c80476e4SDavid E. O'Brien 	    else if (*s >= 'F' && *s <= 'F')
757c80476e4SDavid E. O'Brien 		c += *s - 'A' + 0xA;
758c80476e4SDavid E. O'Brien 	}
759c80476e4SDavid E. O'Brien     }
760c80476e4SDavid E. O'Brien     else if (s[0] == '0' && Isdigit(s[1])) {	/* if 0n, then assume number */
761c80476e4SDavid E. O'Brien 	c = 0;
762c80476e4SDavid E. O'Brien 	for (s++; *s; s++) {	/* convert to octal; skip the first 0 */
763c80476e4SDavid E. O'Brien 	    if (!Isdigit(*s) || *s == '8' || *s == '9') {
764c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 31,
765c80476e4SDavid E. O'Brien 			"bad key specification -- malformed octal number\n"));
766c80476e4SDavid E. O'Brien 		return -1;	/* error */
767c80476e4SDavid E. O'Brien 	    }
768c80476e4SDavid E. O'Brien 	    c = (c * 8) + *s - '0';
769c80476e4SDavid E. O'Brien 	}
770c80476e4SDavid E. O'Brien     }
771c80476e4SDavid E. O'Brien     else if (Isdigit(s[0]) && Isdigit(s[1])) {	/* decimal number */
772c80476e4SDavid E. O'Brien 	c = 0;
773c80476e4SDavid E. O'Brien 	for (; *s; s++) {	/* convert to octal; skip the first 0 */
774c80476e4SDavid E. O'Brien 	    if (!Isdigit(*s)) {
775c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 32,
776c80476e4SDavid E. O'Brien 		       "bad key specification -- malformed decimal number\n"));
777c80476e4SDavid E. O'Brien 		return -1;	/* error */
778c80476e4SDavid E. O'Brien 	    }
779c80476e4SDavid E. O'Brien 	    c = (c * 10) + *s - '0';
780c80476e4SDavid E. O'Brien 	}
781c80476e4SDavid E. O'Brien     }
782c80476e4SDavid E. O'Brien     else {
783c80476e4SDavid E. O'Brien 	keycmd = getkeycmd(&s);
784c80476e4SDavid E. O'Brien 
785c80476e4SDavid E. O'Brien 	if ((s[0] == 'X' || s[0] == 'x') && s[1] == '-') {	/* X- */
786c80476e4SDavid E. O'Brien 	    ctrlx++;
787c80476e4SDavid E. O'Brien 	    s += 2;
788c80476e4SDavid E. O'Brien 	    keycmd = getkeycmd(&s);
789c80476e4SDavid E. O'Brien 	}
790c80476e4SDavid E. O'Brien 	if ((*s == 'm' || *s == 'M') && s[1] == '-') {	/* meta */
791c80476e4SDavid E. O'Brien 	    meta++;
792c80476e4SDavid E. O'Brien 	    s += 2;
793c80476e4SDavid E. O'Brien 	    keycmd = getkeycmd(&s);
794c80476e4SDavid E. O'Brien 	}
795c80476e4SDavid E. O'Brien 	else if (keycmd == F_METANEXT && *s) {	/* meta */
796c80476e4SDavid E. O'Brien 	    meta++;
797c80476e4SDavid E. O'Brien 	    keycmd = getkeycmd(&s);
798c80476e4SDavid E. O'Brien 	}
799c80476e4SDavid E. O'Brien 	if (*s == '^' && s[1]) {
800c80476e4SDavid E. O'Brien 	    control++;
801c80476e4SDavid E. O'Brien 	    s++;
802c80476e4SDavid E. O'Brien 	    keycmd = getkeycmd(&s);
803c80476e4SDavid E. O'Brien 	}
804c80476e4SDavid E. O'Brien 	else if ((*s == 'c' || *s == 'C') && s[1] == '-') {	/* control */
805c80476e4SDavid E. O'Brien 	    control++;
806c80476e4SDavid E. O'Brien 	    s += 2;
807c80476e4SDavid E. O'Brien 	    keycmd = getkeycmd(&s);
808c80476e4SDavid E. O'Brien 	}
809c80476e4SDavid E. O'Brien 
810c80476e4SDavid E. O'Brien 	if (keycmd == F_XKEY) {
811c80476e4SDavid E. O'Brien 	    if (*s == 0) {
812c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 33,
813c80476e4SDavid E. O'Brien 			      "Bad function-key specification.\n"));
814c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 34, "Null key not allowed\n"));
815c80476e4SDavid E. O'Brien 		return (-1);
816c80476e4SDavid E. O'Brien 	    }
817c80476e4SDavid E. O'Brien 	    *sp = s;
818c80476e4SDavid E. O'Brien 	    return (-2);
819c80476e4SDavid E. O'Brien 	}
820c80476e4SDavid E. O'Brien 
821c80476e4SDavid E. O'Brien 	if (s[1] != 0) {	/* if symbolic name */
822c80476e4SDavid E. O'Brien 	    char   *ts;
823c80476e4SDavid E. O'Brien 
824c80476e4SDavid E. O'Brien 	    ts = short2str(s);
825c80476e4SDavid E. O'Brien 	    if (!strcmp(ts, "space") || !strcmp(ts, "Spc"))
826c80476e4SDavid E. O'Brien 		c = ' ';
827c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "return") || !strcmp(ts, "Ret"))
828c80476e4SDavid E. O'Brien 		c = '\r';
829c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "newline") || !strcmp(ts, "Lfd"))
830c80476e4SDavid E. O'Brien 		c = '\n';
831c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "linefeed"))
832c80476e4SDavid E. O'Brien 		c = '\n';
833c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "tab"))
834c80476e4SDavid E. O'Brien 		c = '\t';
835c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "escape") || !strcmp(ts, "Esc"))
836c80476e4SDavid E. O'Brien 		c = CTL_ESC('\033');
837c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "backspace"))
838c80476e4SDavid E. O'Brien 		c = '\b';
839c80476e4SDavid E. O'Brien 	    else if (!strcmp(ts, "delete"))
840c80476e4SDavid E. O'Brien 		c = CTL_ESC('\177');
841c80476e4SDavid E. O'Brien 	    else {
842c80476e4SDavid E. O'Brien 		xprintf(CGETS(20, 35,
843c80476e4SDavid E. O'Brien 			"bad key specification -- unknown name \"%S\"\n"), s);
844c80476e4SDavid E. O'Brien 		return -1;	/* error */
845c80476e4SDavid E. O'Brien 	    }
846c80476e4SDavid E. O'Brien 	}
847c80476e4SDavid E. O'Brien 	else
848c80476e4SDavid E. O'Brien 	    c = *s;		/* just a single char */
849c80476e4SDavid E. O'Brien 
850c80476e4SDavid E. O'Brien 	if (control)
851c80476e4SDavid E. O'Brien 	    c = tocontrol(c);
852c80476e4SDavid E. O'Brien 	if (meta)
853c80476e4SDavid E. O'Brien 	    c |= META;
854c80476e4SDavid E. O'Brien 	if (ctrlx)
855c80476e4SDavid E. O'Brien 	    c |= 0400;
856c80476e4SDavid E. O'Brien     }
857c80476e4SDavid E. O'Brien     return (c & 0777);
858c80476e4SDavid E. O'Brien }
859c80476e4SDavid E. O'Brien 
860c80476e4SDavid E. O'Brien 
861c80476e4SDavid E. O'Brien /*ARGSUSED*/
862c80476e4SDavid E. O'Brien void
863c80476e4SDavid E. O'Brien dobind(v, dummy)
864c80476e4SDavid E. O'Brien     register Char **v;
865c80476e4SDavid E. O'Brien     struct command *dummy;
866c80476e4SDavid E. O'Brien {
867c80476e4SDavid E. O'Brien     register int c;
868c80476e4SDavid E. O'Brien     register struct KeyFuncs *fp;
869c80476e4SDavid E. O'Brien     register int i, prev;
870c80476e4SDavid E. O'Brien     Char   *p, *l;
871c80476e4SDavid E. O'Brien     CStr    cstr;
872c80476e4SDavid E. O'Brien     Char    buf[1000];
873c80476e4SDavid E. O'Brien 
874c80476e4SDavid E. O'Brien     USE(dummy);
875c80476e4SDavid E. O'Brien     /*
876c80476e4SDavid E. O'Brien      * Assume at this point that i'm given 2 or 3 args - 'bind', the f-name,
877c80476e4SDavid E. O'Brien      * and the key; or 'bind' key to print the func for that key.
878c80476e4SDavid E. O'Brien      */
879c80476e4SDavid E. O'Brien 
880c80476e4SDavid E. O'Brien     if (!MapsAreInited)
881c80476e4SDavid E. O'Brien 	ed_InitMaps();
882c80476e4SDavid E. O'Brien 
883c80476e4SDavid E. O'Brien     if (v[1] && v[2] && v[3]) {
884c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 36,
885c80476e4SDavid E. O'Brien 	 "usage: bind [KEY | COMMAND KEY | \"emacs\" | \"vi\" | \"-a\"]\n"));
886c80476e4SDavid E. O'Brien 	return;
887c80476e4SDavid E. O'Brien     }
888c80476e4SDavid E. O'Brien 
889c80476e4SDavid E. O'Brien     if (v[1] && v[2]) {		/* if bind FUNCTION KEY */
890c80476e4SDavid E. O'Brien 	for (fp = FuncNames; fp->name; fp++) {
891c80476e4SDavid E. O'Brien 	    if (strcmp(short2str(v[1]), fp->name) == 0) {
892c80476e4SDavid E. O'Brien 		Char   *s = v[2];
893c80476e4SDavid E. O'Brien 
894c80476e4SDavid E. O'Brien 		if ((c = parsekey(&s)) == -1)
895c80476e4SDavid E. O'Brien 		    return;
896c80476e4SDavid E. O'Brien 		if (c == -2) {	/* extended key */
897c80476e4SDavid E. O'Brien 		    for (i = 0; i < 256; i++) {
898c80476e4SDavid E. O'Brien 			if (i != CTL_ESC('\033') && (CcKeyMap[i] == F_XKEY ||
899c80476e4SDavid E. O'Brien 					 CcAltMap[i] == F_XKEY)) {
900c80476e4SDavid E. O'Brien 			    p = buf;
901c80476e4SDavid E. O'Brien #ifndef _OSD_POSIX /* this is only for ASCII, not for EBCDIC */
902c80476e4SDavid E. O'Brien 			    if (i > 0177) {
903c80476e4SDavid E. O'Brien 				*p++ = 033;
904c80476e4SDavid E. O'Brien 				*p++ = i & ASCII;
905c80476e4SDavid E. O'Brien 			    }
906c80476e4SDavid E. O'Brien 			    else {
907c80476e4SDavid E. O'Brien 				*p++ = (Char) i;
908c80476e4SDavid E. O'Brien 			    }
909c80476e4SDavid E. O'Brien #else /*_OSD_POSIX*/
910c80476e4SDavid E. O'Brien 			    *p++ = (Char) i;
911c80476e4SDavid E. O'Brien #endif /*_OSD_POSIX*/
912c80476e4SDavid E. O'Brien 			    for (l = s; *l != 0; l++) {
913c80476e4SDavid E. O'Brien 				*p++ = *l;
914c80476e4SDavid E. O'Brien 			    }
915c80476e4SDavid E. O'Brien 			    *p = 0;
916c80476e4SDavid E. O'Brien 			    cstr.buf = buf;
917c80476e4SDavid E. O'Brien 			    cstr.len = Strlen(buf);
918c80476e4SDavid E. O'Brien 			    AddXkey(&cstr, XmapCmd(fp->func), XK_CMD);
919c80476e4SDavid E. O'Brien 			}
920c80476e4SDavid E. O'Brien 		    }
921c80476e4SDavid E. O'Brien 		    return;
922c80476e4SDavid E. O'Brien 		}
923c80476e4SDavid E. O'Brien 		if (c & 0400) {
924c80476e4SDavid E. O'Brien 		    if (VImode) {
925c80476e4SDavid E. O'Brien 			CcAltMap[c & APOLLO_0377] = fp->func;
926c80476e4SDavid E. O'Brien 			/* bind the vi cmd mode key */
927c80476e4SDavid E. O'Brien 			if (c & META) {
928c80476e4SDavid E. O'Brien 			    buf[0] = CTL_ESC('\033');
929c80476e4SDavid E. O'Brien 			    buf[1] = c & ASCII;
930c80476e4SDavid E. O'Brien 			    buf[2] = 0;
931c80476e4SDavid E. O'Brien 			    cstr.buf = buf;
932c80476e4SDavid E. O'Brien 			    cstr.len = Strlen(buf);
933c80476e4SDavid E. O'Brien 			    AddXkey(&cstr, XmapCmd(fp->func), XK_CMD);
934c80476e4SDavid E. O'Brien 			}
935c80476e4SDavid E. O'Brien 		    }
936c80476e4SDavid E. O'Brien 		    else {
937c80476e4SDavid E. O'Brien 			buf[0] = CTL_ESC('\030');	/* ^X */
938c80476e4SDavid E. O'Brien 			buf[1] = c & APOLLO_0377;
939c80476e4SDavid E. O'Brien 			buf[2] = 0;
940c80476e4SDavid E. O'Brien 			cstr.buf = buf;
941c80476e4SDavid E. O'Brien 			cstr.len = Strlen(buf);
942c80476e4SDavid E. O'Brien 			AddXkey(&cstr, XmapCmd(fp->func), XK_CMD);
943c80476e4SDavid E. O'Brien 			CcKeyMap[CTL_ESC('\030')] = F_XKEY;
944c80476e4SDavid E. O'Brien 		    }
945c80476e4SDavid E. O'Brien 		}
946c80476e4SDavid E. O'Brien 		else {
947c80476e4SDavid E. O'Brien 		    CcKeyMap[c] = fp->func;	/* bind the key */
948c80476e4SDavid E. O'Brien 		    if (c & META) {
949c80476e4SDavid E. O'Brien 			buf[0] = CTL_ESC('\033');
950c80476e4SDavid E. O'Brien 			buf[1] = c & ASCII;
951c80476e4SDavid E. O'Brien 			buf[2] = 0;
952c80476e4SDavid E. O'Brien 			cstr.buf = buf;
953c80476e4SDavid E. O'Brien 			cstr.len = Strlen(buf);
954c80476e4SDavid E. O'Brien 			AddXkey(&cstr, XmapCmd(fp->func), XK_CMD);
955c80476e4SDavid E. O'Brien 		    }
956c80476e4SDavid E. O'Brien 		}
957c80476e4SDavid E. O'Brien 		return;
958c80476e4SDavid E. O'Brien 	    }
959c80476e4SDavid E. O'Brien 	}
960c80476e4SDavid E. O'Brien 	stderror(ERR_NAME | ERR_STRING, CGETS(20, 37, "Invalid function"));
961c80476e4SDavid E. O'Brien     }
962c80476e4SDavid E. O'Brien     else if (v[1]) {
963c80476e4SDavid E. O'Brien 	char   *cv = short2str(v[1]);
964c80476e4SDavid E. O'Brien 
965c80476e4SDavid E. O'Brien 	if (strcmp(cv, "list") == 0) {
966c80476e4SDavid E. O'Brien 	    for (fp = FuncNames; fp->name; fp++) {
967c80476e4SDavid E. O'Brien 		xprintf("%s\n", fp->name);
968c80476e4SDavid E. O'Brien 	    }
969c80476e4SDavid E. O'Brien 	    return;
970c80476e4SDavid E. O'Brien 	}
971c80476e4SDavid E. O'Brien 	if ((strcmp(cv, "emacs") == 0) ||
972c80476e4SDavid E. O'Brien #ifndef VIDEFAULT
973c80476e4SDavid E. O'Brien 	    (strcmp(cv, "defaults") == 0) ||
974c80476e4SDavid E. O'Brien 	    (strcmp(cv, "default") == 0) ||
975c80476e4SDavid E. O'Brien #endif
976c80476e4SDavid E. O'Brien 	    (strcmp(cv, "mg") == 0) ||
977c80476e4SDavid E. O'Brien 	    (strcmp(cv, "gnumacs") == 0)) {
978c80476e4SDavid E. O'Brien 	    /* reset keys to default */
979c80476e4SDavid E. O'Brien 	    ed_InitEmacsMaps();
980c80476e4SDavid E. O'Brien #ifdef VIDEFAULT
981c80476e4SDavid E. O'Brien 	}
982c80476e4SDavid E. O'Brien 	else if ((strcmp(cv, "vi") == 0)
983c80476e4SDavid E. O'Brien 		 || (strcmp(cv, "default") == 0)
984c80476e4SDavid E. O'Brien 		 || (strcmp(cv, "defaults") == 0)) {
985c80476e4SDavid E. O'Brien #else
986c80476e4SDavid E. O'Brien 	}
987c80476e4SDavid E. O'Brien 	else if (strcmp(cv, "vi") == 0) {
988c80476e4SDavid E. O'Brien #endif
989c80476e4SDavid E. O'Brien 	    ed_InitVIMaps();
990c80476e4SDavid E. O'Brien 	}
991c80476e4SDavid E. O'Brien 	else {			/* want to know what this key does */
992c80476e4SDavid E. O'Brien 	    Char   *s = v[1];
993c80476e4SDavid E. O'Brien 
994c80476e4SDavid E. O'Brien 	    if ((c = parsekey(&s)) == -1)
995c80476e4SDavid E. O'Brien 		return;
996c80476e4SDavid E. O'Brien 	    if (c == -2) {	/* extended key */
997c80476e4SDavid E. O'Brien 		cstr.buf = s;
998c80476e4SDavid E. O'Brien 		cstr.len = Strlen(s);
999c80476e4SDavid E. O'Brien 		PrintXkey(&cstr);
1000c80476e4SDavid E. O'Brien 		return;
1001c80476e4SDavid E. O'Brien 	    }
1002c80476e4SDavid E. O'Brien 	    pkeys(c, c);	/* must be regular key */
1003c80476e4SDavid E. O'Brien 	}
1004c80476e4SDavid E. O'Brien     }
1005c80476e4SDavid E. O'Brien     else {			/* list all the bindings */
1006c80476e4SDavid E. O'Brien 	prev = 0;
1007c80476e4SDavid E. O'Brien 	for (i = 0; i < 256; i++) {
1008c80476e4SDavid E. O'Brien 	    if (CcKeyMap[prev] == CcKeyMap[i])
1009c80476e4SDavid E. O'Brien 		continue;
1010c80476e4SDavid E. O'Brien 	    pkeys(prev, i - 1);
1011c80476e4SDavid E. O'Brien 	    prev = i;
1012c80476e4SDavid E. O'Brien 	}
1013c80476e4SDavid E. O'Brien 	pkeys(prev, i - 1);
1014c80476e4SDavid E. O'Brien 	prev = 0;
1015c80476e4SDavid E. O'Brien 	for (i = 256; i < 512; i++) {
1016c80476e4SDavid E. O'Brien 	    if (CcAltMap[prev & APOLLO_0377] == CcAltMap[i & APOLLO_0377])
1017c80476e4SDavid E. O'Brien 		continue;
1018c80476e4SDavid E. O'Brien 	    pkeys(prev, i - 1);
1019c80476e4SDavid E. O'Brien 	    prev = i;
1020c80476e4SDavid E. O'Brien 	}
1021c80476e4SDavid E. O'Brien 	pkeys(prev, i - 1);
1022c80476e4SDavid E. O'Brien 	cstr.buf = NULL;
1023c80476e4SDavid E. O'Brien 	cstr.len = 0;
1024c80476e4SDavid E. O'Brien 	PrintXkey(&cstr);	/* print all Xkey bindings */
1025c80476e4SDavid E. O'Brien     }
1026c80476e4SDavid E. O'Brien     return;
1027c80476e4SDavid E. O'Brien }
1028c80476e4SDavid E. O'Brien 
1029c80476e4SDavid E. O'Brien static void
1030c80476e4SDavid E. O'Brien pkeys(first, last)
1031c80476e4SDavid E. O'Brien     register int first, last;
1032c80476e4SDavid E. O'Brien {
1033c80476e4SDavid E. O'Brien     register struct KeyFuncs *fp;
1034c80476e4SDavid E. O'Brien     register KEYCMD *map;
1035c80476e4SDavid E. O'Brien     int mask;
1036c80476e4SDavid E. O'Brien     char    buf[8];
1037c80476e4SDavid E. O'Brien 
1038c80476e4SDavid E. O'Brien     if (last & 0400) {
1039c80476e4SDavid E. O'Brien 	map = CcAltMap;
1040c80476e4SDavid E. O'Brien 	first &= APOLLO_0377;
1041c80476e4SDavid E. O'Brien 	last &= APOLLO_0377;
1042c80476e4SDavid E. O'Brien 	mask = 0400;
1043c80476e4SDavid E. O'Brien     }
1044c80476e4SDavid E. O'Brien     else {
1045c80476e4SDavid E. O'Brien 	map = CcKeyMap;
1046c80476e4SDavid E. O'Brien 	mask = 0;
1047c80476e4SDavid E. O'Brien     }
1048c80476e4SDavid E. O'Brien     if (map[first] == F_UNASSIGNED) {
1049c80476e4SDavid E. O'Brien 	if (first == last)
1050c80476e4SDavid E. O'Brien 	    xprintf(CGETS(20, 38, " %s\t\tis undefined\n"),
1051c80476e4SDavid E. O'Brien 		    unparsekey(first | mask));
1052c80476e4SDavid E. O'Brien 	return;
1053c80476e4SDavid E. O'Brien     }
1054c80476e4SDavid E. O'Brien 
1055c80476e4SDavid E. O'Brien     for (fp = FuncNames; fp->name; fp++) {
1056c80476e4SDavid E. O'Brien 	if (fp->func == map[first]) {
1057c80476e4SDavid E. O'Brien 	    if (first == last)
1058c80476e4SDavid E. O'Brien 		xprintf(" %s\t\t%s\n",
1059c80476e4SDavid E. O'Brien 			unparsekey((first & APOLLO_0377) | mask), fp->name);
1060c80476e4SDavid E. O'Brien 	    else {
1061c80476e4SDavid E. O'Brien 		(void) strcpy(buf, unparsekey((first & APOLLO_0377) | mask));
1062c80476e4SDavid E. O'Brien 		xprintf(" %s..%s\t\t%s\n", buf,
1063c80476e4SDavid E. O'Brien 		        unparsekey((last & APOLLO_0377) | mask), fp->name);
1064c80476e4SDavid E. O'Brien 	    }
1065c80476e4SDavid E. O'Brien 	    return;
1066c80476e4SDavid E. O'Brien 	}
1067c80476e4SDavid E. O'Brien     }
1068c80476e4SDavid E. O'Brien     if (map == CcKeyMap) {
1069c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"),
1070c80476e4SDavid E. O'Brien 		unparsekey(first));
1071c80476e4SDavid E. O'Brien 	xprintf("CcKeyMap[%d] == %d\n", first, CcKeyMap[first]);
1072c80476e4SDavid E. O'Brien     }
1073c80476e4SDavid E. O'Brien     else {
1074c80476e4SDavid E. O'Brien 	xprintf(CGETS(20, 11, "BUG!!! %s isn't bound to anything.\n"),
1075c80476e4SDavid E. O'Brien 		unparsekey(first & 0400));
1076c80476e4SDavid E. O'Brien 	xprintf("CcAltMap[%d] == %d\n", first, CcAltMap[first]);
1077c80476e4SDavid E. O'Brien     }
1078c80476e4SDavid E. O'Brien }
1079c80476e4SDavid E. O'Brien #endif /* OBSOLETE */
1080