fix core text and map ownership

This commit is contained in:
2026-08-11 19:32:58 +09:00
parent b63122dd14
commit e70278a3d2
6 changed files with 99 additions and 31 deletions

4
dat.h
View File

@@ -19,6 +19,8 @@ enum
Fontsz = 32, Fontsz = 32,
Fontbase = 4, Fontbase = 4,
Nglyphs = 0x20000, Nglyphs = 0x20000,
Maxrunes = 64,
Maxutf = Maxrunes * UTFmax + 1,
}; };
enum enum
@@ -37,7 +39,7 @@ enum
typedef struct Str Str; typedef struct Str Str;
struct Str struct Str
{ {
Rune r[64]; Rune r[Maxrunes];
int n; int n;
}; };

18
dict.c
View File

@@ -1,7 +1,7 @@
#include "dat.h" #include "dat.h"
#include "fn.h" #include "fn.h"
static void void
dictlookup(Dictreq *req, Dictres *res) dictlookup(Dictreq *req, Dictres *res)
{ {
Lang *l; Lang *l;
@@ -10,6 +10,7 @@ dictlookup(Dictreq *req, Dictres *res)
char *p, *e, *sp; char *p, *e, *sp;
Str tmp; Str tmp;
res->key = req->pre;
res->nkouho = 0; res->nkouho = 0;
if(req->key.n == 0) if(req->key.n == 0)
return; return;
@@ -23,6 +24,10 @@ dictlookup(Dictreq *req, Dictres *res)
p = n->val; p = n->val;
e = p + n->vlen; e = p + n->vlen;
while(res->nkouho < Maxkouho && p < e){ while(res->nkouho < Maxkouho && p < e){
while(p < e && *p == ' ')
p++;
if(p == e)
break;
sp = p; sp = p;
while(p < e && *p != ' ') while(p < e && *p != ' ')
p++; p++;
@@ -47,7 +52,6 @@ dictthread(void*)
while(channbrecv(dictreqc, &req) > 0) while(channbrecv(dictreqc, &req) > 0)
; ;
dictlookup(&req, &res); dictlookup(&req, &res);
res.key = req.pre;
chansend(dictresc, &res); chansend(dictresc, &res);
} }
} }
@@ -57,16 +61,18 @@ dictopen(char *path)
{ {
Hmap *h; Hmap *h;
Biobuf *b; Biobuf *b;
Str key, val; Str key;
char *line, *tab; char *line, *tab;
int len; int len;
b = Bopen(path, OREAD); b = Bopen(path, OREAD);
if(b == nil) if(b == nil)
die("can't open: %s", path); die("can't open: %s", path);
h = hmapalloc(4096, 0); h = hmapalloc(4096);
while((line = Brdstr(b, '\n', 1)) != nil){ while((line = Brdstr(b, '\n', 1)) != nil){
len = strlen(line); len = strlen(line);
if(len > 0 && line[len-1] == '\r')
line[--len] = '\0';
if(len == 0 || line[0] == ';'){ if(len == 0 || line[0] == ';'){
free(line); free(line);
continue; continue;
@@ -78,8 +84,7 @@ dictopen(char *path)
} }
*tab = '\0'; *tab = '\0';
sinit(&key, line, tab - line); sinit(&key, line, tab - line);
sinit(&val, tab+1, len - (tab - line) - 1); hmapset(&h, &key, tab+1, len - (tab - line) - 1);
hmapset(&h, &key, &val);
free(line); free(line);
} }
Bterm(b); Bterm(b);
@@ -99,4 +104,3 @@ dictinit(char *dir)
langs[i].dict = dictopen(path); langs[i].dict = dictopen(path);
} }
} }

7
fn.h
View File

@@ -9,12 +9,14 @@ int scmp(Str*, Str*);
int stoutf(Str*, char*, int); int stoutf(Str*, char*, int);
Rune slastr(Str*); Rune slastr(Str*);
Hmap* hmapalloc(int, int); Hmap* hmapalloc(int);
int hmapset(Hmap**, Str*, Str*); void hmapfree(Hmap*);
void hmapset(Hmap**, Str*, const char*, int);
Hnode* hmapget(Hmap*, Str*); Hnode* hmapget(Hmap*, Str*);
int mapget(Trie*, Str*, Str*); int mapget(Trie*, Str*, Str*);
Trie* trieopen(char*); Trie* trieopen(char*);
void trieclose(Trie*);
char* trieget(Trie*, char*, int, int*); char* trieget(Trie*, char*, int, int*);
int trielookup(Trie*, char*, int, char**, int*); int trielookup(Trie*, char*, int, char**, int*);
@@ -23,6 +25,7 @@ void mapinit(char*);
void dictinit(char*); void dictinit(char*);
void dictthread(void*); void dictthread(void*);
void dictlookup(Dictreq*, Dictres*);
void drawthread(void*); void drawthread(void*);
void imthread(void*); void imthread(void*);

55
hash.c
View File

@@ -18,13 +18,15 @@ hash(Str *s)
} }
Hmap* Hmap*
hmapalloc(int nbuckets, int size) hmapalloc(int nbuckets)
{ {
void *store; void *store;
Hmap *h; Hmap *h;
int nsz; int nsz;
nsz = Tagsize + size; if(nbuckets < 1)
die("hmapalloc: no buckets");
nsz = Tagsize;
store = emalloc(sizeof(*h) + nbuckets * nsz); store = emalloc(sizeof(*h) + nbuckets * nsz);
h = store; h = store;
h->nbs = nbuckets; h->nbs = nbuckets;
@@ -37,7 +39,7 @@ hmapalloc(int nbuckets, int size)
static int static int
keycmp(Hnode *n, Str *key) keycmp(Hnode *n, Str *key)
{ {
char buf[256]; char buf[Maxutf];
int len; int len;
len = stoutf(key, buf, sizeof(buf)); len = stoutf(key, buf, sizeof(buf));
@@ -67,7 +69,7 @@ hmapget(Hmap *h, Str *key)
static char* static char*
sdup(Str *s) sdup(Str *s)
{ {
char buf[256]; char buf[Maxutf];
char *p; char *p;
int n; int n;
@@ -78,15 +80,48 @@ sdup(Str *s)
return p; return p;
} }
int static char*
hmapset(Hmap **store, Str *key, Str *val) 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; Hnode *n;
uchar *v; uchar *v;
Hmap *h; Hmap *h;
int next; int next;
vlong diff; vlong diff;
newval = memdup(val, vlen);
h = *store; h = *store;
v = h->nodes + (hash(key) % h->nbs) * h->nsz; v = h->nodes + (hash(key) % h->nbs) * h->nsz;
for(;;){ for(;;){
@@ -121,9 +156,7 @@ replace:
n->filled = 1; n->filled = 1;
} }
n->next = next; n->next = next;
if(val->n > 0){ free(n->val);
n->val = sdup(val); n->val = newval;
n->vlen = strlen(n->val); n->vlen = vlen;
}
return 0;
} }

24
str.c
View File

@@ -1,11 +1,6 @@
#include "dat.h" #include "dat.h"
#include "fn.h" #include "fn.h"
enum
{
Maxrunes = nelem(((Str*)0)->r),
};
void void
sinit(Str *s, char *src, int n) sinit(Str *s, char *src, int n)
{ {
@@ -13,7 +8,11 @@ sinit(Str *s, char *src, int n)
s->n = 0; s->n = 0;
while(n > 0 && s->n < Maxrunes){ while(n > 0 && s->n < Maxrunes){
if(!fullrune(src, n))
break;
len = chartorune(&s->r[s->n], src); len = chartorune(&s->r[s->n], src);
if(len > n)
break;
s->n++; s->n++;
src += len; src += len;
n -= len; n -= len;
@@ -44,9 +43,10 @@ spopr(Str *s)
void void
sappend(Str *dst, Str *src) 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]; dst->r[dst->n++] = src->r[i];
} }
@@ -66,11 +66,17 @@ scmp(Str *a, Str *b)
int int
stoutf(Str *s, char *buf, int sz) stoutf(Str *s, char *buf, int sz)
{ {
char tmp[UTFmax];
int i, n, len; int i, n, len;
if(sz <= 0)
return 0;
n = 0; n = 0;
for(i = 0; i < s->n && n < sz - UTFmax; i++){ for(i = 0; i < s->n; i++){
len = runetochar(buf + n, &s->r[i]); len = runetochar(tmp, &s->r[i]);
if(len > sz - n - 1)
break;
memmove(buf + n, tmp, len);
n += len; n += len;
} }
buf[n] = '\0'; buf[n] = '\0';

22
trie.c
View File

@@ -53,7 +53,10 @@ insert(Trie *t, char *key, int klen, char *val, int vlen)
ci = add(t, ni, key[i]); ci = add(t, ni, key[i]);
ni = ci; 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; t->nodes[ni].vlen = vlen;
} }
@@ -74,6 +77,9 @@ trieopen(char *path)
t->n = 0; t->n = 0;
t->root = newnode(t); t->root = newnode(t);
while((line = Brdstr(b, '\n', 1)) != nil){ while((line = Brdstr(b, '\n', 1)) != nil){
vlen = strlen(line);
if(vlen > 0 && line[vlen-1] == '\r')
line[--vlen] = '\0';
if(line[0] == '\0'){ if(line[0] == '\0'){
free(line); free(line);
continue; continue;
@@ -87,11 +93,25 @@ trieopen(char *path)
val = tab + 1; val = tab + 1;
vlen = strlen(val); vlen = strlen(val);
insert(t, key, klen, val, vlen); insert(t, key, klen, val, vlen);
free(line);
} }
Bterm(b); Bterm(b);
return t; 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* char*
trieget(Trie *t, char *key, int klen, int *vlen) trieget(Trie *t, char *key, int klen, int *vlen)
{ {