123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*
- * 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;
- 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];
- 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
- printtrie(Biobuf *b, Trie *t)
- {
- int i;
- for(i=0; i<256; i++)
- if(t->link[i])
- printtrie(b, t->link[i]);
- if(t->n > 0) {
- 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");
- }
- void
- main(int argc, char **argv)
- {
- Biobuf bout;
- ARGBEGIN{
- case 'r': /* print rune values */
- rflag = 1;
- break;
- default:
- usage();
- }ARGEND
- if(argc > 1)
- usage();
- readfile(argc == 1 ? argv[0] : "/fd/0");
- Binit(&bout, 1, OWRITE);
- if(root)
- printtrie(&bout, root);
- exits(0);
- }
|