engine: look dictionaries up synchronously
The dictionary thread ran in imthread's own proc, so a lookup could only start once the engine blocked, and it was a trie probe anyway; the emoji and Hanja searches already called dictlookup directly. The request/result channels, sequence numbers, staleness checks and the second draw per Japanese key are gone; dictqjp fills the candidates in place. Emit.dict and Lang.dictq only ever triggered lookups for Vietnamese, which has no dictionary. dictlookup(Lang*, key, out, max) returns the count. The Hanja lookup no longer pre-checks for a single syllable; a reading either has an entry or it does not.
This commit is contained in:
23
dat.h
23
dat.h
@@ -54,7 +54,6 @@ struct Emit
|
|||||||
int eat;
|
int eat;
|
||||||
Str s;
|
Str s;
|
||||||
Str next;
|
Str next;
|
||||||
Str dict;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Tnode Tnode;
|
typedef struct Tnode Tnode;
|
||||||
@@ -91,7 +90,6 @@ struct Lang
|
|||||||
char *dictname;
|
char *dictname;
|
||||||
Emit (*trans)(Im*, Rune);
|
Emit (*trans)(Im*, Rune);
|
||||||
void (*back)(Im*);
|
void (*back)(Im*);
|
||||||
void (*dictq)(Im*);
|
|
||||||
Trie *map;
|
Trie *map;
|
||||||
Trie *dict;
|
Trie *dict;
|
||||||
};
|
};
|
||||||
@@ -190,28 +188,7 @@ struct Keyreq
|
|||||||
Channel *reply;
|
Channel *reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Dictreq Dictreq;
|
|
||||||
struct Dictreq
|
|
||||||
{
|
|
||||||
Str key;
|
|
||||||
Str pre;
|
|
||||||
int lang;
|
|
||||||
u32int seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct Dictres Dictres;
|
|
||||||
struct Dictres
|
|
||||||
{
|
|
||||||
Str key;
|
|
||||||
Str kouho[Maxkouho];
|
|
||||||
int nkouho;
|
|
||||||
int lang;
|
|
||||||
u32int seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Lang langs[];
|
extern Lang langs[];
|
||||||
extern int nlang;
|
extern int nlang;
|
||||||
extern Channel *drawc;
|
extern Channel *drawc;
|
||||||
extern Channel *keyc;
|
extern Channel *keyc;
|
||||||
extern Channel *dictreqc;
|
|
||||||
extern Channel *dictresc;
|
|
||||||
|
|||||||
50
dict.c
50
dict.c
@@ -1,52 +1,34 @@
|
|||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
|
|
||||||
/* Candidates are the space-separated words of the value; the reading itself
|
/*
|
||||||
* is a candidate only for the emoji dictionary. */
|
* Fills out[] with up to max candidates for key: the space-separated words
|
||||||
void
|
* of the entry, minus the key itself except in the emoji dictionary, where
|
||||||
dictlookup(Dictreq *req, Dictres *res)
|
* a query may name its own answer.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dictlookup(Lang *l, Str *key, Str *out, int max)
|
||||||
{
|
{
|
||||||
Lang *l;
|
|
||||||
char *p, *e, *sp;
|
char *p, *e, *sp;
|
||||||
Str tmp;
|
Str tmp;
|
||||||
int vlen;
|
int n, vlen;
|
||||||
|
|
||||||
res->key = req->pre;
|
if(l == nil || key->n == 0 ||
|
||||||
res->nkouho = 0;
|
trielookup(l->dict, key, &p, &vlen) != TrieExact)
|
||||||
res->lang = req->lang;
|
return 0;
|
||||||
res->seq = req->seq;
|
n = 0;
|
||||||
l = getlang(req->lang);
|
|
||||||
if(req->key.n == 0 || l == nil ||
|
|
||||||
trielookup(l->dict, &req->key, &p, &vlen) != TrieExact)
|
|
||||||
return;
|
|
||||||
e = p + vlen;
|
e = p + vlen;
|
||||||
while(res->nkouho < Maxkouho && p < e){
|
while(n < max && p < e){
|
||||||
while(p < e && *p == ' ')
|
while(p < e && *p == ' ')
|
||||||
p++;
|
p++;
|
||||||
sp = p;
|
sp = p;
|
||||||
while(p < e && *p != ' ')
|
while(p < e && *p != ' ')
|
||||||
p++;
|
p++;
|
||||||
if(sinit(&tmp, sp, p - sp) && tmp.n > 0 &&
|
if(sinit(&tmp, sp, p - sp) && tmp.n > 0 &&
|
||||||
(req->lang == LangEMOJI || scmp(&tmp, &req->key) != 0))
|
(l->lang == LangEMOJI || scmp(&tmp, key) != 0))
|
||||||
res->kouho[res->nkouho++] = tmp;
|
out[n++] = tmp;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dictthread(void*)
|
|
||||||
{
|
|
||||||
Dictreq req;
|
|
||||||
static Dictres res;
|
|
||||||
|
|
||||||
threadsetname("dict");
|
|
||||||
for(;;){
|
|
||||||
if(chanrecv(dictreqc, &req) < 0)
|
|
||||||
break;
|
|
||||||
while(channbrecv(dictreqc, &req) > 0)
|
|
||||||
;
|
|
||||||
dictlookup(&req, &res);
|
|
||||||
chansend(dictresc, &res);
|
|
||||||
}
|
}
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Trie*
|
static Trie*
|
||||||
|
|||||||
3
fn.h
3
fn.h
@@ -20,8 +20,7 @@ int trielookup(Trie*, Str*, char**, int*);
|
|||||||
Lang* getlang(int);
|
Lang* getlang(int);
|
||||||
void langinit(char*);
|
void langinit(char*);
|
||||||
|
|
||||||
void dictthread(void*);
|
int dictlookup(Lang*, Str*, Str*, int);
|
||||||
void dictlookup(Dictreq*, Dictres*);
|
|
||||||
|
|
||||||
void drawthread(void*);
|
void drawthread(void*);
|
||||||
void popuparea(Area*, int, Area*, int, int, Area*);
|
void popuparea(Area*, int, Area*, int, int, Area*);
|
||||||
|
|||||||
5
main.c
5
main.c
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
Channel *drawc;
|
Channel *drawc;
|
||||||
Channel *keyc;
|
Channel *keyc;
|
||||||
Channel *dictreqc;
|
|
||||||
Channel *dictresc;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
@@ -56,8 +54,6 @@ threadmain(int argc, char **argv)
|
|||||||
|
|
||||||
drawc = chancreate(sizeof(Drawcmd), 4);
|
drawc = chancreate(sizeof(Drawcmd), 4);
|
||||||
keyc = chancreate(sizeof(Keyreq), 0);
|
keyc = chancreate(sizeof(Keyreq), 0);
|
||||||
dictreqc = chancreate(sizeof(Dictreq), 4);
|
|
||||||
dictresc = chancreate(sizeof(Dictres), 0);
|
|
||||||
langinit(argv[1]);
|
langinit(argv[1]);
|
||||||
srvinit();
|
srvinit();
|
||||||
proccreate(drawthread, nil, 16384);
|
proccreate(drawthread, nil, 16384);
|
||||||
@@ -66,6 +62,5 @@ threadmain(int argc, char **argv)
|
|||||||
display = getenv("DISPLAY");
|
display = getenv("DISPLAY");
|
||||||
if(display != nil && display[0] != '\0')
|
if(display != nil && display[0] != '\0')
|
||||||
proccreate(ximthread, nil, 32768);
|
proccreate(ximthread, nil, 32768);
|
||||||
threadcreate(dictthread, nil, 16384);
|
|
||||||
imthread(nil);
|
imthread(nil);
|
||||||
}
|
}
|
||||||
|
|||||||
157
strans.c
157
strans.c
@@ -6,10 +6,7 @@ static int visible = 0;
|
|||||||
static void *activeowner;
|
static void *activeowner;
|
||||||
static int activecap;
|
static int activecap;
|
||||||
static Caret caret;
|
static Caret caret;
|
||||||
static u32int dictseq;
|
|
||||||
static int candidatechosen;
|
static int candidatechosen;
|
||||||
static void dictqmap(Im*);
|
|
||||||
static void dictqjp(Im*);
|
|
||||||
static void backjp(Im*);
|
static void backjp(Im*);
|
||||||
static int maplookup(Trie*, Str*, Str*);
|
static int maplookup(Trie*, Str*, Str*);
|
||||||
|
|
||||||
@@ -23,20 +20,19 @@ struct Search
|
|||||||
static Search search;
|
static Search search;
|
||||||
|
|
||||||
Lang langs[] = {
|
Lang langs[] = {
|
||||||
{LangEN, nil, nil, nil, nil, nil, nil, nil},
|
{LangEN, nil, nil, nil, nil, nil, nil},
|
||||||
{LangJP, "hira", "kanji", transmap, backjp, dictqjp, nil, nil},
|
{LangJP, "hira", "kanji", transmap, backjp, nil, nil},
|
||||||
{LangJPK, "kata", nil, transmap, backjp, dictqjp, nil, nil},
|
{LangJPK, "kata", nil, transmap, backjp, nil, nil},
|
||||||
{LangKO, nil, nil, transko, backko, nil, nil, nil},
|
{LangKO, nil, nil, transko, backko, nil, nil},
|
||||||
{LangHANJA, nil, "hanja", nil, nil, nil, nil, nil},
|
{LangHANJA, nil, "hanja", nil, nil, nil, nil},
|
||||||
{LangEMOJI, nil, "emoji", nil, nil, nil, nil, nil},
|
{LangEMOJI, nil, "emoji", nil, nil, nil, nil},
|
||||||
{LangVI, "telex", nil, transvi, backvi, dictqmap, nil, nil},
|
{LangVI, "telex", nil, transvi, backvi, nil, nil},
|
||||||
};
|
};
|
||||||
int nlang = nelem(langs);
|
int nlang = nelem(langs);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clearkouho(void)
|
clearkouho(void)
|
||||||
{
|
{
|
||||||
dictseq++;
|
|
||||||
im.nkouho = 0;
|
im.nkouho = 0;
|
||||||
im.sel = -1;
|
im.sel = -1;
|
||||||
candidatechosen = 0;
|
candidatechosen = 0;
|
||||||
@@ -144,19 +140,6 @@ impre(Str *s)
|
|||||||
*s = im.pre;
|
*s = im.pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
setkouho(Dictres *res)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
clearkouho();
|
|
||||||
for(i = 0; i < res->nkouho; i++){
|
|
||||||
im.kouho[i] = res->kouho[i];
|
|
||||||
im.nkouho++;
|
|
||||||
}
|
|
||||||
selectfirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
snapshot(Drawcmd *dc)
|
snapshot(Drawcmd *dc)
|
||||||
{
|
{
|
||||||
@@ -210,43 +193,17 @@ reset(void)
|
|||||||
clearkouho();
|
clearkouho();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Kanji candidates for a complete reading. */
|
||||||
static void
|
static void
|
||||||
dictsend(Im *im, Str *key)
|
dictqjp(void)
|
||||||
{
|
|
||||||
Dictreq old, req;
|
|
||||||
|
|
||||||
req.key = *key;
|
|
||||||
req.lang = im->l->lang;
|
|
||||||
req.seq = dictseq;
|
|
||||||
impre(&req.pre);
|
|
||||||
/* imthread is the sole producer; discard every obsolete queued lookup. */
|
|
||||||
while(channbrecv(dictreqc, &old) > 0)
|
|
||||||
;
|
|
||||||
channbsend(dictreqc, &req);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dictqmap(Im *im)
|
|
||||||
{
|
|
||||||
Str dict;
|
|
||||||
|
|
||||||
clearkouho();
|
|
||||||
if(im->l->map == nil)
|
|
||||||
return;
|
|
||||||
if(!mapget(im->l->map, &im->pre, &dict))
|
|
||||||
return;
|
|
||||||
dictsend(im, &dict);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dictqjp(Im *im)
|
|
||||||
{
|
{
|
||||||
Str reading;
|
Str reading;
|
||||||
|
|
||||||
clearkouho();
|
clearkouho();
|
||||||
if(im->l->dict == nil || !jpreading(im, &reading) || reading.n == 0)
|
if(!jpreading(&im, &reading) || reading.n == 0)
|
||||||
return;
|
return;
|
||||||
dictsend(im, &reading);
|
im.nkouho = dictlookup(im.l, &reading, im.kouho, Maxkouho);
|
||||||
|
selectfirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -355,7 +312,7 @@ dotrans(Rune c, Str *com)
|
|||||||
if(isjp(&im)){
|
if(isjp(&im)){
|
||||||
e.eat = transjp(&im, c, com);
|
e.eat = transjp(&im, c, com);
|
||||||
if(e.eat)
|
if(e.eat)
|
||||||
dictqjp(&im);
|
dictqjp();
|
||||||
else
|
else
|
||||||
clearkouho();
|
clearkouho();
|
||||||
return e.eat;
|
return e.eat;
|
||||||
@@ -380,9 +337,6 @@ dotrans(Rune c, Str *com)
|
|||||||
sappend(com, &e.s);
|
sappend(com, &e.s);
|
||||||
sclear(&im.pre);
|
sclear(&im.pre);
|
||||||
sappend(&im.pre, &e.next);
|
sappend(&im.pre, &e.next);
|
||||||
if(e.eat && e.dict.n > 0){
|
|
||||||
dictsend(&im, &e.dict);
|
|
||||||
}
|
|
||||||
return e.eat;
|
return e.eat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,13 +372,13 @@ Emit
|
|||||||
transmap(Im *im, Rune c)
|
transmap(Im *im, Rune c)
|
||||||
{
|
{
|
||||||
Emit e = {0};
|
Emit e = {0};
|
||||||
Str key;
|
Str key, mapped;
|
||||||
Trie *t;
|
Trie *t;
|
||||||
|
|
||||||
t = im->l->map;
|
t = im->l->map;
|
||||||
key = im->pre;
|
key = im->pre;
|
||||||
sputr(&key, c);
|
sputr(&key, c);
|
||||||
if(maplookup(t, &key, &e.dict)){
|
if(maplookup(t, &key, &mapped)){
|
||||||
e.eat = 1;
|
e.eat = 1;
|
||||||
e.next = key;
|
e.next = key;
|
||||||
return e;
|
return e;
|
||||||
@@ -433,7 +387,7 @@ transmap(Im *im, Rune c)
|
|||||||
e.s = im->pre;
|
e.s = im->pre;
|
||||||
sclear(&key);
|
sclear(&key);
|
||||||
sputr(&key, c);
|
sputr(&key, c);
|
||||||
if(!maplookup(t, &key, &e.dict))
|
if(!maplookup(t, &key, &mapped))
|
||||||
return e;
|
return e;
|
||||||
e.eat = 1;
|
e.eat = 1;
|
||||||
sputr(&e.next, c);
|
sputr(&e.next, c);
|
||||||
@@ -526,40 +480,28 @@ addkouho(Str *s)
|
|||||||
im.kouho[im.nkouho++] = *s;
|
im.kouho[im.nkouho++] = *s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* The typed keys and their transliteration are both emoji queries. */
|
||||||
searchlookup(int lang, Str *key, Dictres *res)
|
|
||||||
{
|
|
||||||
Dictreq req;
|
|
||||||
|
|
||||||
req.key = *key;
|
|
||||||
req.pre = req.key;
|
|
||||||
req.lang = lang;
|
|
||||||
req.seq = 0;
|
|
||||||
dictlookup(&req, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emojiquery(void)
|
emojiquery(void)
|
||||||
{
|
{
|
||||||
static Dictres res;
|
Str kouho[Maxkouho], raw, local;
|
||||||
Str raw, local;
|
int i, n, rawhit, localhit;
|
||||||
int i, rawhit, localhit;
|
|
||||||
|
|
||||||
raw = search.raw;
|
raw = search.raw;
|
||||||
foldascii(&raw);
|
foldascii(&raw);
|
||||||
transstr(im.l, &search.raw, &local);
|
transstr(im.l, &search.raw, &local);
|
||||||
foldascii(&local);
|
foldascii(&local);
|
||||||
clearkouho();
|
clearkouho();
|
||||||
searchlookup(LangEMOJI, &raw, &res);
|
n = dictlookup(getlang(LangEMOJI), &raw, kouho, Maxkouho);
|
||||||
rawhit = res.nkouho != 0;
|
rawhit = n != 0;
|
||||||
for(i = 0; i < res.nkouho; i++)
|
for(i = 0; i < n; i++)
|
||||||
addkouho(&res.kouho[i]);
|
addkouho(&kouho[i]);
|
||||||
localhit = 0;
|
localhit = 0;
|
||||||
if(scmp(&raw, &local) != 0){
|
if(scmp(&raw, &local) != 0){
|
||||||
searchlookup(LangEMOJI, &local, &res);
|
n = dictlookup(getlang(LangEMOJI), &local, kouho, Maxkouho);
|
||||||
localhit = res.nkouho != 0;
|
localhit = n != 0;
|
||||||
for(i = 0; i < res.nkouho; i++)
|
for(i = 0; i < n; i++)
|
||||||
addkouho(&res.kouho[i]);
|
addkouho(&kouho[i]);
|
||||||
}
|
}
|
||||||
search.text = rawhit || !localhit ? raw : local;
|
search.text = rawhit || !localhit ? raw : local;
|
||||||
selectfirst();
|
selectfirst();
|
||||||
@@ -568,16 +510,13 @@ emojiquery(void)
|
|||||||
static void
|
static void
|
||||||
hanjaquery(void)
|
hanjaquery(void)
|
||||||
{
|
{
|
||||||
static Dictres res;
|
|
||||||
Str key;
|
Str key;
|
||||||
|
|
||||||
transstr(im.l, &search.raw, &key);
|
transstr(im.l, &search.raw, &key);
|
||||||
search.text = key;
|
search.text = key;
|
||||||
if(key.n == 1 && key.r[0] >= 0xac00 && key.r[0] <= 0xd7a3){
|
clearkouho();
|
||||||
searchlookup(LangHANJA, &key, &res);
|
im.nkouho = dictlookup(getlang(LangHANJA), &key, im.kouho, Maxkouho);
|
||||||
setkouho(&res);
|
selectfirst();
|
||||||
}else
|
|
||||||
clearkouho();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -766,8 +705,10 @@ transition(u32int ks, u32int mod, Str *com)
|
|||||||
reset();
|
reset();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(im.l->dictq != nil)
|
if(isjp(&im))
|
||||||
im.l->dictq(&im);
|
dictqjp();
|
||||||
|
else
|
||||||
|
clearkouho();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(ks == Kesc){
|
if(ks == Kesc){
|
||||||
@@ -896,7 +837,6 @@ init(void)
|
|||||||
memset(&caret, 0, sizeof caret);
|
memset(&caret, 0, sizeof caret);
|
||||||
activeowner = nil;
|
activeowner = nil;
|
||||||
activecap = 0;
|
activecap = 0;
|
||||||
dictseq = 0;
|
|
||||||
candidatechosen = 0;
|
candidatechosen = 0;
|
||||||
visible = 0;
|
visible = 0;
|
||||||
}
|
}
|
||||||
@@ -1004,41 +944,16 @@ imhandlekey(Keyreq *kr)
|
|||||||
chansend(kr->reply, &res);
|
chansend(kr->reply, &res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
dictresult(Dictres *res)
|
|
||||||
{
|
|
||||||
Str pre;
|
|
||||||
|
|
||||||
impre(&pre);
|
|
||||||
if(search.lang || res->seq != dictseq || res->lang != im.l->lang ||
|
|
||||||
scmp(&res->key, &pre) != 0)
|
|
||||||
return;
|
|
||||||
setkouho(res);
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
imthread(void*)
|
imthread(void*)
|
||||||
{
|
{
|
||||||
static Dictres res;
|
|
||||||
Keyreq kr;
|
Keyreq kr;
|
||||||
Alt alts[] = {
|
|
||||||
{keyc, &kr, CHANRCV, nil},
|
|
||||||
{dictresc, &res, CHANRCV, nil},
|
|
||||||
{nil, nil, CHANEND, nil},
|
|
||||||
};
|
|
||||||
|
|
||||||
threadsetname("im");
|
threadsetname("im");
|
||||||
init();
|
init();
|
||||||
for(;;){
|
for(;;){
|
||||||
switch(alt(alts)){
|
chanrecv(keyc, &kr);
|
||||||
case 0:
|
imhandlekey(&kr);
|
||||||
imhandlekey(&kr);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
dictresult(&res);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,33 +5,22 @@ dictionary_candidates(struct ct *t)
|
|||||||
{
|
{
|
||||||
char many[512], item[8];
|
char many[512], item[8];
|
||||||
char *p;
|
char *p;
|
||||||
Dictreq req;
|
Str kouho[Maxkouho], key;
|
||||||
Dictres res;
|
|
||||||
Trie *saved;
|
Trie *saved;
|
||||||
Lang *lang;
|
Lang *lang;
|
||||||
Str key;
|
int i, n;
|
||||||
int i;
|
|
||||||
|
|
||||||
lang = getlang(LangJP);
|
lang = getlang(LangJP);
|
||||||
saved = lang->dict;
|
saved = lang->dict;
|
||||||
lang->dict = trienew();
|
lang->dict = trienew();
|
||||||
key = mkstr("かな");
|
|
||||||
trieput(lang->dict, "かな", strlen("かな"), " 候補1 かな 候補2 ",
|
trieput(lang->dict, "かな", strlen("かな"), " 候補1 かな 候補2 ",
|
||||||
strlen(" 候補1 かな 候補2 "));
|
strlen(" 候補1 かな 候補2 "));
|
||||||
memset(&req, 0, sizeof req);
|
key = mkstr("かな");
|
||||||
req.key = key;
|
n = dictlookup(lang, &key, kouho, Maxkouho);
|
||||||
req.pre = mkstr("preedit-one");
|
if(CT_EQ_INT(t, 2, n)){
|
||||||
req.lang = LangJP;
|
checkstr(t, "candidate 1", "候補1", &kouho[0]);
|
||||||
req.seq = 17;
|
checkstr(t, "candidate 2", "候補2", &kouho[1]);
|
||||||
dictlookup(&req, &res);
|
}
|
||||||
if(!CT_EQ_INT(t, 2, res.nkouho))
|
|
||||||
goto cleanup;
|
|
||||||
CT_EQ_INT(t, LangJP, res.lang);
|
|
||||||
CT_EQ_UINT(t, 17, res.seq);
|
|
||||||
CT_EQ_INT(t, 0, scmp(&req.pre, &res.key));
|
|
||||||
checkstr(t, "candidate 1", "候補1", &res.kouho[0]);
|
|
||||||
checkstr(t, "candidate 2", "候補2", &res.kouho[1]);
|
|
||||||
key = mkstr("key");
|
|
||||||
p = many;
|
p = many;
|
||||||
for(i = 0; i < Maxkouho+1; i++){
|
for(i = 0; i < Maxkouho+1; i++){
|
||||||
snprint(item, sizeof item, "c%02d", i);
|
snprint(item, sizeof item, "c%02d", i);
|
||||||
@@ -42,56 +31,32 @@ dictionary_candidates(struct ct *t)
|
|||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
trieput(lang->dict, "key", 3, many, strlen(many));
|
trieput(lang->dict, "key", 3, many, strlen(many));
|
||||||
req.key = key;
|
key = mkstr("key");
|
||||||
req.pre = mkstr("preedit-two");
|
n = dictlookup(lang, &key, kouho, Maxkouho);
|
||||||
req.seq = 29;
|
if(CT_EQ_INT(t, Maxkouho, n)){
|
||||||
dictlookup(&req, &res);
|
checkstr(t, "first capped candidate", "c00", &kouho[0]);
|
||||||
if(!CT_EQ_INT(t, Maxkouho, res.nkouho))
|
checkstr(t, "last capped candidate", "c31", &kouho[31]);
|
||||||
goto cleanup;
|
}
|
||||||
CT_EQ_INT(t, LangJP, res.lang);
|
CT_EQ_INT(t, 3, dictlookup(lang, &key, kouho, 3));
|
||||||
CT_EQ_UINT(t, 29, res.seq);
|
|
||||||
CT_EQ_INT(t, 0, scmp(&req.pre, &res.key));
|
|
||||||
checkstr(t, "first capped candidate", "c00", &res.kouho[0]);
|
|
||||||
checkstr(t, "last capped candidate", "c31", &res.kouho[31]);
|
|
||||||
cleanup:
|
|
||||||
trieclose(lang->dict);
|
trieclose(lang->dict);
|
||||||
lang->dict = saved;
|
lang->dict = saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dictionary_misses_clear_result(struct ct *t)
|
dictionary_misses(struct ct *t)
|
||||||
{
|
{
|
||||||
static const struct {
|
Str kouho[Maxkouho], key;
|
||||||
char *name;
|
|
||||||
char *key;
|
|
||||||
char *pre;
|
|
||||||
} cases[] = {
|
|
||||||
{ "empty key", "", "empty-preedit" },
|
|
||||||
{ "missing key", "missing", "missing-preedit" },
|
|
||||||
};
|
|
||||||
Dictreq req;
|
|
||||||
Dictres res;
|
|
||||||
Trie *saved;
|
Trie *saved;
|
||||||
Lang *lang;
|
Lang *lang;
|
||||||
int i;
|
|
||||||
|
|
||||||
lang = getlang(LangJP);
|
lang = getlang(LangJP);
|
||||||
saved = lang->dict;
|
saved = lang->dict;
|
||||||
lang->dict = trienew();
|
lang->dict = trienew();
|
||||||
for(i = 0; i < nelem(cases); i++){
|
key = mkstr("");
|
||||||
memset(&res, 0xa5, sizeof res);
|
CT_EQ_INT(t, 0, dictlookup(lang, &key, kouho, Maxkouho));
|
||||||
req.key = mkstr(cases[i].key);
|
key = mkstr("missing");
|
||||||
req.pre = mkstr(cases[i].pre);
|
CT_EQ_INT(t, 0, dictlookup(lang, &key, kouho, Maxkouho));
|
||||||
req.lang = LangJP;
|
CT_EQ_INT(t, 0, dictlookup(getlang(LangKO), &key, kouho, Maxkouho));
|
||||||
req.seq = 0xf00d0000U + i;
|
|
||||||
dictlookup(&req, &res);
|
|
||||||
if(res.nkouho != 0)
|
|
||||||
CT_ERRORF(t, "%s: want 0 candidates, got %d",
|
|
||||||
cases[i].name, res.nkouho);
|
|
||||||
CT_EQ_INT(t, LangJP, res.lang);
|
|
||||||
CT_EQ_UINT(t, 0xf00d0000U + i, res.seq);
|
|
||||||
checkstr(t, cases[i].name, cases[i].pre, &res.key);
|
|
||||||
}
|
|
||||||
trieclose(lang->dict);
|
trieclose(lang->dict);
|
||||||
lang->dict = saved;
|
lang->dict = saved;
|
||||||
}
|
}
|
||||||
@@ -99,25 +64,17 @@ dictionary_misses_clear_result(struct ct *t)
|
|||||||
void
|
void
|
||||||
dictionary_emoji_identity(struct ct *t)
|
dictionary_emoji_identity(struct ct *t)
|
||||||
{
|
{
|
||||||
Dictreq req;
|
Str kouho[Maxkouho], key;
|
||||||
Dictres res;
|
|
||||||
Trie *saved;
|
Trie *saved;
|
||||||
Lang *lang;
|
Lang *lang;
|
||||||
Str key;
|
|
||||||
|
|
||||||
lang = getlang(LangEMOJI);
|
lang = getlang(LangEMOJI);
|
||||||
saved = lang->dict;
|
saved = lang->dict;
|
||||||
lang->dict = trienew();
|
lang->dict = trienew();
|
||||||
key = mkstr("é");
|
|
||||||
trieput(lang->dict, "é", strlen("é"), "é", strlen("é"));
|
trieput(lang->dict, "é", strlen("é"), "é", strlen("é"));
|
||||||
memset(&req, 0, sizeof req);
|
key = mkstr("é");
|
||||||
req.key = key;
|
if(CT_EQ_INT(t, 1, dictlookup(lang, &key, kouho, Maxkouho)))
|
||||||
req.pre = key;
|
checkstr(t, "emoji identity candidate", "é", &kouho[0]);
|
||||||
req.lang = LangEMOJI;
|
|
||||||
req.seq = 0;
|
|
||||||
dictlookup(&req, &res);
|
|
||||||
if(CT_EQ_INT(t, 1, res.nkouho))
|
|
||||||
checkstr(t, "emoji identity candidate", "é", &res.kouho[0]);
|
|
||||||
trieclose(lang->dict);
|
trieclose(lang->dict);
|
||||||
lang->dict = saved;
|
lang->dict = saved;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,37 +165,6 @@ engine_candidate_shortcut_modifiers(struct ct *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
engine_dictionary_queue_latest_wins(struct ct *t)
|
|
||||||
{
|
|
||||||
Channel *saved;
|
|
||||||
Dictreq old, got;
|
|
||||||
Str key;
|
|
||||||
|
|
||||||
saved = dictreqc;
|
|
||||||
dictreqc = chancreate(sizeof(Dictreq), 1);
|
|
||||||
memset(&old, 0, sizeof old);
|
|
||||||
old.key = mkstr("old-key");
|
|
||||||
old.pre = mkstr("old-preedit");
|
|
||||||
old.lang = LangJP;
|
|
||||||
old.seq = 0;
|
|
||||||
CT_CHECK(t, channbsend(dictreqc, &old) > 0);
|
|
||||||
init();
|
|
||||||
im.l = getlang(LangJP);
|
|
||||||
im.pre = mkstr("new-preedit");
|
|
||||||
key = mkstr("new-key");
|
|
||||||
dictsend(&im, &key);
|
|
||||||
if(CT_CHECK(t, channbrecv(dictreqc, &got) > 0)){
|
|
||||||
checkstr(t, "newest dictionary key", "new-key", &got.key);
|
|
||||||
checkstr(t, "newest dictionary preedit", "new-preedit", &got.pre);
|
|
||||||
CT_EQ_INT(t, LangJP, got.lang);
|
|
||||||
CT_EQ_UINT(t, dictseq, got.seq);
|
|
||||||
}
|
|
||||||
CT_CHECK(t, channbrecv(dictreqc, &got) <= 0);
|
|
||||||
chanfree(dictreqc);
|
|
||||||
dictreqc = saved;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Keyres
|
static Keyres
|
||||||
ownerrequestatcap(void *owner, int cap, int op, Rune key, u32int mod,
|
ownerrequestatcap(void *owner, int cap, int op, Rune key, u32int mod,
|
||||||
Caret *caret)
|
Caret *caret)
|
||||||
@@ -306,66 +275,6 @@ engine_active_owner_reset(struct ct *t)
|
|||||||
checkstr(t, "same owner after reset", "ん", &res.preedit);
|
checkstr(t, "same owner after reset", "ん", &res.preedit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
engine_rejects_stale_dictionary_results(struct ct *t)
|
|
||||||
{
|
|
||||||
Dictreq a, b;
|
|
||||||
Dictres res;
|
|
||||||
Trie *saved;
|
|
||||||
Lang *jp;
|
|
||||||
char one, two;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
jp = getlang(LangJP);
|
|
||||||
saved = jp->dict;
|
|
||||||
jp->dict = trienew();
|
|
||||||
init();
|
|
||||||
im.l = jp;
|
|
||||||
while(channbrecv(dictreqc, &a) > 0)
|
|
||||||
;
|
|
||||||
ownerrequest(&one, Keypress, 'k', 0);
|
|
||||||
ownerrequest(&one, Keypress, 'a', 0);
|
|
||||||
n = 0;
|
|
||||||
while(channbrecv(dictreqc, &a) > 0)
|
|
||||||
n++;
|
|
||||||
if(!CT_CHECK(t, n > 0))
|
|
||||||
goto cleanup;
|
|
||||||
ownerrequest(&one, Keyreset, 0, 0);
|
|
||||||
ownerrequest(&two, Keypress, 'k', 0);
|
|
||||||
ownerrequest(&two, Keypress, 'a', 0);
|
|
||||||
n = 0;
|
|
||||||
while(channbrecv(dictreqc, &b) > 0)
|
|
||||||
n++;
|
|
||||||
if(!CT_CHECK(t, n > 0))
|
|
||||||
goto cleanup;
|
|
||||||
CT_EQ_INT(t, 0, scmp(&a.key, &b.key));
|
|
||||||
CT_EQ_INT(t, 0, scmp(&a.pre, &b.pre));
|
|
||||||
CT_EQ_INT(t, a.lang, b.lang);
|
|
||||||
CT_CHECK(t, a.seq != b.seq);
|
|
||||||
|
|
||||||
memset(&res, 0, sizeof res);
|
|
||||||
res.key = a.pre;
|
|
||||||
res.lang = a.lang;
|
|
||||||
res.seq = a.seq;
|
|
||||||
res.kouho[0] = mkstr("stale");
|
|
||||||
res.nkouho = 1;
|
|
||||||
dictresult(&res);
|
|
||||||
CT_EQ_INT(t, 0, im.nkouho);
|
|
||||||
|
|
||||||
res.key = b.pre;
|
|
||||||
res.lang = b.lang;
|
|
||||||
res.seq = b.seq;
|
|
||||||
res.kouho[0] = mkstr("current");
|
|
||||||
dictresult(&res);
|
|
||||||
if(CT_EQ_INT(t, 1, im.nkouho))
|
|
||||||
checkstr(t, "current dictionary result", "current", &im.kouho[0]);
|
|
||||||
cleanup:
|
|
||||||
while(channbrecv(dictreqc, &a) > 0)
|
|
||||||
;
|
|
||||||
trieclose(jp->dict);
|
|
||||||
jp->dict = saved;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
engine_active_owner_caret(struct ct *t)
|
engine_active_owner_caret(struct ct *t)
|
||||||
{
|
{
|
||||||
@@ -660,7 +569,6 @@ engine_direct_language_modes(struct ct *t)
|
|||||||
CT_EQ_PTR(t, nil, im.l->mapname);
|
CT_EQ_PTR(t, nil, im.l->mapname);
|
||||||
CT_EQ_PTR(t, nil, im.l->map);
|
CT_EQ_PTR(t, nil, im.l->map);
|
||||||
CT_EQ_PTR(t, nil, im.l->dictname);
|
CT_EQ_PTR(t, nil, im.l->dictname);
|
||||||
CT_EQ_PTR(t, nil, im.l->dictq);
|
|
||||||
CT_CHECK(t, strcmp(getlang(LangHANJA)->dictname, "hanja") == 0);
|
CT_CHECK(t, strcmp(getlang(LangHANJA)->dictname, "hanja") == 0);
|
||||||
CT_CHECK(t, keystroke('r', 0, &com));
|
CT_CHECK(t, keystroke('r', 0, &com));
|
||||||
checkstr(t, "Korean without map", "ㄱ", &im.pre);
|
checkstr(t, "Korean without map", "ㄱ", &im.pre);
|
||||||
@@ -789,17 +697,16 @@ draindraw(Drawcmd *last)
|
|||||||
static void
|
static void
|
||||||
setcandidates(int n)
|
setcandidates(int n)
|
||||||
{
|
{
|
||||||
Dictres res;
|
|
||||||
char name[8];
|
char name[8];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(&res, 0, sizeof res);
|
clearkouho();
|
||||||
for(i = 0; i < n; i++){
|
for(i = 0; i < n; i++){
|
||||||
snprint(name, sizeof name, "c%d", i+1);
|
snprint(name, sizeof name, "c%d", i+1);
|
||||||
res.kouho[i] = mkstr(name);
|
im.kouho[i] = mkstr(name);
|
||||||
}
|
}
|
||||||
res.nkouho = n;
|
im.nkouho = n;
|
||||||
setkouho(&res);
|
selectfirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -929,31 +836,20 @@ void
|
|||||||
engine_candidate_completion(struct ct *t)
|
engine_candidate_completion(struct ct *t)
|
||||||
{
|
{
|
||||||
static Rune keys[] = { Kret, Ktab };
|
static Rune keys[] = { Kret, Ktab };
|
||||||
Dictres res;
|
|
||||||
Str com;
|
Str com;
|
||||||
int arrived, i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < nelem(keys); i++)
|
for(i = 0; i < nelem(keys); i++){
|
||||||
for(arrived = 0; arrived < 2; arrived++){
|
init();
|
||||||
init();
|
im.l = getlang(LangJP);
|
||||||
im.l = getlang(LangJP);
|
im.pre = mkstr("reading");
|
||||||
im.pre = mkstr("reading");
|
setcandidates(1);
|
||||||
memset(&res, 0, sizeof res);
|
sclear(&com);
|
||||||
res.key = im.pre;
|
CT_CHECK(t, keystroke(keys[i], 0, &com));
|
||||||
res.lang = LangJP;
|
checkstr(t, "unselected candidate commits reading",
|
||||||
res.seq = dictseq;
|
"reading", &com);
|
||||||
res.kouho[0] = mkstr("candidate");
|
CT_EQ_INT(t, 0, im.nkouho);
|
||||||
res.nkouho = 1;
|
}
|
||||||
if(arrived)
|
|
||||||
dictresult(&res);
|
|
||||||
sclear(&com);
|
|
||||||
CT_CHECK(t, keystroke(keys[i], 0, &com));
|
|
||||||
if(!arrived)
|
|
||||||
dictresult(&res);
|
|
||||||
checkstr(t, "unselected candidate commits reading",
|
|
||||||
"reading", &com);
|
|
||||||
CT_EQ_INT(t, 0, im.nkouho);
|
|
||||||
}
|
|
||||||
|
|
||||||
candidatebegin(2);
|
candidatebegin(2);
|
||||||
im.pre = mkstr("reading");
|
im.pre = mkstr("reading");
|
||||||
@@ -1047,24 +943,22 @@ searchend(Searchfix *f)
|
|||||||
void
|
void
|
||||||
engine_popup_preedit_capability(struct ct *t)
|
engine_popup_preedit_capability(struct ct *t)
|
||||||
{
|
{
|
||||||
Dictres res;
|
|
||||||
Drawcmd dc;
|
Drawcmd dc;
|
||||||
Keyres kres;
|
Keyres kres;
|
||||||
|
Lang *jp;
|
||||||
|
Trie *saved;
|
||||||
char client, inactive;
|
char client, inactive;
|
||||||
|
|
||||||
|
jp = getlang(LangJP);
|
||||||
|
saved = jp->dict;
|
||||||
|
jp->dict = trienew();
|
||||||
|
setdict(jp->dict, "か", "家");
|
||||||
init();
|
init();
|
||||||
im.l = getlang(LangJP);
|
im.l = jp;
|
||||||
draindraw(nil);
|
draindraw(nil);
|
||||||
ownerrequestcap(&client, Cclientpreedit, Keypress, 'k', 0);
|
ownerrequestcap(&client, Cclientpreedit, Keypress, 'k', 0);
|
||||||
ownerrequestcap(&client, Cclientpreedit, Keypress, 'a', 0);
|
ownerrequestcap(&client, Cclientpreedit, Keypress, 'a', 0);
|
||||||
memset(&res, 0, sizeof res);
|
CT_EQ_INT(t, 1, im.nkouho);
|
||||||
res.lang = LangJP;
|
|
||||||
res.key = mkstr("か");
|
|
||||||
res.seq = dictseq;
|
|
||||||
res.kouho[0] = mkstr("家");
|
|
||||||
res.nkouho = 1;
|
|
||||||
dictresult(&res);
|
|
||||||
im.sel = 0;
|
|
||||||
redraw();
|
redraw();
|
||||||
if(CT_CHECK(t, draindraw(&dc) > 0)){
|
if(CT_CHECK(t, draindraw(&dc) > 0)){
|
||||||
CT_EQ_INT(t, 0, dc.pre.n);
|
CT_EQ_INT(t, 0, dc.pre.n);
|
||||||
@@ -1115,6 +1009,8 @@ engine_popup_preedit_capability(struct ct *t)
|
|||||||
|
|
||||||
ownerrequest(&client, Keyrelease, 0, 0);
|
ownerrequest(&client, Keyrelease, 0, 0);
|
||||||
draindraw(nil);
|
draindraw(nil);
|
||||||
|
trieclose(jp->dict);
|
||||||
|
jp->dict = saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1124,9 +1020,6 @@ hanjabegin(Searchfix *f, int lang)
|
|||||||
f->dictlang->dict = trienew();
|
f->dictlang->dict = trienew();
|
||||||
setdict(f->dictlang->dict, "한", "漢 韓");
|
setdict(f->dictlang->dict, "한", "漢 韓");
|
||||||
setdict(f->dictlang->dict, "가", "家");
|
setdict(f->dictlang->dict, "가", "家");
|
||||||
setdict(f->dictlang->dict, "ㄱ", "假");
|
|
||||||
setdict(f->dictlang->dict, "한글", "文");
|
|
||||||
setdict(f->dictlang->dict, "か", "仮");
|
|
||||||
init();
|
init();
|
||||||
im.l = getlang(lang);
|
im.l = getlang(lang);
|
||||||
}
|
}
|
||||||
@@ -1182,22 +1075,9 @@ engine_japanese_readings(struct ct *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
newestrequest(Dictreq *req)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while(channbrecv(dictreqc, req) > 0)
|
|
||||||
n++;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
engine_japanese_candidates(struct ct *t)
|
engine_japanese_candidates(struct ct *t)
|
||||||
{
|
{
|
||||||
Dictreq req;
|
|
||||||
Dictres res;
|
|
||||||
Trie *saved;
|
Trie *saved;
|
||||||
Lang *jp;
|
Lang *jp;
|
||||||
Str com, shown;
|
Str com, shown;
|
||||||
@@ -1213,12 +1093,6 @@ engine_japanese_candidates(struct ct *t)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
shown = shownpre(&im);
|
shown = shownpre(&im);
|
||||||
checkstr(t, "complete Japanese reading", "かんじ", &shown);
|
checkstr(t, "complete Japanese reading", "かんじ", &shown);
|
||||||
if(!CT_CHECK(t, newestrequest(&req) > 0))
|
|
||||||
goto cleanup;
|
|
||||||
checkstr(t, "dictionary lookup key", "かんじ", &req.key);
|
|
||||||
checkstr(t, "dictionary request identity", "かんじ", &req.pre);
|
|
||||||
dictlookup(&req, &res);
|
|
||||||
dictresult(&res);
|
|
||||||
if(!CT_EQ_INT(t, 2, im.nkouho))
|
if(!CT_EQ_INT(t, 2, im.nkouho))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
CT_EQ_INT(t, 0, im.sel);
|
CT_EQ_INT(t, 0, im.sel);
|
||||||
@@ -1228,8 +1102,17 @@ engine_japanese_candidates(struct ct *t)
|
|||||||
CT_EQ_INT(t, 1, im.sel);
|
CT_EQ_INT(t, 1, im.sel);
|
||||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||||
checkstr(t, "selected Kanji", "幹事", &com);
|
checkstr(t, "selected Kanji", "幹事", &com);
|
||||||
|
CT_EQ_INT(t, 0, im.nkouho);
|
||||||
|
/* Backspace looks a complete shorter reading up again. */
|
||||||
|
setdict(jp->dict, "かん", "缶");
|
||||||
|
if(!typekeys(t, "kanji", &com))
|
||||||
|
goto cleanup;
|
||||||
|
CT_CHECK(t, keystroke(Kback, 0, &com));
|
||||||
|
CT_EQ_INT(t, 0, im.nkouho);
|
||||||
|
CT_CHECK(t, keystroke(Kback, 0, &com));
|
||||||
|
if(CT_EQ_INT(t, 1, im.nkouho))
|
||||||
|
checkstr(t, "shorter reading candidate", "缶", &im.kouho[0]);
|
||||||
cleanup:
|
cleanup:
|
||||||
newestrequest(&req);
|
|
||||||
trieclose(jp->dict);
|
trieclose(jp->dict);
|
||||||
jp->dict = saved;
|
jp->dict = saved;
|
||||||
}
|
}
|
||||||
@@ -1294,11 +1177,9 @@ engine_katakana_sequences(struct ct *t)
|
|||||||
{ "xu", "ゥ" },
|
{ "xu", "ゥ" },
|
||||||
{ "vu", "ヴ" },
|
{ "vu", "ヴ" },
|
||||||
};
|
};
|
||||||
Dictreq req;
|
|
||||||
Str com, shown;
|
Str com, shown;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
newestrequest(&req);
|
|
||||||
for(i = 0; i < nelem(cases); i++){
|
for(i = 0; i < nelem(cases); i++){
|
||||||
init();
|
init();
|
||||||
im.l = getlang(LangJPK);
|
im.l = getlang(LangJPK);
|
||||||
@@ -1308,10 +1189,10 @@ engine_katakana_sequences(struct ct *t)
|
|||||||
checkstr(t, cases[i].keys, "", &com);
|
checkstr(t, cases[i].keys, "", &com);
|
||||||
shown = shownpre(&im);
|
shown = shownpre(&im);
|
||||||
checkstr(t, cases[i].keys, cases[i].want, &shown);
|
checkstr(t, cases[i].keys, cases[i].want, &shown);
|
||||||
|
CT_EQ_INT(t, 0, im.nkouho);
|
||||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||||
checkstr(t, "committed Katakana", cases[i].want, &com);
|
checkstr(t, "committed Katakana", cases[i].want, &com);
|
||||||
}
|
}
|
||||||
CT_EQ_INT(t, 0, newestrequest(&req));
|
|
||||||
CT_EQ_PTR(t, nil, getlang(LangJPK)->dictname);
|
CT_EQ_PTR(t, nil, getlang(LangJPK)->dictname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1692,48 +1573,6 @@ engine_emoji_start_and_unknown(struct ct *t)
|
|||||||
searchend(&f);
|
searchend(&f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
engine_emoji_dictionary_identity(struct ct *t)
|
|
||||||
{
|
|
||||||
Dictres res;
|
|
||||||
Searchfix f;
|
|
||||||
|
|
||||||
emojibegin(&f, 0);
|
|
||||||
im.pre = mkstr("same");
|
|
||||||
im.kouho[0] = mkstr("old");
|
|
||||||
im.nkouho = 1;
|
|
||||||
im.sel = 0;
|
|
||||||
memset(&res, 0, sizeof res);
|
|
||||||
res.key = im.pre;
|
|
||||||
res.seq = dictseq;
|
|
||||||
res.kouho[0] = mkstr("wrong");
|
|
||||||
res.nkouho = 1;
|
|
||||||
res.lang = LangJP;
|
|
||||||
dictresult(&res);
|
|
||||||
CT_EQ_INT(t, 1, im.nkouho);
|
|
||||||
checkstr(t, "wrong language ignored", "old", &im.kouho[0]);
|
|
||||||
|
|
||||||
res.lang = LangKO;
|
|
||||||
res.key = mkstr("other");
|
|
||||||
dictresult(&res);
|
|
||||||
CT_EQ_INT(t, 1, im.nkouho);
|
|
||||||
checkstr(t, "wrong preedit ignored", "old", &im.kouho[0]);
|
|
||||||
|
|
||||||
res.key = im.pre;
|
|
||||||
search.lang = LangEMOJI;
|
|
||||||
dictresult(&res);
|
|
||||||
CT_EQ_INT(t, 1, im.nkouho);
|
|
||||||
checkstr(t, "search response ignored", "old", &im.kouho[0]);
|
|
||||||
|
|
||||||
search.lang = 0;
|
|
||||||
res.kouho[0] = mkstr("right");
|
|
||||||
dictresult(&res);
|
|
||||||
CT_EQ_INT(t, 1, im.nkouho);
|
|
||||||
CT_EQ_INT(t, 0, im.sel);
|
|
||||||
checkstr(t, "matching response accepted", "right", &im.kouho[0]);
|
|
||||||
searchend(&f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
engine_hanja_search(struct ct *t)
|
engine_hanja_search(struct ct *t)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,10 +33,8 @@ void engine_candidate_page_metadata(struct ct*);
|
|||||||
void engine_candidate_page_snapshots(struct ct*);
|
void engine_candidate_page_snapshots(struct ct*);
|
||||||
void engine_candidate_page_movement(struct ct*);
|
void engine_candidate_page_movement(struct ct*);
|
||||||
void engine_candidate_completion(struct ct*);
|
void engine_candidate_completion(struct ct*);
|
||||||
void engine_dictionary_queue_latest_wins(struct ct*);
|
|
||||||
void engine_active_owner_lifecycle(struct ct*);
|
void engine_active_owner_lifecycle(struct ct*);
|
||||||
void engine_active_owner_reset(struct ct*);
|
void engine_active_owner_reset(struct ct*);
|
||||||
void engine_rejects_stale_dictionary_results(struct ct*);
|
|
||||||
void engine_active_owner_caret(struct ct*);
|
void engine_active_owner_caret(struct ct*);
|
||||||
void engine_popup_preedit_capability(struct ct*);
|
void engine_popup_preedit_capability(struct ct*);
|
||||||
void engine_vietnamese_client_preedit(struct ct*);
|
void engine_vietnamese_client_preedit(struct ct*);
|
||||||
@@ -57,7 +55,6 @@ void engine_emoji_navigation(struct ct*);
|
|||||||
void engine_search_candidate_keys(struct ct*);
|
void engine_search_candidate_keys(struct ct*);
|
||||||
void engine_emoji_preedit_languages(struct ct*);
|
void engine_emoji_preedit_languages(struct ct*);
|
||||||
void engine_emoji_start_and_unknown(struct ct*);
|
void engine_emoji_start_and_unknown(struct ct*);
|
||||||
void engine_emoji_dictionary_identity(struct ct*);
|
|
||||||
void engine_hanja_search(struct ct*);
|
void engine_hanja_search(struct ct*);
|
||||||
void engine_hanja_unknown_and_cancel(struct ct*);
|
void engine_hanja_unknown_and_cancel(struct ct*);
|
||||||
void engine_hanja_korean_keys(struct ct*);
|
void engine_hanja_korean_keys(struct ct*);
|
||||||
@@ -66,7 +63,7 @@ void engine_hanja_input_languages(struct ct*);
|
|||||||
void engine_randomized_stress(struct ct*);
|
void engine_randomized_stress(struct ct*);
|
||||||
void engine_full_boundary_passthrough(struct ct*);
|
void engine_full_boundary_passthrough(struct ct*);
|
||||||
void dictionary_candidates(struct ct*);
|
void dictionary_candidates(struct ct*);
|
||||||
void dictionary_misses_clear_result(struct ct*);
|
void dictionary_misses(struct ct*);
|
||||||
void dictionary_emoji_identity(struct ct*);
|
void dictionary_emoji_identity(struct ct*);
|
||||||
void ipc_masks_modifiers(struct ct*);
|
void ipc_masks_modifiers(struct ct*);
|
||||||
void ipc_control_and_caret_frames(struct ct*);
|
void ipc_control_and_caret_frames(struct ct*);
|
||||||
|
|||||||
@@ -99,13 +99,12 @@ transmap_states(struct ct *t)
|
|||||||
int eat;
|
int eat;
|
||||||
char *emit;
|
char *emit;
|
||||||
char *next;
|
char *next;
|
||||||
char *mapped;
|
|
||||||
} cases[] = {
|
} cases[] = {
|
||||||
{ "", 'k', 1, "", "k", "" },
|
{ "", 'k', 1, "", "k" },
|
||||||
{ "k", 'a', 1, "", "ka", "か" },
|
{ "k", 'a', 1, "", "ka" },
|
||||||
{ "ka", 's', 1, "か", "s", "" },
|
{ "ka", 's', 1, "か", "s" },
|
||||||
{ "ka", 'q', 0, "か", "", "" },
|
{ "ka", 'q', 0, "か", "" },
|
||||||
{ "k", 'q', 0, "k", "", "" },
|
{ "k", 'q', 0, "k", "" },
|
||||||
};
|
};
|
||||||
Emit e;
|
Emit e;
|
||||||
Im state;
|
Im state;
|
||||||
@@ -125,7 +124,6 @@ transmap_states(struct ct *t)
|
|||||||
i, cases[i].eat, e.eat);
|
i, cases[i].eat, e.eat);
|
||||||
checkstr(t, "emit", cases[i].emit, &e.s);
|
checkstr(t, "emit", cases[i].emit, &e.s);
|
||||||
checkstr(t, "next", cases[i].next, &e.next);
|
checkstr(t, "next", cases[i].next, &e.next);
|
||||||
checkstr(t, "mapped", cases[i].mapped, &e.dict);
|
|
||||||
}
|
}
|
||||||
trieclose(fixture);
|
trieclose(fixture);
|
||||||
state.l->map = saved;
|
state.l->map = saved;
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
Channel *drawc;
|
Channel *drawc;
|
||||||
Channel *keyc;
|
Channel *keyc;
|
||||||
Channel *dictreqc;
|
|
||||||
Channel *dictresc;
|
|
||||||
Lang testvi;
|
Lang testvi;
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -88,10 +86,8 @@ static const struct ct_test tests[] = {
|
|||||||
{ "engine/candidate-page-snapshots", engine_candidate_page_snapshots },
|
{ "engine/candidate-page-snapshots", engine_candidate_page_snapshots },
|
||||||
{ "engine/candidate-page-movement", engine_candidate_page_movement },
|
{ "engine/candidate-page-movement", engine_candidate_page_movement },
|
||||||
{ "engine/candidate-completion", engine_candidate_completion },
|
{ "engine/candidate-completion", engine_candidate_completion },
|
||||||
{ "engine/dictionary-queue-latest", engine_dictionary_queue_latest_wins },
|
|
||||||
{ "engine/active-owner-lifecycle", engine_active_owner_lifecycle },
|
{ "engine/active-owner-lifecycle", engine_active_owner_lifecycle },
|
||||||
{ "engine/active-owner-reset", engine_active_owner_reset },
|
{ "engine/active-owner-reset", engine_active_owner_reset },
|
||||||
{ "engine/rejects-stale-dictionary", engine_rejects_stale_dictionary_results },
|
|
||||||
{ "engine/active-owner-caret", engine_active_owner_caret },
|
{ "engine/active-owner-caret", engine_active_owner_caret },
|
||||||
{ "engine/popup-preedit-capability", engine_popup_preedit_capability },
|
{ "engine/popup-preedit-capability", engine_popup_preedit_capability },
|
||||||
{ "engine/vietnamese-client-preedit", engine_vietnamese_client_preedit },
|
{ "engine/vietnamese-client-preedit", engine_vietnamese_client_preedit },
|
||||||
@@ -112,7 +108,6 @@ static const struct ct_test tests[] = {
|
|||||||
{ "engine/search-candidate-keys", engine_search_candidate_keys },
|
{ "engine/search-candidate-keys", engine_search_candidate_keys },
|
||||||
{ "engine/emoji-preedit-languages", engine_emoji_preedit_languages },
|
{ "engine/emoji-preedit-languages", engine_emoji_preedit_languages },
|
||||||
{ "engine/emoji-start-and-unknown", engine_emoji_start_and_unknown },
|
{ "engine/emoji-start-and-unknown", engine_emoji_start_and_unknown },
|
||||||
{ "engine/emoji-dictionary-identity", engine_emoji_dictionary_identity },
|
|
||||||
{ "engine/hanja-search", engine_hanja_search },
|
{ "engine/hanja-search", engine_hanja_search },
|
||||||
{ "engine/hanja-unknown-cancel", engine_hanja_unknown_and_cancel },
|
{ "engine/hanja-unknown-cancel", engine_hanja_unknown_and_cancel },
|
||||||
{ "engine/hanja-korean-keys", engine_hanja_korean_keys },
|
{ "engine/hanja-korean-keys", engine_hanja_korean_keys },
|
||||||
@@ -120,7 +115,7 @@ static const struct ct_test tests[] = {
|
|||||||
{ "engine/hanja-input-languages", engine_hanja_input_languages },
|
{ "engine/hanja-input-languages", engine_hanja_input_languages },
|
||||||
{ "engine/full-boundary-passthrough", engine_full_boundary_passthrough },
|
{ "engine/full-boundary-passthrough", engine_full_boundary_passthrough },
|
||||||
{ "dict/candidates", dictionary_candidates },
|
{ "dict/candidates", dictionary_candidates },
|
||||||
{ "dict/misses-clear-result", dictionary_misses_clear_result },
|
{ "dict/misses", dictionary_misses },
|
||||||
{ "dict/emoji-identity", dictionary_emoji_identity },
|
{ "dict/emoji-identity", dictionary_emoji_identity },
|
||||||
{ "ipc/masks-modifiers", ipc_masks_modifiers },
|
{ "ipc/masks-modifiers", ipc_masks_modifiers },
|
||||||
{ "ipc/control-caret-frames", ipc_control_and_caret_frames },
|
{ "ipc/control-caret-frames", ipc_control_and_caret_frames },
|
||||||
@@ -166,8 +161,6 @@ threadmain(int argc, char **argv)
|
|||||||
|
|
||||||
drawc = chancreate(sizeof(Drawcmd), 4);
|
drawc = chancreate(sizeof(Drawcmd), 4);
|
||||||
keyc = chancreate(sizeof(Keyreq), 0);
|
keyc = chancreate(sizeof(Keyreq), 0);
|
||||||
dictreqc = chancreate(sizeof(Dictreq), 64);
|
|
||||||
dictresc = chancreate(sizeof(Dictres), 0);
|
|
||||||
testmapinit();
|
testmapinit();
|
||||||
status = CT_RUN_ARGS(tests, argc, argv);
|
status = CT_RUN_ARGS(tests, argc, argv);
|
||||||
for(i = 0; i < nlang; i++){
|
for(i = 0; i < nlang; i++){
|
||||||
@@ -178,7 +171,5 @@ threadmain(int argc, char **argv)
|
|||||||
testvi.map = nil;
|
testvi.map = nil;
|
||||||
chanfree(drawc);
|
chanfree(drawc);
|
||||||
chanfree(keyc);
|
chanfree(keyc);
|
||||||
chanfree(dictreqc);
|
|
||||||
chanfree(dictresc);
|
|
||||||
threadexitsall(status == 0 ? nil : "tests failed");
|
threadexitsall(status == 0 ? nil : "tests failed");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user