src/tree.c

changeset 848
6456036bbb37
parent 845
2615317311b7
     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;

mercurial