From e70278a3d2cc7a122a6967e04352ddebbbcc1a10 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 11 Aug 2026 19:32:58 +0900 Subject: [PATCH] fix core text and map ownership --- dat.h | 4 +++- dict.c | 18 +++++++++++------- fn.h | 7 +++++-- hash.c | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- str.c | 24 +++++++++++++++--------- trie.c | 22 +++++++++++++++++++++- 6 files changed, 99 insertions(+), 31 deletions(-) diff --git a/dat.h b/dat.h index dffeedd..06497db 100644 --- a/dat.h +++ b/dat.h @@ -19,6 +19,8 @@ enum Fontsz = 32, Fontbase = 4, Nglyphs = 0x20000, + Maxrunes = 64, + Maxutf = Maxrunes * UTFmax + 1, }; enum @@ -37,7 +39,7 @@ enum typedef struct Str Str; struct Str { - Rune r[64]; + Rune r[Maxrunes]; int n; }; diff --git a/dict.c b/dict.c index 1e8e1ad..9d5917a 100644 --- a/dict.c +++ b/dict.c @@ -1,7 +1,7 @@ #include "dat.h" #include "fn.h" -static void +void dictlookup(Dictreq *req, Dictres *res) { Lang *l; @@ -10,6 +10,7 @@ dictlookup(Dictreq *req, Dictres *res) char *p, *e, *sp; Str tmp; + res->key = req->pre; res->nkouho = 0; if(req->key.n == 0) return; @@ -23,6 +24,10 @@ dictlookup(Dictreq *req, Dictres *res) 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++; @@ -47,7 +52,6 @@ dictthread(void*) while(channbrecv(dictreqc, &req) > 0) ; dictlookup(&req, &res); - res.key = req.pre; chansend(dictresc, &res); } } @@ -57,16 +61,18 @@ dictopen(char *path) { Hmap *h; Biobuf *b; - Str key, val; + Str key; char *line, *tab; int len; b = Bopen(path, OREAD); if(b == nil) die("can't open: %s", path); - h = hmapalloc(4096, 0); + h = hmapalloc(4096); while((line = Brdstr(b, '\n', 1)) != nil){ len = strlen(line); + if(len > 0 && line[len-1] == '\r') + line[--len] = '\0'; if(len == 0 || line[0] == ';'){ free(line); continue; @@ -78,8 +84,7 @@ dictopen(char *path) } *tab = '\0'; sinit(&key, line, tab - line); - sinit(&val, tab+1, len - (tab - line) - 1); - hmapset(&h, &key, &val); + hmapset(&h, &key, tab+1, len - (tab - line) - 1); free(line); } Bterm(b); @@ -99,4 +104,3 @@ dictinit(char *dir) langs[i].dict = dictopen(path); } } - diff --git a/fn.h b/fn.h index 5936b92..cff3a7b 100644 --- a/fn.h +++ b/fn.h @@ -9,12 +9,14 @@ int scmp(Str*, Str*); int stoutf(Str*, char*, int); Rune slastr(Str*); -Hmap* hmapalloc(int, int); -int hmapset(Hmap**, Str*, Str*); +Hmap* hmapalloc(int); +void hmapfree(Hmap*); +void hmapset(Hmap**, Str*, const char*, int); Hnode* hmapget(Hmap*, Str*); int mapget(Trie*, Str*, Str*); Trie* trieopen(char*); +void trieclose(Trie*); char* trieget(Trie*, char*, int, int*); int trielookup(Trie*, char*, int, char**, int*); @@ -23,6 +25,7 @@ void mapinit(char*); void dictinit(char*); void dictthread(void*); +void dictlookup(Dictreq*, Dictres*); void drawthread(void*); void imthread(void*); diff --git a/hash.c b/hash.c index 347a7dc..1b50926 100644 --- a/hash.c +++ b/hash.c @@ -18,13 +18,15 @@ hash(Str *s) } Hmap* -hmapalloc(int nbuckets, int size) +hmapalloc(int nbuckets) { void *store; Hmap *h; int nsz; - nsz = Tagsize + size; + if(nbuckets < 1) + die("hmapalloc: no buckets"); + nsz = Tagsize; store = emalloc(sizeof(*h) + nbuckets * nsz); h = store; h->nbs = nbuckets; @@ -37,7 +39,7 @@ hmapalloc(int nbuckets, int size) static int keycmp(Hnode *n, Str *key) { - char buf[256]; + char buf[Maxutf]; int len; len = stoutf(key, buf, sizeof(buf)); @@ -67,7 +69,7 @@ hmapget(Hmap *h, Str *key) static char* sdup(Str *s) { - char buf[256]; + char buf[Maxutf]; char *p; int n; @@ -78,15 +80,48 @@ sdup(Str *s) return p; } -int -hmapset(Hmap **store, Str *key, Str *val) +static char* +memdup(const char *src, int n) { + char *p; + + if(n == 0) + return nil; + p = emalloc(n + 1); + memmove(p, src, n); + p[n] = '\0'; + return p; +} + +void +hmapfree(Hmap *h) +{ + Hnode *n; + int i; + + if(h == nil) + return; + for(i = 0; i < h->len; i++){ + n = (Hnode*)(h->nodes + i * h->nsz); + if(!n->filled) + continue; + free(n->key); + free(n->val); + } + free(h); +} + +void +hmapset(Hmap **store, Str *key, const char *val, int vlen) +{ + char *newval; Hnode *n; uchar *v; Hmap *h; int next; vlong diff; + newval = memdup(val, vlen); h = *store; v = h->nodes + (hash(key) % h->nbs) * h->nsz; for(;;){ @@ -121,9 +156,7 @@ replace: n->filled = 1; } n->next = next; - if(val->n > 0){ - n->val = sdup(val); - n->vlen = strlen(n->val); - } - return 0; + free(n->val); + n->val = newval; + n->vlen = vlen; } diff --git a/str.c b/str.c index 2e511fa..75044c2 100644 --- a/str.c +++ b/str.c @@ -1,11 +1,6 @@ #include "dat.h" #include "fn.h" -enum -{ - Maxrunes = nelem(((Str*)0)->r), -}; - void sinit(Str *s, char *src, int n) { @@ -13,7 +8,11 @@ sinit(Str *s, char *src, int n) s->n = 0; while(n > 0 && s->n < Maxrunes){ + if(!fullrune(src, n)) + break; len = chartorune(&s->r[s->n], src); + if(len > n) + break; s->n++; src += len; n -= len; @@ -44,9 +43,10 @@ spopr(Str *s) void sappend(Str *dst, Str *src) { - int i; + int i, n; - for(i = 0; i < src->n && dst->n < Maxrunes; i++) + n = src->n; + for(i = 0; i < n && dst->n < Maxrunes; i++) dst->r[dst->n++] = src->r[i]; } @@ -66,11 +66,17 @@ scmp(Str *a, Str *b) int stoutf(Str *s, char *buf, int sz) { + char tmp[UTFmax]; int i, n, len; + if(sz <= 0) + return 0; n = 0; - for(i = 0; i < s->n && n < sz - UTFmax; i++){ - len = runetochar(buf + n, &s->r[i]); + for(i = 0; i < s->n; i++){ + len = runetochar(tmp, &s->r[i]); + if(len > sz - n - 1) + break; + memmove(buf + n, tmp, len); n += len; } buf[n] = '\0'; diff --git a/trie.c b/trie.c index 759193d..4ffdee8 100644 --- a/trie.c +++ b/trie.c @@ -53,7 +53,10 @@ insert(Trie *t, char *key, int klen, char *val, int vlen) ci = add(t, ni, key[i]); ni = ci; } - t->nodes[ni].val = val; + free(t->nodes[ni].val); + t->nodes[ni].val = emalloc(vlen + 1); + memmove(t->nodes[ni].val, val, vlen); + t->nodes[ni].val[vlen] = '\0'; t->nodes[ni].vlen = vlen; } @@ -74,6 +77,9 @@ trieopen(char *path) t->n = 0; t->root = newnode(t); while((line = Brdstr(b, '\n', 1)) != nil){ + vlen = strlen(line); + if(vlen > 0 && line[vlen-1] == '\r') + line[--vlen] = '\0'; if(line[0] == '\0'){ free(line); continue; @@ -87,11 +93,25 @@ trieopen(char *path) val = tab + 1; vlen = strlen(val); insert(t, key, klen, val, vlen); + free(line); } Bterm(b); return t; } +void +trieclose(Trie *t) +{ + int i; + + if(t == nil) + return; + for(i = 0; i < t->n; i++) + free(t->nodes[i].val); + free(t->nodes); + free(t); +} + char* trieget(Trie *t, char *key, int klen, int *vlen) {