src/tree.c

changeset 836
2672a2f79484
parent 834
04c53b3c8378
child 838
1ce90ab4fab9
     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(

mercurial