1.1 --- a/src/tree.c Mon Feb 19 22:08:09 2024 +0100 1.2 +++ b/src/tree.c Mon Feb 19 22:09:16 2024 +0100 1.3 @@ -178,9 +178,50 @@ 1.4 1.5 static void cx_tree_iter_next(void *it) { 1.6 struct cx_tree_iterator_s *iter = it; 1.7 + off_t const loc_next = iter->loc_next; 1.8 + off_t const loc_children = iter->loc_children; 1.9 + 1.10 // TODO: support mutating iterator 1.11 + // TODO: support visit_on_exit 1.12 1.13 - // TODO: implement 1.14 + void *children = tree_children(iter->node); 1.15 + if (children == NULL) { 1.16 + // search for the next node 1.17 + void *current = iter->node; 1.18 + do { 1.19 + // check if there is a sibling 1.20 + void *next = tree_next(current); 1.21 + if (next == NULL) { 1.22 + // no sibling, check again for parent node 1.23 + --iter->depth; 1.24 + if (iter->depth == 0) { 1.25 + // there is no parent - we have iterated the entire tree 1.26 + // invalidate the iterator and free the node stack 1.27 + iter->node = NULL; 1.28 + current = NULL; 1.29 + iter->stack_capacity = 0; 1.30 + free(iter->stack); 1.31 + iter->stack = NULL; 1.32 + } else { 1.33 + // the parent node can be obtained from the top of stack 1.34 + // this way we can avoid the loc_parent in the iterator 1.35 + current = iter->stack[iter->depth - 1]; 1.36 + } 1.37 + } else { 1.38 + // move to the sibling and break the loop 1.39 + current = NULL; 1.40 + iter->counter++; 1.41 + iter->node = next; 1.42 + // new top of stack is the sibling 1.43 + iter->stack[iter->depth - 1] = next; 1.44 + } 1.45 + } while (current != NULL); 1.46 + } else { 1.47 + // node has children, push the first child onto the stack and enter it 1.48 + cx_array_simple_add(iter->stack, children); 1.49 + iter->node = children; 1.50 + iter->counter++; 1.51 + } 1.52 } 1.53 1.54 CxTreeIterator cx_tree_iterator(