mirror of
https://github.com/attractivechaos/klib
synced 2024-11-23 14:49:50 +03:00
print tree in the Newick format
This commit is contained in:
parent
a98af4643f
commit
7cc91909a9
63
knhx.c
63
knhx.c
@ -91,17 +91,76 @@ knhx1_t *kn_parse(const char *nhx, int *_n, int *_error)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef kroundup32
|
||||
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
|
||||
#endif
|
||||
|
||||
static inline int kputsn(const char *p, int l, kstring_t *s)
|
||||
{
|
||||
if (s->l + l + 1 >= s->m) {
|
||||
s->m = s->l + l + 2;
|
||||
kroundup32(s->m);
|
||||
s->s = (char*)realloc(s->s, s->m);
|
||||
}
|
||||
memcpy(s->s + s->l, p, l);
|
||||
s->l += l; s->s[s->l] = 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
static inline int kputc(int c, kstring_t *s)
|
||||
{
|
||||
if (s->l + 1 >= s->m) {
|
||||
s->m = s->l + 2;
|
||||
kroundup32(s->m);
|
||||
s->s = (char*)realloc(s->s, s->m);
|
||||
}
|
||||
s->s[s->l++] = c; s->s[s->l] = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
static void format_node_recur(const knhx1_t *node, const knhx1_t *p, kstring_t *s, char *numbuf)
|
||||
{
|
||||
if (p->n) {
|
||||
int i;
|
||||
kputc('(', s);
|
||||
for (i = 0; i < p->n; ++i) {
|
||||
if (i) kputc(',', s);
|
||||
format_node_recur(node, &node[p->child[i]], s, numbuf);
|
||||
}
|
||||
kputc(')', s);
|
||||
if (p->name) kputsn(p->name, strlen(p->name), s);
|
||||
if (p->d >= 0) {
|
||||
sprintf(numbuf, ":%g", p->d);
|
||||
kputsn(numbuf, strlen(numbuf), s);
|
||||
}
|
||||
} else kputsn(p->name, strlen(p->name), s);
|
||||
}
|
||||
|
||||
void kn_format(const knhx1_t *node, int root, kstring_t *s) // TODO: get rid of recursion
|
||||
{
|
||||
char numbuf[128];
|
||||
format_node_recur(node, &node[root], s, numbuf);
|
||||
}
|
||||
|
||||
#ifdef KNHX_MAIN
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *s = "((a[abc],d1)x:0.5,((b[&&NHX:S=MOUSE],h2)[&&NHX:S=HUMAN:B=99][blabla][&&NHX:K=foo],c))";
|
||||
knhx1_t *node;
|
||||
int i, n, error;
|
||||
int i, j, n, error;
|
||||
kstring_t str;
|
||||
node = kn_parse(s, &n, &error);
|
||||
for (i = 0; i < n; ++i) {
|
||||
knhx1_t *p = node + i;
|
||||
printf("%s[%d]: %d,%d,%lg\n", p->name, i, p->parent, p->n, p->d);
|
||||
printf("[%d] %s\t%d\t%d\t%g", i, p->name, p->parent, p->n, p->d);
|
||||
for (j = 0; j < p->n; ++j)
|
||||
printf("\t%d", p->child[j]);
|
||||
putchar('\n');
|
||||
}
|
||||
str.l = str.m = 0; str.s = 0;
|
||||
kn_format(node, n-1, &str);
|
||||
puts(str.s);
|
||||
free(str.s);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
19
knhx.h
19
knhx.h
@ -13,4 +13,23 @@ typedef struct {
|
||||
double d;
|
||||
} knhx1_t;
|
||||
|
||||
#ifndef KSTRING_T
|
||||
#define KSTRING_T kstring_t
|
||||
typedef struct __kstring_t {
|
||||
size_t l, m;
|
||||
char *s;
|
||||
} kstring_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
knhx1_t *kn_parse(const char *nhx, int *_n, int *_error);
|
||||
void kn_format(const knhx1_t *node, int root, kstring_t *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user