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 bb7ff349 2009-07-08 mt
13 bb7ff349 2009-07-08 mt enum {
14 bb7ff349 2009-07-08 mt MAXLD = 2, /* latin1.c assumes this is 2 */
15 bb7ff349 2009-07-08 mt };
16 bb7ff349 2009-07-08 mt
17 bb7ff349 2009-07-08 mt char *head = ""
18 bb7ff349 2009-07-08 mt "/*\n"
19 bb7ff349 2009-07-08 mt " * This is automatically generated by %s from /lib/keyboard\n"
20 bb7ff349 2009-07-08 mt " * Edit /lib/keyboard instead.\n"
21 bb7ff349 2009-07-08 mt " */\n";
22 bb7ff349 2009-07-08 mt
23 bb7ff349 2009-07-08 mt /*
24 bb7ff349 2009-07-08 mt * latin1.c assumes that strlen(ld) is at most 2.
25 bb7ff349 2009-07-08 mt * It also assumes that latintab[i].ld can be a prefix of latintab[j].ld
26 bb7ff349 2009-07-08 mt * only when j < i. We ensure this by sorting the output by prefix length.
27 bb7ff349 2009-07-08 mt * The so array is indexed by the character value.
28 bb7ff349 2009-07-08 mt */
29 bb7ff349 2009-07-08 mt
30 bb7ff349 2009-07-08 mt typedef struct Trie Trie;
31 bb7ff349 2009-07-08 mt struct Trie {
32 bb7ff349 2009-07-08 mt int n; /* of characters r */
33 bb7ff349 2009-07-08 mt char seq[MAXLD+1];
34 bb7ff349 2009-07-08 mt Rune r[256];
35 bb7ff349 2009-07-08 mt Trie *link[256];
36 bb7ff349 2009-07-08 mt };
37 bb7ff349 2009-07-08 mt
38 bb7ff349 2009-07-08 mt Trie *root;
39 bb7ff349 2009-07-08 mt
40 bb7ff349 2009-07-08 mt Trie*
41 bb7ff349 2009-07-08 mt mktrie(char *seq)
42 bb7ff349 2009-07-08 mt {
43 bb7ff349 2009-07-08 mt uchar *q;
44 bb7ff349 2009-07-08 mt Trie **tp;
45 bb7ff349 2009-07-08 mt
46 bb7ff349 2009-07-08 mt if(root == nil) {
47 bb7ff349 2009-07-08 mt root = malloc(sizeof *root);
48 bb7ff349 2009-07-08 mt memset(root, 0, sizeof *root);
49 bb7ff349 2009-07-08 mt }
50 bb7ff349 2009-07-08 mt
51 bb7ff349 2009-07-08 mt assert(seq[0] != '\0');
52 bb7ff349 2009-07-08 mt
53 bb7ff349 2009-07-08 mt tp = &root;
54 bb7ff349 2009-07-08 mt for(q=(uchar*)seq; *(q+1) != '\0'; q++) {
55 bb7ff349 2009-07-08 mt tp = &(*tp)->link[*q];
56 bb7ff349 2009-07-08 mt if(*tp == nil) {
57 bb7ff349 2009-07-08 mt *tp = malloc(sizeof(**tp));
58 bb7ff349 2009-07-08 mt assert(*tp != nil);
59 bb7ff349 2009-07-08 mt memset(*tp, 0, sizeof(**tp));
60 bb7ff349 2009-07-08 mt strcpy((*tp)->seq, seq);
61 bb7ff349 2009-07-08 mt (*tp)->seq[q+1-(uchar*)seq] = '\0';
62 bb7ff349 2009-07-08 mt }
63 bb7ff349 2009-07-08 mt }
64 bb7ff349 2009-07-08 mt
65 bb7ff349 2009-07-08 mt assert(*tp != nil);
66 bb7ff349 2009-07-08 mt return *tp;
67 bb7ff349 2009-07-08 mt }
68 bb7ff349 2009-07-08 mt
69 bb7ff349 2009-07-08 mt /* add character sequence s meaning rune r */
70 bb7ff349 2009-07-08 mt void
71 bb7ff349 2009-07-08 mt insert(char *s, Rune r)
72 bb7ff349 2009-07-08 mt {
73 bb7ff349 2009-07-08 mt uchar lastc;
74 bb7ff349 2009-07-08 mt int len;
75 bb7ff349 2009-07-08 mt Trie *t;
76 bb7ff349 2009-07-08 mt
77 bb7ff349 2009-07-08 mt len = strlen(s);
78 bb7ff349 2009-07-08 mt lastc = (uchar)s[len-1];
79 bb7ff349 2009-07-08 mt
80 bb7ff349 2009-07-08 mt t = mktrie(s);
81 bb7ff349 2009-07-08 mt if(t->r[lastc]) {
82 bb7ff349 2009-07-08 mt fprint(2, "warning: table duplicate: %s is %C and %C\n", s, t->r[lastc], r);
83 bb7ff349 2009-07-08 mt return;
84 bb7ff349 2009-07-08 mt }
85 bb7ff349 2009-07-08 mt t->r[lastc] = r;
86 bb7ff349 2009-07-08 mt t->n++;
87 bb7ff349 2009-07-08 mt }
88 bb7ff349 2009-07-08 mt
89 bb7ff349 2009-07-08 mt void
90 bb7ff349 2009-07-08 mt cprintchar(Biobuf *b, int c)
91 bb7ff349 2009-07-08 mt {
92 bb7ff349 2009-07-08 mt /* print a byte c safe for a C string. */
93 bb7ff349 2009-07-08 mt switch(c) {
94 bb7ff349 2009-07-08 mt case '\'':
95 bb7ff349 2009-07-08 mt case '\"':
96 bb7ff349 2009-07-08 mt case '\\':
97 bb7ff349 2009-07-08 mt Bprint(b, "\\%c", c);
98 bb7ff349 2009-07-08 mt break;
99 bb7ff349 2009-07-08 mt case '\t':
100 bb7ff349 2009-07-08 mt Bprint(b, "\\t");
101 bb7ff349 2009-07-08 mt break;
102 bb7ff349 2009-07-08 mt default:
103 bb7ff349 2009-07-08 mt if(isascii(c) && isprint(c))
104 bb7ff349 2009-07-08 mt Bprint(b, "%c", c);
105 bb7ff349 2009-07-08 mt else
106 bb7ff349 2009-07-08 mt Bprint(b, "\\x%.2x", c);
107 bb7ff349 2009-07-08 mt break;
108 bb7ff349 2009-07-08 mt }
109 bb7ff349 2009-07-08 mt }
110 bb7ff349 2009-07-08 mt
111 bb7ff349 2009-07-08 mt void
112 bb7ff349 2009-07-08 mt cprints(Biobuf *b, char *p)
113 bb7ff349 2009-07-08 mt {
114 bb7ff349 2009-07-08 mt while(*p != '\0')
115 bb7ff349 2009-07-08 mt cprintchar(b, *p++);
116 bb7ff349 2009-07-08 mt }
117 bb7ff349 2009-07-08 mt
118 bb7ff349 2009-07-08 mt
119 bb7ff349 2009-07-08 mt void
120 bb7ff349 2009-07-08 mt printtrie(Biobuf *b, Trie *t)
121 bb7ff349 2009-07-08 mt {
122 bb7ff349 2009-07-08 mt int i;
123 bb7ff349 2009-07-08 mt
124 bb7ff349 2009-07-08 mt for(i=0; i<256; i++)
125 bb7ff349 2009-07-08 mt if(t->link[i])
126 bb7ff349 2009-07-08 mt printtrie(b, t->link[i]);
127 bb7ff349 2009-07-08 mt
128 bb7ff349 2009-07-08 mt if(t->n > 0) {
129 bb7ff349 2009-07-08 mt Bprint(b, "\t\"");
130 bb7ff349 2009-07-08 mt cprints(b, t->seq);
131 bb7ff349 2009-07-08 mt Bprint(b, "\", \"");
132 bb7ff349 2009-07-08 mt for(i=0; i<256; i++)
133 bb7ff349 2009-07-08 mt if(t->r[i])
134 bb7ff349 2009-07-08 mt cprintchar(b, i);
135 bb7ff349 2009-07-08 mt Bprint(b, "\",\t");
136 bb7ff349 2009-07-08 mt if(rflag) {
137 bb7ff349 2009-07-08 mt Bprint(b, "{");
138 bb7ff349 2009-07-08 mt for(i=0; i<256; i++)
139 bb7ff349 2009-07-08 mt if(t->r[i])
140 bb7ff349 2009-07-08 mt Bprint(b, " 0x%.4ux,", t->r[i]);
141 bb7ff349 2009-07-08 mt Bprint(b, " }");
142 bb7ff349 2009-07-08 mt } else {
143 bb7ff349 2009-07-08 mt Bprint(b, "L\"");
144 bb7ff349 2009-07-08 mt for(i=0; i<256; i++)
145 bb7ff349 2009-07-08 mt if(t->r[i])
146 bb7ff349 2009-07-08 mt Bprint(b, "%C", t->r[i]);
147 bb7ff349 2009-07-08 mt Bprint(b, "\"");
148 bb7ff349 2009-07-08 mt }
149 bb7ff349 2009-07-08 mt Bprint(b, ",\n");
150 bb7ff349 2009-07-08 mt }
151 bb7ff349 2009-07-08 mt }
152 bb7ff349 2009-07-08 mt
153 bb7ff349 2009-07-08 mt void
154 bb7ff349 2009-07-08 mt readfile(char *fname)
155 bb7ff349 2009-07-08 mt {
156 bb7ff349 2009-07-08 mt Biobuf *b;
157 bb7ff349 2009-07-08 mt char *line, *p;
158 bb7ff349 2009-07-08 mt char *seq;
159 bb7ff349 2009-07-08 mt int inseq;
160 bb7ff349 2009-07-08 mt int lineno;
161 bb7ff349 2009-07-08 mt Rune r;
162 bb7ff349 2009-07-08 mt
163 bb7ff349 2009-07-08 mt if((b = Bopen(fname, OREAD)) == 0) {
164 bb7ff349 2009-07-08 mt fprint(2, "cannot open \"%s\": %r\n", fname);
165 bb7ff349 2009-07-08 mt exits("open");
166 bb7ff349 2009-07-08 mt }
167 bb7ff349 2009-07-08 mt
168 bb7ff349 2009-07-08 mt lineno = 0;
169 bb7ff349 2009-07-08 mt while((line = Brdline(b, '\n')) != 0) {
170 bb7ff349 2009-07-08 mt lineno++;
171 bb7ff349 2009-07-08 mt if(line[0] == '#')
172 bb7ff349 2009-07-08 mt continue;
173 bb7ff349 2009-07-08 mt
174 bb7ff349 2009-07-08 mt r = strtol(line, nil, 16);
175 bb7ff349 2009-07-08 mt p = strchr(line, ' ');
176 bb7ff349 2009-07-08 mt if(r == 0 || p != line+4 || p[0] != ' ' || p[1] != ' ') {
177 bb7ff349 2009-07-08 mt fprint(2, "%s:%d: cannot parse line\n", fname, lineno);
178 bb7ff349 2009-07-08 mt continue;
179 bb7ff349 2009-07-08 mt }
180 bb7ff349 2009-07-08 mt
181 bb7ff349 2009-07-08 mt p = line+6;
182 bb7ff349 2009-07-08 mt /* 00AE Or rO ® registered trade mark sign */
183 bb7ff349 2009-07-08 mt for(inseq=1, seq=p; (uchar)*p < Runeself; p++) {
184 bb7ff349 2009-07-08 mt if(*p == '\0' || isspace(*p)) {
185 bb7ff349 2009-07-08 mt if(inseq && p-seq >= 2) {
186 bb7ff349 2009-07-08 mt *p = '\0';
187 bb7ff349 2009-07-08 mt inseq = 0;
188 bb7ff349 2009-07-08 mt insert(seq, r);
189 bb7ff349 2009-07-08 mt *p = ' ';
190 bb7ff349 2009-07-08 mt }
191 bb7ff349 2009-07-08 mt if(*p == '\0')
192 bb7ff349 2009-07-08 mt break;
193 bb7ff349 2009-07-08 mt } else {
194 bb7ff349 2009-07-08 mt if(!inseq) {
195 bb7ff349 2009-07-08 mt seq = p;
196 bb7ff349 2009-07-08 mt inseq = 1;
197 bb7ff349 2009-07-08 mt }
198 bb7ff349 2009-07-08 mt }
199 bb7ff349 2009-07-08 mt }
200 bb7ff349 2009-07-08 mt }
201 bb7ff349 2009-07-08 mt }
202 bb7ff349 2009-07-08 mt
203 bb7ff349 2009-07-08 mt void
204 bb7ff349 2009-07-08 mt usage(void)
205 bb7ff349 2009-07-08 mt {
206 bb7ff349 2009-07-08 mt fprint(2, "usage: mklatinkbd [-r] [/lib/keyboard]\n");
207 bb7ff349 2009-07-08 mt exits("usage");
208 bb7ff349 2009-07-08 mt }
209 bb7ff349 2009-07-08 mt
210 bb7ff349 2009-07-08 mt void
211 bb7ff349 2009-07-08 mt main(int argc, char **argv)
212 bb7ff349 2009-07-08 mt {
213 bb7ff349 2009-07-08 mt Biobuf bout;
214 bb7ff349 2009-07-08 mt
215 bb7ff349 2009-07-08 mt ARGBEGIN{
216 bb7ff349 2009-07-08 mt case 'r': /* print rune values */
217 bb7ff349 2009-07-08 mt rflag = 1;
218 bb7ff349 2009-07-08 mt break;
219 bb7ff349 2009-07-08 mt default:
220 bb7ff349 2009-07-08 mt usage();
221 bb7ff349 2009-07-08 mt }ARGEND
222 bb7ff349 2009-07-08 mt
223 bb7ff349 2009-07-08 mt if(argc > 1)
224 bb7ff349 2009-07-08 mt usage();
225 bb7ff349 2009-07-08 mt
226 bb7ff349 2009-07-08 mt readfile(argc == 1 ? argv[0] : "/fd/0");
227 bb7ff349 2009-07-08 mt
228 bb7ff349 2009-07-08 mt Binit(&bout, 1, OWRITE);
229 bb7ff349 2009-07-08 mt if(root)
230 bb7ff349 2009-07-08 mt printtrie(&bout, root);
231 bb7ff349 2009-07-08 mt exits(0);
232 bb7ff349 2009-07-08 mt }