Remote whitespace at the ends of lines. Remove blank lines from the ends of files. Change modes on source files so that they are not executable. Signed-off-by: Dan Cross <cross@gajendra.net>
317 lines
5.1 KiB
C
317 lines
5.1 KiB
C
/*
|
|
* Parse /lib/keyboard to create latin1.h table for kernel.
|
|
* mklatinkbd -r prints an array of integers rather than a Rune string literal.
|
|
*/
|
|
|
|
#include <u.h>
|
|
#include <libc.h>
|
|
#include <bio.h>
|
|
#include <ctype.h>
|
|
|
|
int rflag;
|
|
int xflag;
|
|
|
|
enum {
|
|
MAXLD = 2, /* latin1.c assumes this is 2 */
|
|
};
|
|
|
|
char *head = ""
|
|
"/*\n"
|
|
" * This is automatically generated by %s from /lib/keyboard\n"
|
|
" * Edit /lib/keyboard instead.\n"
|
|
" */\n";
|
|
|
|
/*
|
|
* latin1.c assumes that strlen(ld) is at most 2.
|
|
* It also assumes that latintab[i].ld can be a prefix of latintab[j].ld
|
|
* only when j < i. We ensure this by sorting the output by prefix length.
|
|
* The so array is indexed by the character value.
|
|
*/
|
|
|
|
typedef struct Trie Trie;
|
|
struct Trie {
|
|
int n; /* of characters r */
|
|
char seq[MAXLD+1+1];
|
|
Rune r[256];
|
|
Trie *link[256];
|
|
};
|
|
|
|
Trie *root;
|
|
|
|
Trie*
|
|
mktrie(char *seq)
|
|
{
|
|
uchar *q;
|
|
Trie **tp;
|
|
|
|
if(root == nil) {
|
|
root = malloc(sizeof *root);
|
|
memset(root, 0, sizeof *root);
|
|
}
|
|
|
|
assert(seq[0] != '\0');
|
|
|
|
tp = &root;
|
|
for(q=(uchar*)seq; *(q+1) != '\0'; q++) {
|
|
tp = &(*tp)->link[*q];
|
|
if(*tp == nil) {
|
|
*tp = malloc(sizeof(**tp));
|
|
assert(*tp != nil);
|
|
memset(*tp, 0, sizeof(**tp));
|
|
strcpy((*tp)->seq, seq);
|
|
(*tp)->seq[q+1-(uchar*)seq] = '\0';
|
|
}
|
|
}
|
|
|
|
assert(*tp != nil);
|
|
return *tp;
|
|
}
|
|
|
|
/* add character sequence s meaning rune r */
|
|
void
|
|
insert(char *s, Rune r)
|
|
{
|
|
uchar lastc;
|
|
int len;
|
|
Trie *t;
|
|
|
|
len = strlen(s);
|
|
lastc = (uchar)s[len-1];
|
|
|
|
t = mktrie(s);
|
|
if(t->r[lastc]) {
|
|
fprint(2, "warning: table duplicate: %s is %C and %C\n", s, t->r[lastc], r);
|
|
return;
|
|
}
|
|
t->r[lastc] = r;
|
|
t->n++;
|
|
}
|
|
|
|
void
|
|
cprintchar(Biobuf *b, int c)
|
|
{
|
|
/* print a byte c safe for a C string. */
|
|
switch(c) {
|
|
case '\'':
|
|
case '\"':
|
|
case '\\':
|
|
Bprint(b, "\\%c", c);
|
|
break;
|
|
case '\t':
|
|
Bprint(b, "\\t");
|
|
break;
|
|
default:
|
|
if(isascii(c) && isprint(c))
|
|
Bprint(b, "%c", c);
|
|
else
|
|
Bprint(b, "\\x%.2x", c);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
cprints(Biobuf *b, char *p)
|
|
{
|
|
while(*p != '\0')
|
|
cprintchar(b, *p++);
|
|
}
|
|
|
|
void
|
|
xprint(Biobuf *b, int c)
|
|
{
|
|
}
|
|
|
|
void
|
|
printtrie(Biobuf *b, Trie *t)
|
|
{
|
|
int i;
|
|
char *p;
|
|
|
|
for(i=0; i<256; i++)
|
|
if(t->link[i])
|
|
printtrie(b, t->link[i]);
|
|
if(t->n == 0)
|
|
return;
|
|
|
|
if(xflag) {
|
|
for(i=0; i<256; i++) {
|
|
if(t->r[i] == 0)
|
|
continue;
|
|
Bprint(b, "<Multi_key>");
|
|
for(p=t->seq; *p; p++)
|
|
Bprint(b, " %k", *p);
|
|
Bprint(b, " %k : \"%C\" U%04X\n", i, t->r[i], t->r[i]);
|
|
}
|
|
return;
|
|
}
|
|
|
|
Bprint(b, "\t\"");
|
|
cprints(b, t->seq);
|
|
Bprint(b, "\", \"");
|
|
for(i=0; i<256; i++)
|
|
if(t->r[i])
|
|
cprintchar(b, i);
|
|
Bprint(b, "\",\t");
|
|
if(rflag) {
|
|
Bprint(b, "{");
|
|
for(i=0; i<256; i++)
|
|
if(t->r[i])
|
|
Bprint(b, " 0x%.4ux,", t->r[i]);
|
|
Bprint(b, " }");
|
|
} else {
|
|
Bprint(b, "L\"");
|
|
for(i=0; i<256; i++)
|
|
if(t->r[i])
|
|
Bprint(b, "%C", t->r[i]);
|
|
Bprint(b, "\"");
|
|
}
|
|
Bprint(b, ",\n");
|
|
}
|
|
|
|
void
|
|
readfile(char *fname)
|
|
{
|
|
Biobuf *b;
|
|
char *line, *p;
|
|
char *seq;
|
|
int inseq;
|
|
int lineno;
|
|
Rune r;
|
|
|
|
if((b = Bopen(fname, OREAD)) == 0) {
|
|
fprint(2, "cannot open \"%s\": %r\n", fname);
|
|
exits("open");
|
|
}
|
|
|
|
lineno = 0;
|
|
while((line = Brdline(b, '\n')) != 0) {
|
|
lineno++;
|
|
if(line[0] == '#')
|
|
continue;
|
|
|
|
r = strtol(line, nil, 16);
|
|
p = strchr(line, ' ');
|
|
if(r == 0 || p != line+4 || p[0] != ' ' || p[1] != ' ') {
|
|
fprint(2, "%s:%d: cannot parse line\n", fname, lineno);
|
|
continue;
|
|
}
|
|
|
|
p = line+6;
|
|
/* 00AE Or rO ® registered trade mark sign */
|
|
for(inseq=1, seq=p; (uchar)*p < Runeself; p++) {
|
|
if(*p == '\0' || isspace(*p)) {
|
|
if(inseq && p-seq >= 2) {
|
|
*p = '\0';
|
|
inseq = 0;
|
|
insert(seq, r);
|
|
*p = ' ';
|
|
}
|
|
if(*p == '\0')
|
|
break;
|
|
} else {
|
|
if(!inseq) {
|
|
seq = p;
|
|
inseq = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
usage(void)
|
|
{
|
|
fprint(2, "usage: mklatinkbd [-r] [/lib/keyboard]\n");
|
|
exits("usage");
|
|
}
|
|
|
|
int kfmt(Fmt*);
|
|
|
|
void
|
|
main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
Biobuf bout;
|
|
|
|
ARGBEGIN{
|
|
case 'r': /* print rune values */
|
|
rflag = 1;
|
|
break;
|
|
case 'x':
|
|
xflag = 1;
|
|
break;
|
|
default:
|
|
usage();
|
|
}ARGEND
|
|
|
|
if(argc > 1)
|
|
usage();
|
|
|
|
fmtinstall('k', kfmt);
|
|
readfile(argc == 1 ? argv[0] : "/dev/stdin");
|
|
|
|
Binit(&bout, 1, OWRITE);
|
|
if(xflag) {
|
|
Bprint(&bout, "# Generated by mklatinkbd -x; do not edit.\n");
|
|
for(i=0x20; i<0x10000; i++)
|
|
Bprint(&bout, "<Multi_key> <X> <%x> <%x> <%x> <%x> : \"%C\" U%04X\n",
|
|
(i>>12)&0xf, (i>>8)&0xf, (i>>4)&0xf, i&0xf, i, i);
|
|
}
|
|
if(root)
|
|
printtrie(&bout, root);
|
|
exits(0);
|
|
}
|
|
|
|
// X11 key names
|
|
|
|
struct {
|
|
int c;
|
|
char *s;
|
|
} xkey[] = {
|
|
' ', "space",
|
|
'!', "exclam",
|
|
'"', "quotedbl",
|
|
'#', "numbersign",
|
|
'$', "dollar",
|
|
'%', "percent",
|
|
'&', "ampersand",
|
|
'\'', "apostrophe",
|
|
'(', "parenleft",
|
|
')', "parenright",
|
|
'*', "asterisk",
|
|
'+', "plus",
|
|
',', "comma",
|
|
'-', "minus",
|
|
'.', "period",
|
|
'/', "slash",
|
|
':', "colon",
|
|
';', "semicolon",
|
|
'<', "less",
|
|
'=', "equal",
|
|
'>', "greater",
|
|
'?', "question",
|
|
'@', "at",
|
|
'[', "bracketleft",
|
|
'\\', "backslash",
|
|
',', "bracketright",
|
|
'^', "asciicircum",
|
|
'_', "underscore",
|
|
'`', "grave",
|
|
'{', "braceleft",
|
|
'|', "bar",
|
|
'}', "braceright",
|
|
'~', "asciitilde",
|
|
0, 0
|
|
};
|
|
|
|
int
|
|
kfmt(Fmt *f)
|
|
{
|
|
int i, c;
|
|
|
|
c = va_arg(f->args, int);
|
|
for(i=0; xkey[i].s; i++)
|
|
if(xkey[i].c == c)
|
|
return fmtprint(f, "<%s>", xkey[i].s);
|
|
return fmtprint(f, "<%c>", c);
|
|
}
|