#include "dat.h" #include "fn.h" void dictlookup(Dictreq *req, Dictres *res) { Lang *l; Hmap *dict; Hnode *n; char *p, *e, *sp; Str tmp; res->key = req->pre; res->nkouho = 0; res->lang = req->lang; if(req->key.n == 0) return; l = getlang(req->lang); dict = l ? l->dict : nil; if(dict == nil) return; n = hmapget(dict, &req->key); if(n == nil || n->vlen == 0) return; p = n->val; e = p + n->vlen; while(res->nkouho < Maxkouho && p < e){ while(p < e && *p == ' ') p++; if(p == e) break; sp = p; while(p < e && *p != ' ') p++; sinit(&tmp, sp, p - sp); if(req->lang == LangEMOJI || scmp(&tmp, &req->key) != 0) res->kouho[res->nkouho++] = tmp; if(p < e) p++; } } 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); } } static Hmap* dictopen(char *path) { Hmap *h; Biobuf *b; Str key; char *line, *tab; int len, lineno; b = Bopen(path, OREAD); if(b == nil) die("can't open: %s", path); h = hmapalloc(4096); lineno = 0; while((line = Brdstr(b, '\n', 1)) != nil){ lineno++; len = strlen(line); if(len > 0 && line[len-1] == '\r') line[--len] = '\0'; if(len == 0 || line[0] == ';'){ free(line); continue; } tab = strchr(line, '\t'); if(tab == nil || tab >= line + len - 1){ free(line); continue; } *tab = '\0'; if(utflen(line) > Maxrunes) die("dictionary key too long: %s:%d", path, lineno); sinit(&key, line, tab - line); hmapset(&h, &key, tab+1, len - (tab - line) - 1); free(line); } Bterm(b); return h; } void dictinit(char *dir) { char path[1024]; int i; for(i = 0; i < nlang; i++){ if(langs[i].dictname == nil) continue; if(snprint(path, sizeof(path), "%s/%s.dict", dir, langs[i].dictname) >= (int)sizeof path) die("dictionary path too long: %s/%s.dict", dir, langs[i].dictname); langs[i].dict = dictopen(path); } }