tdevdraw: generate Latin-1 table from lib/keyboard - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit bb7ff349fb314edffabb01c418e146d563548058
 (DIR) parent 342866f89cff5d35bc5e8fc7990767ad5d080a3c
 (HTM) Author: Michael Teichgräber <mt@ib.wmipf.de>
       Date:   Wed,  8 Jul 2009 08:34:42 -0700
       
       devdraw: generate Latin-1 table from lib/keyboard
       
       Diffstat:
         M lib/keyboard                        |      13 +++++++++----
         M src/cmd/devdraw/latin1.c            |     101 +------------------------------
         M src/cmd/devdraw/mkfile              |      10 ++++++++++
         A src/cmd/devdraw/mklatinkbd.c        |     232 ++++++++++++++++++++++++++++++
       
       4 files changed, 252 insertions(+), 104 deletions(-)
       ---
 (DIR) diff --git a/lib/keyboard b/lib/keyboard
       t@@ -392,11 +392,14 @@
        2020  dg          †        dagger
        2021  dd          ‡        double dagger
        2022  bu          •        bullet
       +2024  1.          ․ one dot leader
       +2025  2.          ‥ two dot leader
       +2026  3.          … horizontal ellipsis
        203D  !? ?!       ‽        interrobang
        2070  s0          ⁰        superscript digit zero
       -00B9  s1          ⁱ        superscript digit one
       -00B2  s2          ⁲        superscript digit two
       -00B3  s3          ⁳        superscript digit three
       +00B9  s1          ¹        superscript digit one
       +00B2  s2          ²        superscript digit two
       +00B3  s3          ³        superscript digit three
        2074  s4          ⁴        superscript digit four
        2075  s5          ⁵        superscript digit five
        2076  s6          ⁶        superscript digit six
       t@@ -408,9 +411,10 @@
        207C  s=          ⁼        superscript equals sign
        207D  s(          ⁽        superscript opening parenthesis
        207E  s)          ⁾        superscript closing parenthesis
       +2071  si          ⁱ        superscript latin small letter i
        207F  sn          ⁿ        superscript latin small letter n
        2013  en          –        en dash
       -2014  em          –        em dash
       +2014  em          —        em dash
        2080  b0          ₀        subscript digit zero
        2081  b1          ₁        subscript digit one
        2082  b2          ₂        subscript digit two
       t@@ -541,6 +545,7 @@
        22E7  >!~         ⋧        greater than but not equivalent to
        22EF  el          ⋯        midline horizontal ellipsis
        2423              ␣        open box, visible space
       +2639  :(          ☹ sad face
        263A  :)          ☺ smiley face
        2654  wk          ♔        white chess king
        2655  wq          ♕        white chess queen
 (DIR) diff --git a/src/cmd/devdraw/latin1.c b/src/cmd/devdraw/latin1.c
       t@@ -12,106 +12,7 @@ static struct cvlist
                char        *si;                /* options for last input characters */
                Rune        so[60];                /* the corresponding Rune for each si entry */
        } latintab[] = {
       -        " ", " i",        { 0x2423, 0x0131 },
       -        "!~", "-=~",        { 0x2244, 0x2247, 0x2249 },
       -        "!", "!<=>?bmp",        { 0x00a1, 0x226e, 0x2260, 0x226f, 0x203d, 0x2284, 0x2209, 0x2285 },
       -        "\"*", "IUiu",        { 0x03aa, 0x03ab, 0x03ca, 0x03cb },
       -        "\"", "\"AEIOUYaeiouy",        { 0x00a8, 0x00c4, 0x00cb, 0x00cf, 0x00d6, 0x00dc, 0x0178, 0x00e4, 0x00eb, 0x00ef, 0x00f6, 0x00fc, 0x00ff },
       -        "$*", "fhk",        { 0x03d5, 0x03d1, 0x03f0 },
       -        "$", "BEFHILMRVaefglopv",        { 0x212c, 0x2130, 0x2131, 0x210b, 0x2110, 0x2112, 0x2133, 0x211b, 0x01b2, 0x0251, 0x212f, 0x0192, 0x210a, 0x2113, 0x2134, 0x2118, 0x028b },
       -        "\'\"", "Uu",        { 0x01d7, 0x01d8 },
       -        "\'", "\'ACEILNORSUYZacegilnorsuyz",        { 0x00b4, 0x00c1, 0x0106, 0x00c9, 0x00cd, 0x0139, 0x0143, 0x00d3, 0x0154, 0x015a, 0x00da, 0x00dd, 0x0179, 0x00e1, 0x0107, 0x00e9, 0x0123, 0x00ed, 0x013a, 0x0144, 0x00f3, 0x0155, 0x015b, 0x00fa, 0x00fd, 0x017a },
       -        "*", "*ABCDEFGHIKLMNOPQRSTUWXYZabcdefghiklmnopqrstuwxyz",        { 0x2217, 0x0391, 0x0392, 0x039e, 0x0394, 0x0395, 0x03a6, 0x0393, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f, 0x03a0, 0x03a8, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a9, 0x03a7, 0x0397, 0x0396, 0x03b1, 0x03b2, 0x03be, 0x03b4, 0x03b5, 0x03c6, 0x03b3, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf, 0x03c0, 0x03c8, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c9, 0x03c7, 0x03b7, 0x03b6 },
       -        "+", "-O",        { 0x00b1, 0x2295 },
       -        ",", ",ACEGIKLNORSTUacegiklnorstu",        { 0x00b8, 0x0104, 0x00c7, 0x0118, 0x0122, 0x012e, 0x0136, 0x013b, 0x0145, 0x01ea, 0x0156, 0x015e, 0x0162, 0x0172, 0x0105, 0x00e7, 0x0119, 0x0123, 0x012f, 0x0137, 0x013c, 0x0146, 0x01eb, 0x0157, 0x015f, 0x0163, 0x0173 },
       -        "-*", "l",        { 0x019b },
       -        "-", "+-2:>DGHILOTZbdghiltuz~",        { 0x2213, 0x00ad, 0x01bb, 0x00f7, 0x2192, 0x00d0, 0x01e4, 0x0126, 0x0197, 0x0141, 0x2296, 0x0166, 0x01b5, 0x0180, 0x00f0, 0x01e5, 0x210f, 0x0268, 0x0142, 0x0167, 0x0289, 0x01b6, 0x2242 },
       -        ".", ".CEGILOZceglz",        { 0x00b7, 0x010a, 0x0116, 0x0120, 0x0130, 0x013f, 0x2299, 0x017b, 0x010b, 0x0117, 0x0121, 0x0140, 0x017c },
       -        "/", "Oo",        { 0x00d8, 0x00f8 },
       -        "1", "234568",        { 0x00bd, 0x2153, 0x00bc, 0x2155, 0x2159, 0x215b },
       -        "2", "-35",        { 0x01bb, 0x2154, 0x2156 },
       -        "3", "458",        { 0x00be, 0x2157, 0x215c },
       -        "4", "5",        { 0x2158 },
       -        "5", "68",        { 0x215a, 0x215d },
       -        "7", "8",        { 0x215e },
       -        ":", "()-=",        { 0x2639, 0x263a, 0x00f7, 0x2254 },
       -        "<!", "=~",        { 0x2268, 0x22e6 },
       -        "<", "-<=>~",        { 0x2190, 0x00ab, 0x2264, 0x2276, 0x2272 },
       -        "=", ":<=>OV",        { 0x2255, 0x22dc, 0x2261, 0x22dd, 0x229c, 0x21d2 },
       -        ">!", "=~",        { 0x2269, 0x22e7 },
       -        ">", "<=>~",        { 0x2277, 0x2265, 0x00bb, 0x2273 },
       -        "?", "!?",        { 0x203d, 0x00bf },
       -        "@\'", "\'",        { 0x044a },
       -        "@@", "\'EKSTYZekstyz",        { 0x044c, 0x0415, 0x041a, 0x0421, 0x0422, 0x042b, 0x0417, 0x0435, 0x043a, 0x0441, 0x0442, 0x044b, 0x0437 },
       -        "@C", "Hh",        { 0x0427, 0x0427 },
       -        "@E", "Hh",        { 0x042d, 0x042d },
       -        "@K", "Hh",        { 0x0425, 0x0425 },
       -        "@S", "CHch",        { 0x0429, 0x0428, 0x0429, 0x0428 },
       -        "@T", "Ss",        { 0x0426, 0x0426 },
       -        "@Y", "AEOUaeou",        { 0x042f, 0x0415, 0x0401, 0x042e, 0x042f, 0x0415, 0x0401, 0x042e },
       -        "@Z", "Hh",        { 0x0416, 0x0416 },
       -        "@c", "h",        { 0x0447 },
       -        "@e", "h",        { 0x044d },
       -        "@k", "h",        { 0x0445 },
       -        "@s", "ch",        { 0x0449, 0x0448 },
       -        "@t", "s",        { 0x0446 },
       -        "@y", "aeou",        { 0x044f, 0x0435, 0x0451, 0x044e },
       -        "@z", "h",        { 0x0436 },
       -        "@", "ABDFGIJLMNOPRUVXabdfgijlmnopruvx",        { 0x0410, 0x0411, 0x0414, 0x0424, 0x0413, 0x0418, 0x0419, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, 0x0420, 0x0423, 0x0412, 0x0425, 0x0430, 0x0431, 0x0434, 0x0444, 0x0433, 0x0438, 0x0439, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0443, 0x0432, 0x0445 },
       -        "A", "E",        { 0x00c6 },
       -        "C", "ACU",        { 0x22c2, 0x2102, 0x22c3 },
       -        "Dv", "Zz",        { 0x01c4, 0x01c5 },
       -        "D", "-e",        { 0x00d0, 0x2206 },
       -        "G", "-",        { 0x01e4 },
       -        "H", "-H",        { 0x0126, 0x210d },
       -        "I", "-J",        { 0x0197, 0x0132 },
       -        "L", "&-Jj|",        { 0x22c0, 0x0141, 0x01c7, 0x01c8, 0x22c1 },
       -        "M", "#48bs",        { 0x266e, 0x2669, 0x266a, 0x266d, 0x266f },
       -        "N", "JNj",        { 0x01ca, 0x2115, 0x01cb },
       -        "O", "*+-./=EIcoprx",        { 0x229b, 0x2295, 0x2296, 0x2299, 0x2298, 0x229c, 0x0152, 0x01a2, 0x00a9, 0x229a, 0x2117, 0x00ae, 0x2297 },
       -        "P", "P",        { 0x2119 },
       -        "Q", "Q",        { 0x211a },
       -        "R", "R",        { 0x211d },
       -        "S", "123S",        { 0x00b9, 0x00b2, 0x00b3, 0x00a7 },
       -        "T", "-u",        { 0x0166, 0x22a8 },
       -        "V", "=",        { 0x21d0 },
       -        "Y", "R",        { 0x01a6 },
       -        "Z", "-ACSZ",        { 0x01b5, 0xf015, 0xf017, 0xf016, 0x2124 },
       -        "^", "ACEGHIJOSUWYaceghijosuwy",        { 0x00c2, 0x0108, 0x00ca, 0x011c, 0x0124, 0x00ce, 0x0134, 0x00d4, 0x015c, 0x00db, 0x0174, 0x0176, 0x00e2, 0x0109, 0x00ea, 0x011d, 0x0125, 0x00ee, 0x0135, 0x00f4, 0x015d, 0x00fb, 0x0175, 0x0177 },
       -        "_\"", "AUau",        { 0x01de, 0x01d5, 0x01df, 0x01d6 },
       -        "_,", "Oo",        { 0x01ec, 0x01ed },
       -        "_.", "Aa",        { 0x01e0, 0x01e1 },
       -        "_", "AEIOU_aeiou",        { 0x0100, 0x0112, 0x012a, 0x014c, 0x016a, 0x00af, 0x0101, 0x0113, 0x012b, 0x014d, 0x016b },
       -        "`\"", "Uu",        { 0x01db, 0x01dc },
       -        "`", "AEIOUaeiou",        { 0x00c0, 0x00c8, 0x00cc, 0x00d2, 0x00d9, 0x00e0, 0x00e8, 0x00ec, 0x00f2, 0x00f9 },
       -        "a", "ben",        { 0x2194, 0x00e6, 0x2220 },
       -        "b", "()+-0123456789=bknpqru",        { 0x208d, 0x208e, 0x208a, 0x208b, 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, 0x2088, 0x2089, 0x208c, 0x265d, 0x265a, 0x265e, 0x265f, 0x265b, 0x265c, 0x2022 },
       -        "c", "$Oagu",        { 0x00a2, 0x00a9, 0x2229, 0x2245, 0x222a },
       -        "dv", "z",        { 0x01c6 },
       -        "d", "-adegz",        { 0x00f0, 0x2193, 0x2021, 0x00b0, 0x2020, 0x02a3 },
       -        "e", "$lmns",        { 0x20ac, 0x22ef, 0x2014, 0x2013, 0x2205 },
       -        "f", "a",        { 0x2200 },
       -        "g", "$-r",        { 0x00a4, 0x01e5, 0x2207 },
       -        "h", "-v",        { 0x210f, 0x0195 },
       -        "i", "-bfjps",        { 0x0268, 0x2286, 0x221e, 0x0133, 0x2287, 0x222b },
       -        "l", "\"$&\'-jz|",        { 0x201c, 0x00a3, 0x2227, 0x2018, 0x0142, 0x01c9, 0x22c4, 0x2228 },
       -        "m", "iou",        { 0x00b5, 0x2208, 0x00d7 },
       -        "n", "jo",        { 0x01cc, 0x00ac },
       -        "o", "AOUaeiu",        { 0x00c5, 0x229a, 0x016e, 0x00e5, 0x0153, 0x01a3, 0x016f },
       -        "p", "Odgrt",        { 0x2117, 0x2202, 0x00b6, 0x220f, 0x221d },
       -        "r", "\"\'O",        { 0x201d, 0x2019, 0x00ae },
       -        "s", "()+-0123456789=abinoprstu",        { 0x207d, 0x207e, 0x207a, 0x207b, 0x2070, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, 0x207c, 0x00aa, 0x2282, 0x2071, 0x207f, 0x00ba, 0x2283, 0x221a, 0x00df, 0x220d, 0x2211 },
       -        "t", "-efmsu",        { 0x0167, 0x2203, 0x2234, 0x2122, 0x03c2, 0x22a2 },
       -        "u", "-AEGIOUaegiou",        { 0x0289, 0x0102, 0x0114, 0x011e, 0x012c, 0x014e, 0x016c, 0x2191, 0x0115, 0x011f, 0x012d, 0x014f, 0x016d },
       -        "v\"", "Uu",        { 0x01d9, 0x01da },
       -        "v", "ACDEGIKLNORSTUZacdegijklnorstuz",        { 0x01cd, 0x010c, 0x010e, 0x011a, 0x01e6, 0x01cf, 0x01e8, 0x013d, 0x0147, 0x01d1, 0x0158, 0x0160, 0x0164, 0x01d3, 0x017d, 0x01ce, 0x010d, 0x010f, 0x011b, 0x01e7, 0x01d0, 0x01f0, 0x01e9, 0x013e, 0x0148, 0x01d2, 0x0159, 0x0161, 0x0165, 0x01d4, 0x017e },
       -        "w", "bknpqr",        { 0x2657, 0x2654, 0x2658, 0x2659, 0x2655, 0x2656 },
       -        "x", "O",        { 0x2297 },
       -        "y", "$",        { 0x00a5 },
       -        "z", "-",        { 0x01b6 },
       -        "|", "Pp|",        { 0x00de, 0x00fe, 0x00a6 },
       -        "~!", "=",        { 0x2246 },
       -        "~", "-=AINOUainou~",        { 0x2243, 0x2245, 0x00c3, 0x0128, 0x00d1, 0x00d5, 0x0168, 0x00e3, 0x0129, 0x00f1, 0x00f5, 0x0169, 0x2248 },
       +#include "latin1.h"
                0, 0, { 0 }
        };
        
 (DIR) diff --git a/src/cmd/devdraw/mkfile b/src/cmd/devdraw/mkfile
       t@@ -22,3 +22,13 @@ $O.drawclient: drawclient.$O drawfcall.$O
        
        $O.snarf: x11-alloc.$O x11-cload.$O x11-draw.$O x11-fill.$O x11-get.$O x11-init.$O x11-itrans.$O x11-keysym2ucs.$O x11-load.$O x11-pixelbits.$O x11-unload.$O x11-wsys.$O snarf.$O latin1.$O devdraw.$O
                $LD -o $target $prereq
       +
       +$O.mklatinkbd: mklatinkbd.$O
       +        $LD -o $target $prereq
       +
       +latin1.$O: latin1.h
       +
       +latin1.h: $PLAN9/lib/keyboard $O.mklatinkbd
       +        ./$O.mklatinkbd -r $PLAN9/lib/keyboard | sed 's/, }/ }/' >$target
       +
       +CLEANFILES=latin1.h $O.mklatinkbd
 (DIR) diff --git a/src/cmd/devdraw/mklatinkbd.c b/src/cmd/devdraw/mklatinkbd.c
       t@@ -0,0 +1,232 @@
       +/*
       + * 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);
       +}