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);
233 if (!new_group_name[0]) {
234 return "Invalid empty groupname";
238 const char *
label = new_group_name;
243 if (is_bootstrap || remark) {
246 gb_assert(contradicted(is_bootstrap, remark));
250 buf.
cat(
" (would be misinterpreted as ");
253 else { buf.
cat(
"plain inner node"); }
260 while (bootstrap<100.0) bootstrap *= 100.0;
261 while (bootstrap>100.0) bootstrap /= 100.0;
263 buf.
cat(
"a support value of ");
264 buf.
nprintf(20,
"%.0f%%", bootstrap);
273 buf.
cat(
" if re-imported from newick file)");
290 if (em == new_group_name || em[-1] ==
' ' || em[-1] ==
'=') {
297 size_t len = strlen(new_group_name);
302 error =
"Invalid empty group name";
309 if (!error && pedantic) {
311 const char *num =
"0123456789.";
312 size_t numAtStart = strspn(new_group_name, num);
314 if (numAtStart && !new_group_name[numAtStart]) {
315 GB_warningf(
"Warning: group name '%s' may be misinterpreted as bootstrap value\n"
316 "(consider prefixing a non-numeric character)",
322 static const char *TAXCHARS =
"/;";
323 const char *seenTaxChar = strpbrk(new_group_name, TAXCHARS);
325 GB_warningf(
"Warning: group name '%s' contains a '%c' (this will interfere with taxonomy!)",
326 new_group_name, seenTaxChar[0]);
330 if (strchr(new_group_name,
'_')) {
331 GB_warningf(
"Warning: group name '%s' contains a '_' (reserved for overlapping groups)",
336 const char *tilde = strrchr(new_group_name,
'~');
337 if (tilde && tilde[1]) {
338 do ++tilde;
while (isdigit(tilde[0]));
340 GB_warningf(
"Warning: group name '%s' contains a '~' followed by digits only (reserved for splitted groups)",
367 bool node_is_used =
false;
395 if (gb_nonid) node_is_used =
true;
420 if (node->
name) strcpy(dest, node->
name);
423 while ((c1 = (
char *)strchr(dest, 1))) {
426 dest += strlen(dest);
432 if (node->
name)
return dest+1+strlen(node->
name)+1;
443 while ((c = *(c1++))) {
444 if (c == 1)
continue;
450 dest += strlen(c1) + 2;
458 strcpy(dest, buffer);
459 dest += strlen(buffer);
462 dest += strlen(buffer)+1;
484 if (gb_tree) error =
GBS_global_string(
"can't change name of existing tree (to '%s')", tree_name);
496 if (!gb_tree) error =
"No tree name given";
511 char *ctree = ARB_calloc<char>(
size_t(t_size+1));
530 if (!
GB_entry(gb_tree,
"keep_ghostnodes")) {
534 for (gb_node =
GB_entry(gb_tree,
"node");
536 gb_node = gb_node_next)
612 if (autocorrected_tree) {
622 char c = *((*data)++);
626 p1 = strchr(*data, 1);
644 p1 = (
char *)strchr(*data,
',');
648 p1 = (
char *)strchr(*data,
';');
652 if ((*startid < size_of_tree) && (node->
gb_node = gb_tree_nodes[*startid])) {
656 if (!node->
name || !node->
name[0]) {
657 char *auto_rename =
ARB_strdup(
"<missing groupname>");
665 warn =
"Empty groupname detected";
674 "Please check tree for corrupted groups, e.g. by using group search",
677 node->
name = auto_rename;
690 if (!node->
leftson) freenull(node);
705 p1 = (
char *)strchr(*data, 1);
716 error =
"Unexpected end of tree definition.";
719 error =
GBS_global_string(
"Can't interpret tree definition (expected 'N' or 'L' - not '%c')", c);
743 if (i<0 || i >= node_count) {
744 error =
"An inner node of the tree is corrupt";
747 gb_tree_nodes[i] = gb_node;
757 char *ts = treeString;
801 free(groupAtRoot_name);
803 freenull(node->
name);
839 error =
"no treename given";
847 error =
"tree not found";
852 error =
"tree is empty";
857 error =
"has no nodes";
862 error =
"old unsupported tree format";
868 if (tree_size) *tree_size = size;
884 GB_export_errorf(
"Failed to read tree '%s' (Reason: %s)", tree_name, error);
978 if (duplicates || show_status) {
997 if (zombies) *zombies = ltd.
zombies;
1041 get_leftson()->unlink_from_DB();
1042 get_rightson()->unlink_from_DB();
1061 if (!gb_tree)
return false;
1063 return gb_tree_data &&
GB_has_key(gb_tree_data,
"tree_data");
1071 if (!gb_tree)
return NULp;
1082 if (nnodes && *nnodes>maxnodes) {
1083 gb_largest = gb_tree;
1128 if (gb_other == gb_tree) gb_other =
NULp;
1139 if (!gb_tree)
return NULp;
1147 if (strncmp(tree_name,
"tree_", 5) != 0) {
1148 error =
"has to start with 'tree_'";
1153 error =
"no tree selected";
1156 error =
GBS_global_string(
"not a valid treename '%s' (Reason: %s)", tree_name, error);
1193 if (maxTreeNameLen == -1) {
1195 len = strlen(tree_name);
1199 len = maxTreeNameLen;
1203 const int remarkLen = 800;
1206 strcpy(res2, result);
1208 strncat(res2, remark, remarkLen);
1214 GB_warningf(
"Warning: tree '%s' has less than 2 nodes (is invalid + can be deleted).", tree_name);
1255 typedef std::set<indexed_name> ordered_trees;
1256 ordered_trees trees;
1266 trees.insert(iname);
1270 if (tree_count != (
long)trees.size()) {
1273 typedef std::set<int> ints;
1277 GBDATA *gb_tree = gb_first_tree;
1281 if (used_indices.find(idx) != used_indices.end()) {
1284 if (error)
GBK_terminatef(
"failed to fix tree-order (Reason: %s)", error);
1287 used_indices.clear();
1288 gb_tree = gb_first_tree;
1291 used_indices.insert(idx);
1299 for (ordered_trees::const_iterator t = trees.begin(); t != trees.end(); ++t) {
1306 gb_assert(gb_moved_tree && gb_target_tree);
1317 if (!error) error =
set_tree_idx(gb_moved_tree, target_idx);
1329 error =
"No tree selected";
1332 if (!error && strcmp(source_tree, dest_tree) == 0) error =
"source- and dest-tree are the same";
1336 if (!gb_source_tree) error =
GBS_global_string(
"tree '%s' not found", source_tree);
1341 gb_source_tree =
NULp;
1346 gb_assert(contradicted(error, gb_source_tree));
1347 return gb_source_tree;
1357 gb_assert(contradicted(error, gb_dest_tree));
1358 return gb_dest_tree;
1365 if (gb_source_tree) {
1369 int dest_idx = source_idx+1;
1372 if (!error) error =
set_tree_idx(gb_dest_tree, dest_idx);
1383 if (gb_source_tree) {
1387 if (gb_dest_tree) error =
GB_delete(gb_source_tree);
1393 source_name, dest_name, error);
1401 current[0] = tree->
name;
1419 if (count) *count = size;
1431 buf.
nprintf(10, lowPrecision ?
"%.3f" :
"%.5f", length);
1437 bool drop = strncmp(data,
"0.", 2)==0 || strcmp(data,
"-0")==0;
1438 return drop ? data+1 : data;
1443 if ((format&
nWRAP) && indent>0) { out.
put(
'\n'); out.
nput(
' ', indent); }
1452 if ((format&nWRAP) && indent>0) { out.
put(
'\n'); out.
nput(
' ', indent); }
1458 const char *kgroup =
NULp;
1465 if (remark || group || kgroup) {
1480 if (group) out.
cat(
" = ");
1502 #if defined(UNIT_TESTS)
1510 if (compact && (format&
nWRAP)) {
1513 char *compact1 =
GBS_regreplace(result,
"/[\n ]*[)]/)/", &error);
1515 char *compact2 =
GBS_regreplace(compact1,
"/[(][\n ]*/(/", &error);
1516 if (compact2) freeset(result, compact2);
1520 fprintf(stderr,
"Error in GBT_tree_2_newick: %s\n", error);
1544 void TEST_tree_names() {
1553 void TEST_tree_contraints() {
1555 const int MIN_LEAFS = 2;
1571 for (
int i = 3; i<=7; ++i) {
1602 void TEST_copy_rename_delete_tree_order() {
1629 size_t species_count;
1633 for (
int i = 0; species[i]; ++i) species2.put(
ARB_strdup(species[i]));
1653 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");
1665 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");
1682 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");
1685 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");
1688 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");
1691 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");
1709 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");
1714 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");
1717 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");
1720 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");
1796 void TEST_group_keeling() {
1803 const char *topo_tree2 =
"(((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc),(((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste)),((CloTyrob,CloTyro2),CloTyro4)'g2')'outer');";
1804 const char *topo_groups =
"(((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc)'upper',(((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste))'low1',((CloTyrob,CloTyro2)'twoleafs',CloTyro4)'low2')'lower');";
1805 const char *topo_keeled =
"(CloTyrob,(((((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste))'low1',((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc)'upper = !lower')'!low2',CloTyro4)'!twoleafs',CloTyro2));";
1843 const char *topo_keeled2 =
"(CloTyro4,((((CytAquat,(((CurCitre,CorAquat),CelBiazo),CorGluta)),(CloCarni,CloPaste))'low1',((CloTyro3,((CloButyr,CloButy2),CloBifer)),CloInnoc)'upper = !lower')'!low2',(CloTyrob,CloTyro2)'twoleafs'));";
1853 void TEST_tree_remove_leafs() {
1865 const char *org_topo =
"((CloInnoc:.371,(CloTyrob:.009,(CloTyro2:.017,(CloTyro3:1.046,CloTyro4:.061):.026):.017):.274):.029,(CloBifer:.388,((CloCarni:.12,CurCitre:.058):1,((CloPaste:.179,(Zombie1:.12,(CloButy2:.009,CloButyr:0):.564):.01):.131,(CytAquat:.711,(CelBiazo:.059,(CorGluta:.522,(CorAquat:.084,Zombie2:.058):.103):.054):.207):.162):.124):.124):.029);";
1866 const char *rem_marked_topo =
"((CloInnoc:.371,(CloTyrob:.009,(CloTyro2:.017,(CloTyro3:1.046,CloTyro4:.061):.026):.017):.274):.029,(CloBifer:.388,(CloCarni:1,((CloPaste:.179,Zombie1:.01):.131,(CelBiazo:.059,Zombie2:.054):.162):.124):.124):.029);";
1867 const char *rem_unmarked_topo =
"(CurCitre:1,((Zombie1:.12,(CloButy2:.009,CloButyr:0):.564):.131,(CytAquat:.711,(CorGluta:.522,(CorAquat:.084,Zombie2:.058):.103):.207):.162):.124);";
1868 const char *rem_zombies_topo =
"((CloInnoc:.371,(CloTyrob:.009,(CloTyro2:.017,(CloTyro3:1.046,CloTyro4:.061):.026):.017):.274):.029,(CloBifer:.388,((CloCarni:.12,CurCitre:.058):1,((CloPaste:.179,(CloButy2:.009,CloButyr:0):.01):.131,(CytAquat:.711,(CelBiazo:.059,(CorGluta:.522,CorAquat:.103):.054):.207):.162):.124):.124):.029);";
1869 const char *kept_marked_topo =
"(CurCitre:1,((CloButy2:.009,CloButyr:0):.131,(CytAquat:.711,(CorGluta:.522,CorAquat:.103):.207):.162):.124);";
1871 const char *kept_zombies_topo =
"(Zombie1:.131,Zombie2:.162);";
1872 const char *kept_zombies_broken_topo =
"Zombie2;";
1874 const char *empty_topo =
";";
1877 for (
unsigned mode = 0; mode<
ARRAY_ELEMS(tested_modes); ++mode) {
1880 for (
int linked = 0; linked<=1; ++linked) {
1885 bool once = mode == 0 && linked == 0;
1899 int removedCount = 0;
1900 int groupsRemovedCount = 0;
1931 const char *kept_marked_topo_wrapped =
1949 const char *expected_compacted =
1951 " ((CloButy2:.009,\n"
1952 " CloButyr:0):.131,\n"
1953 " (CytAquat:.711,\n"
1954 " (CorGluta:.522,\n"
1955 " CorAquat:.103):.207):.162):.124);";
1964 if (what_next != what) {
2022 #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 cut_tail(size_t byte_count)
void GB_warning(const char *message)
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)
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)
const char * GBT_len2string(GBT_LEN length, bool lowPrecision)
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,...)
void warning(int warning_num, const char *warning_message)
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)
bool remark_will_parse_as_bootstrap(const char *label)
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)
static TreeRoot * autocorrected_tree
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)
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)
GBT_RemarkType parse_bootstrap(double &bootstrap, WarningConsumer report)
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
bool parse_treelabel(const char *&label, double &bootstrap, char *&remark)
#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)
bool GB_has_key(GBDATA *gbd, const char *key)
void autocorrected_warning(const char *warning)
GB_ERROR GB_write_int(GBDATA *gbd, long i)
static GB_ERROR gbt_write_tree_nodes(GBDATA *gb_tree, TreeNode *node, long *startid)
GB_ERROR GBT_check_valid_group_name(const char *new_group_name)
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)
GB_ERROR GBT_link_tree(TreeNode *tree, GBDATA *gb_main, bool show_status)
#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)
void set_auto_modified(bool modified)
GBDATA * GB_entry(GBDATA *father, const char *key)
const char * GBT_name_of_bottom_tree(GBDATA *gb_main)
GB_ERROR GBT_link_tree_and_count(TreeNode *tree, GBDATA *gb_main, bool show_status, int *zombies, int *duplicates)
#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)