diff options
author | Jacob Moody <moody@posixcafe.org> | 2022-08-03 11:14:44 +0000 |
---|---|---|
committer | Jacob Moody <moody@posixcafe.org> | 2022-08-03 11:14:44 +0000 |
commit | 0541a434cb9cfd1a776f1ef29de3a8a7aa1d9b99 (patch) | |
tree | 004121733d38dd829d622e988228b5213d768d96 /sys/src/cmd/ktrans/main.c | |
parent | 30794bba756772ada85b7642beddb42ffc416203 (diff) |
ktrans: 新しい降り
Rewrite of ktrans to act as an overlay to kbdfs.
Move map files outside of the binary in to /lib/ktrans
and get our dictionaries out of /lib while we're at it.
Use \n as an alias for ctrl-\ for first lookup, use ^w
to clear okurigana input. This also in general changes
the logic to never us to 'swallow' a character and always echo
them out, using backspaces for cleaning us up.
Diffstat (limited to 'sys/src/cmd/ktrans/main.c')
-rw-r--r-- | sys/src/cmd/ktrans/main.c | 915 |
1 files changed, 468 insertions, 447 deletions
diff --git a/sys/src/cmd/ktrans/main.c b/sys/src/cmd/ktrans/main.c index fb0cfe230..4105ad242 100644 --- a/sys/src/cmd/ktrans/main.c +++ b/sys/src/cmd/ktrans/main.c @@ -6,379 +6,140 @@ * okamoto@granite.cias.osakafu-u.ac.jp */ -/* - * A glossary on some of the Japanese vocabulary used: - * kana: syllabic letting, either hiragana(ひらがな) or katakana(カタカナ) - * kanji(漢字): borrowed characters, 楽 in 楽しい - * Okurigana(送り仮名): kana tail to kanji, しい in 楽しい - * Joshi(助詞): particle, は in 私は - * Jisho(辞書): dictionary - * kouho(候補): candidate - */ - #include <u.h> #include <libc.h> +#include <ctype.h> #include <bio.h> +#include <fcall.h> +#include <thread.h> +#include <9p.h> + #include "hash.h" #include "ktrans.h" -#define LSIZE 256 +static Hmap *jisho, *zidian; +static int deflang; +static char backspace[64]; -Rune lbuf[LSIZE]; /* hiragana buffer for key input written by send() */ -Hmap *table; -uchar okurigana[LSIZE]; /* buffer for okurigana */ -char okuri = 0; /* buffer/flag for capital input char */ -int in, out; -int llen, olen, joshi = 0; -int natural = 1; /* not Japanese but English mode */ +mainstacksize = 8192*2; -int changelang(int); -int dotrans(Hmap*); -int nrune(char *); -void send(uchar *, int); -Hmap* opendict(Hmap *, char *); - -void -kbdopen(void) +char* +pushutf(char *dst, char *e, char *u, int nrune) { - int n, kinfd, koutfd, fd[2]; - char buf[128]; - int kbd; - - kbd = 1; - if((kinfd = open("/dev/kbd", OREAD)) < 0){ - kbd = 0; - if((kinfd = open("/dev/cons", OREAD)) < 0) - sysfatal("open kbd: %r"); - } - if(bind("#|", "/n/temp", MREPL) < 0) - sysfatal("bind /n/temp: %r"); - if((koutfd = open("/n/temp/data1", OWRITE)) < 0) - sysfatal("open kbd pipe: %r"); - if(bind("/n/temp/data", kbd? "/dev/kbd": "/dev/cons", MREPL) < 0) - sysfatal("bind kbd pipe: %r"); - unmount(nil, "/n/temp"); - if(!kbd){ - in = kinfd; - out = koutfd; - return; - } - if(pipe(fd) < 0) - sysfatal("pipe: %r"); - if(fork()){ - in = out = fd[0]; - close(fd[1]); - close(kinfd); - close(koutfd); - return; - } - close(fd[0]); - if(fork()){ - Biobuf b; - long r; - - Binit(&b, fd[1], OREAD); - while((r = Bgetrune(&b)) >= 0){ - n = snprint(buf, sizeof(buf), "c%C", (Rune)r)+1; - write(koutfd, buf, n); /* pass on result */ - } - } else - while((n = read(kinfd, buf, sizeof(buf))) > 0){ - buf[n-1] = 0; - if(n < 2 || buf[0] != 'c') - write(koutfd, buf, n); /* pass on */ - else - write(fd[1], buf+1, n-2); /* to translator */ + Rune r; + char *p; + char *d; + + if(dst >= e) + return dst; + + d = dst; + p = u; + while(d < e-1){ + if(isascii(*p)){ + if((*d = *p) == '\0') + return d; + p++; + d++; + } else { + p += chartorune(&r, p); + if(r == Runeerror){ + *d = '\0'; + return d; + } + d += runetochar(d, &r); } - exits(nil); + if(nrune > 0 && --nrune == 0) + break; + } + if(d > e-1) + d = e-1; + + *d = '\0'; + return d; } -Map signalmore = { - "_", nil, 1, +typedef struct Str Str; +struct Str { + char b[128]; + char *p; }; -Hmap* -initmap(Map *m, int n) -{ - int i, j; - char buf[16]; - char *s; - Map prev; - Hmap *h; - - h = hmapalloc(n, sizeof(Map)); - for(i = 0; i < n; i++){ - if(m[i].roma == nil || m[i].roma[0] == '\0') - continue; - - //We mark all partial strings so we know when - //we have partial match when ingesting. - j = 2; - for(s = m[i].roma; *s && j <= sizeof buf; s++){ - snprint(buf, j, "%s", m[i].roma); - prev = m[i]; - if(hmapget(h, buf, &prev) == 0){ - if(prev.leadstomore == 1 && s[1] == '\0'){ - //confict; partial & valid input - prev = m[i]; - prev.leadstomore = 1; - } - } - - if(s[1] == '\0'){ - hmaprepl(&h, strdup(buf), &prev, nil, 1); - } else { - hmaprepl(&h, strdup(buf), &signalmore, nil, 1); - } - j++; - } - } - return h; -} +#define strend(s) ((s)->b + sizeof (s)->b) void -usage(void) +resetstr(Str *s, ...) { - fprint(2, "usage: %s\n", argv0); - exits("usage"); + va_list args; + va_start(args, s); + do { + s->p = s->b; + s->p[0] = '\0'; + s = va_arg(args, Str*); + } while(s != nil); + va_end(args); } void -main(int argc, char *argv[]) +popstr(Str *s) { + while(s->p > s->b && (*--s->p & 0xC0)==0x80) + ; - uchar *bp, *ep, buf[128]; - Map lkup, last; - int wantmore; - int n, c; - char *jishoname, *zidianname; - Hmap *jisho, *zidian; - - ARGBEGIN{ - default: usage(); - }ARGEND; - if(argc != 0) - usage(); - - if((jishoname = getenv("jisho")) == nil) - jishoname = "/lib/kanji.jisho"; - jisho = opendict(nil, jishoname); - - if((zidianname = getenv("zidian")) == nil) - zidianname = "/lib/hanzi.zidian"; - zidian = opendict(nil, zidianname); - - hira = table = initmap(mhira, nelem(mhira)); - kata = initmap(mkata, nelem(mkata)); - greek = initmap(mgreek, nelem(mgreek)); - cyril = initmap(mcyril, nelem(mcyril)); - hangul = initmap(mhangul, nelem(mhangul)); - last = (Map){nil, nil, -1}; - - kbdopen(); - if(fork()) - exits(nil); /* parent process will exit */ - - bp = ep = buf; - wantmore = 0; - for (;;) { /* key board input loop */ - getmore: - if (bp>=ep || wantmore) { - if (wantmore==0) - bp = ep = buf; /* clear all */ - n = read(in, ep, &buf[sizeof(buf)]-ep); - if (n<=0) - exits(""); - ep += n; - *ep = '\0'; - } - while (bp<ep) { /* there are input data */ - if (table == hira && natural != 1 && (*bp>'A' && *bp<='Z') && ep-bp<2 - && !strchr("EIOU", *bp)) { - wantmore = 1; - goto getmore; - } - if (!fullrune((char *)bp, ep-bp)) { /* not enough length of input */ - wantmore = 1; - goto getmore; - } - wantmore = 0; - - if (*bp=='') { /* ^x read ktrans-jisho once more */ - jisho = opendict(jisho, jishoname); - zidian = opendict(zidian, zidianname); - llen = 0; - olen = okuri = joshi = 0; - wantmore=0; - bp=ep=buf; - continue; - } - if (*bp=='') { /* ^\ (start translation command) */ - if (table == hanzi) - c = dotrans(zidian); - else - c = dotrans(jisho); - if (c) - *bp = c; /* pointer to translated rune */ - else - bp++; - continue; - } - if (*bp=='') { /* ^l (no translate command) */ - bp++; - llen = 0; - olen = okuri = joshi = 0; - last.kana = nil; - continue; - } - if (changelang(*bp)) { /* change language mode OK */ - bp++; - olen = okuri = joshi = 0; - last.kana = nil; - continue; - } - if (natural || *bp<=' ' || *bp>='{') { /* English mode but not ascii */ - Rune r; - int rlen = chartorune(&r, (char *)bp); - send(bp, rlen); /* write bp to /dev/cons */ - bp += rlen; - last.kana = nil; - continue; - } - if (table == hira && (*bp >= 'A' && *bp <= 'Z') && (*(bp+1) < 'A' - || *(bp+1) > 'Z')) { - *bp = okuri = tolower(*bp); - joshi = olen = 0; - } else if (table == hira && (*bp >= 'A' && *bp <= 'Z') && - (*(bp+1) >= 'A' && *(bp+1) <= 'Z')) { - *bp = okuri = tolower(*bp); - *(bp+1) = tolower(*(bp+1)); - joshi = 1; - olen = 0; - } - if(hmapget(table, (char*)bp, &lkup) < 0){ - if(last.kana != nil){ - send((uchar*)last.kana, strlen(last.kana)); - bp += strlen(last.roma); - } else - send(bp++, 1); - last.kana = nil; - break; - } - /* concatinations; only advance a single character */ - if(lkup.kana != nil && strstr("ッっ", lkup.kana)) - lkup.roma = "_"; - /* partial match */ - if(lkup.kana == nil || lkup.leadstomore == 1){ - if(lkup.kana != nil) - last = lkup; - - wantmore = 1; - break; - } - last.kana = nil; - send((uchar*)lkup.kana, strlen(lkup.kana)); - bp += strlen(lkup.roma); - } - } + s->p[0] = '\0'; } -/* - * send UTF string (p) with length (n) to stdout - * and write rune (r) in global lbuf[] buffer - * or okurigana[] buffer if okuri (verb or joshi) mode - */ -void -send(uchar *p, int n) +Hmap* +openmap(char *file) { + Biobuf *b; + char *s; + Map map; + Hmap *h; + char *key, *val; + Str partial; Rune r; - uchar *ep; - if (write(out, (char*)p, n) != n) - sysfatal("write: %r"); + h = hmapalloc(64, sizeof(Map)); + b = Bopen(file, OREAD); + if(b == nil) + return nil; - if (llen>LSIZE-64) { - memmove((char*)lbuf, (char*)lbuf+64, 64*sizeof(Rune)); - llen -= 64; - } + while(key = Brdstr(b, '\n', 1)){ + if(key[0] == '\0'){ + Err: + free(key); + continue; + } - if(table != hira && table != hanzi) - return; - if(natural && table != hanzi) - return; + val = strchr(key, '\t'); + if(val == nil || val[1] == '\0') + goto Err; - ep = p+n; - if(okuri) - while (olen<LSIZE && p<ep) - okurigana[olen++] = *p++; - else - while (llen<LSIZE && p<ep) { - p += chartorune(&r, (char*)p); - if (r=='\b') { - if (llen>0) - llen--; - continue; + *val = '\0'; + val++; + resetstr(&partial, nil); + for(s = key; *s; s += chartorune(&r, s)){ + partial.p = pushutf(partial.p, strend(&partial), s, 1); + map.leadstomore = 0; + if(hmapget(h, partial.b, &map) == 0){ + if(map.leadstomore == 1 && s[1] == '\0') + map.leadstomore = 1; } - if (r==0x80) /* ignore view key */ - continue; - lbuf[llen++] = r; - } -} - -int -changelang(int c) -{ - switch(c){ - case '': /* ^t (English mode) */ - natural = 1; - table = hira; - llen = 0; - return 1; - break; - - case '': /* ^n (Japanese hiragana mode ) */ - natural = 0; - table = hira; - llen = 0; - return 1; - break; - - case '': /* ^k (Japanese katakana mode) */ - natural = 0; - table = kata; - llen = 0; - return 1; - break; - - case '': /* ^r (Russian mode) */ - natural = 0; - table = cyril; - llen = 0; - return 1; - break; - - case '': /* ^o (Greek mode) */ - natural = 0; - table = greek; - llen = 0; - return 1; - break; - - case '': /* ^s (Korean mode) */ - natural = 0; - table = hangul; - llen = 0; - return 1; - break; - - case '': /* ^c (Chinese mode) */ - natural = 1; - table = hanzi; - llen = 0; - return 1; - break; + if(s[1] == '\0'){ + map.roma = key; + map.kana = val; + hmaprepl(&h, strdup(map.roma), &map, nil, 1); + } else { + map.roma = strdup(partial.b); + map.leadstomore = 1; + map.kana = nil; + hmaprepl(&h, strdup(partial.b), &map, nil, 1); + } + } } - return 0; + Bterm(b); + return h; } Hmap* @@ -404,7 +165,7 @@ opendict(Hmap *h, char *name) free(p); continue; } - dot = utfrune(p, '\t'); + dot = strchr(p, '\t'); if(dot == nil) goto Err; @@ -430,136 +191,396 @@ opendict(Hmap *h, char *name) return h; } -/* - * write translated kanji runes to stdout and return last character - * if it's not ctl-\. if the last is ctl-\, proceed with - * translation of the next kouho - */ +enum{ + LangEN = '', // ^t + LangJP = '', // ^n + LangJPK = '', // ^k + LangRU = '', // ^r + LangEL = '', // ^o + LangKO = '', // ^s + LangZH = '', // ^c +}; + +Hmap *natural; +Hmap *hira, *kata; +Hmap *cyril; +Hmap *greek; +Hmap *hangul; +Hmap *hanzi; + +Hmap **langtab[] = { + [LangEN] &natural, + [LangJP] &hira, + [LangJPK] &kata, + [LangRU] &cyril, + [LangEL] &greek, + [LangKO] &hangul, + [LangZH] &hanzi, +}; + +char *langcodetab[] = { + [LangEN] "en", + [LangJP] "jp", + [LangJPK] "jpk", + [LangRU] "ru", + [LangEL] "el", + [LangKO] "ko", + [LangZH] "zh", +}; + int -dotrans(Hmap *dic) +parselang(char *s) { - Rune *res, r[1]; - char v[1024], *p, tbuf[64], hirabuf[64]; - int j, lastlen, nokouho = 0; - char ch; int i; - char *kouho[16]; - if (llen==0) - return 0; /* don't use kanji transform function */ - if (okuri && joshi != 1) { - lbuf[llen++] = (Rune)okuri; - lbuf[llen] = 0; - }else - lbuf[llen] = 0; - okurigana[olen] = 0; - - /* - * search the matched index for the key word in the dict hash table, and - * return a pointer to the matched kouho, 0 otherwise. - */ - res = lbuf; - for (j=0; *res != L'\0'; j += runetochar(v+j, res++)) - ; - v[j] = '\0'; - strcpy(tbuf, v); - strcpy(hirabuf, v); /* to remember the initial hiragana input */ + for(i = 0; i < nelem(langcodetab); i++){ + if(langcodetab[i] == nil) + continue; + if(strcmp(langcodetab[i], s) == 0) + return i; + } - if (okuri && joshi != 1) /* verb mode */ - hirabuf[strlen(hirabuf) - 1] = '\0'; + return -1; +} - if(hmapget(dic, v, kouho) < 0){ - llen = olen = okuri = joshi = 0; - okurigana[0] = 0; +int +checklang(int *dst, int c) +{ + Hmap **p; + + if(c >= nelem(langtab)) return 0; - } - for(i = 0; i < nelem(kouho) && kouho[i] != nil; i++) { - p = kouho[i]; - lastlen = nrune(tbuf); /* number of rune chars */ - - if (okuri && joshi != 1) /* verb mode */ - for (j=0; j<lastlen-1; j++) - write(out, "\b", 1); /* clear hiragana input */ - else - for (j=0; j<lastlen; j++) - write(out, "\b", 1); /* clear hiragana input */ - - if (okuri) { - lastlen = nrune((char *)okurigana); - for (j=0; j<lastlen; j++) - write(out, "\b", 1); - } - write(out, p, strlen(p)); /* write kanji to stdout */ - if (okuri) - write(out, (char *)okurigana, olen); + p = langtab[c]; + if(p == nil) + return 0; + + *dst = c; + return c; +} + +int +maplkup(int lang, char *s, Map *m) +{ + Hmap **h; - if (read(in, &ch, 1)<=0) /* read from stdin */ - exits(nil); + if(lang >= nelem(langtab)) + return -1; - if (ch == '') { /* if next input is ^\, once again */ - if(i+1 < nelem(kouho) && kouho[i+1] != nil) { /* have next kouho */ - nokouho = 0; - strcpy(tbuf, p); + h = langtab[lang]; + if(h == nil || *h == nil) + return -1; - if (okuri && joshi != 1) /* verb mode */ - for (j=0; j<nrune(tbuf); j++) - write(out, "\b", 1); - continue; - } else { /* the last kouho */ - if (okuri) { - lastlen = nrune((char *)okurigana); - for (j=0; j<lastlen; j++) - write(out, "\b", 1); - } + return hmapget(*h, s, m); +} + +static int +emitutf(Channel *out, char *u, int nrune) +{ + Msg m; + char *e; - for (lastlen=0; *p != 0; p += j) { - j = chartorune(r, p); - lastlen++; + m.code = 'c'; + e = pushutf(m.buf, m.buf + sizeof m.buf, u, nrune); + send(out, &m); + return e - m.buf; +} + +static void +dictthread(void *a) +{ + Trans *t; + Msg m; + Rune r; + int n; + char *p; + Hmap *dict; + char *kouho[16]; + Str line; + Str last; + Str okuri; + int selected; + + enum{ + Kanji, + Okuri, + Joshi, + }; + int mode; + + t = a; + dict = jisho; + selected = -1; + kouho[0] = nil; + mode = Kanji; + resetstr(&last, &line, &okuri, nil); + + threadsetname("dict"); + while(recv(t->dict, &m) != -1){ + for(p = m.buf; *p; p += n){ + n = chartorune(&r, p); + if(r != ''){ + if(selected >= 0){ + resetstr(&okuri, nil); + mode = Kanji; + } + resetstr(&last, nil); + selected = -1; + kouho[0] = nil; + } + switch(r){ + case LangJP: + dict = jisho; + break; + case LangZH: + dict = zidian; + break; + case '': + if(line.b == line.p){ + emitutf(t->output, "", 1); + break; + } + emitutf(t->output, backspace, utflen(line.b)); + /* fallthrough */ + case ' ': case ',': case '.': + case '': + mode = Kanji; + resetstr(&line, &okuri, nil); + break; + case '\b': + if(mode != Kanji){ + if(okuri.p == okuri.b){ + mode = Kanji; + popstr(&line); + }else + popstr(&okuri); + break; + } + popstr(&line); + break; + case '\n': + if(line.b == line.p){ + emitutf(t->output, "\n", 1); + break; + } + /* fallthrough */ + case '': + selected++; + if(selected == 0){ + if(hmapget(dict, line.b, kouho) < 0){ + resetstr(&line, &last, nil); + selected = -1; + break; + } + if(dict == jisho && line.p > line.b && isascii(line.p[-1])) + line.p[-1] = '\0'; + } + if(kouho[selected] == nil){ + /* cycled through all matches; bail */ + emitutf(t->output, backspace, utflen(last.b)); + emitutf(t->output, line.b, 0); + resetstr(&line, &last, &okuri, nil); + selected = -1; + break; } - for (j=0; j<lastlen; j++) - write(out, "\b", 1); + if(okuri.p != okuri.b) + emitutf(t->output, backspace, utflen(okuri.b)); + if(selected == 0) + emitutf(t->output, backspace, utflen(line.b)); + else + emitutf(t->output, backspace, utflen(last.b)); - if(hirabuf[0]) - write(out, hirabuf, strlen(hirabuf)); + emitutf(t->output, kouho[selected], 0); + last.p = pushutf(last.b, strend(&last), kouho[selected], 0); + emitutf(t->output, okuri.b, 0); - if(okurigana[0]) - write(out, (char *)okurigana, olen); + resetstr(&line, nil); + mode = Kanji; + break; + default: + if(dict == zidian){ + line.p = pushutf(line.p, strend(&line), p, 1); + break; + } - olen = okuri = joshi = 0; - okurigana[0] = 0; + if(mode == Joshi){ + okuri.p = pushutf(okuri.p, strend(&okuri), p, 1); + break; + } + + if(isupper(*p)){ + if(mode == Okuri){ + popstr(&line); + mode = Joshi; + okuri.p = pushutf(okuri.p, strend(&okuri), p, 1); + break; + } + mode = Okuri; + *p = tolower(*p); + line.p = pushutf(line.p, strend(&line), p, 1); + okuri.p = pushutf(okuri.b, strend(&okuri), p, 1); + break; + } + if(mode == Kanji) + line.p = pushutf(line.p, strend(&line), p, 1); + else + okuri.p = pushutf(okuri.p, strend(&okuri), p, 1); break; } - } else { - if(!nokouho && i != 0){ /* learn the previous use of the kouho */ - p = kouho[0]; - kouho[0] = kouho[i]; - kouho[i] = p; - hmapupd(&dic, v, kouho); - } - - olen = okuri = joshi = 0; - okurigana[0] = 0; - break; } } - llen = 0; - return ch; + + send(t->done, nil); } -/* - * returns the number of characters in the pointed Rune - */ -int -nrune(char *p) +void +keyproc(void *a) { - int n = 0; + Trans *t; + int lang; + Msg m; + Map lkup; + char *p; + int n; Rune r; + char peek[UTFmax+1]; + Str line; + int mode; + + t = a; + mode = 0; + peek[0] = lang = deflang; + threadcreate(dictthread, a, mainstacksize); + resetstr(&line, nil); + if(lang == LangJP || lang == LangZH) + emitutf(t->dict, peek, 1); + + threadsetname("key"); + while(recv(t->input, &m) != -1){ + if(m.code != 'c'){ + if(m.code == 'q') + send(t->lang, &langcodetab[lang]); + else + send(t->output, &m); + continue; + } + + for(p = m.buf; *p; p += n){ + n = chartorune(&r, p); + if(checklang(&lang, r)){ + emitutf(t->dict, "", 1); + if(lang == LangJP || lang == LangZH) + emitutf(t->dict, p, 1); + resetstr(&line, nil); + continue; + } + if(lang == LangZH || lang == LangJP){ + emitutf(t->dict, p, 1); + if(utfrune("\n", r) != nil){ + resetstr(&line, nil); + continue; + } + if(lang == LangJP && isupper(*p)){ + *p = tolower(*p); + mode++; + } else { + mode = 0; + } + } + + emitutf(t->output, p, 1); + if(lang == LangEN || lang == LangZH) + continue; + if(r == '\b'){ + popstr(&line); + continue; + } + + line.p = pushutf(line.p, strend(&line), p, 1); + if(maplkup(lang, line.b, &lkup) < 0){ + resetstr(&line, nil); + pushutf(peek, peek + sizeof peek, p, 1); + if(maplkup(lang, peek, &lkup) == 0) + line.p = pushutf(line.p, strend(&line), p, 1); + continue; + } + if(lkup.kana == nil) + continue; - while (*p) { - p += chartorune(&r, p); - n++; + if(!lkup.leadstomore) + resetstr(&line, nil); + + if(lang == LangJP){ + emitutf(t->dict, backspace, utflen(lkup.roma)); + emitutf(t->dict, lkup.kana, 0); + } + emitutf(t->output, backspace, utflen(lkup.roma)); + emitutf(t->output, lkup.kana, 0); + } } - return n; + send(t->done, nil); +} + +void +usage(void) +{ + fprint(2, "usage: %s [ -K ] [ -l lang ]\n", argv0); + exits("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + + char *jishoname, *zidianname; + char *kbd, *srv, *mntpt; + + kbd = "/dev/kbd"; + srv = nil; + mntpt = "/mnt/ktrans"; + deflang = LangEN; + ARGBEGIN{ + case 'K': + kbd = nil; + break; + case 'k': + kbd = EARGF(usage()); + break; + case 'l': + deflang = parselang(EARGF(usage())); + if(deflang < 0) + usage(); + break; + case 's': + srv = EARGF(usage()); + break; + case 'm': + mntpt = EARGF(usage()); + break; + default: + usage(); + }ARGEND; + if(argc != 0) + usage(); + + memset(backspace, '\b', sizeof backspace-1); + backspace[sizeof backspace-1] = '\0'; + + if((jishoname = getenv("jisho")) == nil) + jishoname = "/lib/ktrans/kanji.dict"; + jisho = opendict(nil, jishoname); + + if((zidianname = getenv("zidian")) == nil) + zidianname = "/lib/ktrans/wubi.dict"; + zidian = opendict(nil, zidianname); + + natural = hanzi = nil; + hira = openmap("/lib/ktrans/hira.map"); + kata = openmap("/lib/ktrans/kata.map"); + greek = openmap("/lib/ktrans/greek.map"); + cyril = openmap("/lib/ktrans/cyril.map"); + hangul = openmap("/lib/ktrans/hangul.map"); + + launchfs(srv, mntpt, kbd); } |