#include "dat.h" #include "fn.h" /* Appends the space-separated words of a node's entry to out[], up to max. */ static int words(Tnode *nd, Str *out, int n, int max) { char *p, *e, *sp; Str tmp; if(nd->val == nil) return n; p = nd->val; e = p + nd->vlen; while(n < max && p < e){ while(p < e && *p == ' ') p++; sp = p; while(p < e && *p != ' ') p++; if(sinit(&tmp, sp, p - sp) && tmp.n > 0) out[n++] = tmp; } return n; } /* The entries at and below a node, the shortest keys first. */ static int below(Trie *t, int ni, Str *out, int n, int max) { Tnode *nd; int ci; nd = &t->nodes[ni]; n = words(nd, out, n, max); for(ci = nd->child; ci >= 0 && n < max; ci = t->nodes[ci].sibling) n = below(t, ci, out, n, max); return n; } /* Fills out[] with up to max candidates for key: the words of its entry. */ int dictlookup(Trie *t, Str *key, Str *out, int max) { int ni; ni = key->n == 0 ? -1 : trienode(t, key); if(ni < 0) return 0; return words(&t->nodes[ni], out, 0, max); } /* As dictlookup, for every entry key is a prefix of, key's own first. */ int dictprefix(Trie *t, Str *key, Str *out, int max) { int ni; ni = key->n == 0 ? -1 : trienode(t, key); if(ni < 0) return 0; return below(t, ni, out, 0, max); } static Trie* langopen(char *dir, char *name, char *ext) { char *path; Trie *t; path = smprint("%s/%s.%s", dir, name, ext); if(path == nil) die("out of memory"); t = trieopen(path); free(path); return t; } void langinit(char *dir) { Lang *l; for(l = langs; l < langs + nlang; l++){ if(l->mapname != nil) l->map = langopen(dir, l->mapname, "map"); if(l->dictname != nil) l->dict = langopen(dir, l->dictname, "dict"); } }