1.1 --- a/src/tree.c Wed Mar 20 23:35:32 2024 +0100 1.2 +++ b/src/tree.c Wed Apr 03 21:22:23 2024 +0200 1.3 @@ -186,8 +186,17 @@ 1.4 // check if we are currently exiting or entering nodes 1.5 if (iter->exiting) { 1.6 children = NULL; 1.7 + // skipping on exit is pointless, just clear the flag 1.8 + iter->skip = false; 1.9 } else { 1.10 - children = tree_children(iter->node); 1.11 + if (iter->skip) { 1.12 + // skip flag is set, pretend that there are no children 1.13 + iter->skip = false; 1.14 + children = NULL; 1.15 + } else { 1.16 + // try to enter the children (if any) 1.17 + children = tree_children(iter->node); 1.18 + } 1.19 } 1.20 1.21 if (children == NULL) { 1.22 @@ -263,10 +272,12 @@ 1.23 1.24 // visit the root node 1.25 iter.node = root; 1.26 + iter.next = NULL; 1.27 iter.counter = 1; 1.28 iter.depth = 1; 1.29 iter.stack[0] = root; 1.30 iter.exiting = false; 1.31 + iter.skip = false; 1.32 1.33 // assign base iterator functions 1.34 iter.base.mutating = false; 1.35 @@ -310,6 +321,30 @@ 1.36 ptrdiff_t const loc_next = iter->loc_next; 1.37 ptrdiff_t const loc_children = iter->loc_children; 1.38 1.39 + // add the children of the current node to the queue 1.40 + // unless the skip flag is set 1.41 + void *children; 1.42 + if (iter->skip) { 1.43 + iter->skip = false; 1.44 + children = NULL; 1.45 + } else { 1.46 + children = tree_children(iter->node); 1.47 + } 1.48 + if (children != NULL) { 1.49 + struct cx_tree_visitor_queue_s *q; 1.50 + q = malloc(sizeof(struct cx_tree_visitor_queue_s)); 1.51 + q->depth = iter->depth + 1; 1.52 + q->node = children; 1.53 + if (iter->queue_last == NULL) { 1.54 + assert(iter->queue_next == NULL); 1.55 + iter->queue_next = q; 1.56 + } else { 1.57 + iter->queue_last->next = q; 1.58 + } 1.59 + iter->queue_last = q; 1.60 + cx_tree_visitor_enqueue_siblings(iter, children, loc_next); 1.61 + } 1.62 + 1.63 // check if there is a next node 1.64 if (iter->queue_next == NULL) { 1.65 iter->node = NULL; 1.66 @@ -331,23 +366,6 @@ 1.67 1.68 // increment the node counter 1.69 iter->counter++; 1.70 - 1.71 - // add the children of the new node to the queue 1.72 - void *children = tree_children(iter->node); 1.73 - if (children != NULL) { 1.74 - struct cx_tree_visitor_queue_s *q; 1.75 - q = malloc(sizeof(struct cx_tree_visitor_queue_s)); 1.76 - q->depth = iter->depth + 1; 1.77 - q->node = children; 1.78 - if (iter->queue_last == NULL) { 1.79 - assert(iter->queue_next == NULL); 1.80 - iter->queue_next = q; 1.81 - } else { 1.82 - iter->queue_last->next = q; 1.83 - } 1.84 - iter->queue_last = q; 1.85 - cx_tree_visitor_enqueue_siblings(iter, children, loc_next); 1.86 - } 1.87 } 1.88 1.89 CxTreeVisitor cx_tree_visitor( 1.90 @@ -366,19 +384,9 @@ 1.91 iter.node = root; 1.92 iter.counter = 1; 1.93 iter.depth = 1; 1.94 - 1.95 - // put all children of root into the queue 1.96 - void *children = tree_children(root); 1.97 - if (children == NULL) { 1.98 - iter.queue_next = NULL; 1.99 - iter.queue_last = NULL; 1.100 - } else { 1.101 - iter.queue_next = malloc(sizeof(struct cx_tree_visitor_queue_s)); 1.102 - iter.queue_next->depth = 2; 1.103 - iter.queue_next->node = children; 1.104 - iter.queue_last = iter.queue_next; 1.105 - cx_tree_visitor_enqueue_siblings(&iter, children, loc_next); 1.106 - } 1.107 + iter.skip = false; 1.108 + iter.queue_next = NULL; 1.109 + iter.queue_last = NULL; 1.110 1.111 // assign base iterator functions 1.112 iter.base.mutating = false;