#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "INLINE.h"
# include "src/types.h"
# include "src/Identifiable.h"
# include "src/Writable.h"
# include "src/Listable.h"
# include "src/Node.h"
Node *create(const char *classname) {
Node *self;
Newx(self,1,Node);
initialize_node(self);
return self;
}
void initialize_node(Node* self) {
initialize_listable((Listable*)self);
self->parent = NULL;
self->rank = NULL;
self->tree = NULL;
self->branch_length = 0.0;
((Identifiable*)self)->_type = _NODE_;
((Identifiable*)self)->_container = _TREE_;
((Identifiable*)self)->_index = _NODE_IDX_;
}
double get_branch_length(Node* self) {
return self->branch_length;
}
Node* set_raw_branch_length(Node* self, ...) {
Inline_Stack_Vars; // handle variable argument list
if ( Inline_Stack_Items == 2 && Inline_Stack_Item(1) != NULL ) {
SV* value = Inline_Stack_Item(1);
if ( looks_like_number(value) ) {
self->branch_length = SvNV(value);
}
}
else {
self->branch_length = 0.0;
}
return self;
}
Node* set_tree(Node* self, Tree* tree) {
self->tree = tree;
return self;
}
Tree* get_tree(Node* self) {
return self->tree;
}
char* get_rank(Node* self) {
return self->rank;
}
Node* set_rank(Node* self, char * rank) {
self->rank = savepv(rank);
return self;
}
Node* set_raw_parent( Node* self, ... ) {
Inline_Stack_Vars; // handle variable argument list
if ( Inline_Stack_Items == 2 && Inline_Stack_Item(1) != NULL ) {
self->parent = (Node*)SvIV(SvRV(Inline_Stack_Item(1)));
}
else {
self->parent = NULL;
}
return self;
}
Node* get_parent(Node* self) {
return self->parent;
}
Node* set_raw_child( Node* self, Node* child, ... ) {
Inline_Stack_Vars; // handle variable argument list
// determine where to place the child,
// default -1 means at the end
signed int position = -1;
if ( Inline_Stack_Items > 2 ) {
position = SvIV(Inline_Stack_Item(2));
}
if ( position == -1 ) {
insert((Listable*)self, (Identifiable*)child);
}
else {
insert_at_index((Listable*)self,(Identifiable*)child,position);
}
return self;
}
AV* get_children( Node* self ) {
return ((Listable*)self)->entities;
}
Node* get_first_daughter( Node* self ) {
AV* list = ((Listable*)self)->entities;
if ( av_exists(list,0) ) {
SV* sv = *(av_fetch(list, 0, 0));
return (Node*)SvIV(SvRV(sv));
}
return NULL;
}
int is_child_of( Node* self, Node* parent ) {
if ( self->parent != NULL ) {
return ((Identifiable*)self->parent)->id == ((Identifiable*)parent)->id;
}
return 0;
}
int is_ancestor_of( Node* self, Node* desc ) {
Node* p = desc->parent;
int sid = ((Identifiable*)self)->id;
while( p != NULL ) {
if ( ((Identifiable*)p)->id == sid ) {
return 1;
}
p = p->parent;
}
return 0;
}
int is_terminal( Node* self ) {
return ! av_exists(((Listable*)self)->entities, 0);
}
int is_internal( Node* self ) {
return av_exists(((Listable*)self)->entities, 0);
}
int is_root( Node* self ) {
return self->parent == NULL;
}
void destroy_node(Node* self) {
destroy_listable((Listable*)self);
}
MODULE = Bio::PhyloXS::Forest::Node PACKAGE = Bio::PhyloXS::Forest::Node
PROTOTYPES: DISABLE
Node *
create (classname)
const char * classname
void
initialize_node (self)
Node * self
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
initialize_node(self);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */
double
get_branch_length (self)
Node * self
Node *
set_raw_branch_length (self, ...)
Node * self
PREINIT:
I32* temp;
CODE:
temp = PL_markstack_ptr++;
RETVAL = set_raw_branch_length(self);
PL_markstack_ptr = temp;
OUTPUT:
RETVAL
Node *
set_tree (self, tree)
Node * self
Tree * tree
Tree *
get_tree (self)
Node * self
char *
get_rank (self)
Node * self
Node *
set_rank (self, rank)
Node * self
char * rank
Node *
set_raw_parent (self, ...)
Node * self
PREINIT:
I32* temp;
CODE:
temp = PL_markstack_ptr++;
RETVAL = set_raw_parent(self);
PL_markstack_ptr = temp;
OUTPUT:
RETVAL
Node *
get_parent (self)
Node * self
Node *
set_raw_child (self, child, ...)
Node * self
Node * child
PREINIT:
I32* temp;
CODE:
temp = PL_markstack_ptr++;
RETVAL = set_raw_child(self, child);
PL_markstack_ptr = temp;
OUTPUT:
RETVAL
AV *
get_children (self)
Node * self
Node *
get_first_daughter (self)
Node * self
int
is_child_of (self, parent)
Node * self
Node * parent
int
is_ancestor_of (self, desc)
Node * self
Node * desc
int
is_terminal (self)
Node * self
int
is_internal (self)
Node * self
int
is_root (self)
Node * self
void
destroy_node (self)
Node * self
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
destroy_node(self);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */