1/*	$OpenBSD: cinfo.c,v 1.18 2015/03/19 21:22:15 bcallah Exp $	*/
2
3/* This file is in the public domain. */
4
5/*
6 *		Character class tables.
7 * Do it yourself character classification
8 * macros, that understand the multinational character set,
9 * and let me ask some questions the standard macros (in
10 * ctype.h) don't let you ask.
11 */
12
13#include <sys/queue.h>
14#include <signal.h>
15#include <stdio.h>
16#include <string.h>
17
18#include "def.h"
19
20/*
21 * This table, indexed by a character drawn
22 * from the 256 member character set, is used by my
23 * own character type macros to answer questions about the
24 * type of a character. It handles the full multinational
25 * character set, and lets me ask some questions that the
26 * standard "ctype" macros cannot ask.
27 */
28/*
29 * Due to incompatible behaviour between "standard" emacs and
30 * ctags word traversing, '_' character's value is changed on
31 * the fly in ctags mode, hence non-const.
32 */
33char cinfo[256] = {
34	_MG_C, _MG_C, _MG_C, _MG_C,				      /* 0x0X */
35	_MG_C, _MG_C, _MG_C, _MG_C,
36	_MG_C, _MG_C, _MG_C, _MG_C,
37	_MG_C, _MG_C, _MG_C, _MG_C,
38	_MG_C, _MG_C, _MG_C, _MG_C,				      /* 0x1X */
39	_MG_C, _MG_C, _MG_C, _MG_C,
40	_MG_C, _MG_C, _MG_C, _MG_C,
41	_MG_C, _MG_C, _MG_C, _MG_C,
42	0, _MG_P, 0, 0,						      /* 0x2X */
43	_MG_W, _MG_W, 0, _MG_W,
44	0, 0, 0, 0,
45	0, 0, _MG_P, 0,
46	_MG_D | _MG_W, _MG_D | _MG_W, _MG_D | _MG_W, _MG_D | _MG_W,   /* 0x3X */
47	_MG_D | _MG_W, _MG_D | _MG_W, _MG_D | _MG_W, _MG_D | _MG_W,
48	_MG_D | _MG_W, _MG_D | _MG_W, 0, 0,
49	0, 0, 0, _MG_P,
50	0, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,		      /* 0x4X */
51	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
52	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
53	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
54	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,   /* 0x5X */
55	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
56	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, 0,
57	0, 0, 0, 0,
58	0, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,		      /* 0x6X */
59	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
60	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
61	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
62	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,   /* 0x7X */
63	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
64	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, 0,
65	0, 0, 0, _MG_C,
66	0, 0, 0, 0,						      /* 0x8X */
67	0, 0, 0, 0,
68	0, 0, 0, 0,
69	0, 0, 0, 0,
70	0, 0, 0, 0,						      /* 0x9X */
71	0, 0, 0, 0,
72	0, 0, 0, 0,
73	0, 0, 0, 0,
74	0, 0, 0, 0,						      /* 0xAX */
75	0, 0, 0, 0,
76	0, 0, 0, 0,
77	0, 0, 0, 0,
78	0, 0, 0, 0,						      /* 0xBX */
79	0, 0, 0, 0,
80	0, 0, 0, 0,
81	0, 0, 0, 0,
82	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,   /* 0xCX */
83	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
84	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
85	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
86	0, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,		      /* 0xDX */
87	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
88	_MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W, _MG_U | _MG_W,
89	_MG_U | _MG_W, _MG_U | _MG_W, 0, _MG_W,
90	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,   /* 0xEX */
91	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
92	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
93	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
94	0, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,		      /* 0xFX */
95	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
96	_MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W, _MG_L | _MG_W,
97	_MG_L | _MG_W, _MG_L | _MG_W, 0, 0
98};
99
100/*
101 * Find the name of a keystroke.  Needs to be changed to handle 8-bit printing
102 * characters and function keys better.	 Returns a pointer to the terminating
103 * '\0'.  Returns NULL on failure.
104 */
105char *
106getkeyname(char *cp, size_t len, int k)
107{
108	const char	*np;
109	size_t		 copied;
110
111	if (k < 0)
112		k = CHARMASK(k);	/* sign extended char */
113	switch (k) {
114	case CCHR('@'):
115		np = "C-SPC";
116		break;
117	case CCHR('I'):
118		np = "TAB";
119		break;
120	case CCHR('M'):
121		np = "RET";
122		break;
123	case CCHR('['):
124		np = "ESC";
125		break;
126	case ' ':
127		np = "SPC";
128		break;		/* yuck again */
129	case CCHR('?'):
130		np = "DEL";
131		break;
132	default:
133		if (k >= KFIRST && k <= KLAST &&
134		    (np = keystrings[k - KFIRST]) != NULL)
135			break;
136		if (k > CCHR('?')) {
137			*cp++ = '0';
138			*cp++ = ((k >> 6) & 7) + '0';
139			*cp++ = ((k >> 3) & 7) + '0';
140			*cp++ = (k & 7) + '0';
141			*cp = '\0';
142			return (cp);
143		} else if (k < ' ') {
144			*cp++ = 'C';
145			*cp++ = '-';
146			k = CCHR(k);
147			if (ISUPPER(k))
148				k = TOLOWER(k);
149		}
150		*cp++ = k;
151		*cp = '\0';
152		return (cp);
153	}
154	copied = strlcpy(cp, np, len);
155	if (copied >= len)
156		copied = len - 1;
157	return (cp + copied);
158}
159