static void synchronize(struct wdgt *w) { int l = 0; struct proc_t *p = tree_start(tree_root, tree_root); struct process **current = &begin, *z; while(p){ if (*current && p->priv){ (*current)->line = l++; (*current)->proc->priv = *current; p = tree_next(); current = &((*current)->next); continue; } z = malloc(sizeof *z); if (!z) allocate_error(); //allocated++; // proc_win.d_lines++; memset(z, 0, sizeof *z); scr_linserted(w, l); z->line = l++; p->priv = z; z->proc = p; pstat_update(z, 1); if (*current){ z->next = *current; (*current)->prev = &z->next; } *current = z; z->prev = current; current = &(z->next); p = tree_next(); } }
static void search_requirements(struct hash *hash, struct node *n, struct tree *d) { struct tree_node *t, *u; struct tree *providers; t = tree_first(n->need->root); while (t) { providers = tree_new(); get_all_providers(t->n, providers); u = tree_first(providers->root); while (u) { if (!tree_search_node(d, u->n->name)) tree_insert(d, hash_search(hash, u->n->name)); u = tree_next(u); } tree_free_all_nodes(providers); tree_free(providers); t = tree_next(t); } t = tree_first(n->provide->root); while (t) { search_requirements(hash, t->n, d); t = tree_next(t); } }
static void search_dependencies(struct hash *hash, struct node *n, struct tree *d) { struct tree_node *t; char *pkgname; t = tree_first(n->neededby->root); while (t) { if (is_virtual_file(t->n->name)) { pkgname = get_pkgname(t->n->name); if (!tree_search_node(d, pkgname)) tree_insert(d, hash_search(hash, pkgname)); free(pkgname); } t = tree_next(t); } t = tree_first(n->provide->root); while (t) { search_dependencies(hash, t->n, d); t = tree_next(t); } }
void remove_all(struct hash *hash, struct node *n) { struct tree *t; struct tree_node *h, *s; if (n->neededby->root || n->providedby->root) return; h = tree_first(n->provide->root); while (h) { s = tree_search_tree_node(h->n->providedby, n); tree_node_free(h->n->providedby, s); remove_all(hash, h->n); h = tree_next(h); } h = tree_first(n->need->root); while (h) { s = tree_search_tree_node(h->n->neededby, n); tree_node_free(h->n->neededby, s); remove_all(hash, h->n); h = tree_next(h); } t = hash->tbl[hash_index(n->name)]; s = tree_search_tree_node(t, n); tree_node_free(t, s); node_free(n); }
int save_cache(struct hash *hash, char *path) { int i; struct tree_node *s, *t; FILE *file; if ((file = fopen(path, "w")) == NULL) { perror("bee-dep: save_cache: fopen"); return 1; } for (i = 0; i < TBLSIZE; i++) { if (hash->tbl[i]->root) { t = tree_first(hash->tbl[i]->root); while (t) { fprintf(file, "%s %s\n", t->n->name, t->n->type); t = tree_next(t); } } } fprintf(file, "#\n"); for (i = 0; i < TBLSIZE; i++) { if (hash->tbl[i]->root) { t = tree_first(hash->tbl[i]->root); while (t) { if (t->n->need->root) { s = tree_first(t->n->need->root); while (s) { fprintf(file, "%s %s n\n", t->n->name, s->n->name); s = tree_next(s); } } if (t->n->provide->root) { s = tree_first(t->n->provide->root); while (s) { fprintf(file, "%s %s p\n", t->n->name, s->n->name); s = tree_next(s); } } t = tree_next(t); } } } if (fclose(file) == EOF) { perror("bee-dep: save_cache: fclose"); return 1; } return 0; }
int print_conflicts(struct hash *hash) { int i; struct tree_node *t, *s; char *pkgname; for (i = 0; i < TBLSIZE; i++) { t = tree_first(hash->tbl[i]->root); while (t) { if (!IS_FILE(t->n->name) || IS_DIR(t->n) || tree_count(t->n->providedby) < 2) { t = tree_next(t); continue; } printf("%s: ", t->n->name); s = tree_first(t->n->providedby->root); while (s) { if (IS_PKG(s->n)) { printf("%s", s->n->name); } else if (is_virtual_file(s->n->name)) { pkgname = get_pkgname(s->n->name); printf("%s", pkgname); free(pkgname); } else { fprintf(stderr, "bee-dep: print_conflicts: " "could not get pkgname for \"%s\"\n", s->n->name); return 1; } s = tree_next(s); if (!s) puts(""); else printf(" "); } t = tree_next(t); } } return 0; }
/* A list is a sequence of one or more AND-OR-lists separated by the * operators * * ; & * * and optionally terminated by * * ; & <newline> * * ----------------------------------------------------------------------- */ union node *parse_list(struct parser *p) { union node *list; union node **nptr; enum tok_flag tok; /* keep looking for and-or lists */ tree_init(list, nptr); while((*nptr = parse_and_or(p))) { tok = parse_gettok(p, P_DEFAULT); /* <newline> terminates the list and eats the token */ if(tok & T_NL) return list; /* there must be & or ; after the and-or list, otherwise the list will be terminated */ if(!(tok & (T_SEMI | T_BGND))) { p->pushback++; break; } /* & causes async exec of preceding and-or list */ if(tok & T_BGND) (*nptr)->nlist.bgnd = 1; /* now check for another and-or list */ tree_next(nptr); } return list; }
int print_removable(struct hash *hash, char *remove) { struct node *n; struct tree *t; struct tree_node *e; char **dirs, **files; int cnt, dir_cnt, file_cnt, i; if ((n = hash_search(hash, remove)) == NULL) { fprintf(stderr, "bee-dep: print_removable: cannot find \"%s\"\n", remove); return 1; } if (!IS_PKG(n)) { fprintf(stderr, "bee-dep: print_removable: \"%s\": no such package\n", remove); return 1; } t = tree_new(); search_removable(hash, n, t, remove); cnt = tree_count(t); if ((dirs = calloc(cnt, sizeof(*dirs))) == NULL || (files = calloc(cnt, sizeof(*files))) == NULL) { perror("bee-dep: print_removable: calloc"); return 1; } e = tree_first(t->root); dir_cnt = file_cnt = 0; while (e) { if (IS_DIR(e->n)) dirs[dir_cnt++] = e->n->name; else files[file_cnt++] = e->n->name; e = tree_next(e); } sort_dirs(dirs, dir_cnt); for (i = 0; i < file_cnt; i++) puts(files[i]); for (i = 0; i < dir_cnt; i++) puts(dirs[i]); free(dirs); free(files); tree_free(t); return 0; }
int print_broken(struct hash *hash, char print) { int c, i; char h; struct tree_node *t; struct tree *dry; c = 0; for (i = 0; i < TBLSIZE; i++) { t = tree_first(hash->tbl[i]->root); while (t) { h = 0; if (IS_PKG(t->n)) { dry = tree_new(); print_broken_nodes(t->n, &c, &h, print, dry); tree_free(dry); } t = tree_next(t); } } return c; }
int main(int argc, char **argv) { size_t max_path_len = 0; int max_depth = 0; system("pwd"); while (*++argv) { struct tree *t = tree_open(*argv); while (tree_next(t)) { size_t path_len = tree_current_pathlen(t); int depth = tree_current_depth(t); if (path_len > max_path_len) max_path_len = path_len; if (depth > max_depth) max_depth = depth; printf("%s\n", tree_current_path(t)); if (S_ISDIR(tree_current_lstat(t)->st_mode)) tree_descend(t); /* Descend into every dir. */ } tree_close(t); printf("Max path length: %d\n", max_path_len); printf("Max depth: %d\n", max_depth); printf("Final open count: %d\n", t->openCount); printf("Max open count: %d\n", t->maxOpenCount); fflush(stdout); system("pwd"); } return (0); }
/* parse a compound list * * The term compound-list is derived from the grammar in 3.10; it is * equivalent to a sequence of lists, separated by <newline>s, that * can be preceded or followed by an arbitrary number of <newline>s. * ----------------------------------------------------------------------- */ union node *parse_compound_list(struct parser *p) { union node *list; union node **nptr; tree_init(list, nptr); /* skip arbitrary newlines */ while(parse_gettok(p, P_DEFAULT) & T_NL); p->pushback++; for(;;) { /* try to parse a list */ *nptr = parse_list(p); /* skip arbitrary newlines */ while(p->tok & T_NL) parse_gettok(p, P_DEFAULT); p->pushback++; /* no more lists */ if(*nptr == NULL) break; /* parse_list already returns a list, so we must skip over it to get &lastnode->next */ while(*nptr) tree_next(nptr); } return list; }
void print_broken_nodes(struct node *n, int *count, char *header, char print, struct tree *dry) { struct tree_node *t; char *pkgname; t = tree_first(n->provide->root); while (t) { print_broken_nodes(t->n, count, header, print, dry); t = tree_next(t); } /* for the next step we have to assert that n is a virtual file */ if (!is_virtual_file(n->name)) return; t = tree_first(n->need->root); while (t) { if (!tree_count(t->n->providedby)) { (*count)++; if (print) { if (!*(header)) { (*header) = 1; pkgname = get_pkgname(n->name); printf("%s:\n", pkgname); free(pkgname); } /* don't repeat yourself */ if (!tree_search_tree_node(dry, t->n)) { printf(" %s -> %s\n", get_filename(n->name), t->n->name); tree_insert(dry, t->n); } } } t = tree_next(t); } }
static node_t * removeIterateCb(tree_t *aTree, node_t *aNode, void *data) { unsigned *nNodes = (unsigned *)data; node_t *ret = tree_next(aTree, aNode); nodeRemove(aTree, aNode, *nNodes); return ret; }
void check_remove(struct hash *hash, struct node *n, struct tree *r) { struct tree_node *t; t = tree_first(n->provide->root); while (t) { check_remove(hash, t->n, r); t = tree_next(t); } if (tree_count(n->providedby) == 1) add_all_neededby(hash, n, r); }
/* * Write tree to the archive. If pathname is a symbolic link it will be * followed. Other symbolic links are stored as such to the archive. */ static int shar_write_tree(struct archive *a, const char *pathname) { struct tree *t; const struct stat *lst, *st; int error = 0; int tree_ret; int first; assert(a != NULL); assert(pathname != NULL); t = tree_open(pathname); for (first = 1; (tree_ret = tree_next(t)); first = 0) { if (tree_ret == TREE_ERROR_DIR) { warnx("%s: %s", tree_current_path(t), strerror(tree_errno(t))); error = 1; continue; } else if (tree_ret != TREE_REGULAR) continue; if ((lst = tree_current_lstat(t)) == NULL) { warn("%s", tree_current_path(t)); error = 1; continue; } /* * If the symlink was given on command line then * follow it rather than write it as symlink. */ if (first && S_ISLNK(lst->st_mode)) { if ((st = tree_current_stat(t)) == NULL) { warn("%s", tree_current_path(t)); error = 1; continue; } } else st = lst; if (shar_write_entry(a, tree_current_path(t), tree_current_access_path(t), st) != ARCHIVE_OK) error = 1; tree_descend(t); } tree_close(t); return ((error != 0) ? ARCHIVE_WARN : ARCHIVE_OK); }
int print_neededby(struct hash *hash, char *name) { struct node *n; struct tree_node *t; struct tree *all; if ((n = hash_search(hash, name)) == NULL) { fprintf(stderr, "bee-dep: print_needs: cannot find \"%s\"\n", name); return 1; } if (IS_PKG(n)) return print_dependencies(hash, n); all = tree_new(); t = tree_first(n->neededby->root); while (t) { get_all_providers(t->n, all); t = tree_next(t); } t = tree_first(all->root); while (t) { puts(t->n->name); t = tree_next(t); } tree_free_all_nodes(all); tree_free(all); return 0; }
void list_packages(struct hash *hash) { int i; struct tree_node *t; for (i = 0; i < TBLSIZE; i++) { t = tree_first(hash->tbl[i]->root); while (t) { if (IS_PKG(t->n)) puts(t->n->name); t = tree_next(t); } } }
static void get_all_providers(struct node *n, struct tree *all) { struct tree_node *t; t = tree_first(n->providedby->root); while (t) { if (IS_PKG(t->n) && !tree_search_node(all, t->n->name)) tree_insert(all, node_new(t->n->name, "")); get_all_providers(t->n, all); t = tree_next(t); } }
void add_all_neededby(struct hash *hash, struct node *n, struct tree *a) { struct tree_node *t; char *pkgname; t = tree_first(n->neededby->root); while (t) { add_all_neededby(hash, t->n, a); pkgname = get_pkgname(t->n->name); if (is_virtual_file(t->n->name)) tree_insert(a, hash_search(hash, pkgname)); free(pkgname); t = tree_next(t); } }
int get_virtual_files(struct node *n, char *name, struct tree *all) { struct tree_node *t; t = tree_first(n->providedby->root); while (t) { if (!strcmp(name, get_filename(t->n->name)) && !tree_search_node(all, t->n->name)) tree_insert(all, t->n); t = tree_next(t); } return tree_count(all); }
static int count_all_files(struct node *n) { struct tree_node *t; int count; t = tree_first(n->provide->root); count = 0; while (t) { if (IS_FILE(t->n->name)) count++; count += list_all_files(t->n, 0); t = tree_next(t); } return count; }
int count_packages(struct hash *hash) { int i, c; struct tree_node *t; c = 0; for (i = 0; i < TBLSIZE; i++) { t = tree_first(hash->tbl[i]->root); while (t) { if (IS_PKG(t->n)) c++; t = tree_next(t); } } return c; }
void search_removable(struct hash *hash, struct node *n, struct tree *t, char *remove) { struct tree_node *e; char *pkgname; e = tree_first(n->provide->root); while (e) { search_removable(hash, e->n, t, remove); e = tree_next(e); } if (IS_FILE(n->name) && tree_count(n->providedby) <= 1) { pkgname = get_pkgname(n->providedby->root->n->name); if (!strcmp(pkgname, remove)) tree_insert(t, n); free(pkgname); } }
static int print_requirements(struct hash *hash, struct node *n) { struct tree *t; struct tree_node *e; t = tree_new(); search_requirements(hash, n, t); e = tree_first(t->root); while (e) { if (strcmp(n->name, e->n->name) != 0) puts(e->n->name); e = tree_next(e); } tree_free(t); return 0; }
static int list_all_files(struct node *n, char print) { struct tree_node *t; int count; t = tree_first(n->provide->root); count = 0; while (t) { if (IS_FILE(t->n->name)) { count++; if (print) puts(t->n->name); } count += list_all_files(t->n, print); t = tree_next(t); } return count; }
int print_providers(struct hash *hash, char *name) { struct node *n; struct tree_node *t; struct tree *all; if ((n = hash_search(hash, name)) == NULL) { fprintf(stderr, "bee-dep: print_providers: cannot find \"%s\"\n", name); return 1; } if (IS_PKG(n)) { fprintf(stderr, "bee-dep: print_providers: \"%s\" is a package\n", name); return 1; } all = tree_new(); get_all_providers(n, all); t = tree_first(all->root); while (t) { puts(t->n->name); t = tree_next(t); } tree_free_all_nodes(all); tree_free(all); return 0; }
/* parse a compound- or a simple-command * (pipeline and lists are done outside this) * ----------------------------------------------------------------------- */ union node *parse_command(struct parser *p, int tempflags) { enum tok_flag tok; union node *command; union node **rptr; tok = parse_gettok(p, tempflags); switch(tok) { /* T_FOR begins an iteration statement */ case T_FOR: command = parse_for(p); break; /* T_IF begins a case match statement */ case T_CASE: command = parse_case(p); break; /* T_IF begins a conditional statement */ case T_IF: command = parse_if(p); break; /* T_WHILE/T_UNTIL begin a for-loop statement */ case T_WHILE: case T_UNTIL: command = parse_loop(p); break; /* T_LP/T_BEGIN start a grouping compound */ case T_LP: case T_BEGIN: p->pushback++; command = parse_grouping(p); break; /* handle simple commands */ case T_NAME: case T_WORD: case T_REDIR: case T_ASSIGN: p->pushback++; command = parse_simple_command(p); break; /* it wasn't a compound command, return now */ default: p->pushback++; return NULL; } if(command) { /* they all can have redirections, so parse these now */ rptr = &command->ncmd.rdir; /* * in the case of a simple command there are maybe already * redirections in the list (because in a simple command they * can appear between arguments), so skip to the end of the list. */ while(*rptr) tree_next(rptr); while(parse_gettok(p, P_DEFAULT) & T_REDIR) tree_move(p->tree, rptr); } p->pushback++; return command; }
static int update_cache(struct hash *graph) { struct dirent **package; int i, pkg_cnt; char path[PATH_MAX + 1]; struct stat st; struct tree_node *t; if (stat(bee_metadir(), &st) == -1) return 0; if ((pkg_cnt = scandir(bee_metadir(), &package, 0, alphasort)) < 0) { perror("bee-dep: update_cache: scandir"); return 1; } /* skip . and .. */ free(package[0]); free(package[1]); /* add new (not known) packages */ for (i = 2; i < pkg_cnt; i++) { if (hash_search(graph, package[i]->d_name)) continue; printf("adding %s\n", package[i]->d_name); if (sprintf(path, "%s/%s", bee_metadir(), package[i]->d_name) < 0) { perror("bee-dep: update_cache: sprintf"); return 1; } if (stat(path, &st) == -1) { perror("bee-dep: update_cache: stat"); return 1; } if (S_ISDIR(st.st_mode)) { strcat(path, "/DEPENDENCIES"); if (stat(path, &st) == -1) { fprintf(stderr, "bee-dep: update_cache: missing " "DEPENDENCIES file for package \"%s\"\n", package[i]->d_name); return 1; } if (graph_insert_nodes(graph, path)) return 1; } free(package[i]); } free(package); /* remove packages which not exist anymore */ for (i = 0; i < TBLSIZE; i++) { t = tree_first(graph->tbl[i]->root); while (t) { if (IS_PKG(t->n)) { if (sprintf(path, "%s/%s", bee_metadir(), t->n->name) < 0) { perror("bee-dep: update_cache: sprintf"); return 1; } if (stat(path, &st) == -1) { printf("removing %s\n", t->n->name); if (remove_package(graph, t->n->name)) return 1; } } t = tree_next(t); } } return 0; }
int main(void) { tree_t tree; long set[NNODES]; node_t nodes[NNODES], key, *sNode, *nodeA; unsigned i, j, k; fprintf(stderr, "Test begin\n"); /* Initialize tree. */ tree_new(&tree, 42); /* * Empty tree. */ fprintf(stderr, "Empty tree:\n"); /* trp_first(). */ nodeA = tree_first(&tree); if (nodeA == NULL) { fprintf(stderr, "trp_first() --> nil\n"); } else { fprintf(stderr, "trp_first() --> %ld\n", nodeA->key); } /* trp_last(). */ nodeA = tree_last(&tree); if (nodeA == NULL) { fprintf(stderr, "trp_last() --> nil\n"); } else { fprintf(stderr, "trp_last() --> %ld\n", nodeA->key); } /* trp_search(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_search(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "trp_search(0) --> nil\n"); } else { fprintf(stderr, "trp_search(0) --> %ld\n", nodeA->key); } /* trp_nsearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_nsearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "trp_nsearch(0) --> nil\n"); } else { fprintf(stderr, "trp_nsearch(0) --> %ld\n", nodeA->key); } /* trp_psearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_psearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "trp_psearch(0) --> nil\n"); } else { fprintf(stderr, "trp_psearch(0) --> %ld\n", nodeA->key); } /* trp_insert(). */ srandom(42); for (i = 0; i < NSETS; i++) { for (j = 0; j < NNODES; j++) { set[j] = (long) (((double) NNODES) * ((double) random() / ((double)RAND_MAX))); } for (j = 1; j <= NNODES; j++) { #ifdef VERBOSE fprintf(stderr, "Tree %u, %u node%s\n", i, j, j != 1 ? "s" : ""); #endif /* Initialize tree and nodes. */ tree_new(&tree, 42); for (k = 0; k < j; k++) { nodes[k].magic = NODE_MAGIC; nodes[k].key = set[k]; } /* Insert nodes. */ for (k = 0; k < j; k++) { #ifdef VERBOSE fprintf(stderr, "trp_insert(%3ld)", nodes[k].key); #endif tree_insert(&tree, &nodes[k]); #ifdef TREE_PRINT fprintf(stderr, "\n\t tree: "); #endif #ifdef FORWARD_PRINT fprintf(stderr, "\n\tforward: "); #endif assert(k + 1 == treeIterate(&tree)); #ifdef REVERSE_PRINT fprintf(stderr, "\n\treverse: "); #endif assert(k + 1 == treeIterateReverse(&tree)); #ifdef VERBOSE fprintf(stderr, "\n"); #endif sNode = tree_first(&tree); assert(sNode != NULL); sNode = tree_last(&tree); assert(sNode != NULL); sNode = tree_next(&tree, &nodes[k]); sNode = tree_prev(&tree, &nodes[k]); } /* Remove nodes. */ switch (i % 4) { case 0: { for (k = 0; k < j; k++) { nodeRemove(&tree, &nodes[k], j - k); } break; } case 1: { for (k = j; k > 0; k--) { nodeRemove(&tree, &nodes[k-1], k); } break; } case 2: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_iter(&tree, start, removeIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } case 3: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_reverse_iter(&tree, start, removeReverseIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } default: { assert(false); } } } } fprintf(stderr, "Test end\n"); return 0; }
int main(void) { tree_t tree; long set[NNODES]; node_t nodes[NNODES], key, *sNode, *nodeA; unsigned i, j, k, blackHeight, imbalances; fprintf(stderr, "Test begin\n"); /* Initialize tree. */ tree_new(&tree); /* * Empty tree. */ fprintf(stderr, "Empty tree:\n"); /* rb_first(). */ nodeA = tree_first(&tree); if (nodeA == NULL) { fprintf(stderr, "rb_first() --> nil\n"); } else { fprintf(stderr, "rb_first() --> %ld\n", nodeA->key); } /* rb_last(). */ nodeA = tree_last(&tree); if (nodeA == NULL) { fprintf(stderr, "rb_last() --> nil\n"); } else { fprintf(stderr, "rb_last() --> %ld\n", nodeA->key); } /* rb_search(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_search(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "rb_search(0) --> nil\n"); } else { fprintf(stderr, "rb_search(0) --> %ld\n", nodeA->key); } /* rb_nsearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_nsearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "rb_nsearch(0) --> nil\n"); } else { fprintf(stderr, "rb_nsearch(0) --> %ld\n", nodeA->key); } /* rb_psearch(). */ key.key = 0; key.magic = NODE_MAGIC; nodeA = tree_psearch(&tree, &key); if (nodeA == NULL) { fprintf(stderr, "rb_psearch(0) --> nil\n"); } else { fprintf(stderr, "rb_psearch(0) --> %ld\n", nodeA->key); } /* rb_insert(). */ srandom(42); for (i = 0; i < NSETS; i++) { if (i == 0) { // Insert in order. for (j = 0; j < NNODES; j++) { set[j] = j; } } else if (i == 1) { // Insert in reverse order. for (j = 0; j < NNODES; j++) { set[j] = NNODES - j - 1; } } else { for (j = 0; j < NNODES; j++) { set[j] = (long) (((double) NNODES) * ((double) random() / ((double)RAND_MAX))); } } fprintf(stderr, "Tree %u\n", i); for (j = 1; j <= NNODES; j++) { if (verbose) { fprintf(stderr, "Tree %u, %u node%s\n", i, j, j != 1 ? "s" : ""); } /* Initialize tree and nodes. */ tree_new(&tree); tree.rbt_nil.magic = 0; for (k = 0; k < j; k++) { nodes[k].magic = NODE_MAGIC; nodes[k].key = set[k]; } /* Insert nodes. */ for (k = 0; k < j; k++) { if (verbose) { fprintf(stderr, "rb_insert(%3ld)", nodes[k].key); } tree_insert(&tree, &nodes[k]); if (tree_print) { fprintf(stderr, "\n\t tree: "); } rbtn_black_height(node_t, link, &tree, blackHeight); imbalances = treeRecurse(tree.rbt_root, blackHeight, 0, &(tree.rbt_nil)); if (imbalances != 0) { fprintf(stderr, "\nTree imbalance\n"); abort(); } if (forward_print) { fprintf(stderr, "\n\tforward: "); } assert(k + 1 == treeIterate(&tree)); if (reverse_print) { fprintf(stderr, "\n\treverse: "); } assert(k + 1 == treeIterateReverse(&tree)); if (verbose) { fprintf(stderr, "\n"); } sNode = tree_first(&tree); assert(sNode != NULL); sNode = tree_last(&tree); assert(sNode != NULL); sNode = tree_next(&tree, &nodes[k]); sNode = tree_prev(&tree, &nodes[k]); } /* Remove nodes. */ switch (i % 4) { case 0: { for (k = 0; k < j; k++) { nodeRemove(&tree, &nodes[k], j - k); } break; } case 1: { for (k = j; k > 0; k--) { nodeRemove(&tree, &nodes[k-1], k); } break; } case 2: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_iter(&tree, start, removeIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } case 3: { node_t *start; unsigned nNodes = j; start = NULL; do { start = tree_reverse_iter(&tree, start, removeReverseIterateCb, (void *)&nNodes); nNodes--; } while (start != NULL); assert(nNodes == 0); break; } default: { assert(false); } } } } fprintf(stderr, "Test end\n"); return 0; }