text_t *create_text() { text_t *tmp_text = allocate_tree(); tmp_text->left = NULL; tmp_text->color = BLACK; return tmp_text; }
/************************************************************************* * Deep copy a tree. Assume memory is already allocated. *************************************************************************/ void copy_tree (TREE_T * source_tree, TREE_T * dest_tree) { memcpy(dest_tree, source_tree, sizeof(TREE_T)); int i; for (i = 0; i < dest_tree->num_children; i++) { dest_tree->children[i] = allocate_tree(); copy_tree(source_tree->children[i], dest_tree->children[i]); } }
/* dynamically allocate the tree */ static int allocate_tree(merkletree_t *tree, uint64_t size, size_t h) { Rows *rows = (Rows *)tree->rows; if (h == 0) { rows->row[h].outc = size; } rows->row[h].blocks = numblocks(size, tree->blocksize); rows->row[h].out = calloc(1, rows->row[h].blocks * tree->rawoutsize); if (size > 0 && rows->row[h].blocks > 1) { return allocate_tree(tree, size / (tree->blocksize * tree->rawoutsize), ++rows->height); } return (int)++rows->height; }
/* set up the tree */ static inline int setup_tree(merkletree_t *tree, size_t size, const char *alg, size_t blocksize) { if (tree == NULL || alg == NULL || blocksize == 0) { fprintf(stderr, "bad arg\n"); return 0; } memset(tree, 0x0, sizeof(*tree)); if ((tree->rawoutsize = multigest_algs_rawsize(alg) * 2) == 0) { fprintf(stderr, "unrecognised algorithm '%s'\n", alg); return 0; } snprintf(tree->algname, sizeof(tree->algname), "%s", alg); tree->size = size; tree->blocksize = blocksize; tree->rows = calloc(1, sizeof(Rows)); allocate_tree(tree, tree->size, 0); return 1; }
/************************************************************************* * Recursively read a tree from a file. *************************************************************************/ static void read_node (char * one_char, FILE * tree_file, TREE_T ** a_tree) { BOOLEAN_T last_child; int i_child; int i_char; // Allocate memory for the new node. *a_tree = allocate_tree(); // Are we starting a new subtree? if (*one_char == '(') { // Read in the children, one by one. last_child = FALSE; i_child = 0; while (!last_child) { get_non_blank(tree_file, one_char); // Read one child. read_node(one_char, tree_file, &(*a_tree)->children[i_child]); // Increment the number of children. i_child++; // Are we done with this set of children? if (*one_char == ')') { last_child = TRUE; // Allow labels on internal nodes. get_non_blank(tree_file, one_char); i_char = 0; while (*one_char != ':' && *one_char != ',' && *one_char != ')' && *one_char != '[' && *one_char != ';') { // Replace special characters. if ((*one_char & 255) == 255) *one_char = '\''; if ((*one_char & 255) > 175) *one_char -= 48; if ((*one_char & (~127)) != 0) *one_char -= 64; // Only store the first MAX_LABEL characters. if (i_char < MAX_LABEL) (*a_tree)->label[i_char] = *one_char; // Skip line breaks. if (is_eoln(tree_file)) { ignore_value(fscanf(tree_file, "%*[^\n]")); getc(tree_file); } *one_char = getc(tree_file); i_char++; } } } (*a_tree)->num_children = i_child; } // Otherwise, this is a leaf node. else { (*a_tree)->num_children = 0; i_char = 0; do { // Replace special characters. if ((*one_char & 255) == 255) *one_char = '\''; if ((*one_char & 255) > 175) *one_char -= 48; if ((*one_char & (~127)) != 0) *one_char -= 64; // Only store the first MAX_LABEL characters. if (i_char < MAX_LABEL) (*a_tree)->label[i_char] = *one_char; // Skip line breaks. if (is_eoln(tree_file)) { ignore_value(fscanf(tree_file, "%*[^\n]")); getc(tree_file); } *one_char = getc(tree_file); i_char++; } while (*one_char != ':' && *one_char != ',' && *one_char != ')'); if (i_char > MAX_LABEL) i_char = MAX_LABEL; (*a_tree)->label[i_char] = '\0'; } // Get the branch length. if (*one_char == ':') { process_length(one_char, tree_file, *a_tree); (*a_tree)->has_length = TRUE; } }