From 4c7870c21b9e645b349ddb77b091543b72c46bf5 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 23 Apr 2020 21:09:30 -0700 Subject: feat: made calling signature of interface accepting functions more reliable --- sys/libbio/io/newick.c | 76 +++++++++++++++++++----------------- sys/libbio/test.c | 102 ++++++++----------------------------------------- sys/libn/io.c | 4 +- sys/libn/memory.c | 22 ++++++++--- sys/libn/rules.mk | 8 ++-- 5 files changed, 77 insertions(+), 135 deletions(-) (limited to 'sys') diff --git a/sys/libbio/io/newick.c b/sys/libbio/io/newick.c index 82ea0d7..8b02446 100644 --- a/sys/libbio/io/newick.c +++ b/sys/libbio/io/newick.c @@ -65,20 +65,20 @@ tokstr(struct Token tok) // TODO: Bounds checking on buffer static struct Token -lex(io·Peeker s) +lex(io·Peeker s, void* impl) { byte *c; struct Token tok; static byte b[1024]; c = b; - *c = s.get(); + *c = s.get(impl); if (isspace(*c)) { while (isspace(*c)) { - *(++c) = s.get(); + *(++c) = s.get(impl); } - s.unget(*c); + s.unget(impl, *c); Assert(c - b < 1024); *c = 0; @@ -101,11 +101,11 @@ lex(io·Peeker s) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': while (isdigit(*c)) { - NUM: *(++c) = s.get(); + NUM: *(++c) = s.get(impl); } if (*c == '.') goto NUM; - s.unget(*c); + s.unget(impl, *c); Assert(c - b < 1024); *c = 0; @@ -115,10 +115,10 @@ lex(io·Peeker s) default: while (isalnum(*c)) { - *(++c) = s.get(); + *(++c) = s.get(impl); } - s.unget(*c); + s.unget(impl, *c); Assert(c - b < 1024); *c = '\0'; @@ -130,12 +130,12 @@ lex(io·Peeker s) static struct Token -lex_nospace(io·Peeker s) +lex_nospace(io·Peeker s, void *impl) { struct Token tok; - tok = lex(s); + tok = lex(s, impl); if (tok.kind == tok·space) { - tok = lex_nospace(s); + tok = lex_nospace(s, impl); } return tok; @@ -147,7 +147,9 @@ struct Parser bio·Node *root; struct Token tok; + void *fimpl; io·Peeker file; + void *himpl; mem·Allocator heap; }; @@ -162,7 +164,7 @@ parse(struct Parser *p) node = p->root; for (;;) { - tok = lex_nospace(p->file); + tok = lex_nospace(p->file, p->fimpl); switch (tok.kind) { case tok·lparen: @@ -171,7 +173,7 @@ parse(struct Parser *p) goto ERROR; } - node = p->heap.alloc(sizeof(*node)); + node = p->heap.alloc(p->himpl, 1, sizeof(*node)); memset(node, 0, sizeof(*node)); if (p->root) { @@ -208,7 +210,7 @@ parse(struct Parser *p) } node->comment = str·new(""); while (tok.kind != tok·rbrak) { - tok = lex_nospace(p->file); + tok = lex_nospace(p->file, p->fimpl); if (tok.kind == tok·eof || tok.kind == tok·nil) { errorf("incorrect format: unmatched comment bracket '['"); goto ERROR; @@ -223,7 +225,7 @@ parse(struct Parser *p) break; case tok·colon: - tok = lex_nospace(p->file); + tok = lex_nospace(p->file, p->fimpl); if (tok.kind != tok·number) { errorf("incorrect format: expected number after colon"); goto ERROR; @@ -258,7 +260,7 @@ parse(struct Parser *p) goto ERROR; } - node = p->heap.alloc(sizeof(*node)); + node = p->heap.alloc(p->himpl, 1, sizeof(*node)); memset(node, 0, sizeof(*node)); node->name = str·new(tok.lit.s); @@ -280,7 +282,7 @@ parse(struct Parser *p) break; case tok·semi: - p->file.unget(';'); + p->file.unget(p->fimpl, ';'); if (p->lev) { errorf("format error: uneven number of parentheses found at ';'"); goto ERROR; @@ -307,18 +309,20 @@ ERROR: } bio·Tree -bio·readnewick(io·Peeker stream, mem·Allocator heap) +bio·readnewick(io·Peeker stream, void *si, mem·Allocator heap, void *hi) { error err; struct Parser p; bio·Tree tree; p = (struct Parser){ - .lev = 0, - .root = nil, - .tok = (struct Token){ 0 }, - .file = stream, - .heap = heap, + .lev = 0, + .root = nil, + .tok = (struct Token){ 0 }, + .fimpl = si, + .file = stream, + .himpl = hi, + .heap = heap, }; err = parse(&p); if (err) { @@ -334,7 +338,7 @@ bio·readnewick(io·Peeker stream, mem·Allocator heap) // Write error -dump(bio·Node *node, io·Putter out) +dump(bio·Node *node, void *impl, io·Putter out) { byte b[24]; @@ -343,35 +347,35 @@ dump(bio·Node *node, io·Putter out) } bio·Node *child; if (node->nchild) { - out.put('('); + out.put(impl, '('); - dump(node->child[0], out); + dump(node->child[0], impl, out); for (child = node->child[1]; child != nil; child = child->sibling) { - out.put(','); - dump(child, out); + out.put(impl, ','); + dump(child, impl, out); } - out.put(')'); + out.put(impl, ')'); } if (node->name) { - out.putstr(node->name); + out.putstr(impl, node->name); } if (node->parent) { - out.put(':'); + out.put(impl, ':'); snprintf(b, arrlen(b), "%f", node->dist); - out.putstr(b); + out.putstr(impl, b); } return 0; } error -bio·writenewick(bio·Tree tree, io·Putter out) +bio·writenewick(bio·Tree tree, io·Putter out, void* impl) { - dump(tree.root, out); - out.put(';'); - out.put('\n'); + dump(tree.root, impl, out); + out.put(impl, ';'); + out.put(impl, '\n'); return 0; } diff --git a/sys/libbio/test.c b/sys/libbio/test.c index fb79302..115ee46 100644 --- a/sys/libbio/test.c +++ b/sys/libbio/test.c @@ -2,109 +2,37 @@ #include #include -// ----------------------------------------------------------------------- -// Arena allocator - -static mem·Arena* ARENA; - -static -void* -bio·alloc(ulong size) -{ - return mem·arenaalloc(ARENA, size); -} - -static -void* -bio·realloc(void *ptr, ulong size) -{ - void* new = mem·arenaalloc(ARENA, size); - memcpy(new, ptr, size); - - return new; -} - -static -void -bio·free(void *ptr) -{ - /* stub */ -} - -static mem·Allocator arena = {.alloc = &bio·alloc, .realloc = &bio·realloc, .free = &bio·free }; - -// ----------------------------------------------------------------------- -// Read/writer - -/* Static reader thunk */ -static Stream* INPUT; - -static -byte -get() -{ - return io·getbyte(INPUT); -} - -static -error -unget(byte c) -{ - return io·ungetbyte(INPUT, c); -} - -static io·Peeker rdr = {.get = &get, .unget = &unget}; - -/* Static writer thunk */ -static Stream* OUTPUT; - -static -error -put(byte b) -{ - return io·putbyte(OUTPUT, b); -} - -static -int -putstr(string s) -{ - return io·putstring(OUTPUT, s); -} - -static io·Putter wtr = {.put = &put, .putstr = &putstr}; - // ----------------------------------------------------------------------- // Point of entry for testing -void -init() -{ - ARENA = mem·newarena(mem·sys); -} int main() { - init(); - error err; bio·Tree t; - Stream *fd[2]; + mem·Arena *mem; + Stream *fd[2]; + + io·Peeker rdr; + io·Putter wtr; + mem·Allocator al; + + mem = mem·newarena(mem·sys, nil); + rdr = (io·Peeker){.get = &io·getbyte, .unget = &io·ungetbyte}; + wtr = (io·Putter){.put = &io·putbyte, .putstr = &io·putstring}; + al = (mem·Allocator) { .alloc = &mem·arenaalloc, .free = nil, }; fd[0] = io·open("/home/nolln/root/data/test/example.nwk", "r"); fd[1] = io·open("/home/nolln/root/data/test/example.proc.nwk", "w"); - INPUT = fd[0]; - OUTPUT = fd[1]; - - t = bio·readnewick(rdr, arena); - err = bio·writenewick(t, wtr); + t = bio·readnewick(rdr, fd[0], al, mem); + err = bio·writenewick(t, wtr, fd[1]); io·flush(fd[1]); - io·close(fd[0]); io·close(fd[1]); + io·close(fd[0]); + io·close(fd[1]); - mem·freearena(ARENA); return 0; } diff --git a/sys/libn/io.c b/sys/libn/io.c index 7eec74e..ff64ff0 100644 --- a/sys/libn/io.c +++ b/sys/libn/io.c @@ -31,7 +31,7 @@ io·ungetbyte(Stream *s, byte c) return ungetc(c, s); } -vlong +int io·read(Stream *s, int sz, int n, void *buf) { return fread(buf, sz, n, s); @@ -61,7 +61,7 @@ io·putstring(Stream *s, string str) return fputs(str, s); } -vlong +int io·write(Stream *s, int sz, int n, void *buf) { return fwrite(buf, sz, n, s); diff --git a/sys/libn/memory.c b/sys/libn/memory.c index ca0c819..8081569 100644 --- a/sys/libn/memory.c +++ b/sys/libn/memory.c @@ -68,6 +68,8 @@ struct Block struct mem·Arena { mem·Allocator heap; + void *impl; + byte *off; byte *end; struct Block *curr; @@ -75,9 +77,10 @@ struct mem·Arena }; mem·Arena* -mem·newarena(mem·Allocator from) +mem·newarena(mem·Allocator from, void *impl) { - mem·Arena *a = from.alloc(sizeof(*a) + ARENA_BLOCK_SIZE); + mem·Arena *a = from.alloc(impl, 1, sizeof(*a) + ARENA_BLOCK_SIZE); + a->impl = impl; a->heap = from; a->off = a->first.buf; a->end = a->first.buf + ARENA_BLOCK_SIZE; @@ -94,7 +97,7 @@ grow(mem·Arena *a, vlong min) struct Block *blk; size = ALIGN_UP(MAX(min, ARENA_BLOCK_SIZE), ARENA_ALIGN); - blk = a->heap.alloc(sizeof(*blk) + size); + blk = a->heap.alloc(a->impl, 1, sizeof(*blk) + size); a->off = blk->buf; a->end = a->off + size; @@ -106,9 +109,16 @@ grow(mem·Arena *a, vlong min) } void* -mem·arenaalloc(mem·Arena *a, ulong size) +mem·arenaalloc(mem·Arena *a, uint n, ulong size) { + if (!n) { + return nil; + } + void *ptr; + // TODO(nnoll): check for overflow + size = n * size; + if (size > (ulong)(a->end - a->off)) { grow(a, size); Assert(size <= (uintptr)(a->end - a->off)); @@ -131,9 +141,9 @@ mem·freearena(mem·Arena *a) it = a->first.next; while (it != nil) { next = it->next; - a->heap.free(it); + a->heap.free(a->impl, it); it = next; } - a->heap.free(a); + a->heap.free(a->impl, a); } diff --git a/sys/libn/rules.mk b/sys/libn/rules.mk index 15f2f2d..19e4c50 100644 --- a/sys/libn/rules.mk +++ b/sys/libn/rules.mk @@ -29,14 +29,14 @@ BINS_$(d) := $(patsubst $(SRC_DIR)/%, $(OBJ_DIR)/%, $(BINS_$(d))) BINS := $(BINS) $(BINS_$(d)) # Local rules -# $(LIBS_$(d)) := TGTFLAGS := -# $(LIBS_$(d)) := TGTINCS := -# $(LIBS_$(d)) := TGTLIBS := +# $(LIBS_$(d)) := TCFLAGS := +# $(LIBS_$(d)) := TCINCS := +# $(LIBS_$(d)) := TCLIBS := $(LIBS_$(d)): $(OBJS_$(d)) $(ARCHIVE) -$(BINS_$(d)): TCLIBS := $(LIBS_$(d)) +$(BINS_$(d)): TCLIBS := $(LIBS_$(d)) $(LIB_DIR)/vendor/libz.a $(BINS_$(d)): $(OBJ_DIR)/libn/test.o $(LINK) -- cgit v1.2.1