src/tree.c

changeset 833
5c926801f052
parent 830
c4dae6fe6d5b
child 834
04c53b3c8378
     1.1 --- a/src/tree.c	Sun Feb 18 13:16:38 2024 +0100
     1.2 +++ b/src/tree.c	Sun Feb 18 13:38:42 2024 +0100
     1.3 @@ -109,17 +109,14 @@
     1.4      }
     1.5  
     1.6      // create a working stack
     1.7 -    size_t work_cap = 32;
     1.8 -    size_t work_size = 0;
     1.9 -    void const **work = malloc(sizeof(void*) * work_cap);
    1.10 -    #define work_add(node) cx_array_add(&work, &work_size, &work_cap, \
    1.11 -        sizeof(void*), &(node), cx_array_default_reallocator)
    1.12 +    cx_array_declare(void const*, work);
    1.13 +    cx_array_initialize(work, 32);
    1.14  
    1.15      // add the children of root to the working stack
    1.16      {
    1.17          void *c = tree_children(root);
    1.18          while (c != NULL) {
    1.19 -            work_add(c);
    1.20 +            cx_array_simple_add(work, c);
    1.21              c = tree_next(c);
    1.22          }
    1.23      }
    1.24 @@ -146,7 +143,7 @@
    1.25              // if children might contain the data, add them to the stack
    1.26              void *c = tree_children(node);
    1.27              while (c != NULL) {
    1.28 -                work_add(c);
    1.29 +                cx_array_simple_add(work, c);
    1.30                  c = tree_next(c);
    1.31              }
    1.32  
    1.33 @@ -165,7 +162,6 @@
    1.34      }
    1.35  
    1.36      // free the working queue and return
    1.37 -    #undef workq_add
    1.38      free(work);
    1.39      return ret;
    1.40  }
    1.41 @@ -180,14 +176,6 @@
    1.42      return iter->node;
    1.43  }
    1.44  
    1.45 -static void cx_tree_iter_stack_add(
    1.46 -        struct cx_tree_iterator_s *iter,
    1.47 -        void *node
    1.48 -) {
    1.49 -    cx_array_add(&iter->stack, &iter->depth, &iter->stack_capacity,
    1.50 -        sizeof(void*), &node, cx_array_default_reallocator);
    1.51 -}
    1.52 -
    1.53  static void cx_tree_iter_next(void *it) {
    1.54      struct cx_tree_iterator_s *iter = it;
    1.55      // TODO: support mutating iterator
    1.56 @@ -195,77 +183,28 @@
    1.57      // TODO: implement
    1.58  }
    1.59  
    1.60 -
    1.61  CxTreeIterator cx_tree_iterator(
    1.62          void *root,
    1.63 -        int passes,
    1.64 +        bool visit_on_exit,
    1.65          ptrdiff_t loc_children,
    1.66          ptrdiff_t loc_next
    1.67  ) {
    1.68      CxTreeIterator iter;
    1.69      iter.loc_children = loc_children;
    1.70      iter.loc_next = loc_next;
    1.71 -    iter.requested_passes = passes;
    1.72 -
    1.73 -    // invalidate iterator immediately when passes is invalid
    1.74 -    if ((passes & (CX_TREE_ITERATOR_ENTER |
    1.75 -                   CX_TREE_ITERATOR_NEXT_CHILD |
    1.76 -                   CX_TREE_ITERATOR_EXIT)) == 0) {
    1.77 -        iter.stack = NULL;
    1.78 -        iter.node = NULL;
    1.79 -        return iter;
    1.80 -    }
    1.81 +    iter.visit_on_exit = visit_on_exit;
    1.82  
    1.83      // allocate stack
    1.84      iter.stack_capacity = 16;
    1.85      iter.stack = malloc(sizeof(void *) * 16);
    1.86      iter.depth = 0;
    1.87  
    1.88 -    // determine start
    1.89 -    if ((passes & CX_TREE_ITERATOR_ENTER) == 0) {
    1.90 -        // we have to skip the first "entering" passes
    1.91 -        void *s = NULL;
    1.92 -        void *n = root;
    1.93 -        iter.counter = 0;
    1.94 -        do {
    1.95 -            iter.counter++;
    1.96 -            iter.source = s;
    1.97 -            iter.node = n;
    1.98 -            cx_tree_iter_stack_add(&iter, n);
    1.99 -            s = n;
   1.100 -            n = tree_children(n);
   1.101 -        } while (n != NULL);
   1.102 -        // found a leaf node s (might be root itself if it has no children)
   1.103 -
   1.104 -        // check if there is a sibling
   1.105 -        n = tree_next(s);
   1.106 -
   1.107 -        if (n == NULL) {
   1.108 -            // no sibling found, exit back to parent node
   1.109 -            // TODO: implement
   1.110 -        } else {
   1.111 -            // there is a sibling
   1.112 -            if ((passes & CX_TREE_ITERATOR_EXIT) == 0) {
   1.113 -                // no exit requested, conclude that only next_child is requested
   1.114 -                iter.source = s;
   1.115 -                iter.node = n;
   1.116 -                iter.counter++;
   1.117 -                iter.current_pass = CX_TREE_ITERATOR_NEXT_CHILD;
   1.118 -            } else {
   1.119 -                // exit requested, so we have found our first pass
   1.120 -                // iter.node and iter.source are still correct
   1.121 -                iter.current_pass = CX_TREE_ITERATOR_EXIT;
   1.122 -            }
   1.123 -        }
   1.124 -    } else {
   1.125 -        // enter passes are requested, we can start by entering the root node
   1.126 -        iter.source = NULL;
   1.127 -        iter.node = root;
   1.128 -        iter.current_pass = CX_TREE_ITERATOR_ENTER;
   1.129 -        iter.counter = 1;
   1.130 -        iter.depth = 1;
   1.131 -        iter.stack[0] = root;
   1.132 -    }
   1.133 +    // visit the root node
   1.134 +    iter.node = root;
   1.135 +    iter.counter = 1;
   1.136 +    iter.depth = 1;
   1.137 +    iter.stack[0] = root;
   1.138 +    iter.exiting = false;
   1.139  
   1.140      // assign base iterator functions
   1.141      iter.base.mutating = false;

mercurial