aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-04-22 19:51:30 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-04-22 19:51:30 -0700
commit7f1b6ff70b97e424ce73314809838c7cd94f3ae7 (patch)
tree405e5d2e84b931b7d2ab764db13d295598b16828
parent18383b973877f4c30c878414a51c0b44ea5dafe4 (diff)
feat: interfaces of newick io more general. can now take arbitrary readers/writers
-rw-r--r--Makefile2
-rw-r--r--include/libbio.h7
-rw-r--r--include/libn.h4
-rw-r--r--sys/libbio/io/newick.c47
-rw-r--r--sys/libbio/test.c47
5 files changed, 75 insertions, 32 deletions
diff --git a/Makefile b/Makefile
index 13e8c14..3b58bea 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
+CFLAGS := -g -fno-strict-aliasing -fwrapv -fms-extensions -Wno-microsoft-anon-tag
AFLAGS := -f elf64
INCS := -I$(INC_DIR)
ELIBS :=
diff --git a/include/libbio.h b/include/libbio.h
index 9f54015..3cdab4e 100644
--- a/include/libbio.h
+++ b/include/libbio.h
@@ -25,16 +25,17 @@ typedef struct bio·Tree
} bio·Tree;
/* newick i/o */
-bio·Tree bio·readnewick(Stream *file, mem·Allocator heap);
-error bio·writenewick(bio·Tree tree, Stream *out);
+bio·Tree bio·readnewick(io·Peeker stream, mem·Allocator heap);
+error bio·writenewick(bio·Tree tree, io·Putter out);
// -----------------------------------------------------------------------
// Sequences
+#if 0
typedef struct bio·FastaReader bio·FastaReader;
/* fasta/q i/o */
bio·Seq *bio·newfastareader(Stream *file, mem·Allocator heap);
bio·Seq *bio·readfasta(bio·FastaParser *p);
error bio·writefasta(bio·Seq *seq, Stream *out);
-
+#endif
diff --git a/include/libn.h b/include/libn.h
index 67d131d..d2479e4 100644
--- a/include/libn.h
+++ b/include/libn.h
@@ -112,13 +112,13 @@ int io·seek(Stream *s, long off, enum SeekPos origin);
typedef struct io·Reader
{
int (*read)(int n, void *buf);
-};
+} io·Reader;
typedef struct io·Peeker
{
byte (*get)(void);
error (*unget)(byte);
-};
+} io·Peeker;
typedef struct io·FullReader
{
diff --git a/sys/libbio/io/newick.c b/sys/libbio/io/newick.c
index 0004fac..82ea0d7 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(Stream *s)
+lex(io·Peeker s)
{
byte *c;
struct Token tok;
static byte b[1024];
c = b;
- *c = io·getbyte(s);
+ *c = s.get();
if (isspace(*c)) {
while (isspace(*c)) {
- *(++c) = io·getbyte(s);
+ *(++c) = s.get();
}
- io·ungetbyte(s, *c);
+ s.unget(*c);
Assert(c - b < 1024);
*c = 0;
@@ -101,11 +101,11 @@ lex(Stream *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) = io·getbyte(s);
+ NUM: *(++c) = s.get();
}
if (*c == '.') goto NUM;
- io·ungetbyte(s, *c);
+ s.unget(*c);
Assert(c - b < 1024);
*c = 0;
@@ -115,10 +115,10 @@ lex(Stream *s)
default:
while (isalnum(*c)) {
- *(++c) = io·getbyte(s);
+ *(++c) = s.get();
}
- io·ungetbyte(s, *c);
+ s.unget(*c);
Assert(c - b < 1024);
*c = '\0';
@@ -130,7 +130,7 @@ lex(Stream *s)
static
struct Token
-lex_nospace(Stream *s)
+lex_nospace(io·Peeker s)
{
struct Token tok;
tok = lex(s);
@@ -147,7 +147,7 @@ struct Parser
bio·Node *root;
struct Token tok;
- Stream *file;
+ io·Peeker file;
mem·Allocator heap;
};
@@ -280,7 +280,7 @@ parse(struct Parser *p)
break;
case tok·semi:
- io·ungetbyte(p->file, ';');
+ p->file.unget(';');
if (p->lev) {
errorf("format error: uneven number of parentheses found at ';'");
goto ERROR;
@@ -307,7 +307,7 @@ ERROR:
}
bio·Tree
-bio·readnewick(Stream *file, mem·Allocator heap)
+bio·readnewick(io·Peeker stream, mem·Allocator heap)
{
error err;
struct Parser p;
@@ -317,7 +317,7 @@ bio·readnewick(Stream *file, mem·Allocator heap)
.lev = 0,
.root = nil,
.tok = (struct Token){ 0 },
- .file = file,
+ .file = stream,
.heap = heap,
};
err = parse(&p);
@@ -334,7 +334,7 @@ bio·readnewick(Stream *file, mem·Allocator heap)
// Write
error
-dump(bio·Node *node, Stream *out)
+dump(bio·Node *node, io·Putter out)
{
byte b[24];
@@ -343,36 +343,35 @@ dump(bio·Node *node, Stream *out)
}
bio·Node *child;
if (node->nchild) {
- io·putbyte(out, '(');
+ out.put('(');
dump(node->child[0], out);
for (child = node->child[1]; child != nil; child = child->sibling) {
- io·putbyte(out, ',');
+ out.put(',');
dump(child, out);
}
- io·putbyte(out, ')');
+ out.put(')');
}
if (node->name) {
- io·putstring(out, node->name);
+ out.putstr(node->name);
}
if (node->parent) {
- io·putbyte(out, ':');
+ out.put(':');
snprintf(b, arrlen(b), "%f", node->dist);
- io·putstring(out, b);
+ out.putstr(b);
}
return 0;
}
error
-bio·writenewick(bio·Tree tree, Stream *out)
+bio·writenewick(bio·Tree tree, io·Putter out)
{
dump(tree.root, out);
- io·putbyte(out, ';');
- io·putbyte(out, '\n');
- io·flush(out);
+ out.put(';');
+ out.put('\n');
return 0;
}
diff --git a/sys/libbio/test.c b/sys/libbio/test.c
index 18bb993..3941290 100644
--- a/sys/libbio/test.c
+++ b/sys/libbio/test.c
@@ -34,6 +34,45 @@ bio·free(void *ptr)
static mem·Allocator arena = {.alloc = &bio·alloc, .realloc = &bio·realloc, .free = &bio·free };
// -----------------------------------------------------------------------
+// Read/writer
+
+static Stream* INPUT;
+
+static
+byte
+get()
+{
+ return io·getbyte(INPUT);
+}
+
+static
+error
+unget(byte c)
+{
+ return io·ungetbyte(INPUT, c);
+}
+
+static io·Peeker peeker = {.get = &get, .unget = &unget};
+
+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 putter = {.put = &put, .putstr = &putstr};
+
+// -----------------------------------------------------------------------
// Point of entry for testing
void
@@ -54,11 +93,15 @@ main()
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];
+
printf("starting\n");
- t = bio·readnewick(fd[0], arena);
- err = bio·writenewick(t, fd[1]);
+ t = bio·readnewick(peeker, arena);
+ err = bio·writenewick(t, putter);
printf("ending\n");
+ io·flush(fd[1]);
io·close(fd[0]); io·close(fd[1]);
return 0;
}