aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-04-23 21:09:30 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-04-23 21:09:30 -0700
commit4c7870c21b9e645b349ddb77b091543b72c46bf5 (patch)
treef53a77257b62c7ef0729f176daa4c49c5bf57587
parent1a6c99600617f069d6d167fb3d33142a07fe0936 (diff)
feat: made calling signature of interface accepting functions more reliable
-rw-r--r--Makefile2
-rw-r--r--compile_commands.json62
-rw-r--r--include/libbio.h4
-rw-r--r--include/libn.h78
-rw-r--r--sys/libbio/io/newick.c76
-rw-r--r--sys/libbio/test.c102
-rw-r--r--sys/libn/io.c4
-rw-r--r--sys/libn/memory.c22
-rw-r--r--sys/libn/rules.mk8
9 files changed, 196 insertions, 162 deletions
diff --git a/Makefile b/Makefile
index 3b58bea..cb9951c 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ LIB_DIR := lib
OBJ_DIR := build
# Flags, Libraries and Includes
-CFLAGS := -g -fno-strict-aliasing -fwrapv -fms-extensions -Wno-microsoft-anon-tag
+CFLAGS := -g -fno-strict-aliasing -fwrapv -fms-extensions -Wno-microsoft-anon-tag -Wno-incompatible-function-pointer-types
AFLAGS := -f elf64
INCS := -I$(INC_DIR)
ELIBS :=
diff --git a/compile_commands.json b/compile_commands.json
index aa79c9d..68f271e 100644
--- a/compile_commands.json
+++ b/compile_commands.json
@@ -7,12 +7,68 @@
"-fno-strict-aliasing",
"-fwrapv",
"-fms-extensions",
+ "-Wno-microsoft-anon-tag",
+ "-Wno-incompatible-function-pointer-types",
"-Iinclude",
"-o",
- "build/libbio/io/newick.o",
- "sys/libbio/io/newick.c"
+ "build/libn/flate.o",
+ "sys/libn/flate.c"
],
"directory": "/home/nolln/root",
- "file": "sys/libbio/io/newick.c"
+ "file": "sys/libn/flate.c"
+ },
+ {
+ "arguments": [
+ "clang",
+ "-c",
+ "-g",
+ "-fno-strict-aliasing",
+ "-fwrapv",
+ "-fms-extensions",
+ "-Wno-microsoft-anon-tag",
+ "-Wno-incompatible-function-pointer-types",
+ "-Iinclude",
+ "-o",
+ "build/libn/bufio.o",
+ "sys/libn/bufio.c"
+ ],
+ "directory": "/home/nolln/root",
+ "file": "sys/libn/bufio.c"
+ },
+ {
+ "arguments": [
+ "clang",
+ "-c",
+ "-g",
+ "-fno-strict-aliasing",
+ "-fwrapv",
+ "-fms-extensions",
+ "-Wno-microsoft-anon-tag",
+ "-Wno-incompatible-function-pointer-types",
+ "-Iinclude",
+ "-o",
+ "build/libn/error.o",
+ "sys/libn/error.c"
+ ],
+ "directory": "/home/nolln/root",
+ "file": "sys/libn/error.c"
+ },
+ {
+ "arguments": [
+ "clang",
+ "-c",
+ "-g",
+ "-fno-strict-aliasing",
+ "-fwrapv",
+ "-fms-extensions",
+ "-Wno-microsoft-anon-tag",
+ "-Wno-incompatible-function-pointer-types",
+ "-Iinclude",
+ "-o",
+ "build/libn/coro.o",
+ "sys/libn/coro.c"
+ ],
+ "directory": "/home/nolln/root",
+ "file": "sys/libn/coro.c"
}
] \ No newline at end of file
diff --git a/include/libbio.h b/include/libbio.h
index 3cdab4e..2dc3d45 100644
--- a/include/libbio.h
+++ b/include/libbio.h
@@ -25,8 +25,8 @@ typedef struct bio·Tree
} bio·Tree;
/* newick i/o */
-bio·Tree bio·readnewick(io·Peeker stream, mem·Allocator heap);
-error bio·writenewick(bio·Tree tree, io·Putter out);
+bio·Tree bio·readnewick(io·Peeker stream, void*, mem·Allocator heap, void*);
+error bio·writenewick(bio·Tree tree, io·Putter out, void*);
// -----------------------------------------------------------------------
// Sequences
diff --git a/include/libn.h b/include/libn.h
index d2479e4..6547713 100644
--- a/include/libn.h
+++ b/include/libn.h
@@ -1,7 +1,7 @@
#pragma once
// ------------------------------------------------------------------------
-// Standard library
+// standard library
#include <assert.h>
#include <stdlib.h>
@@ -16,7 +16,7 @@
#include <sys/types.h>
// ----------------------------------------------------------------------------
-// Dynamic array.
+// dynamic array
typedef struct bufHdr
{
@@ -48,24 +48,49 @@ void* bufgrow(void*, vlong, vlong);
void _bufpop(void*, int, vlong);
// -----------------------------------------------------------------------------
-// Memory allocation
+// interfaces
+// TODO(nnoll): Think about this idea
+/*
+typedef struct Iface {
+ void* impl;
+ byte fcn[];
+} Iface;
+*/
+// -----------------------------------------------------------------------------
+// memory allocation
+/* allocator interface */
typedef struct mem·Allocator {
- void *(*alloc)(ulong size);
- void *(*realloc)(void *ptr, ulong size);
- void (*free)(void *ptr);
+ void *(*alloc)(void *iface, uint n, ulong size);
+ void (*free)(void *iface, void *ptr);
} mem·Allocator;
-static mem·Allocator mem·sys = { .alloc = &malloc, .realloc = &realloc, .free = &free };
+/* system implementation */
+static
+void ·free(void* _, void* ptr) {
+ return free(ptr);
+}
+
+static
+void *·alloc(void* _, uint n, ulong size) {
+ return malloc(n*size);
+}
+
+// TODO(nnoll): Allow for nil iterfaces?
+static
+mem·Allocator mem·sys = {
+ .alloc = ·alloc,
+ .free = ·free
+};
typedef struct mem·Arena mem·Arena;
-mem·Arena *mem·newarena(mem·Allocator from);
-void *mem·arenaalloc(mem·Arena *A, ulong size);
+mem·Arena *mem·newarena(mem·Allocator from, void*);
+void *mem·arenaalloc(mem·Arena *A, uint n, ulong size);
void mem·freearena(mem·Arena *A);
// -----------------------------------------------------------------------------
-// Co-routines
+// coroutines
typedef struct Coro Coro;
@@ -80,7 +105,7 @@ error coro·free(Coro *c);
#include ".include/str.h"
// -----------------------------------------------------------------------------
-// Maps or dictionaries
+// maps
#include ".include/map.h"
@@ -99,25 +124,25 @@ Stream *io·open(byte *name, byte *mode);
error io·close(Stream *s);
byte io·getbyte(Stream *s);
error io·ungetbyte(Stream *s, byte c);
-vlong io·read(Stream *s, int sz, int n, void *buf);
+int io·read(Stream *s, int sz, int n, void *buf);
int io·readln(Stream *s, int n, byte* buf);
error io·putbyte(Stream *s, byte c);
int io·putstring(Stream *s, string str);
-vlong io·write(Stream *s, int sz, int n, void *buf);
+int io·write(Stream *s, int sz, int n, void *buf);
int io·flush(Stream *s);
int io·seek(Stream *s, long off, enum SeekPos origin);
-/* Generic I/O interfaces */
+/* generic I/O interfaces */
typedef struct io·Reader
{
- int (*read)(int n, void *buf);
+ int (*read)(void*, int sz, int n, void *buf);
} io·Reader;
typedef struct io·Peeker
{
- byte (*get)(void);
- error (*unget)(byte);
+ byte (*get)(void*);
+ error (*unget)(void*, byte);
} io·Peeker;
typedef struct io·FullReader
@@ -128,13 +153,13 @@ typedef struct io·FullReader
typedef struct io·Writer
{
- int (*write)(int n, void *buf);
+ int (*write)(void*, int sz, int n, void *buf);
} io·Writer;
typedef struct io·Putter
{
- error (*put)(byte);
- int (*putstr)(string);
+ error (*put)(void*, byte);
+ int (*putstr)(void*, string);
} io·Putter;
typedef struct io·FullWriter
@@ -150,7 +175,18 @@ typedef struct io·ReadWriter
} io·ReadWriter;
// -----------------------------------------------------------------------------
-// Buffered I/O
+// libflate
+
+typedef struct gz·Reader gz·Reader;
+typedef struct gz·Writer gz·Writer;
+
+gz·Reader *gz·newreader(io·Reader rdr, void* r, mem·Allocator mem, void* m);
+int gz·read(gz·Reader *rdr, int sz, int n, void *buf);
+error gz·freereader(gz·Reader *rdr);
+
+gz·Writer *gz·newwriter(io·Writer wtr, void* w, mem·Allocator mem, void* m);
+error gz·freewriter(gz·Writer *wtr);
+int gz·write(gz·Writer *wtr, int sz, int n, void *buf);
// -----------------------------------------------------------------------------
// Error handling functions.
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
@@ -3,108 +3,36 @@
#include <libbio.h>
// -----------------------------------------------------------------------
-// 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)