From 4eabf5d72c6b01bbf11180280ef9d28d5fe587bf Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 28 Apr 2020 11:59:59 -0700 Subject: feat: added number of nodes & leafs to tree data structure --- sys/libbio/io/newick.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) (limited to 'sys/libbio/io/newick.c') diff --git a/sys/libbio/io/newick.c b/sys/libbio/io/newick.c index 0c9921b..81b5195 100644 --- a/sys/libbio/io/newick.c +++ b/sys/libbio/io/newick.c @@ -65,20 +65,22 @@ tokstr(struct Token tok) // TODO: Bounds checking on buffer static struct Token -lex(io·Peeker s, void* impl) +lex(io·Peeker s, void* fp) { +#define isvalidchar(C) (' ' < (C) && (C) < ':') || (':' < (C) && (C) <= '~') + byte *c; struct Token tok; static byte b[1024]; c = b; - *c = s.get(impl); + *c = s.get(fp); if (isspace(*c)) { while (isspace(*c)) { - *(++c) = s.get(impl); + *(++c) = s.get(fp); } - s.unget(impl, *c); + s.unget(fp, *c); Assert(c - b < 1024); *c = 0; @@ -101,11 +103,11 @@ lex(io·Peeker s, void* impl) 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(impl); + NUM: *(++c) = s.get(fp); } if (*c == '.') goto NUM; - s.unget(impl, *c); + s.unget(fp, *c); Assert(c - b < 1024); *c = 0; @@ -114,11 +116,12 @@ lex(io·Peeker s, void* impl) return tok; default: - while (isalnum(*c)) { - *(++c) = s.get(impl); + while (isvalidchar(*c)) { + *(++c) = s.get(fp); } + printf("ended on character %c\n", *c); - s.unget(impl, *c); + s.unget(fp, *c); Assert(c - b < 1024); *c = '\0'; @@ -126,6 +129,7 @@ lex(io·Peeker s, void* impl) tok.lit.s = b; return tok; } +#undef isvalidchar } static @@ -248,7 +252,6 @@ parse(struct Parser *p) goto ERROR; } node->name = str·new(tok.lit.s); - printf("settting name %s\n", node->name); } else { if (p->tok.kind != tok·lparen && p->tok.kind != tok·comma) { errorf("format error: misplaced identifier for leaf found"); @@ -308,12 +311,21 @@ ERROR: return 1; } -bio·Tree -bio·readnewick(io·Peeker stream, void *s, mem·Allocator heap, void *h) +error +bio·readnewick(io·Peeker stream, void *s, mem·Allocator heap, void *h, bio·Tree *tree) { error err; struct Parser p; - bio·Tree tree; + enum + { + error·nil, + error·notree, + error·parse, + }; + + if (!tree) { + return error·notree; + } p = (struct Parser){ .lev = 0, @@ -327,11 +339,17 @@ bio·readnewick(io·Peeker stream, void *s, mem·Allocator heap, void *h) err = parse(&p); if (err) { errorf("parsing failed\n"); - return tree; + return error·parse; } - tree.root = p.root; - return tree; + tree->root = p.root; + tree->nleaf = 0; + tree->nnode = 0; + + phylo·countnodes(tree->root, &tree->nnode); + phylo·countleafs(tree->root, &tree->nleaf); + + return error·nil; } // ----------------------------------------------------------------------- -- cgit v1.2.1