diff -r 97df2e4c68fb -r 5c926801f052 src/tree.c --- a/src/tree.c Sun Feb 18 13:16:38 2024 +0100 +++ b/src/tree.c Sun Feb 18 13:38:42 2024 +0100 @@ -109,17 +109,14 @@ } // create a working stack - size_t work_cap = 32; - size_t work_size = 0; - void const **work = malloc(sizeof(void*) * work_cap); - #define work_add(node) cx_array_add(&work, &work_size, &work_cap, \ - sizeof(void*), &(node), cx_array_default_reallocator) + cx_array_declare(void const*, work); + cx_array_initialize(work, 32); // add the children of root to the working stack { void *c = tree_children(root); while (c != NULL) { - work_add(c); + cx_array_simple_add(work, c); c = tree_next(c); } } @@ -146,7 +143,7 @@ // if children might contain the data, add them to the stack void *c = tree_children(node); while (c != NULL) { - work_add(c); + cx_array_simple_add(work, c); c = tree_next(c); } @@ -165,7 +162,6 @@ } // free the working queue and return - #undef workq_add free(work); return ret; } @@ -180,14 +176,6 @@ return iter->node; } -static void cx_tree_iter_stack_add( - struct cx_tree_iterator_s *iter, - void *node -) { - cx_array_add(&iter->stack, &iter->depth, &iter->stack_capacity, - sizeof(void*), &node, cx_array_default_reallocator); -} - static void cx_tree_iter_next(void *it) { struct cx_tree_iterator_s *iter = it; // TODO: support mutating iterator @@ -195,77 +183,28 @@ // TODO: implement } - CxTreeIterator cx_tree_iterator( void *root, - int passes, + bool visit_on_exit, ptrdiff_t loc_children, ptrdiff_t loc_next ) { CxTreeIterator iter; iter.loc_children = loc_children; iter.loc_next = loc_next; - iter.requested_passes = passes; - - // invalidate iterator immediately when passes is invalid - if ((passes & (CX_TREE_ITERATOR_ENTER | - CX_TREE_ITERATOR_NEXT_CHILD | - CX_TREE_ITERATOR_EXIT)) == 0) { - iter.stack = NULL; - iter.node = NULL; - return iter; - } + iter.visit_on_exit = visit_on_exit; // allocate stack iter.stack_capacity = 16; iter.stack = malloc(sizeof(void *) * 16); iter.depth = 0; - // determine start - if ((passes & CX_TREE_ITERATOR_ENTER) == 0) { - // we have to skip the first "entering" passes - void *s = NULL; - void *n = root; - iter.counter = 0; - do { - iter.counter++; - iter.source = s; - iter.node = n; - cx_tree_iter_stack_add(&iter, n); - s = n; - n = tree_children(n); - } while (n != NULL); - // found a leaf node s (might be root itself if it has no children) - - // check if there is a sibling - n = tree_next(s); - - if (n == NULL) { - // no sibling found, exit back to parent node - // TODO: implement - } else { - // there is a sibling - if ((passes & CX_TREE_ITERATOR_EXIT) == 0) { - // no exit requested, conclude that only next_child is requested - iter.source = s; - iter.node = n; - iter.counter++; - iter.current_pass = CX_TREE_ITERATOR_NEXT_CHILD; - } else { - // exit requested, so we have found our first pass - // iter.node and iter.source are still correct - iter.current_pass = CX_TREE_ITERATOR_EXIT; - } - } - } else { - // enter passes are requested, we can start by entering the root node - iter.source = NULL; - iter.node = root; - iter.current_pass = CX_TREE_ITERATOR_ENTER; - iter.counter = 1; - iter.depth = 1; - iter.stack[0] = root; - } + // visit the root node + iter.node = root; + iter.counter = 1; + iter.depth = 1; + iter.stack[0] = root; + iter.exiting = false; // assign base iterator functions iter.base.mutating = false;