24 #define GBT_PUT_DATA 1
25 #define GBT_GET_SIZE 0
51 bool deleteSelf =
false;
78 if (removed) (*removed)++;
96 if (tree->
name && groups_removed) (*groups_removed)++;
127 if (idx>max_idx) max_idx = idx;
150 if (idx>best_idx && idx<infrontof_idx) {
152 gb_infrontof = gb_tree;
162 int best_idx = INT_MAX;
166 if (idx>behind_idx && idx<best_idx) {
214 if (!error) error =
GB_write_int(gb_tree_order_flag, 1);
217 if (error)
GBK_terminatef(
"failed to order trees (Reason: %s)", error);
241 if (em == new_group_name || em[-1] ==
' ' || em[-1] ==
'=') {
248 size_t len = strlen(new_group_name);
253 error =
"Invalid empty group name";
259 const char *
label = new_group_name;
263 while (bootstrap<100.0) bootstrap *= 100.0;
264 while (bootstrap>100.0) bootstrap /= 100.0;
269 buf.
cat(
" (would be misinterpreted as ");
271 else { buf.
cat(
"plain inner node"); }
272 buf.
cat(
" with a support value of "); buf.
nprintf(20,
"%.0f%%", bootstrap);
273 buf.
cat(
" if re-imported from newick file)");
280 if (!error && pedantic) {
282 const char *num =
"0123456789.";
283 size_t numAtStart = strspn(new_group_name, num);
285 if (numAtStart && !new_group_name[numAtStart]) {
286 GB_warningf(
"Warning: group name '%s' may be misinterpreted as bootstrap value\n"
287 "(consider prefixing a non-numeric character)",
293 static const char *TAXCHARS =
"/;";
294 const char *seenTaxChar = strpbrk(new_group_name, TAXCHARS);
296 GB_warningf(
"Warning: group name '%s' contains a '%c' (this will interfere with taxonomy!)",
297 new_group_name, seenTaxChar[0]);
301 if (strchr(new_group_name,
'_')) {
302 GB_warningf(
"Warning: group name '%s' contains a '_' (reserved for overlapping groups)",
307 const char *tilde = strrchr(new_group_name,
'~');
308 if (tilde && tilde[1]) {
309 do ++tilde;
while (isdigit(tilde[0]));
311 GB_warningf(
"Warning: group name '%s' contains a '~' followed by digits only (reserved for splitted groups)",
338 bool node_is_used =
false;
366 if (gb_nonid) node_is_used =
true;
391 if (node->
name) strcpy(dest, node->
name);
394 while ((c1 = (
char *)strchr(dest, 1))) {
397 dest += strlen(dest);
403 if (node->
name)
return dest+1+strlen(node->
name)+1;
414 while ((c = *(c1++))) {
415 if (c == 1)
continue;
421 dest += strlen(c1) + 2;
429 strcpy(dest, buffer);
430 dest += strlen(buffer);
433 dest += strlen(buffer)+1;
455 if (gb_tree) error =
GBS_global_string(
"can't change name of existing tree (to '%s')", tree_name);
467 if (!gb_tree) error =
"No tree name given";
482 char *ctree = ARB_calloc<char>(
size_t(t_size+1));
501 if (!
GB_entry(gb_tree,
"keep_ghostnodes")) {
505 for (gb_node =
GB_entry(gb_tree,
"node");
507 gb_node = gb_node_next)
584 char c = *((*data)++);
588 p1 = strchr(*data, 1);
606 p1 = (
char *)strchr(*data,
',');
610 p1 = (
char *)strchr(*data,
';');
614 if ((*startid < size_of_tree) && (node->
gb_node = gb_tree_nodes[*startid])) {
618 if (!node->
name || !node->
name[0]) {
619 char *auto_rename =
ARB_strdup(
"<missing groupname>");
627 warn =
"Empty groupname detected";
636 "Please check tree for corrupted groups, e.g. by using group search",
639 node->
name = auto_rename;
652 if (!node->
leftson) freenull(node);
667 p1 = (
char *)strchr(*data, 1);
678 error =
"Unexpected end of tree definition.";
681 error =
GBS_global_string(
"Can't interpret tree definition (expected 'N' or 'L' - not '%c')", c);
705 if (i<0 || i >= node_count) {
706 error =
"An inner node of the tree is corrupt";
709 gb_tree_nodes[i] = gb_node;
719 char *ts = treeString;
750 free(groupAtRoot_name);
752 freenull(node->
name);
786 error =
"no treename given";
794 error =
"tree not found";
799 error =
"tree is empty";
804 error =
"has no nodes";
809 error =
"old unsupported tree format";
815 if (tree_size) *tree_size = size;
832 GB_export_errorf(
"Failed to read tree '%s' (Reason: %s)", tree_name, error);
926 if (duplicates || show_status) {
945 if (zombies) *zombies = ltd.
zombies;
982 get_leftson()->unlink_from_DB();
983 get_rightson()->unlink_from_DB();
1002 if (!gb_tree)
return false;
1004 return gb_tree_data &&
GB_has_key(gb_tree_data,
"tree_data");
1012 if (!gb_tree)
return NULp;
1023 if (nnodes && *nnodes>maxnodes) {
1024 gb_largest = gb_tree;
1069 if (gb_other == gb_tree) gb_other =
NULp;
1080 if (!gb_tree)
return NULp;
1088 if (strncmp(tree_name,
"tree_", 5) != 0) {
1089 error =
"has to start with 'tree_'";
1094 error =
"no tree selected";
1097 error =
GBS_global_string(
"not a valid treename '%s' (Reason: %s)", tree_name, error);
1133 if (maxTreeNameLen == -1) {
1135 len = strlen(tree_name);
1139 len = maxTreeNameLen;
1143 const int remarkLen = 800;
1146 strcpy(res2, result);
1148 strncat(res2, remark, remarkLen);
1191 typedef std::set<indexed_name> ordered_trees;
1192 ordered_trees trees;
1202 trees.insert(iname);
1206 if (tree_count != (
long)trees.size()) {
1209 typedef std::set<int> ints;
1213 GBDATA *gb_tree = gb_first_tree;
1217 if (used_indices.find(idx) != used_indices.end()) {
1220 if (error)
GBK_terminatef(
"failed to fix tree-order (Reason: %s)", error);
1223 used_indices.clear();
1224 gb_tree = gb_first_tree;
1227 used_indices.insert(idx);
1235 for (ordered_trees::const_iterator t = trees.begin(); t != trees.end(); ++t) {
1242 gb_assert(gb_moved_tree && gb_target_tree);
1253 if (!error) error =
set_tree_idx(gb_moved_tree, target_idx);
1265 error =
"No tree selected";
1268 if (!error && strcmp(source_tree, dest_tree) == 0) error =
"source- and dest-tree are the same";
1272 if (!gb_source_tree) error =
GBS_global_string(
"tree '%s' not found", source_tree);
1277 gb_source_tree =
NULp;
1282 gb_assert(contradicted(error, gb_source_tree));
1283 return gb_source_tree;
1293 gb_assert(contradicted(error, gb_dest_tree));
1294 return gb_dest_tree;
1301 if (gb_source_tree) {
1305 int dest_idx = source_idx+1;
1308 if (!error) error =
set_tree_idx(gb_dest_tree, dest_idx);
1319 if (gb_source_tree) {
1323 if (gb_dest_tree) error =
GB_delete(gb_source_tree);
1329 source_name, dest_name, error);
1337 current[0] = tree->
name;
1355 if (count) *count = size;
1362 if ((format&
nWRAP) && indent>0) { out.
put(
'\n'); out.
nput(
' ', indent); }
1371 if ((format&nWRAP) && indent>0) { out.
put(
'\n'); out.
nput(
' ', indent); }
1377 const char *kgroup =
NULp;
1384 if (remark || group || kgroup) {
1388 if (group) out.
put(
':');
1390 if (group) out.
cat(group);
1392 if (group) out.
cat(
" = ");
1417 if (compact && (format&
nWRAP)) {
1420 char *compact1 =
GBS_regreplace(result,
"/[\n ]*[)]/)/", &error);
1422 char *compact2 =
GBS_regreplace(compact1,
"/[(][\n ]*/(/", &error);
1423 if (compact2) freeset(result, compact2);
1427 fprintf(stderr,
"Error in GBT_tree_2_newick: %s\n", error);
1451 void TEST_tree_names() {
1460 void TEST_tree_contraints() {
1462 const int MIN_LEAFS = 2;
1478 for (
int i = 3; i<=7; ++i) {
1509 void TEST_copy_rename_delete_tree_order() {
1536 size_t species_count;
1540 for (
int i = 0; species[i]; ++i) species2.put(
ARB_strdup(species[i]));
1560 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"8:tree_test|tree_tree2|tree_groups|tree_keeled|tree_keeled_2|tree_nj|tree_nj_bs|tree_removal");
1572 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"8:tree_tree2|tree_groups|tree_keeled|tree_keeled_2|tree_nj|tree_nj_bs|tree_removal|tree_test");
1589 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"8:tree_test|tree_tree2|tree_groups|tree_keeled|tree_keeled_2|tree_nj|tree_nj_bs|tree_removal");
1592 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"8:tree_tree2|tree_test|tree_groups|tree_keeled|tree_keeled_2|tree_nj|tree_nj_bs|tree_removal");
1595 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"8:tree_tree2|tree_test|tree_groups|tree_keeled|tree_keeled_2|tree_removal|tree_nj|tree_nj_bs");
1598 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"8:tree_tree2|tree_test|tree_groups|tree_keeled|tree_keeled_2|tree_removal|tree_nj|tree_nj_bs");
1616 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"9:tree_tree2|tree_test|tree_test_copy|tree_groups|tree_keeled|tree_keeled_2|tree_removal|tree_nj|tree_nj_bs");
1621 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"9:tree_tree2|tree_test|tree_test_copy|tree_groups|tree_keeled|tree_keeled_2|tree_removal|tree_renamed_nj|tree_nj_bs");
1624 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"9:tree_renamed_tree2|tree_test|tree_test_copy|tree_groups|tree_keeled|tree_keeled_2|tree_removal|tree_renamed_nj|tree_nj_bs");
1627 TEST_EXPECT_EQUAL(getTreeOrder(gb_main),
"9:tree_renamed_tree2|tree_test|tree_renamed_test_copy|tree_groups|tree_keeled|tree_keeled_2|tree_removal|tree_renamed_nj|tree_nj_bs");
1703 void TEST_group_keeling() {
1710 const char *topo_tree2 =
"(((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc),(((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste)),((CloTyrob,CloTyro2),CloTyro4)'g2')'outer');";
1711 const char *topo_groups =
"(((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc)'upper',(((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste))'low1',((CloTyrob,CloTyro2)'twoleafs',CloTyro4)'low2')'lower');";
1712 const char *topo_keeled =
"(CloTyrob,(((((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste))'low1',((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc)'upper = !lower')'!low2',CloTyro4)'!twoleafs',CloTyro2));";
1750 const char *topo_keeled2 =
"(CloTyro4,((((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste))'low1',((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc)'upper = !lower')'!low2',(CloTyrob,CloTyro2)'twoleafs'));";
1760 void TEST_tree_remove_leafs() {
1772 const char *org_topo =
"((CloInnoc:0.371,(CloTyrob:0.009,(CloTyro2:0.017,(CloTyro3:1.046,CloTyro4:0.061):0.026):0.017):0.274):0.029,(CloBifer:0.388,((CloCarni:0.120,CurCitre:0.058):1.000,((CloPaste:0.179,(Zombie1:0.120,(CloButy2:0.009,CloButyr:0.000):0.564):0.010):0.131,(CytAquat:0.711,(CelBiazo:0.059,(CorGluta:0.522,(CorAquat:0.084,Zombie2:0.058):0.103):0.054):0.207):0.162):0.124):0.124):0.029);";
1773 const char *rem_marked_topo =
"((CloInnoc:0.371,(CloTyrob:0.009,(CloTyro2:0.017,(CloTyro3:1.046,CloTyro4:0.061):0.026):0.017):0.274):0.029,(CloBifer:0.388,(CloCarni:1.000,((CloPaste:0.179,Zombie1:0.010):0.131,(CelBiazo:0.059,Zombie2:0.054):0.162):0.124):0.124):0.029);";
1774 const char *rem_unmarked_topo =
"(CurCitre:1.000,((Zombie1:0.120,(CloButy2:0.009,CloButyr:0.000):0.564):0.131,(CytAquat:0.711,(CorGluta:0.522,(CorAquat:0.084,Zombie2:0.058):0.103):0.207):0.162):0.124);";
1775 const char *rem_zombies_topo =
"((CloInnoc:0.371,(CloTyrob:0.009,(CloTyro2:0.017,(CloTyro3:1.046,CloTyro4:0.061):0.026):0.017):0.274):0.029,(CloBifer:0.388,((CloCarni:0.120,CurCitre:0.058):1.000,((CloPaste:0.179,(CloButy2:0.009,CloButyr:0.000):0.010):0.131,(CytAquat:0.711,(CelBiazo:0.059,(CorGluta:0.522,CorAquat:0.103):0.054):0.207):0.162):0.124):0.124):0.029);";
1776 const char *kept_marked_topo =
"(CurCitre:1.000,((CloButy2:0.009,CloButyr:0.000):0.131,(CytAquat:0.711,(CorGluta:0.522,CorAquat:0.103):0.207):0.162):0.124);";
1778 const char *kept_zombies_topo =
"(Zombie1:0.131,Zombie2:0.162);";
1779 const char *kept_zombies_broken_topo =
"Zombie2;";
1781 const char *empty_topo =
";";
1784 for (
unsigned mode = 0; mode<
ARRAY_ELEMS(tested_modes); ++mode) {
1787 for (
int linked = 0; linked<=1; ++linked) {
1792 bool once = mode == 0 && linked == 0;
1806 int removedCount = 0;
1807 int groupsRemovedCount = 0;
1838 const char *kept_marked_topo_wrapped =
1840 " CurCitre:1.000,\n"
1843 " CloButy2:0.009,\n"
1847 " CytAquat:0.711,\n"
1849 " CorGluta:0.522,\n"
1856 const char *expected_compacted =
1857 "(CurCitre:1.000,\n"
1858 " ((CloButy2:0.009,\n"
1859 " CloButyr:0.000):0.131,\n"
1860 " (CytAquat:0.711,\n"
1861 " (CorGluta:0.522,\n"
1862 " CorAquat:0.103):0.207):0.162):0.124);";
1871 if (what_next != what) {
1929 #endif // UNIT_TESTS
GB_ERROR GB_check_key(const char *key) __ATTR__USERESULT
GB_ERROR GB_copy_dropProtectMarksAndTempstate(GBDATA *dest, GBDATA *source)
GBDATA * GB_open(const char *path, const char *opent)
void put(const char *elem)
AliDataPtr format(AliDataPtr data, const size_t wanted_len, GB_ERROR &error)
TreeNode * GBT_remove_leafs(TreeNode *tree, GBT_TreeRemoveType mode, const GB_HASH *species_hash, int *removed, int *groups_removed)
GBT_RemarkType parse_bootstrap(double &bootstrap) const
long GB_read_int(GBDATA *gbd)
GBDATA * GB_child(GBDATA *father)
#define implicated(hypothesis, conclusion)
TreeNode * findLeafNamed(const char *wantedName)
long GBS_write_hash(GB_HASH *hs, const char *key, long val)
GBDATA * GBT_get_tree_data(GBDATA *gb_main)
bool operator<(const indexed_name &other) const
static GB_CSTR * fill_species_name_array(GB_CSTR *current, const TreeNode *tree)
const TreeNode * get_root_node() const
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
bool has_group_info() const
GBDATA * GBT_find_next_tree(GBDATA *gb_tree)
static GB_ERROR reserve_tree_idx(GBDATA *gb_treedata, int idx)
char * GBT_tree_2_newick(const TreeNode *tree, NewickFormat format, bool compact)
GB_ERROR GBT_rename_tree(GBDATA *gb_main, const char *source_name, const char *dest_name)
GBDATA * get_next_tree(GBDATA *gb_tree)
GBDATA * GB_nextEntry(GBDATA *entry)
#define TEST_EXPECT_STRARRAY_CONTAINS(strings, separator, expected)
static GBDATA * get_source_and_check_target_tree(GBDATA *gb_main, const char *source_tree, const char *dest_tree, GB_ERROR &error)
int get_max_tree_idx(GBDATA *gb_treedata)
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
char * ARB_strdup(const char *str)
void setKeeledState(int keeledState)
CONSTEXPR_INLINE int nodes_2_innerNodes(int nodes, TreeModel model)
TreeRoot * get_tree_root() const
GB_ERROR GBT_copy_tree(GBDATA *gb_main, const char *source_name, const char *dest_name)
static GB_ERROR gbt_is_invalid(bool is_root, const TreeNode *tree)
#define TEST_EXPECT_NEWICK__BROKEN(format, tree, expected_newick)
GB_ERROR GBT_log_to_named_trees_remark(GBDATA *gb_main, const char *tree_name, const char *log_entry, bool stamp)
const char * GBS_global_string(const char *templat,...)
GBDATA * GBT_find_tree(GBDATA *gb_main, const char *tree_name)
CONSTEXPR_INLINE int leafs_2_innerNodes(int leafs, TreeModel model)
void GBK_terminatef(const char *templat,...)
const char * GBT_tree_info_string(GBDATA *gb_main, const char *tree_name, int maxTreeNameLen)
void nput(char c, size_t count)
void GBS_free_hash(GB_HASH *hs)
GB_HASH * GBT_create_species_hash(GBDATA *gb_main)
char * GBS_regreplace(const char *str, const char *regReplExpr, GB_ERROR *error)
void cat(const char *from)
bool GB_allow_compression(GBDATA *gb_main, bool allow_compression)
const char * GBT_existing_tree(GBDATA *gb_main, const char *tree_name)
static char * gbt_write_tree_rek_new(const TreeNode *node, char *dest, long mode)
static TreeNode * gbt_read_tree_rek(char **data, long *startid, GBDATA **gb_tree_nodes, TreeRoot *troot, int size_of_tree, GB_ERROR &error)
const char * GBT_name_of_largest_tree(GBDATA *gb_main)
#define ARRAY_ELEMS(array)
char buffer[MESSAGE_BUFFERSIZE]
GBDATA * GB_get_father(GBDATA *gbd)
static TreeNode * read_tree_and_size_internal(GBDATA *gb_tree, GBDATA *gb_ctree, TreeRoot *troot, int node_count, GB_ERROR &error)
GB_ERROR GB_delete(GBDATA *&source)
static GB_ERROR gbt_link_tree_to_hash_rek(TreeNode *tree, link_tree_data *ltd)
GB_BUFFER GB_give_other_buffer(GB_CBUFFER buffer, long size)
static GB_ERROR gbt_write_tree(GBDATA *gb_main, GBDATA *gb_tree, const char *tree_name, TreeNode *tree)
TreeNode * GBT_read_tree_and_size(GBDATA *gb_main, const char *tree_name, TreeRoot *troot, int *tree_size)
GBDATA * GBT_find_bottom_tree(GBDATA *gb_main)
void GB_raise_user_flag(GBDATA *gbd, unsigned char user_bit)
#define TEST_PUBLISH(testfunction)
bool GB_user_flag(GBDATA *gbd, unsigned char user_bit)
static GBDATA * find_largest_tree(GBDATA *gb_main)
CONSTEXPR_INLINE int leafs_2_nodes(int leafs, TreeModel model)
static void ensure_trees_have_order(GBDATA *gb_treedata)
GB_ERROR GB_await_error()
NOT4PERL long * GBT_read_int(GBDATA *gb_container, const char *fieldpath)
GBDATA * GBT_find_top_tree(GBDATA *gb_main)
GB_ERROR GBT_overwrite_tree(GBDATA *gb_tree, TreeNode *tree)
GBDATA * GB_create_container(GBDATA *father, const char *key)
#define TEST_EXPECT(cond)
void GB_warningf(const char *templat,...)
#define TEST_EXPECT_NEWICK(format, tree, expected_newick)
GB_CSTR GB_read_key_pntr(GBDATA *gbd)
virtual TreeNode * makeNode() const =0
GBDATA * GB_create(GBDATA *father, const char *key, GB_TYPES type)
bool parse_treelabel(const char *&label, double &bootstrap)
GB_ERROR GBT_write_tree_with_remark(GBDATA *gb_main, const char *tree_name, TreeNode *tree, const char *remark)
GB_ERROR GBT_is_invalid(const TreeNode *tree)
static void tree_set_default_order(GBDATA *gb_tree)
long GB_number_of_subentries(GBDATA *gbd)
int keeledStateInfo() const
int GB_read_security_write(GBDATA *gbd)
CONSTEXPR_INLINE int leafs_2_edges(int leafs, TreeModel model)
#define TEST_EXPECT_EQUAL__BROKEN(expr, want, got)
GB_ERROR GBT_write_tree(GBDATA *gb_main, const char *tree_name, TreeNode *tree)
#define TEST_REJECT(cond)
#define TEST_REJECT_NULL(n)
GB_ERROR set_tree_idx(GBDATA *gb_tree, int idx)
static void error(const char *msg)
GBDATA * GB_get_root(GBDATA *gbd)
bool is_root_node() const
GB_CSTR * GBT_get_names_of_species_in_tree(const TreeNode *tree, size_t *count)
bool is_keeled_group() const
#define RETURN_LOCAL_ALLOC(mallocation)
void GBT_get_tree_names(ConstStrArray &names, GBDATA *gb_main, bool sorted)
GB_write_int const char GB_write_autoconv_string WRITE_SKELETON(write_pointer, GBDATA *,"%p", GB_write_pointer) char *AW_awa if)(!gb_var) return strdup("")
NOT4PERL GB_ERROR GBT_move_tree(GBDATA *gb_moved_tree, GBT_ORDER_MODE mode, GBDATA *gb_target_tree)
size_t GBT_count_leafs(const TreeNode *tree)
static SearchTree * tree[SEARCH_PATTERNS]
GBDATA * get_tree_with_idx(GBDATA *gb_treedata, int at_idx)
int GB_read_flag(GBDATA *gbd)
bool is_tree(GBDATA *gb_tree)
static GB_ERROR write_tree_remark(GBDATA *gb_tree, const char *remark)
GB_ERROR GBT_log_to_tree_remark(GBDATA *gb_tree, const char *log_entry, bool stamp)
char * GBS_log_action_to(const char *comment, const char *action, bool stamp)
GB_ERROR GBT_link_tree(TreeNode *tree, GBDATA *gb_main, bool show_status, int *zombies, int *duplicates)
bool GB_has_key(GBDATA *gbd, const char *key)
GB_ERROR GB_write_int(GBDATA *gbd, long i)
static GB_ERROR gbt_write_tree_nodes(GBDATA *gb_tree, TreeNode *node, long *startid)
const char * GBT_get_tree_name(GBDATA *gb_tree)
bool has_no_remark() const
static GB_ERROR GBT_link_tree_using_species_hash(TreeNode *tree, bool show_status, GB_HASH *species_hash, int *zombies, int *duplicates)
CONSTEXPR_INLINE int edges_2_leafs(int edges, TreeModel model)
char * GBT_join_strings(const CharPtrArray &strings, char separator)
GB_ERROR GB_export_errorf(const char *templat,...)
long GBT_size_of_tree(GBDATA *gb_main, const char *tree_name)
TYPE * ARB_calloc(size_t nelem)
#define IF_ASSERTION_USED(x)
TreeNode * fixDeletedSon()
#define TEST_EXPECT_NULL(n)
#define GB_GROUP_NAME_MAX
static GBDATA * copy_tree_container(GBDATA *gb_source_tree, const char *newName, GB_ERROR &error)
GBDATA * get_tree_infrontof_idx(GBDATA *gb_treedata, int infrontof_idx)
bool is_inner_node_with_remark() const
GB_ERROR GBT_write_string(GBDATA *gb_container, const char *fieldpath, const char *content)
void nprintf(size_t maxlen, const char *templat,...) __ATTR__FORMAT_MEMBER(2)
void announce_tree_constructed()
GBDATA * GBT_tree_behind(GBDATA *gb_tree)
char * GB_read_string(GBDATA *gbd)
GBDATA * get_first_tree(GBDATA *gb_main)
GBDATA * GBT_find_or_create(GBDATA *father, const char *key, long delete_level)
CONSTEXPR_INLINE int nodes_2_leafs(int nodes, TreeModel model)
void GBT_message(GBDATA *gb_main, const char *msg)
const char * GBS_static_string(const char *str)
bool has_son(const TreeNode *father, const TreeNode *son)
GB_ERROR GBT_check_tree_name(const char *tree_name)
GB_ERROR GBT_write_group_name(GBDATA *gb_group_name, const char *new_group_name, bool pedantic)
void set_remark(const char *newRemark)
float GB_atof(const char *str)
#define TEST_EXPECT_NO_ERROR(call)
void GB_clear_user_flag(GBDATA *gbd, unsigned char user_bit)
void GBT_unlink_tree(TreeNode *tree)
#define TEST_EXPECT_ERROR_CONTAINS(call, part)
GB_ERROR GB_test_delete_possible(GBDATA *gb_obj)
void reserve(size_t forElems)
const char * get_data() const
GB_ERROR GBT_write_tree_remark(GBDATA *gb_main, const char *tree_name, const char *remark)
GBDATA * get_tree_behind_idx(GBDATA *gb_treedata, int behind_idx)
GBDATA * GB_nextChild(GBDATA *child)
GBT_LEN get_branchlength() const
GB_transaction ta(gb_var)
GB_ERROR GBT_write_int(GBDATA *gb_container, const char *fieldpath, long content)
int get_tree_idx(GBDATA *gb_tree)
void destroy(TreeNode *that)
GB_CSTR GB_read_char_pntr(GBDATA *gbd)
static void tree2newick(const TreeNode *tree, GBS_strstruct &out, NewickFormat format, int indent)
GB_ERROR GBT_write_name_to_groupData(GBDATA *gb_group, bool createNameEntry, const char *new_group_name, bool pedantic)
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
const char * get_remark() const
void set_bootstrap_seen(bool seen)
const char * GBT_read_char_pntr(GBDATA *gb_container, const char *fieldpath)
GBDATA * GBT_tree_infrontof(GBDATA *gb_tree)
#define TEST_EXPECT_EQUAL(expr, want)
bool is_normal_group() const
void cat_sQuoted(const char *from)
long GBS_read_hash(const GB_HASH *hs, const char *key)
GBDATA * GB_entry(GBDATA *father, const char *key)
const char * GBT_name_of_bottom_tree(GBDATA *gb_main)
#define GB_USERFLAG_GHOSTNODE
char * GBS_global_string_copy(const char *templat,...)
void GB_close(GBDATA *gbd)
GB_HASH * GBS_create_hash(long estimated_elements, GB_CASE case_sens)
static GB_ERROR gbt_invalid_because(const TreeNode *tree, const char *reason)