Moved taxonomy source code to a dependencies subdir for separation of

dependencies.
This commit is contained in:
Nate Coraor
2008-04-03 17:14:31 +00:00
parent b4d0ff6cab
commit 5668c8aa43
13 changed files with 0 additions and 5882 deletions
-890
View File
@@ -1,890 +0,0 @@
/* Produced by texiweb from libavl.w on 2002/08/24 at 13:21. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
The author may be contacted at <blp@gnu.org> on the Internet, or
write to Ben Pfaff, Stanford University, Computer Science Dept., 353
Serra Mall, Stanford CA 94305, USA.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "avl.h"
/* Creates and returns a new table
with comparison function |compare| using parameter |param|
and memory allocator |allocator|.
Returns |NULL| if memory allocation failed. */
struct avl_table *
avl_create (avl_comparison_func *compare, void *param,
struct libavl_allocator *allocator)
{
struct avl_table *tree;
assert (compare != NULL);
if (allocator == NULL)
allocator = &avl_allocator_default;
tree = allocator->libavl_malloc (allocator, sizeof *tree);
if (tree == NULL)
return NULL;
tree->avl_root = NULL;
tree->avl_compare = compare;
tree->avl_param = param;
tree->avl_alloc = allocator;
tree->avl_count = 0;
tree->avl_generation = 0;
return tree;
}
/* Search |tree| for an item matching |item|, and return it if found.
Otherwise return |NULL|. */
void *
avl_find (const struct avl_table *tree, const void *item)
{
const struct avl_node *p;
assert (tree != NULL && item != NULL);
for (p = tree->avl_root; p != NULL; )
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp < 0)
p = p->avl_link[0];
else if (cmp > 0)
p = p->avl_link[1];
else /* |cmp == 0| */
return p->avl_data;
}
return NULL;
}
/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
If a duplicate item is found in the tree,
returns a pointer to the duplicate without inserting |item|.
Returns |NULL| in case of memory allocation failure. */
void **
avl_probe (struct avl_table *tree, void *item)
{
struct avl_node *y, *z; /* Top node to update balance factor, and parent. */
struct avl_node *p, *q; /* Iterator, and parent. */
struct avl_node *n; /* Newly inserted node. */
struct avl_node *w; /* New root of rebalanced subtree. */
int dir; /* Direction to descend. */
unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */
int k = 0; /* Number of cached results. */
assert (tree != NULL && item != NULL);
z = (struct avl_node *) &tree->avl_root;
y = tree->avl_root;
dir = 0;
for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir])
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp == 0)
return &p->avl_data;
if (p->avl_balance != 0)
z = q, y = p, k = 0;
da[k++] = dir = cmp > 0;
}
n = q->avl_link[dir] =
tree->avl_alloc->libavl_malloc (tree->avl_alloc, sizeof *n);
if (n == NULL)
return NULL;
tree->avl_count++;
n->avl_data = item;
n->avl_link[0] = n->avl_link[1] = NULL;
n->avl_balance = 0;
if (y == NULL)
return &n->avl_data;
for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++)
if (da[k] == 0)
p->avl_balance--;
else
p->avl_balance++;
if (y->avl_balance == -2)
{
struct avl_node *x = y->avl_link[0];
if (x->avl_balance == -1)
{
w = x;
y->avl_link[0] = x->avl_link[1];
x->avl_link[1] = y;
x->avl_balance = y->avl_balance = 0;
}
else
{
assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
w->avl_link[0] = x;
y->avl_link[0] = w->avl_link[1];
w->avl_link[1] = y;
if (w->avl_balance == -1)
x->avl_balance = 0, y->avl_balance = +1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == +1| */
x->avl_balance = -1, y->avl_balance = 0;
w->avl_balance = 0;
}
}
else if (y->avl_balance == +2)
{
struct avl_node *x = y->avl_link[1];
if (x->avl_balance == +1)
{
w = x;
y->avl_link[1] = x->avl_link[0];
x->avl_link[0] = y;
x->avl_balance = y->avl_balance = 0;
}
else
{
assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
w->avl_link[1] = x;
y->avl_link[1] = w->avl_link[0];
w->avl_link[0] = y;
if (w->avl_balance == +1)
x->avl_balance = 0, y->avl_balance = -1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == -1| */
x->avl_balance = +1, y->avl_balance = 0;
w->avl_balance = 0;
}
}
else
return &n->avl_data;
z->avl_link[y != z->avl_link[0]] = w;
tree->avl_generation++;
return &n->avl_data;
}
/* Inserts |item| into |table|.
Returns |NULL| if |item| was successfully inserted
or if a memory allocation error occurred.
Otherwise, returns the duplicate item. */
void *
avl_insert (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
return p == NULL || *p == item ? NULL : *p;
}
/* Inserts |item| into |table|, replacing any duplicate item.
Returns |NULL| if |item| was inserted without replacing a duplicate,
or if a memory allocation error occurred.
Otherwise, returns the item that was replaced. */
void *
avl_replace (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
if (p == NULL || *p == item)
return NULL;
else
{
void *r = *p;
*p = item;
return r;
}
}
/* Deletes from |tree| and returns an item matching |item|.
Returns a null pointer if no matching item found. */
void *
avl_delete (struct avl_table *tree, const void *item)
{
/* Stack of nodes. */
struct avl_node *pa[AVL_MAX_HEIGHT]; /* Nodes. */
unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */
int k; /* Stack pointer. */
struct avl_node *p; /* Traverses tree to find node to delete. */
int cmp; /* Result of comparison between |item| and |p|. */
assert (tree != NULL && item != NULL);
k = 0;
p = (struct avl_node *) &tree->avl_root;
for (cmp = -1; cmp != 0;
cmp = tree->avl_compare (item, p->avl_data, tree->avl_param))
{
int dir = cmp > 0;
pa[k] = p;
da[k++] = dir;
p = p->avl_link[dir];
if (p == NULL)
return NULL;
}
item = p->avl_data;
if (p->avl_link[1] == NULL)
pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];
else
{
struct avl_node *r = p->avl_link[1];
if (r->avl_link[0] == NULL)
{
r->avl_link[0] = p->avl_link[0];
r->avl_balance = p->avl_balance;
pa[k - 1]->avl_link[da[k - 1]] = r;
da[k] = 1;
pa[k++] = r;
}
else
{
struct avl_node *s;
int j = k++;
for (;;)
{
da[k] = 0;
pa[k++] = r;
s = r->avl_link[0];
if (s->avl_link[0] == NULL)
break;
r = s;
}
s->avl_link[0] = p->avl_link[0];
r->avl_link[0] = s->avl_link[1];
s->avl_link[1] = p->avl_link[1];
s->avl_balance = p->avl_balance;
pa[j - 1]->avl_link[da[j - 1]] = s;
da[j] = 1;
pa[j] = s;
}
}
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
assert (k > 0);
while (--k > 0)
{
struct avl_node *y = pa[k];
if (da[k] == 0)
{
y->avl_balance++;
if (y->avl_balance == +1)
break;
else if (y->avl_balance == +2)
{
struct avl_node *x = y->avl_link[1];
if (x->avl_balance == -1)
{
struct avl_node *w;
assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
w->avl_link[1] = x;
y->avl_link[1] = w->avl_link[0];
w->avl_link[0] = y;
if (w->avl_balance == +1)
x->avl_balance = 0, y->avl_balance = -1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == -1| */
x->avl_balance = +1, y->avl_balance = 0;
w->avl_balance = 0;
pa[k - 1]->avl_link[da[k - 1]] = w;
}
else
{
y->avl_link[1] = x->avl_link[0];
x->avl_link[0] = y;
pa[k - 1]->avl_link[da[k - 1]] = x;
if (x->avl_balance == 0)
{
x->avl_balance = -1;
y->avl_balance = +1;
break;
}
else
x->avl_balance = y->avl_balance = 0;
}
}
}
else
{
y->avl_balance--;
if (y->avl_balance == -1)
break;
else if (y->avl_balance == -2)
{
struct avl_node *x = y->avl_link[0];
if (x->avl_balance == +1)
{
struct avl_node *w;
assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
w->avl_link[0] = x;
y->avl_link[0] = w->avl_link[1];
w->avl_link[1] = y;
if (w->avl_balance == -1)
x->avl_balance = 0, y->avl_balance = +1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == +1| */
x->avl_balance = -1, y->avl_balance = 0;
w->avl_balance = 0;
pa[k - 1]->avl_link[da[k - 1]] = w;
}
else
{
y->avl_link[0] = x->avl_link[1];
x->avl_link[1] = y;
pa[k - 1]->avl_link[da[k - 1]] = x;
if (x->avl_balance == 0)
{
x->avl_balance = +1;
y->avl_balance = -1;
break;
}
else
x->avl_balance = y->avl_balance = 0;
}
}
}
}
tree->avl_count--;
tree->avl_generation++;
return (void *) item;
}
/* Refreshes the stack of parent pointers in |trav|
and updates its generation number. */
static void
trav_refresh (struct avl_traverser *trav)
{
assert (trav != NULL);
trav->avl_generation = trav->avl_table->avl_generation;
if (trav->avl_node != NULL)
{
avl_comparison_func *cmp = trav->avl_table->avl_compare;
void *param = trav->avl_table->avl_param;
struct avl_node *node = trav->avl_node;
struct avl_node *i;
trav->avl_height = 0;
for (i = trav->avl_table->avl_root; i != node; )
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
assert (i != NULL);
trav->avl_stack[trav->avl_height++] = i;
i = i->avl_link[cmp (node->avl_data, i->avl_data, param) > 0];
}
}
}
/* Initializes |trav| for use with |tree|
and selects the null node. */
void
avl_t_init (struct avl_traverser *trav, struct avl_table *tree)
{
trav->avl_table = tree;
trav->avl_node = NULL;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its least-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
avl_t_first (struct avl_traverser *trav, struct avl_table *tree)
{
struct avl_node *x;
assert (tree != NULL && trav != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
x = tree->avl_root;
if (x != NULL)
while (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
}
trav->avl_node = x;
return x != NULL ? x->avl_data : NULL;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its greatest-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
avl_t_last (struct avl_traverser *trav, struct avl_table *tree)
{
struct avl_node *x;
assert (tree != NULL && trav != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
x = tree->avl_root;
if (x != NULL)
while (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
}
trav->avl_node = x;
return x != NULL ? x->avl_data : NULL;
}
/* Searches for |item| in |tree|.
If found, initializes |trav| to the item found and returns the item
as well.
If there is no matching item, initializes |trav| to the null item
and returns |NULL|. */
void *
avl_t_find (struct avl_traverser *trav, struct avl_table *tree, void *item)
{
struct avl_node *p, *q;
assert (trav != NULL && tree != NULL && item != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
for (p = tree->avl_root; p != NULL; p = q)
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp < 0)
q = p->avl_link[0];
else if (cmp > 0)
q = p->avl_link[1];
else /* |cmp == 0| */
{
trav->avl_node = p;
return p->avl_data;
}
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = p;
}
trav->avl_height = 0;
trav->avl_node = NULL;
return NULL;
}
/* Attempts to insert |item| into |tree|.
If |item| is inserted successfully, it is returned and |trav| is
initialized to its location.
If a duplicate is found, it is returned and |trav| is initialized to
its location. No replacement of the item occurs.
If a memory allocation failure occurs, |NULL| is returned and |trav|
is initialized to the null item. */
void *
avl_t_insert (struct avl_traverser *trav, struct avl_table *tree, void *item)
{
void **p;
assert (trav != NULL && tree != NULL && item != NULL);
p = avl_probe (tree, item);
if (p != NULL)
{
trav->avl_table = tree;
trav->avl_node =
((struct avl_node *)
((char *) p - offsetof (struct avl_node, avl_data)));
trav->avl_generation = tree->avl_generation - 1;
return *p;
}
else
{
avl_t_init (trav, tree);
return NULL;
}
}
/* Initializes |trav| to have the same current node as |src|. */
void *
avl_t_copy (struct avl_traverser *trav, const struct avl_traverser *src)
{
assert (trav != NULL && src != NULL);
if (trav != src)
{
trav->avl_table = src->avl_table;
trav->avl_node = src->avl_node;
trav->avl_generation = src->avl_generation;
if (trav->avl_generation == trav->avl_table->avl_generation)
{
trav->avl_height = src->avl_height;
memcpy (trav->avl_stack, (const void *) src->avl_stack,
sizeof *trav->avl_stack * trav->avl_height);
}
}
return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
}
/* Returns the next data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
avl_t_next (struct avl_traverser *trav)
{
struct avl_node *x;
assert (trav != NULL);
if (trav->avl_generation != trav->avl_table->avl_generation)
trav_refresh (trav);
x = trav->avl_node;
if (x == NULL)
{
return avl_t_first (trav, trav->avl_table);
}
else if (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
while (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
}
}
else
{
struct avl_node *y;
do
{
if (trav->avl_height == 0)
{
trav->avl_node = NULL;
return NULL;
}
y = x;
x = trav->avl_stack[--trav->avl_height];
}
while (y == x->avl_link[1]);
}
trav->avl_node = x;
return x->avl_data;
}
/* Returns the previous data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
avl_t_prev (struct avl_traverser *trav)
{
struct avl_node *x;
assert (trav != NULL);
if (trav->avl_generation != trav->avl_table->avl_generation)
trav_refresh (trav);
x = trav->avl_node;
if (x == NULL)
{
return avl_t_last (trav, trav->avl_table);
}
else if (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
while (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
}
}
else
{
struct avl_node *y;
do
{
if (trav->avl_height == 0)
{
trav->avl_node = NULL;
return NULL;
}
y = x;
x = trav->avl_stack[--trav->avl_height];
}
while (y == x->avl_link[0]);
}
trav->avl_node = x;
return x->avl_data;
}
/* Returns |trav|'s current item. */
void *
avl_t_cur (struct avl_traverser *trav)
{
assert (trav != NULL);
return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
}
/* Replaces the current item in |trav| by |new| and returns the item replaced.
|trav| must not have the null item selected.
The new item must not upset the ordering of the tree. */
void *
avl_t_replace (struct avl_traverser *trav, void *new)
{
void *old;
assert (trav != NULL && trav->avl_node != NULL && new != NULL);
old = trav->avl_node->avl_data;
trav->avl_node->avl_data = new;
return old;
}
static void
copy_error_recovery (struct avl_node **stack, int height,
struct avl_table *new, avl_item_func *destroy)
{
assert (stack != NULL && height >= 0 && new != NULL);
for (; height > 2; height -= 2)
stack[height - 1]->avl_link[1] = NULL;
avl_destroy (new, destroy);
}
/* Copies |org| to a newly created tree, which is returned.
If |copy != NULL|, each data item in |org| is first passed to |copy|,
and the return values are inserted into the tree,
with |NULL| return values taken as indications of failure.
On failure, destroys the partially created new tree,
applying |destroy|, if non-null, to each item in the new tree so far,
and returns |NULL|.
If |allocator != NULL|, it is used for allocation in the new tree.
Otherwise, the same allocator used for |org| is used. */
struct avl_table *
avl_copy (const struct avl_table *org, avl_copy_func *copy,
avl_item_func *destroy, struct libavl_allocator *allocator)
{
struct avl_node *stack[2 * (AVL_MAX_HEIGHT + 1)];
int height = 0;
struct avl_table *new;
const struct avl_node *x;
struct avl_node *y;
assert (org != NULL);
new = avl_create (org->avl_compare, org->avl_param,
allocator != NULL ? allocator : org->avl_alloc);
if (new == NULL)
return NULL;
new->avl_count = org->avl_count;
if (new->avl_count == 0)
return new;
x = (const struct avl_node *) &org->avl_root;
y = (struct avl_node *) &new->avl_root;
for (;;)
{
while (x->avl_link[0] != NULL)
{
assert (height < 2 * (AVL_MAX_HEIGHT + 1));
y->avl_link[0] =
new->avl_alloc->libavl_malloc (new->avl_alloc,
sizeof *y->avl_link[0]);
if (y->avl_link[0] == NULL)
{
if (y != (struct avl_node *) &new->avl_root)
{
y->avl_data = NULL;
y->avl_link[1] = NULL;
}
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
stack[height++] = (struct avl_node *) x;
stack[height++] = y;
x = x->avl_link[0];
y = y->avl_link[0];
}
y->avl_link[0] = NULL;
for (;;)
{
y->avl_balance = x->avl_balance;
if (copy == NULL)
y->avl_data = x->avl_data;
else
{
y->avl_data = copy (x->avl_data, org->avl_param);
if (y->avl_data == NULL)
{
y->avl_link[1] = NULL;
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
}
if (x->avl_link[1] != NULL)
{
y->avl_link[1] =
new->avl_alloc->libavl_malloc (new->avl_alloc,
sizeof *y->avl_link[1]);
if (y->avl_link[1] == NULL)
{
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
x = x->avl_link[1];
y = y->avl_link[1];
break;
}
else
y->avl_link[1] = NULL;
if (height <= 2)
return new;
y = stack[--height];
x = stack[--height];
}
}
}
/* Frees storage allocated for |tree|.
If |destroy != NULL|, applies it to each data item in inorder. */
void
avl_destroy (struct avl_table *tree, avl_item_func *destroy)
{
struct avl_node *p, *q;
assert (tree != NULL);
for (p = tree->avl_root; p != NULL; p = q)
if (p->avl_link[0] == NULL)
{
q = p->avl_link[1];
if (destroy != NULL && p->avl_data != NULL)
destroy (p->avl_data, tree->avl_param);
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
}
else
{
q = p->avl_link[0];
p->avl_link[0] = q->avl_link[1];
q->avl_link[1] = p;
}
tree->avl_alloc->libavl_free (tree->avl_alloc, tree);
}
/* Allocates |size| bytes of space using |malloc()|.
Returns a null pointer if allocation fails. */
void *
avl_malloc (struct libavl_allocator *allocator, size_t size)
{
assert (allocator != NULL && size > 0);
return malloc (size);
}
/* Frees |block|. */
void
avl_free (struct libavl_allocator *allocator, void *block)
{
assert (allocator != NULL && block != NULL);
free (block);
}
/* Default memory allocator that uses |malloc()| and |free()|. */
struct libavl_allocator avl_allocator_default =
{
avl_malloc,
avl_free
};
#undef NDEBUG
#include <assert.h>
/* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */
void
(avl_assert_insert) (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
assert (p != NULL && *p == item);
}
/* Asserts that |avl_delete()| really removes |item| from |table|,
and returns the removed item. */
void *
(avl_assert_delete) (struct avl_table *table, void *item)
{
void *p = avl_delete (table, item);
assert (p != NULL);
return p;
}
-115
View File
@@ -1,115 +0,0 @@
/* Produced by texiweb from libavl.w on 2002/08/24 at 13:21. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
The author may be contacted at <blp@gnu.org> on the Internet, or
write to Ben Pfaff, Stanford University, Computer Science Dept., 353
Serra Mall, Stanford CA 94305, USA.
*/
#ifndef AVL_H
#define AVL_H 1
#include <stddef.h>
/* Function types. */
typedef int avl_comparison_func (const void *avl_a, const void *avl_b,
void *avl_param);
typedef void avl_item_func (void *avl_item, void *avl_param);
typedef void *avl_copy_func (void *avl_item, void *avl_param);
#ifndef LIBAVL_ALLOCATOR
#define LIBAVL_ALLOCATOR
/* Memory allocator. */
struct libavl_allocator
{
void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
};
#endif
/* Default memory allocator. */
extern struct libavl_allocator avl_allocator_default;
void *avl_malloc (struct libavl_allocator *, size_t);
void avl_free (struct libavl_allocator *, void *);
/* Maximum AVL height. */
#ifndef AVL_MAX_HEIGHT
#define AVL_MAX_HEIGHT 32
#endif
/* Tree data structure. */
struct avl_table
{
struct avl_node *avl_root; /* Tree's root. */
avl_comparison_func *avl_compare; /* Comparison function. */
void *avl_param; /* Extra argument to |avl_compare|. */
struct libavl_allocator *avl_alloc; /* Memory allocator. */
size_t avl_count; /* Number of items in tree. */
unsigned long avl_generation; /* Generation number. */
};
/* An AVL tree node. */
struct avl_node
{
struct avl_node *avl_link[2]; /* Subtrees. */
void *avl_data; /* Pointer to data. */
signed char avl_balance; /* Balance factor. */
};
/* AVL traverser structure. */
struct avl_traverser
{
struct avl_table *avl_table; /* Tree being traversed. */
struct avl_node *avl_node; /* Current node in tree. */
struct avl_node *avl_stack[AVL_MAX_HEIGHT];
/* All the nodes above |avl_node|. */
size_t avl_height; /* Number of nodes in |avl_parent|. */
unsigned long avl_generation; /* Generation number. */
};
/* Table functions. */
struct avl_table *avl_create (avl_comparison_func *, void *,
struct libavl_allocator *);
struct avl_table *avl_copy (const struct avl_table *, avl_copy_func *,
avl_item_func *, struct libavl_allocator *);
void avl_destroy (struct avl_table *, avl_item_func *);
void **avl_probe (struct avl_table *, void *);
void *avl_insert (struct avl_table *, void *);
void *avl_replace (struct avl_table *, void *);
void *avl_delete (struct avl_table *, const void *);
void *avl_find (const struct avl_table *, const void *);
void avl_assert_insert (struct avl_table *, void *);
void *avl_assert_delete (struct avl_table *, void *);
#define avl_count(table) ((size_t) (table)->avl_count)
/* Table traverser functions. */
void avl_t_init (struct avl_traverser *, struct avl_table *);
void *avl_t_first (struct avl_traverser *, struct avl_table *);
void *avl_t_last (struct avl_traverser *, struct avl_table *);
void *avl_t_find (struct avl_traverser *, struct avl_table *, void *);
void *avl_t_insert (struct avl_traverser *, struct avl_table *, void *);
void *avl_t_copy (struct avl_traverser *, const struct avl_traverser *);
void *avl_t_next (struct avl_traverser *);
void *avl_t_prev (struct avl_traverser *);
void *avl_t_cur (struct avl_traverser *);
void *avl_t_replace (struct avl_traverser *, void *);
#endif /* avl.h */
-22
View File
@@ -1,22 +0,0 @@
COMPILE
=======
On Max OS X:
$gcc -o tree2PS-fast -fast avl.c tree2ps.c
On Linux:
Insert the following near the top of tree2ps.c
#define isnumber (c) ( (c>='0') && (c<='9'))
Replace -fast with -O3 (the letter 'O'):
$gcc -o tree2PS-fast -O3 avl.c tree2ps.c
INSTALL
=======
Place the binary into a directory that is listed in setup_paths.sh script located in the root of Galaxy installation
-961
View File
@@ -1,961 +0,0 @@
#include "avl.h"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#define DEFAULT_STRING_ALLOC 16L
#define NUMBER_OF_TAX_FIELDS 22
char *rankLabels [NUMBER_OF_TAX_FIELDS] =
{"root" ,
"superkingdom",
"kingdom" ,
"subkingdom" ,
"superphylum" ,
"phylum" ,
"subphylum" ,
"superclass" ,
"class" ,
"subclass" ,
"superorder" ,
"order" ,
"suborder" ,
"superfamily" ,
"family" ,
"subfamily" ,
"tribe" ,
"subtribe" ,
"genus" ,
"subgenus" ,
"species" ,
"subspecies"
};
static char *const Usage = "tree2ps newick_file ps_output_file max_tree_level (<=0 to show all levels) font_size (in 2-255, 8 is a good default) \nmax_leaves (<=0 to show all) count_duplicate_tax_id (0 or 1; with 0 multiple copies of the same taxid count as 1)\n";
char validTaxonNameChar[256];
long fontSize = 8,
showMaxNodes = 0;
double ySpacing,
xPadding,
globalXPad,
globalYPad,
lineWidth = 2.,
countScaler;
char countDuplicateTaxID = 0;
/*---------------------------------------------------------------------------------------------------- */
double _timesCharWidths[256]= // Hardcoded relative widths of all 255 characters in the Times font, for the use of PSTreeString
{
0,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0,0.25098,0.721569,0.721569,0.721569,0,0.721569,0.721569,
0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0.721569,0,0.721569,0.721569,
0.25098,0.333333,0.407843,0.501961,0.501961,0.831373,0.776471,0.180392,0.333333,0.333333,0.501961,0.564706,0.25098,0.333333,0.25098,0.278431,
0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.278431,0.278431,0.564706,0.564706,0.564706,0.443137,
0.921569,0.721569,0.666667,0.666667,0.721569,0.611765,0.556863,0.721569,0.721569,0.333333,0.388235,0.721569,0.611765,0.890196,0.721569,0.721569,
0.556863,0.721569,0.666667,0.556863,0.611765,0.721569,0.721569,0.945098,0.721569,0.721569,0.611765,0.333333,0.278431,0.333333,0.470588,0.501961,
0.333333,0.443137,0.501961,0.443137,0.501961,0.443137,0.333333,0.501961,0.501961,0.278431,0.278431,0.501961,0.278431,0.776471,0.501961,0.501961,
0.501961,0.501961,0.333333,0.388235,0.278431,0.501961,0.501961,0.721569,0.501961,0.501961,0.443137,0.478431,0.2,0.478431,0.541176,0.721569,
0.721569,0.721569,0.666667,0.611765,0.721569,0.721569,0.721569,0.443137,0.443137,0.443137,0.443137,0.443137,0.443137,0.443137,0.443137,0.443137,
0.443137,0.443137,0.278431,0.278431,0.278431,0.278431,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,0.501961,
0.501961,0.4,0.501961,0.501961,0.501961,0.34902,0.454902,0.501961,0.760784,0.760784,0.980392,0.333333,0.333333,0.54902,0.890196,0.721569,
0.713725,0.54902,0.54902,0.54902,0.501961,0.576471,0.494118,0.713725,0.823529,0.54902,0.27451,0.27451,0.309804,0.768627,0.666667,0.501961,
0.443137,0.333333,0.564706,0.54902,0.501961,0.54902,0.611765,0.501961,0.501961,1,0.25098,0.721569,0.721569,0.721569,0.890196,0.721569,
0.501961,1,0.443137,0.443137,0.333333,0.333333,0.54902,0.494118,0.501961,0.721569,0.168627,0.745098,0.333333,0.333333,0.556863,0.556863,
0.501961,0.25098,0.333333,0.443137,1,0.721569,0.611765,0.721569,0.611765,0.611765,0.333333,0.333333,0.333333,0.333333,0.721569,0.721569,
0.788235,0.721569,0.721569,0.721569,0.721569,0.278431,0.333333,0.333333,0.333333,0.333333,0.333333,0.333333,0.333333,0.333333,0.333333,0.333333
},
_maxTimesCharWidth = 0.980392;
/*---------------------------------------------------------------------------------------------------- */
void check_pointer (void*);
/*---------------------------------------------------------------------------------------------------- */
struct avl_table * uniqueTags = NULL;
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString
{
char *sData;
long sLength,
saLength;
}
*globalNameBuffer;
/*---------------------------------------------------------------------------------------------------- */
struct vector
{
long *vData;
long vLength,
vaLength;
} * treeLabelWidths,
* nodeCountsByLevel,
* leafCountsByLevel;
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString *allocateNewString (void)
{
struct bufferedString *newS = (struct bufferedString*)malloc (sizeof (struct bufferedString));
check_pointer (newS);
check_pointer (newS->sData = (char*)malloc (DEFAULT_STRING_ALLOC+1));
newS->sLength = 0;
newS->saLength = DEFAULT_STRING_ALLOC;
newS->sData[0] = 0;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
struct vector *allocateNewVector (void)
{
struct vector *newS = (struct vector*)malloc (sizeof (struct vector));
check_pointer (newS);
check_pointer (newS->vData = (long*)malloc (DEFAULT_STRING_ALLOC*sizeof(long)));
newS->vLength = 0;
newS->vaLength = DEFAULT_STRING_ALLOC;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
void clear_buffered_string (struct bufferedString* theString)
{
theString->sLength = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void clear_vector (struct vector* v)
{
v->vLength = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void reportError (FILE* f,const char * err, long cci)
{
char buffer[33];
fprintf (stderr, "ERROR: %s. Tree string position %d\n", err, cci);
fprintf (stderr, "?");
buffer[fread (buffer,1,32,f)] = 0;
fprintf (stderr, "%s\n", buffer);
exit (1);
}
/*---------------------------------------------------------------------------------------------------- */
void appendCharacterToString (struct bufferedString * s, const char c)
{
long addThis;
if (s->saLength == s->sLength)
{
addThis = s->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
s->saLength += addThis;
check_pointer (s->sData = realloc (s->sData,s->saLength+1));
}
s->sData[s->sLength] = c;
s->sData[++s->sLength] = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void appendValueToVector (struct vector * v, long c)
{
long addThis;
if (v->vaLength == v->vLength)
{
addThis = v->vaLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
v->vaLength += addThis;
check_pointer (v->vData = realloc (v->vData,sizeof(long)*v->vaLength));
}
v->vData[v->vLength++] = c;
}
/*---------------------------------------------------------------------------------------------------- */
long popValueFromVector (struct vector * v)
{
if (v->vLength)
return v->vData[--v->vLength];
return 0;
}
/*---------------------------------------------------------------------------------------------------- */
long appendRangeToString (struct bufferedString * d, struct bufferedString *s, long from, long to)
{
long addThis,
pl = to-from+1;
if (pl<=0)
return -1;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = from; addThis <=to; addThis++)
d->sData[d->sLength++] = s->sData[addThis];
d->sData[d->sLength] = 0;
return pl;
}
/*---------------------------------------------------------------------------------------------------- */
void appendCharRangeToString (struct bufferedString * d, char * buffer)
{
long addThis,
pl = strlen(buffer);
if (pl<=0)
return;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = 0; addThis <pl; addThis++)
d->sData[d->sLength++] = buffer[addThis];
d->sData[d->sLength] = 0;
}
/*---------------------------------------------------------------------------------------------------- */
long appendCharBufferToString (struct bufferedString * d, const char * b)
{
long addThis,
pl = strlen (b);
if (pl<=0)
return -1;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = 0; addThis <pl; addThis++)
d->sData[d->sLength++] = b[addThis];
d->sData[d->sLength] = 0;
return pl;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
struct treeNode
{
struct treeNode * parent;
long startIndex,
hitCount,
childrenCount,
length;
struct vector * children;
} *globalTreeRoot;
/*---------------------------------------------------------------------------------------------------- */
struct treeNode * allocateNewTreeNode (void)
{
struct treeNode *newN = (struct treeNode*)malloc (sizeof (struct treeNode));
check_pointer (newN);
newN->parent = NULL;
newN->startIndex = 0;
newN->length = 0;
newN->hitCount = 0;
newN->childrenCount = 0;
newN->children = allocateNewVector();
check_pointer (newN->children);
return newN;
}
/*---------------------------------------------------------------------------------------------------- */
void addAChild (struct treeNode* p, struct treeNode * c)
{
long i = 0;
for (; i<p->children->vLength; i++)
if (((struct treeNode**)p->children->vData)[i] == c)
break;
if (p->children->vLength == i)
{
appendValueToVector (p->children, (long)c);
c->parent = p;
}
}
/*---------------------------------------------------------------------------------------------------- */
void destroyTreeNode (struct treeNode* n)
{
free (n->children);
free (n);
}
/*---------------------------------------------------------------------------------------------------- */
long traverseTree (struct treeNode* n, long maxDepth, long currentDepth, long* height, long *depth)
{
long i = 0;
double w = 0.;
char buffer[255];
if (currentDepth <= maxDepth)
{
if (currentDepth > *depth)
*depth = currentDepth;
if (currentDepth >= treeLabelWidths->vLength)
{
appendValueToVector (treeLabelWidths, 0);
appendValueToVector (nodeCountsByLevel,0);
appendValueToVector (leafCountsByLevel,0);
}
if (n->children->vLength)
{
nodeCountsByLevel->vData[currentDepth] ++;
//fprintf (stdout, "%d %d %d\n", currentDepth, maxDepth, *height);
if (currentDepth == maxDepth)
(*height) ++;
for (i=0; i<n->children->vLength; i++)
n->childrenCount += traverseTree (((struct treeNode**)n->children->vData)[i], maxDepth, currentDepth+1,height,depth);
}
else
{
leafCountsByLevel->vData[currentDepth] ++;
(*height) ++;
n->childrenCount = countDuplicateTaxID?n->hitCount:1;
}
sprintf (buffer,":%d", n->childrenCount);
for (i=0; i<n->length; i++)
w += _timesCharWidths[*(globalNameBuffer->sData + n->startIndex + i)];
for (i=0; buffer[i]; i++)
w += _timesCharWidths[buffer[i]];
w *= fontSize;
w += 0.5;
if (w > treeLabelWidths->vData[currentDepth])
treeLabelWidths->vData[currentDepth] = w;
}
else
{
if (n->children->vLength)
for (i=0; i<n->children->vLength; i++)
n->childrenCount += traverseTree (((struct treeNode**)n->children->vData)[i], maxDepth, currentDepth+1,height,depth);
else
n->childrenCount = countDuplicateTaxID?n->hitCount:1;
}
return n->childrenCount;
}
/*---------------------------------------------------------------------------------------------------- */
void drawGradient (FILE* f, double left, double top, double right, double bottom)
{
double color = 0.,
step = 1./(right-left),
i = left;
fprintf (f, "currentlinewidth 1 setlinewidth \n");
for (i=left; i<right; i+=1.0)
{
color = step*(i-left);
fprintf (f, "%g %g %g setrgbcolor \n", 1.-color*color*color, 0.5*color, color );
fprintf (f, "newpath %g %g moveto %g %g lineto stroke\n",i,top,i,bottom);
}
fprintf (f, "0 0 0 setrgbcolor %g %g %g %g rectstroke setlinewidth\n",left, top, right-left, bottom-top);
fprintf (f, "%g %g (100\\%%) centertext\n", left, bottom - fontSize-2);
fprintf (f, "%g %g (50\\%%) centertext\n", 0.5*(left+right), bottom - fontSize-2);
fprintf (f, "%g %g (0\\%%) centertext\n", right, bottom - fontSize-2);
}
/*---------------------------------------------------------------------------------------------------- */
void drawPSLine (FILE* f, double left, double top, double right, double bottom, double lineWidth, double color)
{
//color = sin(color*0.5*3.14);
fprintf (f, "%g %g %g setrgbcolor \n", 1.-color*color*color, 0.5*color, color);
if (lineWidth > 0.)
fprintf (f, "%g setlinewidth ");
fprintf (f, "newpath %g %g moveto %g %g lineto stroke\n",left,top,right,bottom);
}
/*---------------------------------------------------------------------------------------------------- */
void drawTextInAbox (FILE* f, long from, long to, long childrenCount, double x, double y)
{
long i;
fprintf (f, "newpath %g %g moveto (", x,y);
if (from>=0)
for (i=from; i<to; i++)
fputc (globalNameBuffer->sData[i],f);
else
fprintf (f,"N/A");
fprintf (f, ":%d) drawletter\n", childrenCount);
}
/*---------------------------------------------------------------------------------------------------- */
void drawTextInAbox2 (FILE* f, long splits, long childrenCount, long level, double x, double y)
{
long i;
fprintf (f, "newpath %g %g moveto (%d %s", x,y, splits, level<NUMBER_OF_TAX_FIELDS?rankLabels[level]:"n/a");
fprintf (f, ":%d) drawletter2\n", childrenCount);
}
/*---------------------------------------------------------------------------------------------------- */
double traverseTreePS (FILE* f, struct treeNode* n, long maxDepth, long currentDepth, double parentX, double* currentLeafY, double* childX)
{
double myX,
myY,
minChildY = 0.,
maxChildY = 0.,
t;
long i;
if (currentDepth <= maxDepth)
{
if (currentDepth)
myX = parentX + treeLabelWidths->vData[currentDepth-1] + xPadding;
else
myX = parentX;
if (n->children->vLength && maxDepth > currentDepth)
{
minChildY = traverseTreePS (f,((struct treeNode**)n->children->vData)[0], maxDepth, currentDepth+1,myX,currentLeafY,&t);
drawPSLine (f, myX, minChildY, t, minChildY,-1., 1. - ((struct treeNode**)n->children->vData)[0]->childrenCount * countScaler);
for (i=1; i<n->children->vLength-1; i++)
{
maxChildY = traverseTreePS (f,((struct treeNode**)n->children->vData)[i], maxDepth, currentDepth+1,myX,currentLeafY,&t);
drawPSLine (f, myX, maxChildY, t, maxChildY,-1.,1. - ((struct treeNode**)n->children->vData)[i]->childrenCount * countScaler);
}
if (i<n->children->vLength)
{
maxChildY = traverseTreePS(f,((struct treeNode**)n->children->vData)[i], maxDepth, currentDepth+1,myX,currentLeafY,&t);
drawPSLine (f, myX, maxChildY, t, maxChildY,-1.,1. - ((struct treeNode**)n->children->vData)[i]->childrenCount * countScaler);
}
else
maxChildY = minChildY;
if (maxChildY > minChildY)
{
drawPSLine (f, myX, minChildY, myX, maxChildY,-1.,1.-n->childrenCount * countScaler);
}
myY = (minChildY+maxChildY)*0.5;
}
else
{
myY = *currentLeafY;
*currentLeafY += ySpacing;
}
//fprintf (stdout, "%d %d\n", n->startIndex, n->length);
if (!(n->length == 1 && globalNameBuffer->sData[n->startIndex] == 'n'))
drawTextInAbox (f, n->startIndex, n->startIndex+n->length, n->childrenCount, myX, myY-fontSize/2);
else
{
if (n->children->vLength)
{
if (currentDepth == maxDepth)
{
i = currentDepth;
while (n->children->vLength == 1)
{
n = ((struct treeNode**)n->children->vData)[0];
i++;
}
if (!(n->length == 1 && globalNameBuffer->sData[n->startIndex] == 'n'))
drawTextInAbox (f, n->startIndex, n->startIndex+n->length, n->childrenCount, myX, myY-fontSize/2);
else
drawTextInAbox2 (f, n->children->vLength, n->childrenCount, i, myX, myY-fontSize/2);
}
}
else
drawTextInAbox (f, -1, 0, n->childrenCount, myX, myY-fontSize/2);
}
}
*childX = myX;
return myY;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
struct storedSequenceTag
{
long startIndex,
length;
};
/*---------------------------------------------------------------------------------------------------- */
struct storedSequenceTag *allocateStringTag (void)
{
struct storedSequenceTag *newS = (struct storedSequenceTag*)malloc (sizeof (struct storedSequenceTag));
check_pointer (newS);
newS->startIndex = -1;
newS->length = 0;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
int compare_tags (const void *avl_a, const void *avl_b, void * xtra)
{
char* n1 = globalNameBuffer->sData+((struct storedSequenceTag*)avl_a)->startIndex,
* n2 = globalNameBuffer->sData+((struct storedSequenceTag*)avl_b)->startIndex;
long l1 = ((struct storedSequenceTag*)avl_a)->length,
l2 = ((struct storedSequenceTag*)avl_b)->length,
i;
signed char c;
for (i = 0; i < l1 && i < l2; i++)
{
c = n1[i] - n2[i];
if (c < 0)
return -1;
if (c>0)
return 1;
}
if (l1 < l2)
return -1;
if (l1 > l2)
return 1;
return 0;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
void check_pointer (void * p)
{
if (p == NULL)
{
fprintf (stderr,"Memory allocation error\n");
exit (1);
}
}
/*---------------------------------------------------------------------------------------------------- */
int compare_strings (const struct bufferedString * s1, const struct bufferedString * s2)
{
long upTo,
i;
if (s1->sLength>s2->sLength)
upTo = s2->sLength;
else
upTo = s1->sLength;
for (i=0; i<upTo; i++)
{
int res = (s1->sData[i]-s2->sData[i]);
if (res < 0)
return -1;
else
if (res>0)
return 1;
}
if (s1->sLength == s2->sLength)
return 0;
return 1-2*(s1->sLength<s2->sLength);
}
/*---------------------------------------------------------------------------------------------------- */
void destroy_string (struct bufferedString* aStr)
{
free (aStr->sData);
free (aStr);
}
/*---------------------------------------------------------------------------------------------------- */
int main (int argc, const char * argv[])
{
struct storedSequenceTag *sTag = allocateStringTag(),
*sTag2 = allocateStringTag(),
*sTag3;
struct avl_traverser avlt;
struct treeNode *currentParent = NULL,
*currentNode;
struct vector *nodeStack = allocateNewVector();
char automatonState = 0,
currentChar = 0,
buffa [255];
double Ycoord = 0.0,
Xcoord = 0.0,
t;
long currentCharID = 0,
indexer,
indexer2,
indexer3,
maxTreeLevel = 0,
branchWeight = 0;
FILE * psFile = NULL,
* inFile = NULL;
globalNameBuffer = allocateNewString();
check_pointer (uniqueTags = avl_create (compare_tags, NULL, NULL));
for (indexer = 0; indexer < 256; indexer ++)
validTaxonNameChar[indexer] = 1;
validTaxonNameChar[','] = 0;
validTaxonNameChar[')'] = 0;
validTaxonNameChar['('] = 0;
validTaxonNameChar[':'] = 0;
if (argc != 7)
{
fprintf (stderr,"%s",Usage);
return 1;
}
maxTreeLevel = atoi (argv[3]);
if (maxTreeLevel < 1)
maxTreeLevel = 0xfffffffL;
inFile = fopen (argv[1], "rb");
if (!inFile)
{
fprintf (stderr, "Failed to open the input file %s\n", argv[1]);
return 1;
}
psFile = fopen (argv[2], "wb");
if (!psFile)
{
fprintf (stderr, "Failed to open the tree output file %s\n", argv[2]);
return 1;
}
fontSize = atoi (argv[4]);
if (fontSize < 2)
fontSize = 2;
if (fontSize > 255)
fontSize = 255;
showMaxNodes = atoi (argv[5]);
if (showMaxNodes <= 0)
showMaxNodes = 0x7FFFFFFFL;
countDuplicateTaxID = atoi (argv[6]);
ySpacing = fontSize+2*lineWidth + 5;
xPadding = fontSize*2;
globalXPad = fontSize;
globalYPad = fontSize*3/2;
currentChar = fgetc(inFile);
while (1)
{
currentCharID ++;
//fprintf (stderr, "%d %c %d %d\n", currentCharID, currentChar, automatonState,nodeStack->vLength);
switch (automatonState)
{
case 0: /* waiting for the opening '(' */
if (currentChar == '(')
{
automatonState = 1; /* create new node*/
globalTreeRoot = allocateNewTreeNode();
appendValueToVector (nodeStack, (long)globalTreeRoot);
currentChar = fgetc(inFile);
}
break;
case 1: /* starting node read; first pass */
case 8: /* starting node read */
{
if (currentChar == ',')
{
if (automatonState == 1)
reportError (inFile,"empty first clade node name", currentCharID);
currentNode = allocateNewTreeNode();
appendValueToVector (nodeStack, (long)currentNode);
automatonState = 8;
currentChar = fgetc(inFile);
}
else
{
if (currentChar == ')')
{
automatonState = 2;
currentChar = fgetc(inFile);
}
else
{
if (currentChar == '(')
{
currentNode = allocateNewTreeNode();
appendValueToVector (nodeStack, (long)currentNode);
currentChar = fgetc(inFile);
//automatonState = 1;
}
else
{
if (automatonState == 1)
{
currentNode = allocateNewTreeNode();
appendValueToVector (nodeStack, (long)currentNode);
}
currentCharID--;
automatonState = 2;
}
}
}
break;
}
case 2: /* reading first node character */
{
if (!validTaxonNameChar[currentChar])
reportError (inFile,"empty node name", currentCharID);
sTag->startIndex = globalNameBuffer->sLength;
sTag->length = 1;
appendCharacterToString (globalNameBuffer, currentChar);
automatonState = 3;
currentChar = fgetc(inFile);
}
break;
case 3: /* reading additional node characters */
{
if (validTaxonNameChar[currentChar])
{
sTag->length++;
appendCharacterToString (globalNameBuffer, currentChar);
currentChar = fgetc(inFile);
}
else
{
if (currentChar == ':')
{
automatonState = 4; /* read branch length */
currentChar = fgetc(inFile);
}
else
{
currentCharID--;
if (currentChar == ',' || currentChar == ')')
automatonState = 6; /* finish up a node read */
else
reportError (inFile,"unexpected '(' character following a branch name", currentCharID);
}
}
}
break;
case 4: /* initial read in branch length */
{
if (isnumber (currentChar))
{
automatonState = 5;
sTag2->startIndex = globalNameBuffer->sLength;
sTag2->length = 1;
appendCharacterToString (globalNameBuffer,currentChar);
currentChar = fgetc(inFile);
}
else
reportError (inFile,"expected a digit following ':'", currentCharID);
break;
}
case 5: /* continued read branch length */
{
if (isnumber (currentChar))
{
sTag2->length++;
appendCharacterToString (globalNameBuffer,currentChar);
currentChar = fgetc(inFile);
}
else
{
currentCharID --;
if (currentChar == ',' || currentChar == ')')
automatonState = 6; /* finish up a node read */
else
reportError (inFile,"expected a ',' or a ')' following a branch length", currentCharID);
}
break;
}
case 6: /* create a new node with a name and a branch length */
{
currentNode = (struct treeNode*) popValueFromVector (nodeStack);
if (!currentNode)
reportError (inFile,"incorrect tree structure", currentCharID);
if (sTag2->length)
{
//fprintf (stderr, "%d %s\n", sTag2->length, globalNameBuffer->sData+sTag2->startIndex);
currentNode->hitCount = atoi (globalNameBuffer->sData+sTag2->startIndex);
globalNameBuffer->sLength -= sTag2->length;
globalNameBuffer->sData[globalNameBuffer->sLength] = 0;
}
sTag3 = *(struct storedSequenceTag**)avl_probe (uniqueTags,sTag);
if (sTag == sTag3) // new node
sTag = allocateStringTag();
else
{
//fprintf (stderr, "%d %s\n", sTag->length, globalNameBuffer->sData+sTag->startIndex);
globalNameBuffer->sLength -= sTag->length;
globalNameBuffer->sData[globalNameBuffer->sLength] = 0;
//fprintf (stderr, "Duplicate %s %d %d %d\n", globalNameBuffer->sData,globalNameBuffer->sLength,
// sTag3->startIndex, sTag3->length);
}
currentNode->startIndex = sTag3->startIndex;
currentNode->length = sTag3->length;
if (nodeStack->vLength) // add current node to the parent
addAChild ((struct treeNode*) nodeStack->vData[nodeStack->vLength-1],currentNode);
else
if (currentNode != globalTreeRoot)
reportError (inFile,"imbalanced paretheses: too many closing ')'", currentCharID);
else
//if (feof (inFile))
{
automatonState = 1;
break;
}
currentCharID--;
//currentChar = fgetc(inFile);
automatonState = 8; // go back to reading more nodes
}
break;
}
if (feof (inFile))
if (automatonState == 3 || automatonState == 5)
automatonState = 6;
else
break;
}
if (automatonState != 1)
reportError (inFile,"imbalanced paretheses in the tree", currentCharID);
indexer = 0; indexer2 = 0; indexer3 = 0;
treeLabelWidths = allocateNewVector();
nodeCountsByLevel = allocateNewVector();
leafCountsByLevel = allocateNewVector();
traverseTree (globalTreeRoot, maxTreeLevel, 0, & indexer, & indexer2);
//fprintf (stdout, "Height:%d Depth:%d\n", indexer, indexer2);
Xcoord = 0;
for (indexer3 = 0; indexer3 < treeLabelWidths->vLength; indexer3++)
if (Xcoord < treeLabelWidths->vData[indexer3])
Xcoord = treeLabelWidths->vData[indexer3];
t = 16 * _maxTimesCharWidth * fontSize + 0.5;
if (t>Xcoord)
treeLabelWidths->vData[treeLabelWidths->vLength-1] = t;
else
treeLabelWidths->vData[treeLabelWidths->vLength-1] = Xcoord;
Xcoord = globalXPad;
for (indexer3 = 1; indexer3 < leafCountsByLevel->vLength; indexer3++)
leafCountsByLevel->vData[indexer3] += leafCountsByLevel->vData[indexer3-1];
for (indexer3 = 0; indexer3 < treeLabelWidths->vLength; indexer3++)
{
//fprintf (stdout, "Level %d, nodes %d\n", indexer3, nodeCountsByLevel->vData[indexer3] + leafCountsByLevel->vData[indexer3]);
if (nodeCountsByLevel->vData[indexer3] + leafCountsByLevel->vData[indexer3] > showMaxNodes && indexer3 < maxTreeLevel)
{
maxTreeLevel = indexer3-1;
indexer = nodeCountsByLevel->vData[maxTreeLevel] + leafCountsByLevel->vData[maxTreeLevel];
break;
}
Xcoord += treeLabelWidths->vData[indexer3] + xPadding;
}
Ycoord = 3.*globalYPad + indexer * ySpacing;
countScaler = 1./(countDuplicateTaxID?globalTreeRoot->hitCount:globalTreeRoot->childrenCount);
fprintf (psFile,"%% PS file for the tree '%s'.\n%% Generated by tree2PS on %s\n<< /PageSize [%d %d] >> setpagedevice\n %g setlinewidth\n1 setlinecap\n",
argv[1], argv[1],
(long)(Xcoord+0.5), (long)(Ycoord+0.5), lineWidth);
fprintf (psFile, "/Times-Roman findfont %d scalefont\nsetfont\n",fontSize);
fprintf (psFile,"/drawletter {2 0 rmoveto 1 copy false charpath pathbbox 2 index 3 sub sub exch 3 index 3 sub sub exch 0.85 setgray 4 copy rectfill 0 setgray 3 index 3 index currentlinewidth 0.5 setlinewidth 7 3 roll rectstroke setlinewidth exch 1.5 add exch 1.5 add moveto show} def\n/centertext {dup newpath 0 0 moveto false charpath closepath pathbbox pop exch pop exch sub 2 div 4 -1 roll exch sub 3 -1 roll newpath moveto show} def\n");
fprintf (psFile,"/drawletter2 {2 0 rmoveto 1 copy false charpath pathbbox 2 index 3 sub sub exch 3 index 3 sub sub exch 1 0.5 0 setrgbcolor 4 copy rectfill 0 setgray 3 index 3 index currentlinewidth 0.5 setlinewidth 7 3 roll rectstroke setlinewidth exch 1.5 add exch 1.5 add moveto show} def\n/centertext {dup newpath 0 0 moveto false charpath closepath pathbbox pop exch pop exch sub 2 div 4 -1 roll exch sub 3 -1 roll newpath moveto show} def\n");
t = globalXPad*2. + 100. + 2*fontSize;
drawGradient (psFile, globalXPad*2., Ycoord - 0.5*globalYPad, t<Xcoord ? t : Xcoord, Ycoord - globalYPad*1.5);
Ycoord = globalYPad;
traverseTreePS (psFile, globalTreeRoot, maxTreeLevel, 0, globalXPad, &Ycoord, &Ycoord);
fclose (inFile);
fclose (psFile);
return 0;
}
-890
View File
@@ -1,890 +0,0 @@
/* Produced by texiweb from libavl.w on 2002/08/24 at 13:21. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
The author may be contacted at <blp@gnu.org> on the Internet, or
write to Ben Pfaff, Stanford University, Computer Science Dept., 353
Serra Mall, Stanford CA 94305, USA.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "avl.h"
/* Creates and returns a new table
with comparison function |compare| using parameter |param|
and memory allocator |allocator|.
Returns |NULL| if memory allocation failed. */
struct avl_table *
avl_create (avl_comparison_func *compare, void *param,
struct libavl_allocator *allocator)
{
struct avl_table *tree;
assert (compare != NULL);
if (allocator == NULL)
allocator = &avl_allocator_default;
tree = allocator->libavl_malloc (allocator, sizeof *tree);
if (tree == NULL)
return NULL;
tree->avl_root = NULL;
tree->avl_compare = compare;
tree->avl_param = param;
tree->avl_alloc = allocator;
tree->avl_count = 0;
tree->avl_generation = 0;
return tree;
}
/* Search |tree| for an item matching |item|, and return it if found.
Otherwise return |NULL|. */
void *
avl_find (const struct avl_table *tree, const void *item)
{
const struct avl_node *p;
assert (tree != NULL && item != NULL);
for (p = tree->avl_root; p != NULL; )
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp < 0)
p = p->avl_link[0];
else if (cmp > 0)
p = p->avl_link[1];
else /* |cmp == 0| */
return p->avl_data;
}
return NULL;
}
/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
If a duplicate item is found in the tree,
returns a pointer to the duplicate without inserting |item|.
Returns |NULL| in case of memory allocation failure. */
void **
avl_probe (struct avl_table *tree, void *item)
{
struct avl_node *y, *z; /* Top node to update balance factor, and parent. */
struct avl_node *p, *q; /* Iterator, and parent. */
struct avl_node *n; /* Newly inserted node. */
struct avl_node *w; /* New root of rebalanced subtree. */
int dir; /* Direction to descend. */
unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */
int k = 0; /* Number of cached results. */
assert (tree != NULL && item != NULL);
z = (struct avl_node *) &tree->avl_root;
y = tree->avl_root;
dir = 0;
for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir])
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp == 0)
return &p->avl_data;
if (p->avl_balance != 0)
z = q, y = p, k = 0;
da[k++] = dir = cmp > 0;
}
n = q->avl_link[dir] =
tree->avl_alloc->libavl_malloc (tree->avl_alloc, sizeof *n);
if (n == NULL)
return NULL;
tree->avl_count++;
n->avl_data = item;
n->avl_link[0] = n->avl_link[1] = NULL;
n->avl_balance = 0;
if (y == NULL)
return &n->avl_data;
for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++)
if (da[k] == 0)
p->avl_balance--;
else
p->avl_balance++;
if (y->avl_balance == -2)
{
struct avl_node *x = y->avl_link[0];
if (x->avl_balance == -1)
{
w = x;
y->avl_link[0] = x->avl_link[1];
x->avl_link[1] = y;
x->avl_balance = y->avl_balance = 0;
}
else
{
assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
w->avl_link[0] = x;
y->avl_link[0] = w->avl_link[1];
w->avl_link[1] = y;
if (w->avl_balance == -1)
x->avl_balance = 0, y->avl_balance = +1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == +1| */
x->avl_balance = -1, y->avl_balance = 0;
w->avl_balance = 0;
}
}
else if (y->avl_balance == +2)
{
struct avl_node *x = y->avl_link[1];
if (x->avl_balance == +1)
{
w = x;
y->avl_link[1] = x->avl_link[0];
x->avl_link[0] = y;
x->avl_balance = y->avl_balance = 0;
}
else
{
assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
w->avl_link[1] = x;
y->avl_link[1] = w->avl_link[0];
w->avl_link[0] = y;
if (w->avl_balance == +1)
x->avl_balance = 0, y->avl_balance = -1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == -1| */
x->avl_balance = +1, y->avl_balance = 0;
w->avl_balance = 0;
}
}
else
return &n->avl_data;
z->avl_link[y != z->avl_link[0]] = w;
tree->avl_generation++;
return &n->avl_data;
}
/* Inserts |item| into |table|.
Returns |NULL| if |item| was successfully inserted
or if a memory allocation error occurred.
Otherwise, returns the duplicate item. */
void *
avl_insert (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
return p == NULL || *p == item ? NULL : *p;
}
/* Inserts |item| into |table|, replacing any duplicate item.
Returns |NULL| if |item| was inserted without replacing a duplicate,
or if a memory allocation error occurred.
Otherwise, returns the item that was replaced. */
void *
avl_replace (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
if (p == NULL || *p == item)
return NULL;
else
{
void *r = *p;
*p = item;
return r;
}
}
/* Deletes from |tree| and returns an item matching |item|.
Returns a null pointer if no matching item found. */
void *
avl_delete (struct avl_table *tree, const void *item)
{
/* Stack of nodes. */
struct avl_node *pa[AVL_MAX_HEIGHT]; /* Nodes. */
unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */
int k; /* Stack pointer. */
struct avl_node *p; /* Traverses tree to find node to delete. */
int cmp; /* Result of comparison between |item| and |p|. */
assert (tree != NULL && item != NULL);
k = 0;
p = (struct avl_node *) &tree->avl_root;
for (cmp = -1; cmp != 0;
cmp = tree->avl_compare (item, p->avl_data, tree->avl_param))
{
int dir = cmp > 0;
pa[k] = p;
da[k++] = dir;
p = p->avl_link[dir];
if (p == NULL)
return NULL;
}
item = p->avl_data;
if (p->avl_link[1] == NULL)
pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];
else
{
struct avl_node *r = p->avl_link[1];
if (r->avl_link[0] == NULL)
{
r->avl_link[0] = p->avl_link[0];
r->avl_balance = p->avl_balance;
pa[k - 1]->avl_link[da[k - 1]] = r;
da[k] = 1;
pa[k++] = r;
}
else
{
struct avl_node *s;
int j = k++;
for (;;)
{
da[k] = 0;
pa[k++] = r;
s = r->avl_link[0];
if (s->avl_link[0] == NULL)
break;
r = s;
}
s->avl_link[0] = p->avl_link[0];
r->avl_link[0] = s->avl_link[1];
s->avl_link[1] = p->avl_link[1];
s->avl_balance = p->avl_balance;
pa[j - 1]->avl_link[da[j - 1]] = s;
da[j] = 1;
pa[j] = s;
}
}
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
assert (k > 0);
while (--k > 0)
{
struct avl_node *y = pa[k];
if (da[k] == 0)
{
y->avl_balance++;
if (y->avl_balance == +1)
break;
else if (y->avl_balance == +2)
{
struct avl_node *x = y->avl_link[1];
if (x->avl_balance == -1)
{
struct avl_node *w;
assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
w->avl_link[1] = x;
y->avl_link[1] = w->avl_link[0];
w->avl_link[0] = y;
if (w->avl_balance == +1)
x->avl_balance = 0, y->avl_balance = -1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == -1| */
x->avl_balance = +1, y->avl_balance = 0;
w->avl_balance = 0;
pa[k - 1]->avl_link[da[k - 1]] = w;
}
else
{
y->avl_link[1] = x->avl_link[0];
x->avl_link[0] = y;
pa[k - 1]->avl_link[da[k - 1]] = x;
if (x->avl_balance == 0)
{
x->avl_balance = -1;
y->avl_balance = +1;
break;
}
else
x->avl_balance = y->avl_balance = 0;
}
}
}
else
{
y->avl_balance--;
if (y->avl_balance == -1)
break;
else if (y->avl_balance == -2)
{
struct avl_node *x = y->avl_link[0];
if (x->avl_balance == +1)
{
struct avl_node *w;
assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
w->avl_link[0] = x;
y->avl_link[0] = w->avl_link[1];
w->avl_link[1] = y;
if (w->avl_balance == -1)
x->avl_balance = 0, y->avl_balance = +1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == +1| */
x->avl_balance = -1, y->avl_balance = 0;
w->avl_balance = 0;
pa[k - 1]->avl_link[da[k - 1]] = w;
}
else
{
y->avl_link[0] = x->avl_link[1];
x->avl_link[1] = y;
pa[k - 1]->avl_link[da[k - 1]] = x;
if (x->avl_balance == 0)
{
x->avl_balance = +1;
y->avl_balance = -1;
break;
}
else
x->avl_balance = y->avl_balance = 0;
}
}
}
}
tree->avl_count--;
tree->avl_generation++;
return (void *) item;
}
/* Refreshes the stack of parent pointers in |trav|
and updates its generation number. */
static void
trav_refresh (struct avl_traverser *trav)
{
assert (trav != NULL);
trav->avl_generation = trav->avl_table->avl_generation;
if (trav->avl_node != NULL)
{
avl_comparison_func *cmp = trav->avl_table->avl_compare;
void *param = trav->avl_table->avl_param;
struct avl_node *node = trav->avl_node;
struct avl_node *i;
trav->avl_height = 0;
for (i = trav->avl_table->avl_root; i != node; )
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
assert (i != NULL);
trav->avl_stack[trav->avl_height++] = i;
i = i->avl_link[cmp (node->avl_data, i->avl_data, param) > 0];
}
}
}
/* Initializes |trav| for use with |tree|
and selects the null node. */
void
avl_t_init (struct avl_traverser *trav, struct avl_table *tree)
{
trav->avl_table = tree;
trav->avl_node = NULL;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its least-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
avl_t_first (struct avl_traverser *trav, struct avl_table *tree)
{
struct avl_node *x;
assert (tree != NULL && trav != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
x = tree->avl_root;
if (x != NULL)
while (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
}
trav->avl_node = x;
return x != NULL ? x->avl_data : NULL;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its greatest-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
avl_t_last (struct avl_traverser *trav, struct avl_table *tree)
{
struct avl_node *x;
assert (tree != NULL && trav != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
x = tree->avl_root;
if (x != NULL)
while (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
}
trav->avl_node = x;
return x != NULL ? x->avl_data : NULL;
}
/* Searches for |item| in |tree|.
If found, initializes |trav| to the item found and returns the item
as well.
If there is no matching item, initializes |trav| to the null item
and returns |NULL|. */
void *
avl_t_find (struct avl_traverser *trav, struct avl_table *tree, void *item)
{
struct avl_node *p, *q;
assert (trav != NULL && tree != NULL && item != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
for (p = tree->avl_root; p != NULL; p = q)
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp < 0)
q = p->avl_link[0];
else if (cmp > 0)
q = p->avl_link[1];
else /* |cmp == 0| */
{
trav->avl_node = p;
return p->avl_data;
}
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = p;
}
trav->avl_height = 0;
trav->avl_node = NULL;
return NULL;
}
/* Attempts to insert |item| into |tree|.
If |item| is inserted successfully, it is returned and |trav| is
initialized to its location.
If a duplicate is found, it is returned and |trav| is initialized to
its location. No replacement of the item occurs.
If a memory allocation failure occurs, |NULL| is returned and |trav|
is initialized to the null item. */
void *
avl_t_insert (struct avl_traverser *trav, struct avl_table *tree, void *item)
{
void **p;
assert (trav != NULL && tree != NULL && item != NULL);
p = avl_probe (tree, item);
if (p != NULL)
{
trav->avl_table = tree;
trav->avl_node =
((struct avl_node *)
((char *) p - offsetof (struct avl_node, avl_data)));
trav->avl_generation = tree->avl_generation - 1;
return *p;
}
else
{
avl_t_init (trav, tree);
return NULL;
}
}
/* Initializes |trav| to have the same current node as |src|. */
void *
avl_t_copy (struct avl_traverser *trav, const struct avl_traverser *src)
{
assert (trav != NULL && src != NULL);
if (trav != src)
{
trav->avl_table = src->avl_table;
trav->avl_node = src->avl_node;
trav->avl_generation = src->avl_generation;
if (trav->avl_generation == trav->avl_table->avl_generation)
{
trav->avl_height = src->avl_height;
memcpy (trav->avl_stack, (const void *) src->avl_stack,
sizeof *trav->avl_stack * trav->avl_height);
}
}
return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
}
/* Returns the next data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
avl_t_next (struct avl_traverser *trav)
{
struct avl_node *x;
assert (trav != NULL);
if (trav->avl_generation != trav->avl_table->avl_generation)
trav_refresh (trav);
x = trav->avl_node;
if (x == NULL)
{
return avl_t_first (trav, trav->avl_table);
}
else if (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
while (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
}
}
else
{
struct avl_node *y;
do
{
if (trav->avl_height == 0)
{
trav->avl_node = NULL;
return NULL;
}
y = x;
x = trav->avl_stack[--trav->avl_height];
}
while (y == x->avl_link[1]);
}
trav->avl_node = x;
return x->avl_data;
}
/* Returns the previous data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
avl_t_prev (struct avl_traverser *trav)
{
struct avl_node *x;
assert (trav != NULL);
if (trav->avl_generation != trav->avl_table->avl_generation)
trav_refresh (trav);
x = trav->avl_node;
if (x == NULL)
{
return avl_t_last (trav, trav->avl_table);
}
else if (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
while (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
}
}
else
{
struct avl_node *y;
do
{
if (trav->avl_height == 0)
{
trav->avl_node = NULL;
return NULL;
}
y = x;
x = trav->avl_stack[--trav->avl_height];
}
while (y == x->avl_link[0]);
}
trav->avl_node = x;
return x->avl_data;
}
/* Returns |trav|'s current item. */
void *
avl_t_cur (struct avl_traverser *trav)
{
assert (trav != NULL);
return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
}
/* Replaces the current item in |trav| by |new| and returns the item replaced.
|trav| must not have the null item selected.
The new item must not upset the ordering of the tree. */
void *
avl_t_replace (struct avl_traverser *trav, void *new)
{
void *old;
assert (trav != NULL && trav->avl_node != NULL && new != NULL);
old = trav->avl_node->avl_data;
trav->avl_node->avl_data = new;
return old;
}
static void
copy_error_recovery (struct avl_node **stack, int height,
struct avl_table *new, avl_item_func *destroy)
{
assert (stack != NULL && height >= 0 && new != NULL);
for (; height > 2; height -= 2)
stack[height - 1]->avl_link[1] = NULL;
avl_destroy (new, destroy);
}
/* Copies |org| to a newly created tree, which is returned.
If |copy != NULL|, each data item in |org| is first passed to |copy|,
and the return values are inserted into the tree,
with |NULL| return values taken as indications of failure.
On failure, destroys the partially created new tree,
applying |destroy|, if non-null, to each item in the new tree so far,
and returns |NULL|.
If |allocator != NULL|, it is used for allocation in the new tree.
Otherwise, the same allocator used for |org| is used. */
struct avl_table *
avl_copy (const struct avl_table *org, avl_copy_func *copy,
avl_item_func *destroy, struct libavl_allocator *allocator)
{
struct avl_node *stack[2 * (AVL_MAX_HEIGHT + 1)];
int height = 0;
struct avl_table *new;
const struct avl_node *x;
struct avl_node *y;
assert (org != NULL);
new = avl_create (org->avl_compare, org->avl_param,
allocator != NULL ? allocator : org->avl_alloc);
if (new == NULL)
return NULL;
new->avl_count = org->avl_count;
if (new->avl_count == 0)
return new;
x = (const struct avl_node *) &org->avl_root;
y = (struct avl_node *) &new->avl_root;
for (;;)
{
while (x->avl_link[0] != NULL)
{
assert (height < 2 * (AVL_MAX_HEIGHT + 1));
y->avl_link[0] =
new->avl_alloc->libavl_malloc (new->avl_alloc,
sizeof *y->avl_link[0]);
if (y->avl_link[0] == NULL)
{
if (y != (struct avl_node *) &new->avl_root)
{
y->avl_data = NULL;
y->avl_link[1] = NULL;
}
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
stack[height++] = (struct avl_node *) x;
stack[height++] = y;
x = x->avl_link[0];
y = y->avl_link[0];
}
y->avl_link[0] = NULL;
for (;;)
{
y->avl_balance = x->avl_balance;
if (copy == NULL)
y->avl_data = x->avl_data;
else
{
y->avl_data = copy (x->avl_data, org->avl_param);
if (y->avl_data == NULL)
{
y->avl_link[1] = NULL;
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
}
if (x->avl_link[1] != NULL)
{
y->avl_link[1] =
new->avl_alloc->libavl_malloc (new->avl_alloc,
sizeof *y->avl_link[1]);
if (y->avl_link[1] == NULL)
{
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
x = x->avl_link[1];
y = y->avl_link[1];
break;
}
else
y->avl_link[1] = NULL;
if (height <= 2)
return new;
y = stack[--height];
x = stack[--height];
}
}
}
/* Frees storage allocated for |tree|.
If |destroy != NULL|, applies it to each data item in inorder. */
void
avl_destroy (struct avl_table *tree, avl_item_func *destroy)
{
struct avl_node *p, *q;
assert (tree != NULL);
for (p = tree->avl_root; p != NULL; p = q)
if (p->avl_link[0] == NULL)
{
q = p->avl_link[1];
if (destroy != NULL && p->avl_data != NULL)
destroy (p->avl_data, tree->avl_param);
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
}
else
{
q = p->avl_link[0];
p->avl_link[0] = q->avl_link[1];
q->avl_link[1] = p;
}
tree->avl_alloc->libavl_free (tree->avl_alloc, tree);
}
/* Allocates |size| bytes of space using |malloc()|.
Returns a null pointer if allocation fails. */
void *
avl_malloc (struct libavl_allocator *allocator, size_t size)
{
assert (allocator != NULL && size > 0);
return malloc (size);
}
/* Frees |block|. */
void
avl_free (struct libavl_allocator *allocator, void *block)
{
assert (allocator != NULL && block != NULL);
free (block);
}
/* Default memory allocator that uses |malloc()| and |free()|. */
struct libavl_allocator avl_allocator_default =
{
avl_malloc,
avl_free
};
#undef NDEBUG
#include <assert.h>
/* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */
void
(avl_assert_insert) (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
assert (p != NULL && *p == item);
}
/* Asserts that |avl_delete()| really removes |item| from |table|,
and returns the removed item. */
void *
(avl_assert_delete) (struct avl_table *table, void *item)
{
void *p = avl_delete (table, item);
assert (p != NULL);
return p;
}
-115
View File
@@ -1,115 +0,0 @@
/* Produced by texiweb from libavl.w on 2002/08/24 at 13:21. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
The author may be contacted at <blp@gnu.org> on the Internet, or
write to Ben Pfaff, Stanford University, Computer Science Dept., 353
Serra Mall, Stanford CA 94305, USA.
*/
#ifndef AVL_H
#define AVL_H 1
#include <stddef.h>
/* Function types. */
typedef int avl_comparison_func (const void *avl_a, const void *avl_b,
void *avl_param);
typedef void avl_item_func (void *avl_item, void *avl_param);
typedef void *avl_copy_func (void *avl_item, void *avl_param);
#ifndef LIBAVL_ALLOCATOR
#define LIBAVL_ALLOCATOR
/* Memory allocator. */
struct libavl_allocator
{
void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
};
#endif
/* Default memory allocator. */
extern struct libavl_allocator avl_allocator_default;
void *avl_malloc (struct libavl_allocator *, size_t);
void avl_free (struct libavl_allocator *, void *);
/* Maximum AVL height. */
#ifndef AVL_MAX_HEIGHT
#define AVL_MAX_HEIGHT 32
#endif
/* Tree data structure. */
struct avl_table
{
struct avl_node *avl_root; /* Tree's root. */
avl_comparison_func *avl_compare; /* Comparison function. */
void *avl_param; /* Extra argument to |avl_compare|. */
struct libavl_allocator *avl_alloc; /* Memory allocator. */
size_t avl_count; /* Number of items in tree. */
unsigned long avl_generation; /* Generation number. */
};
/* An AVL tree node. */
struct avl_node
{
struct avl_node *avl_link[2]; /* Subtrees. */
void *avl_data; /* Pointer to data. */
signed char avl_balance; /* Balance factor. */
};
/* AVL traverser structure. */
struct avl_traverser
{
struct avl_table *avl_table; /* Tree being traversed. */
struct avl_node *avl_node; /* Current node in tree. */
struct avl_node *avl_stack[AVL_MAX_HEIGHT];
/* All the nodes above |avl_node|. */
size_t avl_height; /* Number of nodes in |avl_parent|. */
unsigned long avl_generation; /* Generation number. */
};
/* Table functions. */
struct avl_table *avl_create (avl_comparison_func *, void *,
struct libavl_allocator *);
struct avl_table *avl_copy (const struct avl_table *, avl_copy_func *,
avl_item_func *, struct libavl_allocator *);
void avl_destroy (struct avl_table *, avl_item_func *);
void **avl_probe (struct avl_table *, void *);
void *avl_insert (struct avl_table *, void *);
void *avl_replace (struct avl_table *, void *);
void *avl_delete (struct avl_table *, const void *);
void *avl_find (const struct avl_table *, const void *);
void avl_assert_insert (struct avl_table *, void *);
void *avl_assert_delete (struct avl_table *, void *);
#define avl_count(table) ((size_t) (table)->avl_count)
/* Table traverser functions. */
void avl_t_init (struct avl_traverser *, struct avl_table *);
void *avl_t_first (struct avl_traverser *, struct avl_table *);
void *avl_t_last (struct avl_traverser *, struct avl_table *);
void *avl_t_find (struct avl_traverser *, struct avl_table *, void *);
void *avl_t_insert (struct avl_traverser *, struct avl_table *, void *);
void *avl_t_copy (struct avl_traverser *, const struct avl_traverser *);
void *avl_t_next (struct avl_traverser *);
void *avl_t_prev (struct avl_traverser *);
void *avl_t_cur (struct avl_traverser *);
void *avl_t_replace (struct avl_traverser *, void *);
#endif /* avl.h */
-22
View File
@@ -1,22 +0,0 @@
COMPILE
=======
On Max OS X:
$gcc -o taxonomy2tree -fast avl.c taxonomy2tree.c
On Linux:
Insert the following near the top of taxonomy2tree.c
#define isnumber (c) ( (c>='0') && (c<='9'))
Replace -fast with -O3 (the letter 'O'):
$gcc -o taxonomy2tree -O3 avl.c taxonomy2tree.c
INSTALL
=======
Place the binary into a directory that is listed in setup_paths.sh script located in the root of Galaxy installation
-961
View File
@@ -1,961 +0,0 @@
#include "avl.h"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#define DEFAULT_STRING_ALLOC 16L
#define NUMBER_OF_FIELDS 24
#define NUMBER_OF_TAX_FIELDS 22
#define AVL_THRESHOLD 64
char *rankLabels [NUMBER_OF_TAX_FIELDS] =
{"root" ,
"superkingdom",
"kingdom" ,
"subkingdom" ,
"superphylum" ,
"phylum" ,
"subphylum" ,
"superclass" ,
"class" ,
"subclass" ,
"superorder" ,
"order" ,
"suborder" ,
"superfamily" ,
"family" ,
"subfamily" ,
"tribe" ,
"subtribe" ,
"genus" ,
"subgenus" ,
"species" ,
"subspecies"
};
static char *const Usage = "taxonomy2tree tax_dump_file(tab separated taxonomy dump) max_tree_level (<=0 to show all levels) file_for_the_tree file_for_tab_sep_summary include-empty-nodes(optional; 0 or 1; default 0)\n";
/*---------------------------------------------------------------------------------------------------- */
void check_pointer (void*);
char validTaxonNameChar[256];
long currentLineID = 1;
/*---------------------------------------------------------------------------------------------------- */
struct avl_table * idTagAVL = NULL,
* uniqueTags = NULL,
** byLevel = NULL;
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString
{
char *sData;
long sLength,
saLength;
}
*globalNameBuffer;
/*---------------------------------------------------------------------------------------------------- */
struct vector
{
long *vData;
long vLength,
vaLength;
};
/*---------------------------------------------------------------------------------------------------- */
void reportError (char * theMessage)
{
fprintf (stderr, "\nERROR: %s\n", theMessage);
exit (1);
}
/*---------------------------------------------------------------------------------------------------- */
void reportErrorLine (char * theMessage, long lineID)
{
fprintf (stderr, "SKIPPED line %d: %s\n", lineID, theMessage);
}
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString *allocateNewString (void)
{
struct bufferedString *newS = (struct bufferedString*)malloc (sizeof (struct bufferedString));
check_pointer (newS);
check_pointer (newS->sData = (char*)malloc (DEFAULT_STRING_ALLOC+1));
newS->sLength = 0;
newS->saLength = DEFAULT_STRING_ALLOC;
newS->sData[0] = 0;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
struct vector *allocateNewVector (void)
{
struct vector *newS = (struct vector*)malloc (sizeof (struct vector));
check_pointer (newS);
check_pointer (newS->vData = (long*)malloc (DEFAULT_STRING_ALLOC*sizeof(long)));
newS->vLength = 0;
newS->vaLength = DEFAULT_STRING_ALLOC;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
void clear_buffered_string (struct bufferedString* theString)
{
theString->sLength = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void clear_vector (struct vector* v)
{
v->vLength = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void appendCharacterToString (struct bufferedString * s, const char c)
{
long addThis;
if (s->saLength == s->sLength)
{
addThis = s->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
s->saLength += addThis;
check_pointer (s->sData = realloc (s->sData,s->saLength+1));
}
s->sData[s->sLength] = c;
s->sData[++s->sLength] = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void appendValueToVector (struct vector * v, long c)
{
long addThis;
if (v->vaLength == v->vLength)
{
addThis = v->vaLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
v->vaLength += addThis;
check_pointer (v->vData = realloc (v->vData,sizeof(long)*v->vaLength));
}
v->vData[v->vLength++] = c;
}
/*---------------------------------------------------------------------------------------------------- */
long appendRangeToString (struct bufferedString * d, struct bufferedString *s, long from, long to)
{
long addThis,
pl = to-from+1;
if (pl<=0)
return -1;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = from; addThis <=to; addThis++)
d->sData[d->sLength++] = s->sData[addThis];
d->sData[d->sLength] = 0;
return pl;
}
/*---------------------------------------------------------------------------------------------------- */
void appendCharRangeToString (struct bufferedString * d, char * buffer)
{
long addThis,
pl = strlen(buffer);
if (pl<=0)
return;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = 0; addThis <pl; addThis++)
d->sData[d->sLength++] = buffer[addThis];
d->sData[d->sLength] = 0;
}
/*---------------------------------------------------------------------------------------------------- */
long appendCharBufferToString (struct bufferedString * d, const char * b)
{
long addThis,
pl = strlen (b);
if (pl<=0)
return -1;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = 0; addThis <pl; addThis++)
d->sData[d->sLength++] = b[addThis];
d->sData[d->sLength] = 0;
return pl;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
struct treeNode
{
struct treeNode * parent;
long startIndex,
hitCount,
length
,beenhere;
struct vector * children;
struct avl_table* cachedChildren;
} *globalTreeRoot;
/*---------------------------------------------------------------------------------------------------- */
struct treeNode * allocateNewTreeNode (void)
{
struct treeNode *newN = (struct treeNode*)malloc (sizeof (struct treeNode));
check_pointer (newN);
newN->parent = NULL;
newN->startIndex = 0;
newN->length = 0;
newN->hitCount = 0;
newN->beenhere = 0;
newN->cachedChildren = NULL;
newN->children = allocateNewVector();
check_pointer (newN->children);
return newN;
}
/*---------------------------------------------------------------------------------------------------- */
int compare_tree_nodes (const void *avl_a, const void *avl_b, void * xtra)
{
long t1 = ((struct treeNode*)avl_a)->startIndex,
t2 = ((struct treeNode*)avl_b)->startIndex;
if (t1 < t2)
return -1;
if (t1 > t2)
return 1;
return 0;
}
/*---------------------------------------------------------------------------------------------------- */
void destroyTreeNode (struct treeNode* n)
{
if (n->cachedChildren)
avl_destroy (n->cachedChildren, NULL);
free (n->children);
free (n);
}
/*---------------------------------------------------------------------------------------------------- */
void printTreeNode (FILE* f, struct treeNode* n)
{
long i = 0;
fprintf (f, "Node name: ");
if (n->startIndex>=0)
{
for (;i < n->length; i++)
fputc (globalNameBuffer->sData[n->startIndex + i], f);
}
else
fprintf (f, " empty node");
fprintf (f, "\nHit count %d (backup %d)\n", n->hitCount, n->beenhere);
}
/*---------------------------------------------------------------------------------------------------- */
void traverseCheck (struct treeNode* n, char first)
{
long i = 0;
if (!first && n->startIndex >= 0 && n->beenhere != n->hitCount)
{
printTreeNode (stderr, n);
//reportError ("DEATH AND DECAY, BIZNATCH!\n");
}
for (i = 0; i<n->children->vLength; i++)
traverseCheck (((struct treeNode**)n->children->vData)[i], first);
if (first)
{
if (n->children->vLength == 0)
n->beenhere = n->hitCount;
if (n->parent)
n->parent->beenhere += n->beenhere;
}
}
/*---------------------------------------------------------------------------------------------------- */
void traverseTree (FILE *summaryFile, struct treeNode* n, long maxDepth, long currentDepth)
{
long i = 0;
char c;
if (currentDepth <= maxDepth)
{
if (n->children->vLength && maxDepth > currentDepth)
{
if (n->startIndex < 0)
{
for (i=0; i>n->startIndex && currentDepth - i < maxDepth; i--)
fputc ('(', summaryFile);
if (i == n->startIndex)
i = 0;
}
else
fputc ('(',summaryFile);
if (i==0)
for (; i<n->children->vLength; i++)
{
traverseTree (summaryFile, ((struct treeNode**)n->children->vData)[i], maxDepth, currentDepth+1);
if (i<n->children->vLength-1)
fputc (',',summaryFile);
}
if (n->startIndex < 0)
for (i=0; i>n->startIndex+1 && currentDepth - i < maxDepth; i--)
fprintf (summaryFile,")n:%d", n->hitCount);
fputc (')',summaryFile);
}
if (n->startIndex>= 0)
{
for (i=n->startIndex; i<n->startIndex+n->length;i++)
{
c = globalNameBuffer->sData[i];
if (validTaxonNameChar [c])
fputc (c,summaryFile);
else
fputc ('_',summaryFile);
}
fprintf (summaryFile,":%d", n->hitCount);
}
else
fprintf (summaryFile, "n:%d", n->hitCount);
}
}
/*---------------------------------------------------------------------------------------------------- */
struct treeNode * addAChild (struct treeNode* p, struct treeNode * c, char killIfD)
{
struct treeNode * c2 = NULL;
long i = 0;
char addNode = 0;
if (p->cachedChildren)
{
if ((c2 = ((struct treeNode*)avl_find (p->cachedChildren, c))) == NULL)
addNode = 1;
/*else
{
if (c2->startIndex > globalNameBuffer->sLength || c2->startIndex < 0)
printf ("Reject node add %x %d %d\n", c2, c2->startIndex, c->startIndex);
}*/
}
else
{
for (; i<p->children->vLength; i++)
if (((struct treeNode**)p->children->vData)[i]->startIndex == c->startIndex)
break;
addNode = (p->children->vLength == i);
}
if (addNode)
{
if (c->parent && c->parent != p)
{
c2 = allocateNewTreeNode();
c2->startIndex = c->startIndex;
c2->length = c->length;
c2->hitCount = 1;
//if (p->cachedChildren)
// fprintf (stdout, "%x %x\n", p, c->parent);
c = c2;
}
c->parent = p;
appendValueToVector (p->children, (long)c);
if (p->children->vLength > AVL_THRESHOLD)
if (p->cachedChildren == NULL)
{
//fprintf (stdout, "Switch %d\n", currentLineID);
// switch over the the avl representation of nodes
p->cachedChildren = avl_create (compare_tree_nodes, NULL, NULL);
for (i=0; i<p->children->vLength; i++)
avl_probe(p->cachedChildren, ((struct node**)p->children->vData)[i]);
}
else
avl_probe (p->cachedChildren, c);
}
else
{
if (killIfD)
destroyTreeNode (c);
if (c2)
return c2;
else
c = ((struct treeNode**)p->children->vData)[i];
}
return c;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
struct storedIDTag
{
long taxID,
hit_count;
struct treeNode * tNode;
};
/*---------------------------------------------------------------------------------------------------- */
struct storedIDTag *allocateIDTag (void)
{
struct storedIDTag *newS = (struct storedIDTag*)malloc (sizeof (struct storedIDTag));
check_pointer (newS);
newS->taxID = -1;
newS->hit_count = 0;
newS->tNode = NULL;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
int compare_id_tags (const void *avl_a, const void *avl_b, void * xtra)
{
long t1 = ((struct storedIDTag*)avl_a)->taxID,
t2 = ((struct storedIDTag*)avl_b)->taxID;
if (t1 < t2)
return -1;
if (t1 > t2)
return 1;
return 0;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
struct storedSequenceTag
{
long startIndex,
length;
struct treeNode * refNode;
};
/*---------------------------------------------------------------------------------------------------- */
struct storedSequenceTag *allocateStringTag (void)
{
struct storedSequenceTag *newS = (struct storedSequenceTag*)malloc (sizeof (struct storedSequenceTag));
check_pointer (newS);
newS->startIndex = -1;
newS->length = 0;
newS->refNode = NULL;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
/*
struct storedSequenceTag * storedSequenceTag (void)
{
struct storedSequenceTag *newS = (struct storedSequenceTag*)malloc (sizeof (struct storedSequenceTag));
check_pointer (newS);
newS->startIndex = 0;
newS->length = 0;
return newS;
}*/
/*---------------------------------------------------------------------------------------------------- */
int compare_tags (const void *avl_a, const void *avl_b, void * xtra)
{
char* n1 = globalNameBuffer->sData+((struct storedSequenceTag*)avl_a)->startIndex,
* n2 = globalNameBuffer->sData+((struct storedSequenceTag*)avl_b)->startIndex;
long l1 = ((struct storedSequenceTag*)avl_a)->length,
l2 = ((struct storedSequenceTag*)avl_b)->length,
i;
signed char c;
for (i = 0; i < l1 && i < l2; i++)
{
c = n1[i] - n2[i];
if (c < 0)
return -1;
if (c>0)
return 1;
}
if (l1 < l2)
return -1;
if (l1 > l2)
return 1;
return 0;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
void check_pointer (void * p)
{
if (p == NULL)
{
fprintf (stderr,"Memory allocation error\n");
exit (1);
}
}
/*---------------------------------------------------------------------------------------------------- */
int compare_strings (const struct bufferedString * s1, const struct bufferedString * s2)
{
long upTo,
i;
if (s1->sLength>s2->sLength)
upTo = s2->sLength;
else
upTo = s1->sLength;
for (i=0; i<upTo; i++)
{
int res = (s1->sData[i]-s2->sData[i]);
if (res < 0)
return -1;
else
if (res>0)
return 1;
}
if (s1->sLength == s2->sLength)
return 0;
return 1-2*(s1->sLength<s2->sLength);
}
/*---------------------------------------------------------------------------------------------------- */
void destroy_string (struct bufferedString* aStr)
{
free (aStr->sData);
free (aStr);
}
/*---------------------------------------------------------------------------------------------------- */
int main (int argc, const char * argv[])
{
struct bufferedString **currentBuffers;
struct storedIDTag *aTag = allocateIDTag(),
*aTag2;
struct storedSequenceTag *sTag = allocateStringTag(),
*sTag2,
*sTag3;
struct avl_traverser avlt;
struct treeNode *currentParent = NULL,
*currentNode;
char automatonState = 0,
currentField = 0,
currentChar = 0,
showEmptyNodes = 0;
long expectedFields = NUMBER_OF_FIELDS,
indexer,
indexer2,
indexer3,
maxTreeLevel = 0,
setEOF = 0,
nRunCounter = 0;
FILE * treeFile = NULL,
* summaryFile = NULL,
* inFile = NULL;
globalNameBuffer = allocateNewString();
globalTreeRoot = allocateNewTreeNode();
currentBuffers = (struct bufferedString**)malloc (expectedFields*sizeof (struct bufferedString*));
byLevel = (struct avl_table**)malloc (sizeof (struct avl_table*) * NUMBER_OF_TAX_FIELDS);
check_pointer (uniqueTags = avl_create (compare_tags, NULL, NULL));
check_pointer (idTagAVL = avl_create (compare_id_tags, NULL, NULL));
for (indexer = 0; indexer < NUMBER_OF_TAX_FIELDS; indexer++)
check_pointer (byLevel[indexer] = avl_create (compare_tags, NULL, NULL));
for (indexer = 0; indexer < expectedFields; indexer++)
currentBuffers[indexer] = allocateNewString();
if (argc != 6 && argc != 5)
{
fprintf (stderr,"%s",Usage);
return 1;
}
maxTreeLevel = atoi (argv[2]);
inFile = fopen (argv[1], "rb");
if (!inFile)
{
fprintf (stderr, "Failed to open the input file %s\n", argv[1]);
return 1;
}
treeFile = fopen (argv[3], "wb");
if (!treeFile)
{
fprintf (stderr, "Failed to open the tree output file %s\n", argv[3]);
return 1;
}
summaryFile = fopen (argv[4], "wb");
if (!summaryFile)
{
fprintf (stderr, "Failed to open the summary output file %s\n", argv[4]);
return 1;
}
if (argc == 6)
showEmptyNodes = atoi (argv[5]);
currentChar = fgetc(inFile);
currentField = 0;
while (setEOF < 2)
{
switch (automatonState)
{
case 0: /* start of the line; expecting numbers or charcters */
if (isalnum(currentChar))
{
automatonState = 1; /* reading sequence ID */
appendCharacterToString(currentBuffers[currentField],toupper(currentChar));
}
else
if (!(currentChar == '\n' || currentChar == '\r'))
{
reportErrorLine ("Could not find a valid gid number to start the line",currentLineID);
automatonState = 6;
continue;
}
break;
case 1: /* reading sequence ID */
if (currentChar == '\t')
{
automatonState = 2;
continue;
}
else
{
if (currentChar == '\n' || currentChar == '\r')
{
reportErrorLine ("Expected a tab following the gid",currentLineID);
automatonState = 6;
continue;
}
else
appendCharacterToString(currentBuffers[currentField],toupper(currentChar));
}
break;
case 2: /* looking for a \t or a \n|\r*/
if (currentChar == '\t')
{
currentField ++;
if (currentField < expectedFields)
automatonState = 3;
//reportErrorLine ("Too many fields",currentLineID);
//automatonState = 6;
//continue;
}
else
if (currentChar == '\n' || currentChar == '\r')
// finish the read
{
if (currentField < expectedFields-1)
reportErrorLine ("Too few fields",currentLineID);
aTag->taxID = atoi (currentBuffers[1]->sData);
aTag->hit_count = 1;
aTag2 = *(struct storedIDTag**)avl_probe(idTagAVL, aTag);
//fprintf (stdout, "%d %d %x %x\n", currentLineID,aTag->taxID,aTag,aTag2);
if (aTag == aTag2) // new taxID
{
// process fields
currentParent = globalTreeRoot;
nRunCounter = 0;
for (indexer = NUMBER_OF_FIELDS-NUMBER_OF_TAX_FIELDS; indexer < NUMBER_OF_FIELDS; indexer++)
{
indexer2 = strlen(currentBuffers[indexer]->sData);
//fprintf (stdout, "%d %d\n", indexer, nRunCounter,indexer2);
if ((currentBuffers[indexer])->sData[0] == 'n' && indexer2 == 1)
nRunCounter++;
else
{
indexer3 = globalNameBuffer->sLength;
appendRangeToString (globalNameBuffer,currentBuffers[indexer],0,indexer2-1);
sTag->startIndex = indexer3;
sTag->length = indexer2;
sTag2 = *(struct storedSequenceTag**)avl_probe (uniqueTags,sTag);
if (sTag == sTag2) // added
sTag = allocateStringTag();
else
globalNameBuffer->sLength = indexer3;
sTag->startIndex = sTag2->startIndex;
sTag->length = sTag2->length;
sTag3 = *(struct storedSequenceTag**)avl_probe (byLevel[indexer-(NUMBER_OF_FIELDS-NUMBER_OF_TAX_FIELDS)],sTag);
if (sTag == sTag3) // new node
{
//fprintf (stderr, "Add node level %d %d\n",indexer-(NUMBER_OF_FIELDS-NUMBER_OF_TAX_FIELDS), sTag2->startIndex);
sTag3 = sTag;
sTag3->refNode = allocateNewTreeNode();
sTag3->refNode->length = sTag2->length;
sTag3->refNode->startIndex = sTag2->startIndex;
sTag3->refNode->parent = NULL;
sTag = allocateStringTag();
}
//else
//fprintf (stderr, "Have node %x %x %c%c %d\n",sTag3->refNode, (currentBuffers[indexer])->sData[0],(currentBuffers[indexer])->sData[1], currentParent->children->vLength);
sTag3->refNode->hitCount++;
if (showEmptyNodes && nRunCounter>0)
{
currentNode = allocateNewTreeNode();
currentNode->startIndex = -nRunCounter;
currentNode->hitCount = 1;
if (currentParent)
currentParent = addAChild (currentParent,currentNode,1);
else
reportError ("Attempting to attach an empty node a null parent.");
}
if (currentParent)
currentParent = addAChild (currentParent,sTag3->refNode,0);
else
currentParent = sTag3->refNode;
nRunCounter = 0;
}
}
if (nRunCounter>0)
{
currentNode = allocateNewTreeNode();
currentNode->startIndex = -nRunCounter;
currentNode->hitCount = 1;
if (currentParent)
currentParent = addAChild (currentParent,currentNode,1);
else
reportError ("Attempting to attach an empty node a null parent.");
}
aTag->tNode = currentParent;
aTag = allocateIDTag();
}
else
{
aTag2->hit_count++;
currentParent = aTag2->tNode;
while (currentParent)
{
currentParent->hitCount++;
currentParent = currentParent->parent;
}
//printf ("Duplicate tag %d %d\n", aTag2->hit_count, aTag2->taxID);
}
//traverseCheck (globalTreeRoot);
automatonState = 5;
continue;
}
else
{
if (currentField < expectedFields)
{
reportErrorLine ("Expected a tab following a field",currentLineID);
automatonState = 6;
continue;
}
}
break;
case 3: /* read a field */
if (currentChar == '\t')
{
automatonState = 2;
continue;
}
else
if (currentChar == '\n' || currentChar == '\r')
{
currentField++;
automatonState = 2;
continue;
}
else
{
if (currentChar == '\'')
automatonState = 4;
else
appendCharacterToString(currentBuffers[currentField],currentChar);
}
break;
case 4: /* inside ' ' */
if (currentChar == '\'')
automatonState = 3;
else
if (currentChar == '\n' || currentChar == '\r')
{
reportErrorLine ("Premature line end while reading a literal",currentLineID);
automatonState = 5;
}
else
appendCharacterToString(currentBuffers[currentField],currentChar);
break;
case 5:
automatonState = 0;
currentLineID ++;
currentField = 0;
for (indexer = 0; indexer < expectedFields; indexer++)
clear_buffered_string(currentBuffers[indexer]);
break;
case 6:
if (currentChar == '\n' || currentChar == '\r')
automatonState = 5;
break;
}
currentChar = fgetc(inFile);
if (feof (inFile))
{
setEOF ++;
currentChar = '\n';
}
}
fprintf (stderr, "Read %d unique taxIDs\n", avl_count (idTagAVL));
fclose (inFile);
indexer3 = ((maxTreeLevel>0)?(maxTreeLevel+1):0xfffffL);
if (indexer3 > NUMBER_OF_TAX_FIELDS)
indexer3 = NUMBER_OF_TAX_FIELDS;
for (indexer = 0; indexer < indexer3; indexer++)
{
avl_t_init (&avlt, byLevel[indexer]);
sTag = (struct storedSequenceTag*)avl_t_first (&avlt, byLevel[indexer]);
while (sTag)
{
fprintf (summaryFile, "%s\t", rankLabels[indexer]);
for (indexer2 = 0; indexer2 < sTag->length; indexer2++)
fputc(*(globalNameBuffer->sData+sTag->startIndex+indexer2),summaryFile);
fprintf (summaryFile, "\t%d\n", sTag->refNode->hitCount);
sTag = (struct storedSequenceTag*)avl_t_next (&avlt);
}
//fprintf (stderr, "Level %d unique IDs = %d\n", indexer, avl_count (byLevel[indexer]));
}
for (indexer = 0; indexer < 256; indexer ++)
validTaxonNameChar[indexer] = 1;
validTaxonNameChar[','] = 0;
validTaxonNameChar[')'] = 0;
validTaxonNameChar['('] = 0;
validTaxonNameChar[':'] = 0;
traverseTree (treeFile,((struct treeNode**)globalTreeRoot->children->vData)[0],(maxTreeLevel>0)?(maxTreeLevel+1):0xfffffL,0);
fclose (treeFile);
traverseCheck (((struct treeNode**)globalTreeRoot->children->vData)[0], 1);
traverseCheck (((struct treeNode**)globalTreeRoot->children->vData)[0], 0);
return 0;
}
-93
View File
@@ -1,93 +0,0 @@
137 9913 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Laurasiatheria n Ruminantia n Bovidae Bovinae n n Bos n Bos taurus n
565 9913 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Laurasiatheria n Ruminantia n Bovidae Bovinae n n Bos n Bos taurus n
723 9913 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Laurasiatheria n Ruminantia n Bovidae Bovinae n n Bos n Bos taurus n
724 9913 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Laurasiatheria n Ruminantia n Bovidae Bovinae n n Bos n Bos taurus n
725 9913 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Laurasiatheria n Ruminantia n Bovidae Bovinae n n Bos n Bos taurus n
1707 9986 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Euarchontoglires Lagomorpha n n Leporidae n n n Oryctolagus n Oryctolagus cuniculus n
1708 9986 root Eukaryota Metazoa n n Chordata Craniata Gnathostomata Mammalia n Euarchontoglires Lagomorpha n n Leporidae n n n Oryctolagus n Oryctolagus cuniculus n
2474 27373 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Acaulosporaceae n n n Acaulospora n Acaulospora rugosa n
2480 27374 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Acaulosporaceae n n n Acaulospora n Acaulospora spinosa n
2484 4971 root Eukaryota Fungi Dikarya n Basidiomycota n n Tremellomycetes n n Tremellales n n Tremellaceae n n n Bulleromyces n Bulleromyces albus n
2485 5007 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Dekkera n Dekkera bruxellensis n
2486 4808 root Eukaryota Fungi n n Blastocladiomycota n n Blastocladiomycetes n n Blastocladiales n n Blastocladiaceae n n n Blastocladiella n Blastocladiella emersonii n
2507 5476 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n n n n n Candida n Candida albicans n
2575 5478 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n n n n n Candida n Candida glabrata n
2588 5501 root Eukaryota Fungi Dikarya n Ascomycota Pezizomycotina n Eurotiomycetes Eurotiomycetidae n Onygenales n n n n n n Coccidioides n Coccidioides immitis n
2616 5207 root Eukaryota Fungi Dikarya n Basidiomycota n n Tremellomycetes n n Tremellales n n Tremellaceae n n n Filobasidiella n Filobasidiella neoformans n
2685 58641 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Debaryomyces n Debaryomyces hansenii Debaryomyces hansenii var. hansenii
2686 4959 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Debaryomyces n Debaryomyces hansenii n
2687 5793 root Eukaryota n n n n n n n Myxogastromycetidae n Physariida n n n n n n Didymium n Didymium iridis n
2694 27376 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Acaulosporaceae n n n Entrophospora n Entrophospora colombiana n
2709 4872 root Eukaryota Fungi n n n Mucoromycotina n n n n Endogonales n n Endogonaceae n n n Endogone n Endogone pisiformis n
2711 27377 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Acaulosporaceae n n n Entrophospora n Entrophospora sp. WV 796 n
2737 27378 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Gigasporaceae n n n Gigaspora n Gigaspora albida n
2738 27380 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Glomerales n n Glomeraceae n n n Glomus n Glomus etunicatum n
2742 27379 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Gigasporaceae n n n Gigaspora n Gigaspora gigantea n
2743 4876 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Glomerales n n Glomeraceae n n n Glomus n Glomus intraradices n
2744 44941 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Gigasporaceae n n n Gigaspora n Gigaspora rosea n
2745 27381 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Glomerales n n Glomeraceae n n n Glomus n Glomus mosseae n
2759 5037 root Eukaryota Fungi Dikarya n Ascomycota Pezizomycotina n Eurotiomycetes Eurotiomycetidae n Onygenales n n Ajellomycetaceae n n n Ajellomyces n Ajellomyces capsulatus n
2806 28985 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Kluyveromyces n Kluyveromyces lactis n
2922 4803 root Eukaryota n n n n n n n n n Lagenidiales n n Lagenidiaceae n n n Lagenidium n Lagenidium giganteum n
2924 5278 root Eukaryota Fungi Dikarya n Basidiomycota Pucciniomycotina n n Microbotryomycetes n Leucosporidiales n n n n n n Leucosporidium n Leucosporidium scottii n
2961 4841 root Eukaryota Fungi n n n Mucoromycotina n n n n Mucorales n n Mucoraceae n n n Mucor n Mucor racemosus n
3080 5141 root Eukaryota Fungi Dikarya n Ascomycota Pezizomycotina n Sordariomycetes Sordariomycetidae n Sordariales n n Sordariaceae n n n Neurospora n Neurospora crassa n
3093 4927 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Pichia n Pichia anomala n
3105 5145 root Eukaryota Fungi Dikarya n Ascomycota Pezizomycotina n Sordariomycetes Sordariomycetidae n Sordariales n n Lasiosphaeriaceae n n n Podospora n Podospora anserina n
3179 4926 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Pichia n Pichia membranifaciens n
3182 4788 root Eukaryota n n n n n n n n n Peronosporales n n n n n n Phytophthora n Phytophthora megasperma n
3185 5791 root Eukaryota n n n n n n n Myxogastromycetidae n Physariida n n n n n n Physarum n Physarum polycephalum n
3221 5791 root Eukaryota n n n n n n n Myxogastromycetidae n Physariida n n n n n n Physarum n Physarum polycephalum n
3225 5791 root Eukaryota n n n n n n n Myxogastromycetidae n Physariida n n n n n n Physarum n Physarum polycephalum n
3273 5286 root Eukaryota Fungi Dikarya n Basidiomycota Pucciniomycotina n n Microbotryomycetes n Sporidiobolales n n n n n n Rhodosporidium n Rhodosporidium toruloides n
4347 4932 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Saccharomyces n Saccharomyces cerevisiae n
4844 27383 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Gigasporaceae n n n Scutellospora n Scutellospora dipapillosa n
4893 4896 root Eukaryota Fungi Dikarya n Ascomycota Taphrinomycotina n Schizosaccharomycetes n n Schizosaccharomycetales n n Schizosaccharomycetaceae n n n Schizosaccharomyces n Schizosaccharomyces pombe n
5039 27384 root Eukaryota Fungi n n Glomeromycota n n Glomeromycetes n n Diversisporales n n Gigasporaceae n n n Scutellospora n Scutellospora pellucida n
5075 4896 root Eukaryota Fungi Dikarya n Ascomycota Taphrinomycotina n Schizosaccharomycetes n n Schizosaccharomycetales n n Schizosaccharomycetaceae n n n Schizosaccharomyces n Schizosaccharomyces pombe n
5153 40563 root Eukaryota Fungi Dikarya n Basidiomycota Pucciniomycotina n n Microbotryomycetes n Sporidiobolales n n n n n n Sporobolomyces n Sporobolomyces roseus n
5174 5554 root Eukaryota Fungi Dikarya n Basidiomycota n n Tremellomycetes n n Tremellales n n n n n n Trichosporon n Trichosporon cutaneum n
5175 4950 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Torulaspora n Torulaspora delbrueckii n
5186 5551 root Eukaryota Fungi Dikarya n Ascomycota Pezizomycotina n Eurotiomycetes Eurotiomycetidae n Onygenales n n Arthrodermataceae n n n Trichophyton n Trichophyton rubrum n
5232 5270 root Eukaryota Fungi Dikarya n Basidiomycota Ustilaginomycotina n Ustilaginomycetes n n Ustilaginales n n Ustilaginaceae n n n Ustilago n Ustilago maydis n
5257 4956 root Eukaryota Fungi Dikarya n Ascomycota Saccharomycotina n Saccharomycetes n n Saccharomycetales n n Saccharomycetaceae n n n Zygosaccharomyces n Zygosaccharomyces rouxii n
5552 7160 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Nematocera Culicoidea Culicidae Culicinae Culicini n Aedes Stegomyia Aedes albopictus n
5654 7119 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera Amphiesmenoptera Lepidoptera Glossata Bombycoidea Saturniidae Saturniinae Saturniini n Antheraea n Antheraea pernyi n
5691 7642 root Eukaryota Metazoa n n Echinodermata n Echinozoa Echinoidea Euechinoidea Echinacea Arbacoida n n Arbaciidae n n n Arbacia n Arbacia sp. n
5702 85549 root Eukaryota Metazoa n n Arthropoda Crustacea n Branchiopoda Sarsostraca n Anostraca n n Artemiidae n n n Artemia n Artemia salina n
5704 6108 root Eukaryota Metazoa n n Cnidaria n n Anthozoa Hexacorallia n Actiniaria Nynantheae n Actiniidae n n n Anemonia n Anemonia sulcata n
5713 5866 root Eukaryota n n n Apicomplexa n n Aconoidasida n n n n n Babesiidae n n n Babesia n Babesia bigemina n
5714 5866 root Eukaryota n n n Apicomplexa n n Aconoidasida n n n n n Babesiidae n n n Babesia n Babesia bigemina n
5715 5866 root Eukaryota n n n Apicomplexa n n Aconoidasida n n n n n Babesiidae n n n Babesia n Babesia bigemina n
5716 5871 root Eukaryota n n n Apicomplexa n n Aconoidasida n n n n n Babesiidae n n n Babesia n Babesia caballi n
5718 5872 root Eukaryota n n n Apicomplexa n n Aconoidasida n n n n n Babesiidae n n n Babesia n Babesia equi n
5907 7091 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera Amphiesmenoptera Lepidoptera Glossata Bombycoidea Bombycidae Bombycinae n n Bombyx n Bombyx mori n
5909 7091 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera Amphiesmenoptera Lepidoptera Glossata Bombycoidea Bombycidae Bombycinae n n Bombyx n Bombyx mori n
5914 7091 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera Amphiesmenoptera Lepidoptera Glossata Bombycoidea Bombycidae Bombycinae n n Bombyx n Bombyx mori n
5919 7091 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera Amphiesmenoptera Lepidoptera Glossata Bombycoidea Bombycidae Bombycinae n n Bombyx n Bombyx mori n
5954 7038 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Hemiptera n Aleyrodoidea Aleyrodidae Aleyrodinae n n Bemisia n Bemisia tabaci n
5955 7038 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Hemiptera n Aleyrodoidea Aleyrodidae Aleyrodinae n n Bemisia n Bemisia tabaci n
6830 6239 root Eukaryota Metazoa n n Nematoda n n Chromadorea n n Rhabditida n Rhabditoidea Rhabditidae Peloderinae n n Caenorhabditis n Caenorhabditis elegans n
6831 7373 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Oestroidea Calliphoridae Calliphorinae n n Calliphora n Calliphora vicina n
6997 5808 root Eukaryota n n n Apicomplexa n n Coccidia n n Eucoccidiorida Eimeriorina n Cryptosporidiidae n n n Cryptosporidium n Cryptosporidium muris n
6998 5808 root Eukaryota n n n Apicomplexa n n Coccidia n n Eucoccidiorida Eimeriorina n Cryptosporidiidae n n n Cryptosporidium n Cryptosporidium muris n
7001 5807 root Eukaryota n n n Apicomplexa n n Coccidia n n Eucoccidiorida Eimeriorina n Cryptosporidiidae n n n Cryptosporidium n Cryptosporidium parvum n
7002 5807 root Eukaryota n n n Apicomplexa n n Coccidia n n Eucoccidiorida Eimeriorina n Cryptosporidiidae n n n Cryptosporidium n Cryptosporidium parvum n
7082 7154 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Nematocera Chironomoidea Chironomidae Chironominae Chironomini n Chironomus Chironomus Chironomus thummi n
7131 6565 root Eukaryota Metazoa n n Mollusca n n Bivalvia Pteriomorphia n Ostreoida n Ostreoidea Ostreidae n n n Crassostrea n Crassostrea virginica n
7349 44689 root Eukaryota n n n n n n n n n Dictyosteliida n n n n n n Dictyostelium n Dictyostelium discoideum n
7431 7224 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Drosophila Drosophila hydei n
7493 7227 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Sophophora Drosophila melanogaster n
7692 7227 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Sophophora Drosophila melanogaster n
7956 7227 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Sophophora Drosophila melanogaster n
8419 7227 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Sophophora Drosophila melanogaster n
8456 7227 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Sophophora Drosophila melanogaster n
9202 7244 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Ephydroidea Drosophilidae Drosophilinae Drosophilini Drosophilina Drosophila Drosophila Drosophila virilis n
9270 29932 root Eukaryota Metazoa n n Arthropoda Chelicerata n Arachnida n n Araneae Mygalomorphae n Theraphosidae n n n Aphonopelma n Aphonopelma sp. n
9330 27887 root Eukaryota Metazoa n n Platyhelminthes n n Trematoda Digenea n Strigeidida n Strigeoidea Fellodistomidae n n n Fellodistomum n Fellodistomum fellis n
9349 6174 root Eukaryota Metazoa n n Platyhelminthes n n Turbellaria n n Lecithoepitheliata n n Prorhynchidae n n n Geocentrophora n Geocentrophora intersticialis n
9377 7394 root Eukaryota Metazoa n n Arthropoda n Hexapoda Insecta Neoptera n Diptera Brachycera Hippoboscoidea Glossinidae n n n Glossina Glossina Glossina morsitans n
9380 6175 root Eukaryota Metazoa n n Platyhelminthes n n Turbellaria n n Lecithoepitheliata n n Prorhynchidae n n n Geocentrophora n Geocentrophora porfirievae n
9383 6176 root Eukaryota Metazoa n n Platyhelminthes n n Turbellaria n n Lecithoepitheliata n n Prorhynchidae n n n Geocentrophora n Geocentrophora sphyrocephala n
9430 7733 root Eukaryota Metazoa n n Chordata Urochordata n Ascidiacea n n Stolidobranchia n n Pyuridae n n n Herdmania n Herdmania momus n
9505 27877 root Eukaryota Metazoa n n Platyhelminthes n n Trematoda Digenea n Plagiorchiida Allocreadiata Lepocreadioidea Lepocreadiidae n n n Lepidapedon n Lepidapedon elongatum n
-890
View File
@@ -1,890 +0,0 @@
/* Produced by texiweb from libavl.w on 2002/08/24 at 13:21. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
The author may be contacted at <blp@gnu.org> on the Internet, or
write to Ben Pfaff, Stanford University, Computer Science Dept., 353
Serra Mall, Stanford CA 94305, USA.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "avl.h"
/* Creates and returns a new table
with comparison function |compare| using parameter |param|
and memory allocator |allocator|.
Returns |NULL| if memory allocation failed. */
struct avl_table *
avl_create (avl_comparison_func *compare, void *param,
struct libavl_allocator *allocator)
{
struct avl_table *tree;
assert (compare != NULL);
if (allocator == NULL)
allocator = &avl_allocator_default;
tree = allocator->libavl_malloc (allocator, sizeof *tree);
if (tree == NULL)
return NULL;
tree->avl_root = NULL;
tree->avl_compare = compare;
tree->avl_param = param;
tree->avl_alloc = allocator;
tree->avl_count = 0;
tree->avl_generation = 0;
return tree;
}
/* Search |tree| for an item matching |item|, and return it if found.
Otherwise return |NULL|. */
void *
avl_find (const struct avl_table *tree, const void *item)
{
const struct avl_node *p;
assert (tree != NULL && item != NULL);
for (p = tree->avl_root; p != NULL; )
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp < 0)
p = p->avl_link[0];
else if (cmp > 0)
p = p->avl_link[1];
else /* |cmp == 0| */
return p->avl_data;
}
return NULL;
}
/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
If a duplicate item is found in the tree,
returns a pointer to the duplicate without inserting |item|.
Returns |NULL| in case of memory allocation failure. */
void **
avl_probe (struct avl_table *tree, void *item)
{
struct avl_node *y, *z; /* Top node to update balance factor, and parent. */
struct avl_node *p, *q; /* Iterator, and parent. */
struct avl_node *n; /* Newly inserted node. */
struct avl_node *w; /* New root of rebalanced subtree. */
int dir; /* Direction to descend. */
unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */
int k = 0; /* Number of cached results. */
assert (tree != NULL && item != NULL);
z = (struct avl_node *) &tree->avl_root;
y = tree->avl_root;
dir = 0;
for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir])
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp == 0)
return &p->avl_data;
if (p->avl_balance != 0)
z = q, y = p, k = 0;
da[k++] = dir = cmp > 0;
}
n = q->avl_link[dir] =
tree->avl_alloc->libavl_malloc (tree->avl_alloc, sizeof *n);
if (n == NULL)
return NULL;
tree->avl_count++;
n->avl_data = item;
n->avl_link[0] = n->avl_link[1] = NULL;
n->avl_balance = 0;
if (y == NULL)
return &n->avl_data;
for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++)
if (da[k] == 0)
p->avl_balance--;
else
p->avl_balance++;
if (y->avl_balance == -2)
{
struct avl_node *x = y->avl_link[0];
if (x->avl_balance == -1)
{
w = x;
y->avl_link[0] = x->avl_link[1];
x->avl_link[1] = y;
x->avl_balance = y->avl_balance = 0;
}
else
{
assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
w->avl_link[0] = x;
y->avl_link[0] = w->avl_link[1];
w->avl_link[1] = y;
if (w->avl_balance == -1)
x->avl_balance = 0, y->avl_balance = +1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == +1| */
x->avl_balance = -1, y->avl_balance = 0;
w->avl_balance = 0;
}
}
else if (y->avl_balance == +2)
{
struct avl_node *x = y->avl_link[1];
if (x->avl_balance == +1)
{
w = x;
y->avl_link[1] = x->avl_link[0];
x->avl_link[0] = y;
x->avl_balance = y->avl_balance = 0;
}
else
{
assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
w->avl_link[1] = x;
y->avl_link[1] = w->avl_link[0];
w->avl_link[0] = y;
if (w->avl_balance == +1)
x->avl_balance = 0, y->avl_balance = -1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == -1| */
x->avl_balance = +1, y->avl_balance = 0;
w->avl_balance = 0;
}
}
else
return &n->avl_data;
z->avl_link[y != z->avl_link[0]] = w;
tree->avl_generation++;
return &n->avl_data;
}
/* Inserts |item| into |table|.
Returns |NULL| if |item| was successfully inserted
or if a memory allocation error occurred.
Otherwise, returns the duplicate item. */
void *
avl_insert (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
return p == NULL || *p == item ? NULL : *p;
}
/* Inserts |item| into |table|, replacing any duplicate item.
Returns |NULL| if |item| was inserted without replacing a duplicate,
or if a memory allocation error occurred.
Otherwise, returns the item that was replaced. */
void *
avl_replace (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
if (p == NULL || *p == item)
return NULL;
else
{
void *r = *p;
*p = item;
return r;
}
}
/* Deletes from |tree| and returns an item matching |item|.
Returns a null pointer if no matching item found. */
void *
avl_delete (struct avl_table *tree, const void *item)
{
/* Stack of nodes. */
struct avl_node *pa[AVL_MAX_HEIGHT]; /* Nodes. */
unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */
int k; /* Stack pointer. */
struct avl_node *p; /* Traverses tree to find node to delete. */
int cmp; /* Result of comparison between |item| and |p|. */
assert (tree != NULL && item != NULL);
k = 0;
p = (struct avl_node *) &tree->avl_root;
for (cmp = -1; cmp != 0;
cmp = tree->avl_compare (item, p->avl_data, tree->avl_param))
{
int dir = cmp > 0;
pa[k] = p;
da[k++] = dir;
p = p->avl_link[dir];
if (p == NULL)
return NULL;
}
item = p->avl_data;
if (p->avl_link[1] == NULL)
pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];
else
{
struct avl_node *r = p->avl_link[1];
if (r->avl_link[0] == NULL)
{
r->avl_link[0] = p->avl_link[0];
r->avl_balance = p->avl_balance;
pa[k - 1]->avl_link[da[k - 1]] = r;
da[k] = 1;
pa[k++] = r;
}
else
{
struct avl_node *s;
int j = k++;
for (;;)
{
da[k] = 0;
pa[k++] = r;
s = r->avl_link[0];
if (s->avl_link[0] == NULL)
break;
r = s;
}
s->avl_link[0] = p->avl_link[0];
r->avl_link[0] = s->avl_link[1];
s->avl_link[1] = p->avl_link[1];
s->avl_balance = p->avl_balance;
pa[j - 1]->avl_link[da[j - 1]] = s;
da[j] = 1;
pa[j] = s;
}
}
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
assert (k > 0);
while (--k > 0)
{
struct avl_node *y = pa[k];
if (da[k] == 0)
{
y->avl_balance++;
if (y->avl_balance == +1)
break;
else if (y->avl_balance == +2)
{
struct avl_node *x = y->avl_link[1];
if (x->avl_balance == -1)
{
struct avl_node *w;
assert (x->avl_balance == -1);
w = x->avl_link[0];
x->avl_link[0] = w->avl_link[1];
w->avl_link[1] = x;
y->avl_link[1] = w->avl_link[0];
w->avl_link[0] = y;
if (w->avl_balance == +1)
x->avl_balance = 0, y->avl_balance = -1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == -1| */
x->avl_balance = +1, y->avl_balance = 0;
w->avl_balance = 0;
pa[k - 1]->avl_link[da[k - 1]] = w;
}
else
{
y->avl_link[1] = x->avl_link[0];
x->avl_link[0] = y;
pa[k - 1]->avl_link[da[k - 1]] = x;
if (x->avl_balance == 0)
{
x->avl_balance = -1;
y->avl_balance = +1;
break;
}
else
x->avl_balance = y->avl_balance = 0;
}
}
}
else
{
y->avl_balance--;
if (y->avl_balance == -1)
break;
else if (y->avl_balance == -2)
{
struct avl_node *x = y->avl_link[0];
if (x->avl_balance == +1)
{
struct avl_node *w;
assert (x->avl_balance == +1);
w = x->avl_link[1];
x->avl_link[1] = w->avl_link[0];
w->avl_link[0] = x;
y->avl_link[0] = w->avl_link[1];
w->avl_link[1] = y;
if (w->avl_balance == -1)
x->avl_balance = 0, y->avl_balance = +1;
else if (w->avl_balance == 0)
x->avl_balance = y->avl_balance = 0;
else /* |w->avl_balance == +1| */
x->avl_balance = -1, y->avl_balance = 0;
w->avl_balance = 0;
pa[k - 1]->avl_link[da[k - 1]] = w;
}
else
{
y->avl_link[0] = x->avl_link[1];
x->avl_link[1] = y;
pa[k - 1]->avl_link[da[k - 1]] = x;
if (x->avl_balance == 0)
{
x->avl_balance = +1;
y->avl_balance = -1;
break;
}
else
x->avl_balance = y->avl_balance = 0;
}
}
}
}
tree->avl_count--;
tree->avl_generation++;
return (void *) item;
}
/* Refreshes the stack of parent pointers in |trav|
and updates its generation number. */
static void
trav_refresh (struct avl_traverser *trav)
{
assert (trav != NULL);
trav->avl_generation = trav->avl_table->avl_generation;
if (trav->avl_node != NULL)
{
avl_comparison_func *cmp = trav->avl_table->avl_compare;
void *param = trav->avl_table->avl_param;
struct avl_node *node = trav->avl_node;
struct avl_node *i;
trav->avl_height = 0;
for (i = trav->avl_table->avl_root; i != node; )
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
assert (i != NULL);
trav->avl_stack[trav->avl_height++] = i;
i = i->avl_link[cmp (node->avl_data, i->avl_data, param) > 0];
}
}
}
/* Initializes |trav| for use with |tree|
and selects the null node. */
void
avl_t_init (struct avl_traverser *trav, struct avl_table *tree)
{
trav->avl_table = tree;
trav->avl_node = NULL;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its least-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
avl_t_first (struct avl_traverser *trav, struct avl_table *tree)
{
struct avl_node *x;
assert (tree != NULL && trav != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
x = tree->avl_root;
if (x != NULL)
while (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
}
trav->avl_node = x;
return x != NULL ? x->avl_data : NULL;
}
/* Initializes |trav| for |tree|
and selects and returns a pointer to its greatest-valued item.
Returns |NULL| if |tree| contains no nodes. */
void *
avl_t_last (struct avl_traverser *trav, struct avl_table *tree)
{
struct avl_node *x;
assert (tree != NULL && trav != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
x = tree->avl_root;
if (x != NULL)
while (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
}
trav->avl_node = x;
return x != NULL ? x->avl_data : NULL;
}
/* Searches for |item| in |tree|.
If found, initializes |trav| to the item found and returns the item
as well.
If there is no matching item, initializes |trav| to the null item
and returns |NULL|. */
void *
avl_t_find (struct avl_traverser *trav, struct avl_table *tree, void *item)
{
struct avl_node *p, *q;
assert (trav != NULL && tree != NULL && item != NULL);
trav->avl_table = tree;
trav->avl_height = 0;
trav->avl_generation = tree->avl_generation;
for (p = tree->avl_root; p != NULL; p = q)
{
int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
if (cmp < 0)
q = p->avl_link[0];
else if (cmp > 0)
q = p->avl_link[1];
else /* |cmp == 0| */
{
trav->avl_node = p;
return p->avl_data;
}
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = p;
}
trav->avl_height = 0;
trav->avl_node = NULL;
return NULL;
}
/* Attempts to insert |item| into |tree|.
If |item| is inserted successfully, it is returned and |trav| is
initialized to its location.
If a duplicate is found, it is returned and |trav| is initialized to
its location. No replacement of the item occurs.
If a memory allocation failure occurs, |NULL| is returned and |trav|
is initialized to the null item. */
void *
avl_t_insert (struct avl_traverser *trav, struct avl_table *tree, void *item)
{
void **p;
assert (trav != NULL && tree != NULL && item != NULL);
p = avl_probe (tree, item);
if (p != NULL)
{
trav->avl_table = tree;
trav->avl_node =
((struct avl_node *)
((char *) p - offsetof (struct avl_node, avl_data)));
trav->avl_generation = tree->avl_generation - 1;
return *p;
}
else
{
avl_t_init (trav, tree);
return NULL;
}
}
/* Initializes |trav| to have the same current node as |src|. */
void *
avl_t_copy (struct avl_traverser *trav, const struct avl_traverser *src)
{
assert (trav != NULL && src != NULL);
if (trav != src)
{
trav->avl_table = src->avl_table;
trav->avl_node = src->avl_node;
trav->avl_generation = src->avl_generation;
if (trav->avl_generation == trav->avl_table->avl_generation)
{
trav->avl_height = src->avl_height;
memcpy (trav->avl_stack, (const void *) src->avl_stack,
sizeof *trav->avl_stack * trav->avl_height);
}
}
return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
}
/* Returns the next data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
avl_t_next (struct avl_traverser *trav)
{
struct avl_node *x;
assert (trav != NULL);
if (trav->avl_generation != trav->avl_table->avl_generation)
trav_refresh (trav);
x = trav->avl_node;
if (x == NULL)
{
return avl_t_first (trav, trav->avl_table);
}
else if (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
while (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
}
}
else
{
struct avl_node *y;
do
{
if (trav->avl_height == 0)
{
trav->avl_node = NULL;
return NULL;
}
y = x;
x = trav->avl_stack[--trav->avl_height];
}
while (y == x->avl_link[1]);
}
trav->avl_node = x;
return x->avl_data;
}
/* Returns the previous data item in inorder
within the tree being traversed with |trav|,
or if there are no more data items returns |NULL|. */
void *
avl_t_prev (struct avl_traverser *trav)
{
struct avl_node *x;
assert (trav != NULL);
if (trav->avl_generation != trav->avl_table->avl_generation)
trav_refresh (trav);
x = trav->avl_node;
if (x == NULL)
{
return avl_t_last (trav, trav->avl_table);
}
else if (x->avl_link[0] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[0];
while (x->avl_link[1] != NULL)
{
assert (trav->avl_height < AVL_MAX_HEIGHT);
trav->avl_stack[trav->avl_height++] = x;
x = x->avl_link[1];
}
}
else
{
struct avl_node *y;
do
{
if (trav->avl_height == 0)
{
trav->avl_node = NULL;
return NULL;
}
y = x;
x = trav->avl_stack[--trav->avl_height];
}
while (y == x->avl_link[0]);
}
trav->avl_node = x;
return x->avl_data;
}
/* Returns |trav|'s current item. */
void *
avl_t_cur (struct avl_traverser *trav)
{
assert (trav != NULL);
return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
}
/* Replaces the current item in |trav| by |new| and returns the item replaced.
|trav| must not have the null item selected.
The new item must not upset the ordering of the tree. */
void *
avl_t_replace (struct avl_traverser *trav, void *new)
{
void *old;
assert (trav != NULL && trav->avl_node != NULL && new != NULL);
old = trav->avl_node->avl_data;
trav->avl_node->avl_data = new;
return old;
}
static void
copy_error_recovery (struct avl_node **stack, int height,
struct avl_table *new, avl_item_func *destroy)
{
assert (stack != NULL && height >= 0 && new != NULL);
for (; height > 2; height -= 2)
stack[height - 1]->avl_link[1] = NULL;
avl_destroy (new, destroy);
}
/* Copies |org| to a newly created tree, which is returned.
If |copy != NULL|, each data item in |org| is first passed to |copy|,
and the return values are inserted into the tree,
with |NULL| return values taken as indications of failure.
On failure, destroys the partially created new tree,
applying |destroy|, if non-null, to each item in the new tree so far,
and returns |NULL|.
If |allocator != NULL|, it is used for allocation in the new tree.
Otherwise, the same allocator used for |org| is used. */
struct avl_table *
avl_copy (const struct avl_table *org, avl_copy_func *copy,
avl_item_func *destroy, struct libavl_allocator *allocator)
{
struct avl_node *stack[2 * (AVL_MAX_HEIGHT + 1)];
int height = 0;
struct avl_table *new;
const struct avl_node *x;
struct avl_node *y;
assert (org != NULL);
new = avl_create (org->avl_compare, org->avl_param,
allocator != NULL ? allocator : org->avl_alloc);
if (new == NULL)
return NULL;
new->avl_count = org->avl_count;
if (new->avl_count == 0)
return new;
x = (const struct avl_node *) &org->avl_root;
y = (struct avl_node *) &new->avl_root;
for (;;)
{
while (x->avl_link[0] != NULL)
{
assert (height < 2 * (AVL_MAX_HEIGHT + 1));
y->avl_link[0] =
new->avl_alloc->libavl_malloc (new->avl_alloc,
sizeof *y->avl_link[0]);
if (y->avl_link[0] == NULL)
{
if (y != (struct avl_node *) &new->avl_root)
{
y->avl_data = NULL;
y->avl_link[1] = NULL;
}
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
stack[height++] = (struct avl_node *) x;
stack[height++] = y;
x = x->avl_link[0];
y = y->avl_link[0];
}
y->avl_link[0] = NULL;
for (;;)
{
y->avl_balance = x->avl_balance;
if (copy == NULL)
y->avl_data = x->avl_data;
else
{
y->avl_data = copy (x->avl_data, org->avl_param);
if (y->avl_data == NULL)
{
y->avl_link[1] = NULL;
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
}
if (x->avl_link[1] != NULL)
{
y->avl_link[1] =
new->avl_alloc->libavl_malloc (new->avl_alloc,
sizeof *y->avl_link[1]);
if (y->avl_link[1] == NULL)
{
copy_error_recovery (stack, height, new, destroy);
return NULL;
}
x = x->avl_link[1];
y = y->avl_link[1];
break;
}
else
y->avl_link[1] = NULL;
if (height <= 2)
return new;
y = stack[--height];
x = stack[--height];
}
}
}
/* Frees storage allocated for |tree|.
If |destroy != NULL|, applies it to each data item in inorder. */
void
avl_destroy (struct avl_table *tree, avl_item_func *destroy)
{
struct avl_node *p, *q;
assert (tree != NULL);
for (p = tree->avl_root; p != NULL; p = q)
if (p->avl_link[0] == NULL)
{
q = p->avl_link[1];
if (destroy != NULL && p->avl_data != NULL)
destroy (p->avl_data, tree->avl_param);
tree->avl_alloc->libavl_free (tree->avl_alloc, p);
}
else
{
q = p->avl_link[0];
p->avl_link[0] = q->avl_link[1];
q->avl_link[1] = p;
}
tree->avl_alloc->libavl_free (tree->avl_alloc, tree);
}
/* Allocates |size| bytes of space using |malloc()|.
Returns a null pointer if allocation fails. */
void *
avl_malloc (struct libavl_allocator *allocator, size_t size)
{
assert (allocator != NULL && size > 0);
return malloc (size);
}
/* Frees |block|. */
void
avl_free (struct libavl_allocator *allocator, void *block)
{
assert (allocator != NULL && block != NULL);
free (block);
}
/* Default memory allocator that uses |malloc()| and |free()|. */
struct libavl_allocator avl_allocator_default =
{
avl_malloc,
avl_free
};
#undef NDEBUG
#include <assert.h>
/* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */
void
(avl_assert_insert) (struct avl_table *table, void *item)
{
void **p = avl_probe (table, item);
assert (p != NULL && *p == item);
}
/* Asserts that |avl_delete()| really removes |item| from |table|,
and returns the removed item. */
void *
(avl_assert_delete) (struct avl_table *table, void *item)
{
void *p = avl_delete (table, item);
assert (p != NULL);
return p;
}
-115
View File
@@ -1,115 +0,0 @@
/* Produced by texiweb from libavl.w on 2002/08/24 at 13:21. */
/* libavl - library for manipulation of binary trees.
Copyright (C) 1998-2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
The author may be contacted at <blp@gnu.org> on the Internet, or
write to Ben Pfaff, Stanford University, Computer Science Dept., 353
Serra Mall, Stanford CA 94305, USA.
*/
#ifndef AVL_H
#define AVL_H 1
#include <stddef.h>
/* Function types. */
typedef int avl_comparison_func (const void *avl_a, const void *avl_b,
void *avl_param);
typedef void avl_item_func (void *avl_item, void *avl_param);
typedef void *avl_copy_func (void *avl_item, void *avl_param);
#ifndef LIBAVL_ALLOCATOR
#define LIBAVL_ALLOCATOR
/* Memory allocator. */
struct libavl_allocator
{
void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
};
#endif
/* Default memory allocator. */
extern struct libavl_allocator avl_allocator_default;
void *avl_malloc (struct libavl_allocator *, size_t);
void avl_free (struct libavl_allocator *, void *);
/* Maximum AVL height. */
#ifndef AVL_MAX_HEIGHT
#define AVL_MAX_HEIGHT 32
#endif
/* Tree data structure. */
struct avl_table
{
struct avl_node *avl_root; /* Tree's root. */
avl_comparison_func *avl_compare; /* Comparison function. */
void *avl_param; /* Extra argument to |avl_compare|. */
struct libavl_allocator *avl_alloc; /* Memory allocator. */
size_t avl_count; /* Number of items in tree. */
unsigned long avl_generation; /* Generation number. */
};
/* An AVL tree node. */
struct avl_node
{
struct avl_node *avl_link[2]; /* Subtrees. */
void *avl_data; /* Pointer to data. */
signed char avl_balance; /* Balance factor. */
};
/* AVL traverser structure. */
struct avl_traverser
{
struct avl_table *avl_table; /* Tree being traversed. */
struct avl_node *avl_node; /* Current node in tree. */
struct avl_node *avl_stack[AVL_MAX_HEIGHT];
/* All the nodes above |avl_node|. */
size_t avl_height; /* Number of nodes in |avl_parent|. */
unsigned long avl_generation; /* Generation number. */
};
/* Table functions. */
struct avl_table *avl_create (avl_comparison_func *, void *,
struct libavl_allocator *);
struct avl_table *avl_copy (const struct avl_table *, avl_copy_func *,
avl_item_func *, struct libavl_allocator *);
void avl_destroy (struct avl_table *, avl_item_func *);
void **avl_probe (struct avl_table *, void *);
void *avl_insert (struct avl_table *, void *);
void *avl_replace (struct avl_table *, void *);
void *avl_delete (struct avl_table *, const void *);
void *avl_find (const struct avl_table *, const void *);
void avl_assert_insert (struct avl_table *, void *);
void *avl_assert_delete (struct avl_table *, void *);
#define avl_count(table) ((size_t) (table)->avl_count)
/* Table traverser functions. */
void avl_t_init (struct avl_traverser *, struct avl_table *);
void *avl_t_first (struct avl_traverser *, struct avl_table *);
void *avl_t_last (struct avl_traverser *, struct avl_table *);
void *avl_t_find (struct avl_traverser *, struct avl_table *, void *);
void *avl_t_insert (struct avl_traverser *, struct avl_table *, void *);
void *avl_t_copy (struct avl_traverser *, const struct avl_traverser *);
void *avl_t_next (struct avl_traverser *);
void *avl_t_prev (struct avl_traverser *);
void *avl_t_cur (struct avl_traverser *);
void *avl_t_replace (struct avl_traverser *, void *);
#endif /* avl.h */
-787
View File
@@ -1,787 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include "avl.h"
#define NUMBER_OF_TAX_FIELDS 22
char *rankLabels [NUMBER_OF_TAX_FIELDS] =
{"root" ,
"superkingdom",
"kingdom" ,
"subkingdom" ,
"superphylum" ,
"phylum" ,
"subphylum" ,
"superclass" ,
"class" ,
"subclass" ,
"superorder" ,
"order" ,
"suborder" ,
"superfamily" ,
"family" ,
"subfamily" ,
"tribe" ,
"subtribe" ,
"genus" ,
"subgenus" ,
"species" ,
"subspecies"
};
char noValue[] = "n\t",
rootValue[] = "toor\t",
usage[] = "Incorrect number of arguments.\nExpected arguments: tax_id->label file, tax_id->hierarchy file, input file (gid taxid pairs), output file (24 columns)";
/*#define DEBUG_ME*/
/*---------------------------------------------------------------------------------------------------- */
void check_pointer (void*);
/*---------------------------------------------------------------------------------------------------- */
struct avl_table * nameTagAVL = NULL,
* rankLabelAVL = NULL;
#define DEFAULT_STRING_ALLOC 16L
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString
{
char *sData;
long sLength,
saLength;
}
*globalNameBuffer;
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString *allocateNewString (void)
{
struct bufferedString *newS = (struct bufferedString*)malloc (sizeof (struct bufferedString));
check_pointer (newS);
check_pointer (newS->sData = (char*)malloc (DEFAULT_STRING_ALLOC+1));
newS->sLength = 0;
newS->saLength = DEFAULT_STRING_ALLOC;
newS->sData[0] = 0;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
void clear_buffered_string (struct bufferedString* theString)
{
theString->sLength = 0;
}
/*---------------------------------------------------------------------------------------------------- */
void appendCharacterToString (struct bufferedString * s, const char c)
{
long addThis;
if (s->saLength == s->sLength)
{
addThis = s->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
s->saLength += addThis;
check_pointer (s->sData = realloc (s->sData,s->saLength+1));
}
s->sData[s->sLength] = c;
s->sData[++s->sLength] = 0;
}
/*---------------------------------------------------------------------------------------------------- */
long appendRangeToString (struct bufferedString * d, struct bufferedString *s, long from, long to)
{
long addThis,
pl = to-from+1;
if (pl<=0)
return -1;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = from; addThis <=to; addThis++)
d->sData[d->sLength++] = s->sData[addThis];
d->sData[d->sLength] = 0;
return pl;
}
/*---------------------------------------------------------------------------------------------------- */
void appendCharRangeToString (struct bufferedString * d, char * buffer)
{
long addThis,
pl = strlen(buffer);
if (pl<=0)
return;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = 0; addThis <pl; addThis++)
d->sData[d->sLength++] = buffer[addThis];
d->sData[d->sLength] = 0;
}
/*---------------------------------------------------------------------------------------------------- */
long appendCharBufferToString (struct bufferedString * d, const char * b)
{
long addThis,
pl = strlen (b);
if (pl<=0)
return -1;
if (d->saLength < d->sLength + pl)
{
addThis = d->saLength / 8;
if (DEFAULT_STRING_ALLOC > addThis)
addThis = DEFAULT_STRING_ALLOC;
if (addThis < pl)
addThis = pl;
d->saLength += addThis;
check_pointer (d->sData = realloc (d->sData,d->saLength+1));
}
for (addThis = 0; addThis <pl; addThis++)
d->sData[d->sLength++] = b[addThis];
d->sData[d->sLength] = 0;
return pl;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
struct storedNameTag
{
long taxID,
startIndex,
length;
char taxonomy_level;
struct storedNameTag * parent;
};
/*---------------------------------------------------------------------------------------------------- */
struct storedNameTag * allocateNameTag (void)
{
struct storedNameTag *newS = (struct storedNameTag*)malloc (sizeof (struct storedNameTag));
check_pointer (newS);
newS->taxID = 0;
newS->startIndex = 0;
newS->length = 0;
newS->parent = NULL;
newS->taxonomy_level = -1;
return newS;
}
/*---------------------------------------------------------------------------------------------------- */
int compare_tags (const void *avl_a, const void *avl_b, void * xtra)
{
long n1 = ((struct storedNameTag*)avl_a)->taxID;
long n2 = ((struct storedNameTag*)avl_b)->taxID;
if (n1 > n2) return 1;
if (n1 < n2) return -1;
return 0;
}
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString * nameByID (long taxID)
{
static struct storedNameTag queryTag;
struct storedNameTag * res;
struct bufferedString * resStr = NULL;
queryTag.taxID = taxID;
res = (struct storedNameTag *)avl_find(nameTagAVL, &queryTag);
if (res)
{
resStr = allocateNewString();
appendRangeToString(resStr,globalNameBuffer,res->startIndex,res->startIndex+res->length-1);
}
return resStr;
}
/*---------------------------------------------------------------------------------------------------- */
struct storedNameTag * tagByID (long taxID)
{
static struct storedNameTag queryTag;
queryTag.taxID = taxID;
return (struct storedNameTag *)avl_find(nameTagAVL, &queryTag);
}
/*---------------------------------------------------------------------------------------------------- */
struct bufferedString * walkPath (long taxID)
{
struct storedNameTag * currentTag = tagByID(taxID);
if (!currentTag)
return NULL;
struct bufferedString * resStr = allocateNewString();
long k,
level = NUMBER_OF_TAX_FIELDS-1;
char // buffer [32],
first_record = 1;
while (currentTag) {
if (currentTag->taxonomy_level >= 0)
{
if (first_record)
{
for (k = currentTag->taxonomy_level+1; k < NUMBER_OF_TAX_FIELDS; k++)
appendCharBufferToString(resStr,noValue);
first_record = 0;
}
else
{
for (k=currentTag->taxonomy_level+1; k<level; k++)
appendCharBufferToString(resStr,noValue);
}
//appendCharacterToString(resStr,')');
//sprintf (buffer, "%d", currentTag->taxonomy_level);
//for (k=strlen(buffer)-1; k>=0; k--)
// appendCharacterToString(resStr,buffer[k]);
//appendCharacterToString(resStr,'(');
for (k=currentTag->startIndex+currentTag->length-1; k>=currentTag->startIndex; k--)
appendCharacterToString(resStr,globalNameBuffer->sData[k]);
appendCharacterToString(resStr,'\t');
level = currentTag->taxonomy_level;
}
currentTag = currentTag->parent;
}
for (k = level-1; k ; k--)
appendCharBufferToString(resStr,noValue);
appendCharBufferToString(resStr,rootValue);
return resStr;
}
/*---------------------------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------------------------- */
void check_pointer (void * p)
{
if (p == NULL)
{
fprintf (stderr,"Memory allocation error\n");
exit (1);
}
}
/*---------------------------------------------------------------------------------------------------- */
int compare_strings (struct bufferedString * s1, struct bufferedString * s2)
{
long upTo,
i;
if (s1->sLength>s2->sLength)
upTo = s2->sLength;
else
upTo = s1->sLength;
for (i=0; i<upTo; i++)
{
int res = (s1->sData[i]-s2->sData[i]);
if (res < 0)
return -1;
else
if (res>0)
return 1;
}
if (s1->sLength == s2->sLength)
return 0;
return 1-2*(s1->sLength<s2->sLength);
}
/*---------------------------------------------------------------------------------------------------- */
int compare_tag_strings (const void *avl_a, const void *avl_b, void * xtra)
{
struct storedNameTag* s1 = (struct storedNameTag*)avl_a;
struct storedNameTag* s2 = (struct storedNameTag*)avl_b;
char *buffa = ((struct bufferedString*)xtra)->sData;
long upTo,
i;
if (s1->length>s2->length)
upTo = s2->length;
else
upTo = s1->length;
for (i=0; i<upTo; i++)
{
int res = (int)buffa[s1->startIndex+i]-buffa[s2->startIndex+i];
if (res < 0)
return -1;
else
if (res>0)
return 1;
}
if (s1->length == s2->length)
return 0;
return 1-2*(s1->length<s2->length);
}
/*---------------------------------------------------------------------------------------------------- */
void destroy_string (struct bufferedString* aStr)
{
free (aStr->sData);
free (aStr);
}
/*---------------------------------------------------------------------------------------------------- */
void reportError (char * theMessage)
{
fprintf (stderr, "\nERROR: %s\n", theMessage);
exit (1);
}
/*---------------------------------------------------------------------------------------------------- */
void reportErrorLine (char * theMessage, long lineID)
{
fprintf (stderr, "\nERROR in line %d: %s\n", lineID, theMessage);
exit (1);
}
/*---------------------------------------------------------------------------------------------------- */
int main (int argc, const char * argv[])
{
FILE *inFile,
*structFile,
*queryFile,
*outFile;
struct bufferedString *scientificName = allocateNewString(),
**currentBuffers,
*qry;
struct storedNameTag *aTag,
*aTag2,
*aTag3 = allocateNameTag();
char automatonState = 0,
currentField = 0,
currentChar = 0,
taxonBuffer [1024],
firstLine;
long currentLineID = 1,
expectedFields = 4,
indexer,
indexer2;
if (argc != 5)
{
fprintf (stderr,"%s\n", usage);
return 1;
}
appendCharBufferToString(scientificName, "scientific name");
globalNameBuffer = allocateNewString();
currentBuffers = (struct bufferedString**)malloc (expectedFields*sizeof (struct bufferedString*));
nameTagAVL = avl_create (compare_tags, NULL, NULL);
rankLabelAVL = avl_create (compare_tag_strings, globalNameBuffer, NULL);
for (indexer = 0; indexer < expectedFields; indexer++)
currentBuffers[indexer] = allocateNewString();
for (indexer = 0; indexer < NUMBER_OF_TAX_FIELDS; indexer++)
{
aTag = allocateNameTag ();
aTag->startIndex = globalNameBuffer->sLength;
appendCharBufferToString (globalNameBuffer,rankLabels[indexer]);
aTag->taxonomy_level = indexer;
aTag->length = strlen(rankLabels[indexer]);
if ((aTag2 = *avl_probe(rankLabelAVL, aTag)) != aTag)
reportErrorLine ("Duplicate taxonomic rank name", aTag2->taxonomy_level);
}
inFile = fopen (argv[1], "rb");
if (!inFile)
{
fprintf (stderr,"Failed to open input file: %s\n", argv[1]);
return 1;
}
structFile = fopen (argv[2], "rb");
if (!structFile)
{
fprintf (stderr,"Failed to open input file: %s\n", argv[2]);
return 1;
}
queryFile = fopen (argv[3], "rb");
if (!queryFile)
{
fprintf (stderr,"Failed to open input file: %s\n", argv[3]);
return 1;
}
outFile = fopen (argv[4], "w");
if (!outFile)
{
fprintf (stderr,"Failed to open output file: %s\n", argv[3]);
return 1;
}
currentChar = fgetc(inFile);
while (!feof(inFile))
{
switch (automatonState)
{
case 0: /* start of the line; expecting numbers */
if (currentChar >= '0' && currentChar <='9')
{
automatonState = 1; /* reading sequence ID */
appendCharacterToString(currentBuffers[currentField],currentChar);
}
else
if (!(currentChar == '\n' || currentChar == '\r'))
reportErrorLine ("Could not find a valid sequence ID to start the line",currentLineID);
break;
case 1: /* reading sequence ID */
if (currentChar >= '0' && currentChar <='9')
appendCharacterToString(currentBuffers[currentField],currentChar);
else
if (currentChar == '\t')
automatonState = 2;
else
reportErrorLine ("Expected a tab following the tax ID",currentLineID);
break;
case 2: /* looking for a | */
if (currentChar != '|')
reportErrorLine ("Expected a '|' following the tab",currentLineID);
else
automatonState = 3;
break;
case 3: /* looking for a \t or a \n|\r*/
if (currentChar == '\t')
{
automatonState = 4;
currentField ++;
if (currentField == expectedFields)
reportErrorLine ("Too many fields",currentLineID);
}
else
if (currentChar == '\n' || currentChar == '\r')
{
if (currentField < expectedFields-1)
reportErrorLine ("Too few fields",currentLineID);
automatonState = 0;
currentLineID ++;
currentField = 0;
if (compare_strings(currentBuffers[3],scientificName)==0)
{
aTag = allocateNameTag();
aTag->taxID = atoi(currentBuffers[0]->sData);
aTag->startIndex = globalNameBuffer->sLength;
aTag->length = appendRangeToString(globalNameBuffer,currentBuffers[1],0,currentBuffers[1]->sLength-1);
if (aTag->length <= 0)
reportErrorLine ("Empty name tag",currentLineID);
if (*avl_probe(nameTagAVL,aTag) != aTag)
reportErrorLine ("Duplicate name tag",currentLineID);
}
for (indexer = 0; indexer < expectedFields; indexer++)
clear_buffered_string(currentBuffers[indexer]);
}
else
reportErrorLine ("Expected a tab following the '|'",currentLineID);
break;
case 4: /* read a field */
if (currentChar == '\t')
automatonState = 2;
else
if (currentChar == '\n' || currentChar == '\r')
reportErrorLine ("Unexpected end-of-line",currentLineID);
else
appendCharacterToString(currentBuffers[currentField],currentChar);
break;
}
currentChar = fgetc(inFile);
}
fclose (inFile);
for (indexer = 0; indexer < expectedFields; indexer++)
destroy_string(currentBuffers[indexer]);
free(currentBuffers);
expectedFields = 13;
currentBuffers = (struct bufferedString**)malloc (expectedFields*sizeof (struct bufferedString*));
for (indexer = 0; indexer < expectedFields; indexer++)
currentBuffers[indexer] = allocateNewString();
automatonState = 0;
currentLineID = 1;
currentField = 0;
currentChar = fgetc(structFile);
while (!feof(structFile))
{
switch (automatonState)
{
case 0: /* start of the line; expecting numbers */
if (currentChar >= '0' && currentChar <='9')
{
automatonState = 1; /* reading sequence ID */
appendCharacterToString(currentBuffers[currentField],currentChar);
}
else
if (!(currentChar == '\n' || currentChar == '\r'))
reportErrorLine ("Could not find a valid sequence ID to start the line",currentLineID);
break;
case 1: /* reading sequence ID */
if (currentChar >= '0' && currentChar <='9')
appendCharacterToString(currentBuffers[currentField],currentChar);
else
if (currentChar == '\t')
automatonState = 2;
else
reportErrorLine ("Expected a tab following the tax ID",currentLineID);
break;
case 2: /* looking for a | */
if (currentChar != '|')
reportErrorLine ("Expected a '|' following the tab",currentLineID);
else
automatonState = 3;
break;
case 3: /* looking for a \t or a \n|\r*/
if (currentChar == '\t')
{
automatonState = 4;
currentField ++;
if (currentField == expectedFields)
reportErrorLine ("Too many fields",currentLineID);
}
else
if (currentChar == '\n' || currentChar == '\r')
{
if (currentField < expectedFields-1)
reportErrorLine ("Too few fields",currentLineID);
aTag = tagByID(atoi(currentBuffers[0]->sData));
aTag2 = tagByID(atoi(currentBuffers[1]->sData));
if (! (aTag && aTag2))
reportErrorLine ("Invalid ID tag",currentLineID);
if (aTag2 != aTag)
{
aTag->parent = aTag2;
aTag3->startIndex = globalNameBuffer->sLength;
aTag3->length = currentBuffers[2]->sLength;
appendRangeToString (globalNameBuffer, currentBuffers[2], 0, currentBuffers[2]->sLength-1);
aTag2 = avl_find (rankLabelAVL, aTag3);
if (aTag2)
aTag->taxonomy_level = aTag2->taxonomy_level;
globalNameBuffer->sLength = aTag3->startIndex;
}
currentField = 0;
automatonState = 0;
currentLineID ++;
for (indexer = 0; indexer < expectedFields; indexer++)
clear_buffered_string(currentBuffers[indexer]);
}
else
reportErrorLine ("Expected a tab following the '|'",currentLineID);
break;
case 4: /* read a field */
if (currentChar == '\t')
automatonState = 2;
else
if (currentChar == '\n' || currentChar == '\r')
reportErrorLine ("Unexpected end-of-line",currentLineID);
else
appendCharacterToString(currentBuffers[currentField],currentChar);
break;
}
currentChar = fgetc(structFile);
}
fclose (structFile);
for (indexer = 0; indexer < expectedFields; indexer++)
destroy_string(currentBuffers[indexer]);
free(currentBuffers);
expectedFields = 2;
currentBuffers = (struct bufferedString**)malloc (expectedFields*sizeof (struct bufferedString*));
for (indexer = 0; indexer <= expectedFields; indexer++)
currentBuffers[indexer] = allocateNewString();
automatonState = 0;
currentLineID = 1;
currentField = 0;
firstLine = 1;
currentChar = fgetc(queryFile);
while (!feof(queryFile))
{
switch (automatonState)
{
case 0: /* start of the line; expecting numbers */
if (!isspace(currentChar))
{
automatonState = 1; /* reading sequence ID */
appendCharacterToString(currentBuffers[currentField],currentChar);
}
else
if (!(currentChar == '\n' || currentChar == '\r'))
reportErrorLine ("Could not find a valid sequence ID to start the line",currentLineID);
break;
case 1: /* reading sequence ID */
if ((currentField == 1 && currentChar >= '0' && currentChar <='9')||(currentField == 0 && currentChar != '\n' && currentChar != '\r' && currentChar != '\t'))
appendCharacterToString(currentBuffers[currentField],currentChar);
else
if (currentChar == '\t')
{
automatonState = 1;
currentField ++;
if (currentField == expectedFields)
automatonState = 2;
}
else
if (currentChar == '\n' || currentChar == '\r')
{
currentField++;
automatonState = 2;
ungetc (currentChar,queryFile);
}
else
reportErrorLine ("Expected a tab following a Tax/GID",currentLineID);
break;
case 2:
if (currentChar == '\n' || currentChar == '\r')
{
if (currentField == expectedFields)
{
indexer2 = atoi (currentBuffers[1]->sData); // TaxID
qry = walkPath (indexer2);
if (firstLine)
firstLine = 0;
else
fputc ('\n',outFile);
fprintf (outFile,"%s\t%d", currentBuffers[0]->sData, indexer2);
if (qry)
{
for (indexer = qry->sLength-1; indexer >= 0; indexer--)
fputc (qry->sData[indexer], outFile);
destroy_string(qry);
}
else
fprintf (outFile, "\tNULL");
if (currentBuffers[expectedFields]->sLength)
fprintf (outFile, "\t%s", currentBuffers[expectedFields]->sData);
}
currentLineID ++;
currentField = 0;
for (indexer = 0; indexer <= expectedFields; indexer++)
clear_buffered_string(currentBuffers[indexer]);
automatonState = 0;
}
else
appendCharacterToString(currentBuffers[currentField],currentChar);
}
currentChar = fgetc(queryFile);
}
fclose (queryFile);
fclose (outFile);
return 0;
}
-21
View File
@@ -1,21 +0,0 @@
COMPILE
=======
On Max OS X:
$gcc -o taxBuilder -fast avl.c main.c
On Linux:
Insert the following near the top of main.c
#define isnumber (c) ( (c>='0') && (c<='9'))
Replace -fast with -O3 (the letter 'O'):
$gcc -o taxBuilder -O3 avl.c main.c
INSTALL
=======
Place the binary into a directory that is listed in setup_paths.sh script located in the root of Galaxy installation