Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/aux/mklatinkbd.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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