Blame


1 bb7ff349 2009-07-08 mt /*
2 bb7ff349 2009-07-08 mt * Parse /lib/keyboard to create latin1.h table for kernel.
3 bb7ff349 2009-07-08 mt * mklatinkbd -r prints an array of integers rather than a Rune string literal.
4 bb7ff349 2009-07-08 mt */
5 bb7ff349 2009-07-08 mt
6 bb7ff349 2009-07-08 mt #include <u.h>
7 bb7ff349 2009-07-08 mt #include <libc.h>
8 bb7ff349 2009-07-08 mt #include <bio.h>
9 bb7ff349 2009-07-08 mt #include <ctype.h>
10 bb7ff349 2009-07-08 mt
11 bb7ff349 2009-07-08 mt int rflag;
12 b567422f 2011-01-02 rsc int xflag;
13 bb7ff349 2009-07-08 mt
14 bb7ff349 2009-07-08 mt enum {
15 bb7ff349 2009-07-08 mt MAXLD = 2, /* latin1.c assumes this is 2 */
16 bb7ff349 2009-07-08 mt };
17 bb7ff349 2009-07-08 mt
18 bb7ff349 2009-07-08 mt char *head = ""
19 bb7ff349 2009-07-08 mt "/*\n"
20 bb7ff349 2009-07-08 mt " * This is automatically generated by %s from /lib/keyboard\n"
21 bb7ff349 2009-07-08 mt " * Edit /lib/keyboard instead.\n"
22 bb7ff349 2009-07-08 mt " */\n";
23 bb7ff349 2009-07-08 mt
24 bb7ff349 2009-07-08 mt /*
25 bb7ff349 2009-07-08 mt * latin1.c assumes that strlen(ld) is at most 2.
26 bb7ff349 2009-07-08 mt * It also assumes that latintab[i].ld can be a prefix of latintab[j].ld
27 bb7ff349 2009-07-08 mt * only when j < i. We ensure this by sorting the output by prefix length.
28 bb7ff349 2009-07-08 mt * The so array is indexed by the character value.
29 bb7ff349 2009-07-08 mt */
30 bb7ff349 2009-07-08 mt
31 bb7ff349 2009-07-08 mt typedef struct Trie Trie;
32 bb7ff349 2009-07-08 mt struct Trie {
33 bb7ff349 2009-07-08 mt int n; /* of characters r */
34 42ef984c 2011-04-04 rsc char seq[MAXLD+1+1];
35 bb7ff349 2009-07-08 mt Rune r[256];
36 bb7ff349 2009-07-08 mt Trie *link[256];
37 bb7ff349 2009-07-08 mt };
38 bb7ff349 2009-07-08 mt
39 bb7ff349 2009-07-08 mt Trie *root;
40 bb7ff349 2009-07-08 mt
41 bb7ff349 2009-07-08 mt Trie*
42 bb7ff349 2009-07-08 mt mktrie(char *seq)
43 bb7ff349 2009-07-08 mt {
44 bb7ff349 2009-07-08 mt uchar *q;
45 bb7ff349 2009-07-08 mt Trie **tp;
46 bb7ff349 2009-07-08 mt
47 bb7ff349 2009-07-08 mt if(root == nil) {
48 bb7ff349 2009-07-08 mt root = malloc(sizeof *root);
49 bb7ff349 2009-07-08 mt memset(root, 0, sizeof *root);
50 bb7ff349 2009-07-08 mt }
51 bb7ff349 2009-07-08 mt
52 bb7ff349 2009-07-08 mt assert(seq[0] != '\0');
53 bb7ff349 2009-07-08 mt
54 bb7ff349 2009-07-08 mt tp = &root;
55 bb7ff349 2009-07-08 mt for(q=(uchar*)seq; *(q+1) != '\0'; q++) {
56 bb7ff349 2009-07-08 mt tp = &(*tp)->link[*q];
57 bb7ff349 2009-07-08 mt if(*tp == nil) {
58 bb7ff349 2009-07-08 mt *tp = malloc(sizeof(**tp));
59 bb7ff349 2009-07-08 mt assert(*tp != nil);
60 bb7ff349 2009-07-08 mt memset(*tp, 0, sizeof(**tp));
61 bb7ff349 2009-07-08 mt strcpy((*tp)->seq, seq);
62 bb7ff349 2009-07-08 mt (*tp)->seq[q+1-(uchar*)seq] = '\0';
63 bb7ff349 2009-07-08 mt }
64 bb7ff349 2009-07-08 mt }
65 bb7ff349 2009-07-08 mt
66 bb7ff349 2009-07-08 mt assert(*tp != nil);
67 bb7ff349 2009-07-08 mt return *tp;
68 bb7ff349 2009-07-08 mt }
69 bb7ff349 2009-07-08 mt
70 bb7ff349 2009-07-08 mt /* add character sequence s meaning rune r */
71 bb7ff349 2009-07-08 mt void
72 bb7ff349 2009-07-08 mt insert(char *s, Rune r)
73 bb7ff349 2009-07-08 mt {
74 bb7ff349 2009-07-08 mt uchar lastc;
75 bb7ff349 2009-07-08 mt int len;
76 bb7ff349 2009-07-08 mt Trie *t;
77 bb7ff349 2009-07-08 mt
78 bb7ff349 2009-07-08 mt len = strlen(s);
79 bb7ff349 2009-07-08 mt lastc = (uchar)s[len-1];
80 bb7ff349 2009-07-08 mt
81 bb7ff349 2009-07-08 mt t = mktrie(s);
82 bb7ff349 2009-07-08 mt if(t->r[lastc]) {
83 bb7ff349 2009-07-08 mt fprint(2, "warning: table duplicate: %s is %C and %C\n", s, t->r[lastc], r);
84 bb7ff349 2009-07-08 mt return;
85 bb7ff349 2009-07-08 mt }
86 bb7ff349 2009-07-08 mt t->r[lastc] = r;
87 bb7ff349 2009-07-08 mt t->n++;
88 bb7ff349 2009-07-08 mt }
89 bb7ff349 2009-07-08 mt
90 bb7ff349 2009-07-08 mt void
91 bb7ff349 2009-07-08 mt cprintchar(Biobuf *b, int c)
92 bb7ff349 2009-07-08 mt {
93 bb7ff349 2009-07-08 mt /* print a byte c safe for a C string. */
94 bb7ff349 2009-07-08 mt switch(c) {
95 bb7ff349 2009-07-08 mt case '\'':
96 bb7ff349 2009-07-08 mt case '\"':
97 bb7ff349 2009-07-08 mt case '\\':
98 bb7ff349 2009-07-08 mt Bprint(b, "\\%c", c);
99 bb7ff349 2009-07-08 mt break;
100 bb7ff349 2009-07-08 mt case '\t':
101 bb7ff349 2009-07-08 mt Bprint(b, "\\t");
102 bb7ff349 2009-07-08 mt break;
103 bb7ff349 2009-07-08 mt default:
104 bb7ff349 2009-07-08 mt if(isascii(c) && isprint(c))
105 bb7ff349 2009-07-08 mt Bprint(b, "%c", c);
106 bb7ff349 2009-07-08 mt else
107 bb7ff349 2009-07-08 mt Bprint(b, "\\x%.2x", c);
108 bb7ff349 2009-07-08 mt break;
109 bb7ff349 2009-07-08 mt }
110 bb7ff349 2009-07-08 mt }
111 bb7ff349 2009-07-08 mt
112 bb7ff349 2009-07-08 mt void
113 bb7ff349 2009-07-08 mt cprints(Biobuf *b, char *p)
114 bb7ff349 2009-07-08 mt {
115 bb7ff349 2009-07-08 mt while(*p != '\0')
116 bb7ff349 2009-07-08 mt cprintchar(b, *p++);
117 bb7ff349 2009-07-08 mt }
118 bb7ff349 2009-07-08 mt
119 b567422f 2011-01-02 rsc void
120 b567422f 2011-01-02 rsc xprint(Biobuf *b, int c)
121 b567422f 2011-01-02 rsc {
122 b567422f 2011-01-02 rsc }
123 bb7ff349 2009-07-08 mt
124 bb7ff349 2009-07-08 mt void
125 bb7ff349 2009-07-08 mt printtrie(Biobuf *b, Trie *t)
126 bb7ff349 2009-07-08 mt {
127 bb7ff349 2009-07-08 mt int i;
128 b567422f 2011-01-02 rsc char *p;
129 bb7ff349 2009-07-08 mt
130 bb7ff349 2009-07-08 mt for(i=0; i<256; i++)
131 bb7ff349 2009-07-08 mt if(t->link[i])
132 bb7ff349 2009-07-08 mt printtrie(b, t->link[i]);
133 b567422f 2011-01-02 rsc if(t->n == 0)
134 b567422f 2011-01-02 rsc return;
135 b567422f 2011-01-02 rsc
136 b567422f 2011-01-02 rsc if(xflag) {
137 b567422f 2011-01-02 rsc for(i=0; i<256; i++) {
138 b567422f 2011-01-02 rsc if(t->r[i] == 0)
139 b567422f 2011-01-02 rsc continue;
140 b567422f 2011-01-02 rsc Bprint(b, "<Multi_key>");
141 b567422f 2011-01-02 rsc for(p=t->seq; *p; p++)
142 b567422f 2011-01-02 rsc Bprint(b, " %k", *p);
143 b567422f 2011-01-02 rsc Bprint(b, " %k : \"%C\" U%04X\n", i, t->r[i], t->r[i]);
144 b567422f 2011-01-02 rsc }
145 b567422f 2011-01-02 rsc return;
146 b567422f 2011-01-02 rsc }
147 bb7ff349 2009-07-08 mt
148 b567422f 2011-01-02 rsc Bprint(b, "\t\"");
149 b567422f 2011-01-02 rsc cprints(b, t->seq);
150 b567422f 2011-01-02 rsc Bprint(b, "\", \"");
151 b567422f 2011-01-02 rsc for(i=0; i<256; i++)
152 b567422f 2011-01-02 rsc if(t->r[i])
153 b567422f 2011-01-02 rsc cprintchar(b, i);
154 b567422f 2011-01-02 rsc Bprint(b, "\",\t");
155 b567422f 2011-01-02 rsc if(rflag) {
156 b567422f 2011-01-02 rsc Bprint(b, "{");
157 bb7ff349 2009-07-08 mt for(i=0; i<256; i++)
158 bb7ff349 2009-07-08 mt if(t->r[i])
159 b567422f 2011-01-02 rsc Bprint(b, " 0x%.4ux,", t->r[i]);
160 b567422f 2011-01-02 rsc Bprint(b, " }");
161 b567422f 2011-01-02 rsc } else {
162 b567422f 2011-01-02 rsc Bprint(b, "L\"");
163 b567422f 2011-01-02 rsc for(i=0; i<256; i++)
164 b567422f 2011-01-02 rsc if(t->r[i])
165 b567422f 2011-01-02 rsc Bprint(b, "%C", t->r[i]);
166 b567422f 2011-01-02 rsc Bprint(b, "\"");
167 b567422f 2011-01-02 rsc }
168 b567422f 2011-01-02 rsc Bprint(b, ",\n");
169 bb7ff349 2009-07-08 mt }
170 bb7ff349 2009-07-08 mt
171 bb7ff349 2009-07-08 mt void
172 bb7ff349 2009-07-08 mt readfile(char *fname)
173 bb7ff349 2009-07-08 mt {
174 bb7ff349 2009-07-08 mt Biobuf *b;
175 bb7ff349 2009-07-08 mt char *line, *p;
176 bb7ff349 2009-07-08 mt char *seq;
177 bb7ff349 2009-07-08 mt int inseq;
178 bb7ff349 2009-07-08 mt int lineno;
179 bb7ff349 2009-07-08 mt Rune r;
180 bb7ff349 2009-07-08 mt
181 bb7ff349 2009-07-08 mt if((b = Bopen(fname, OREAD)) == 0) {
182 bb7ff349 2009-07-08 mt fprint(2, "cannot open \"%s\": %r\n", fname);
183 bb7ff349 2009-07-08 mt exits("open");
184 bb7ff349 2009-07-08 mt }
185 bb7ff349 2009-07-08 mt
186 bb7ff349 2009-07-08 mt lineno = 0;
187 bb7ff349 2009-07-08 mt while((line = Brdline(b, '\n')) != 0) {
188 bb7ff349 2009-07-08 mt lineno++;
189 bb7ff349 2009-07-08 mt if(line[0] == '#')
190 bb7ff349 2009-07-08 mt continue;
191 bb7ff349 2009-07-08 mt
192 bb7ff349 2009-07-08 mt r = strtol(line, nil, 16);
193 bb7ff349 2009-07-08 mt p = strchr(line, ' ');
194 bb7ff349 2009-07-08 mt if(r == 0 || p != line+4 || p[0] != ' ' || p[1] != ' ') {
195 bb7ff349 2009-07-08 mt fprint(2, "%s:%d: cannot parse line\n", fname, lineno);
196 bb7ff349 2009-07-08 mt continue;
197 bb7ff349 2009-07-08 mt }
198 bb7ff349 2009-07-08 mt
199 bb7ff349 2009-07-08 mt p = line+6;
200 bb7ff349 2009-07-08 mt /* 00AE Or rO ® registered trade mark sign */
201 bb7ff349 2009-07-08 mt for(inseq=1, seq=p; (uchar)*p < Runeself; p++) {
202 bb7ff349 2009-07-08 mt if(*p == '\0' || isspace(*p)) {
203 bb7ff349 2009-07-08 mt if(inseq && p-seq >= 2) {
204 bb7ff349 2009-07-08 mt *p = '\0';
205 bb7ff349 2009-07-08 mt inseq = 0;
206 bb7ff349 2009-07-08 mt insert(seq, r);
207 bb7ff349 2009-07-08 mt *p = ' ';
208 bb7ff349 2009-07-08 mt }
209 bb7ff349 2009-07-08 mt if(*p == '\0')
210 bb7ff349 2009-07-08 mt break;
211 bb7ff349 2009-07-08 mt } else {
212 bb7ff349 2009-07-08 mt if(!inseq) {
213 bb7ff349 2009-07-08 mt seq = p;
214 bb7ff349 2009-07-08 mt inseq = 1;
215 bb7ff349 2009-07-08 mt }
216 bb7ff349 2009-07-08 mt }
217 bb7ff349 2009-07-08 mt }
218 bb7ff349 2009-07-08 mt }
219 bb7ff349 2009-07-08 mt }
220 bb7ff349 2009-07-08 mt
221 bb7ff349 2009-07-08 mt void
222 bb7ff349 2009-07-08 mt usage(void)
223 bb7ff349 2009-07-08 mt {
224 bb7ff349 2009-07-08 mt fprint(2, "usage: mklatinkbd [-r] [/lib/keyboard]\n");
225 bb7ff349 2009-07-08 mt exits("usage");
226 bb7ff349 2009-07-08 mt }
227 bb7ff349 2009-07-08 mt
228 b567422f 2011-01-02 rsc int kfmt(Fmt*);
229 b567422f 2011-01-02 rsc
230 bb7ff349 2009-07-08 mt void
231 bb7ff349 2009-07-08 mt main(int argc, char **argv)
232 bb7ff349 2009-07-08 mt {
233 b567422f 2011-01-02 rsc int i;
234 bb7ff349 2009-07-08 mt Biobuf bout;
235 bb7ff349 2009-07-08 mt
236 bb7ff349 2009-07-08 mt ARGBEGIN{
237 bb7ff349 2009-07-08 mt case 'r': /* print rune values */
238 bb7ff349 2009-07-08 mt rflag = 1;
239 b567422f 2011-01-02 rsc break;
240 b567422f 2011-01-02 rsc case 'x':
241 b567422f 2011-01-02 rsc xflag = 1;
242 bb7ff349 2009-07-08 mt break;
243 bb7ff349 2009-07-08 mt default:
244 bb7ff349 2009-07-08 mt usage();
245 bb7ff349 2009-07-08 mt }ARGEND
246 bb7ff349 2009-07-08 mt
247 bb7ff349 2009-07-08 mt if(argc > 1)
248 bb7ff349 2009-07-08 mt usage();
249 bb7ff349 2009-07-08 mt
250 b567422f 2011-01-02 rsc fmtinstall('k', kfmt);
251 b567422f 2011-01-02 rsc readfile(argc == 1 ? argv[0] : "/dev/stdin");
252 bb7ff349 2009-07-08 mt
253 bb7ff349 2009-07-08 mt Binit(&bout, 1, OWRITE);
254 b567422f 2011-01-02 rsc if(xflag) {
255 b567422f 2011-01-02 rsc Bprint(&bout, "# Generated by mklatinkbd -x; do not edit.\n");
256 b567422f 2011-01-02 rsc for(i=0x20; i<0x10000; i++)
257 b567422f 2011-01-02 rsc Bprint(&bout, "<Multi_key> <X> <%x> <%x> <%x> <%x> : \"%C\" U%04X\n",
258 b567422f 2011-01-02 rsc (i>>12)&0xf, (i>>8)&0xf, (i>>4)&0xf, i&0xf, i, i);
259 b567422f 2011-01-02 rsc }
260 bb7ff349 2009-07-08 mt if(root)
261 bb7ff349 2009-07-08 mt printtrie(&bout, root);
262 bb7ff349 2009-07-08 mt exits(0);
263 bb7ff349 2009-07-08 mt }
264 b567422f 2011-01-02 rsc
265 b567422f 2011-01-02 rsc // X11 key names
266 b567422f 2011-01-02 rsc
267 b567422f 2011-01-02 rsc struct {
268 b567422f 2011-01-02 rsc int c;
269 b567422f 2011-01-02 rsc char *s;
270 b567422f 2011-01-02 rsc } xkey[] = {
271 b567422f 2011-01-02 rsc ' ', "space",
272 b567422f 2011-01-02 rsc '!', "exclam",
273 b567422f 2011-01-02 rsc '"', "quotedbl",
274 b567422f 2011-01-02 rsc '#', "numbersign",
275 b567422f 2011-01-02 rsc '$', "dollar",
276 b567422f 2011-01-02 rsc '%', "percent",
277 b567422f 2011-01-02 rsc '&', "ampersand",
278 b567422f 2011-01-02 rsc '\'', "apostrophe",
279 b567422f 2011-01-02 rsc '(', "parenleft",
280 b567422f 2011-01-02 rsc ')', "parenright",
281 b567422f 2011-01-02 rsc '*', "asterisk",
282 b567422f 2011-01-02 rsc '+', "plus",
283 b567422f 2011-01-02 rsc ',', "comma",
284 b567422f 2011-01-02 rsc '-', "minus",
285 b567422f 2011-01-02 rsc '.', "period",
286 b567422f 2011-01-02 rsc '/', "slash",
287 b567422f 2011-01-02 rsc ':', "colon",
288 b567422f 2011-01-02 rsc ';', "semicolon",
289 b567422f 2011-01-02 rsc '<', "less",
290 b567422f 2011-01-02 rsc '=', "equal",
291 b567422f 2011-01-02 rsc '>', "greater",
292 b567422f 2011-01-02 rsc '?', "question",
293 b567422f 2011-01-02 rsc '@', "at",
294 b567422f 2011-01-02 rsc '[', "bracketleft",
295 b567422f 2011-01-02 rsc '\\', "backslash",
296 b567422f 2011-01-02 rsc ',', "bracketright",
297 b567422f 2011-01-02 rsc '^', "asciicircum",
298 b567422f 2011-01-02 rsc '_', "underscore",
299 b567422f 2011-01-02 rsc '`', "grave",
300 b567422f 2011-01-02 rsc '{', "braceleft",
301 b567422f 2011-01-02 rsc '|', "bar",
302 b567422f 2011-01-02 rsc '}', "braceright",
303 b567422f 2011-01-02 rsc '~', "asciitilde",
304 2bde5673 2011-01-02 rsc 0, 0
305 b567422f 2011-01-02 rsc };
306 b567422f 2011-01-02 rsc
307 b567422f 2011-01-02 rsc int
308 b567422f 2011-01-02 rsc kfmt(Fmt *f)
309 b567422f 2011-01-02 rsc {
310 b567422f 2011-01-02 rsc int i, c;
311 b567422f 2011-01-02 rsc
312 b567422f 2011-01-02 rsc c = va_arg(f->args, int);
313 b567422f 2011-01-02 rsc for(i=0; xkey[i].s; i++)
314 b567422f 2011-01-02 rsc if(xkey[i].c == c)
315 b567422f 2011-01-02 rsc return fmtprint(f, "<%s>", xkey[i].s);
316 b567422f 2011-01-02 rsc return fmtprint(f, "<%c>", c);
317 b567422f 2011-01-02 rsc }
318 b567422f 2011-01-02 rsc
319 b567422f 2011-01-02 rsc