Rizin
unix-like reverse engineering framework and cli tools
tree.c File Reference
#include <rz_util.h>
#include <rz_vector.h>

Go to the source code of this file.

Functions

static void tree_dfs_node (RTreeNode *r, RTreeVisitor *vis)
 
static void rz_tree_node_free (RTreeNode *n)
 
static void node_free (RTreeNode *n, RTreeVisitor *vis)
 
static void free_all_children (RTree *t)
 
static void update_depth (RTreeNode *n, RTreeVisitor *vis)
 
static RTreeNodenode_new (RTree *t, void *data)
 
RZ_API RTreerz_tree_new (void)
 
RZ_API void rz_tree_free (RTree *t)
 
RZ_API void rz_tree_reset (RTree *t)
 
RZ_API RTreeNoderz_tree_add_node (RTree *t, RTreeNode *node, void *child_data)
 
RZ_API void rz_tree_dfs (RTree *t, RTreeVisitor *vis)
 
RZ_API void rz_tree_bfs (RTree *t, RTreeVisitor *vis)
 

Function Documentation

◆ free_all_children()

static void free_all_children ( RTree t)
static

Definition at line 51 of file tree.c.

51  {
52  RTreeVisitor vis = { 0 };
54  rz_tree_bfs(t, &vis);
55 }
static void node_free(RTreeNode *n, RTreeVisitor *vis)
Definition: tree.c:47
RZ_API void rz_tree_bfs(RTree *t, RTreeVisitor *vis)
Definition: tree.c:132
void(* RTreeNodeVisitCb)(RTreeNode *n, RTreeVisitor *vis)
Definition: rz_tree.h:27
void(* post_visit)(RTreeNode *, struct rz_tree_visitor_t *)
Definition: rz_tree.h:23

References node_free(), rz_tree_visitor_t::post_visit, and rz_tree_bfs().

Referenced by rz_tree_free(), and rz_tree_reset().

◆ node_free()

static void node_free ( RTreeNode n,
RTreeVisitor vis 
)
static

Definition at line 47 of file tree.c.

47  {
49 }
static void rz_tree_node_free(RTreeNode *n)
Definition: tree.c:39
int n
Definition: mipsasm.c:19

References n, and rz_tree_node_free().

Referenced by free_all_children().

◆ node_new()

static RTreeNode* node_new ( RTree t,
void *  data 
)
static

Definition at line 61 of file tree.c.

61  {
63  if (!n) {
64  return NULL;
65  }
66  n->children = rz_list_new();
67  n->data = data;
68  n->tree = t;
69  return n;
70 }
#define NULL
Definition: cris-opc.c:27
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
#define RZ_NEW0(x)
Definition: rz_types.h:284

References n, NULL, rz_list_new(), and RZ_NEW0.

Referenced by rz_tree_add_node().

◆ rz_tree_add_node()

RZ_API RTreeNode* rz_tree_add_node ( RTree t,
RTreeNode node,
void *  child_data 
)

Definition at line 99 of file tree.c.

99  {
100  RTreeNode *child;
101  RTreeVisitor vis = { 0 };
102 
103  /* a NULL node is allowed only the first time, to set the root */
104  if (!t || (node && node->tree != t) || (t->root && !node)) {
105  return NULL;
106  }
107 
108  child = node_new(t, child_data);
109  if (!node && !t->root) {
110  t->root = child;
111  } else if (node) {
112  rz_list_append(node->children, child);
113  node->n_children++;
114  }
115  child->parent = node;
116 
117  /* update depth */
119  tree_dfs_node(child, &vis);
120 
121  return child;
122 }
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
static void tree_dfs_node(RTreeNode *r, RTreeVisitor *vis)
Definition: tree.c:7
static RTreeNode * node_new(RTree *t, void *data)
Definition: tree.c:61
static void update_depth(RTreeNode *n, RTreeVisitor *vis)
Definition: tree.c:57
unsigned int n_children
Definition: rz_tree.h:11
struct rz_tree_node_t * parent
Definition: rz_tree.h:8
struct rz_tree_t * tree
Definition: rz_tree.h:9
RzList * children
Definition: rz_tree.h:10
RTreeNode * root
Definition: rz_tree.h:18
void(* pre_visit)(RTreeNode *, struct rz_tree_visitor_t *)
Definition: rz_tree.h:22

References rz_tree_node_t::children, rz_tree_node_t::n_children, node_new(), NULL, rz_tree_node_t::parent, rz_tree_visitor_t::pre_visit, rz_tree_t::root, rz_list_append(), rz_tree_node_t::tree, tree_dfs_node(), and update_depth().

Referenced by add_trace_tree_child(), and do_debug_trace_calls().

◆ rz_tree_bfs()

RZ_API void rz_tree_bfs ( RTree t,
RTreeVisitor vis 
)

Definition at line 132 of file tree.c.

132  {
133  if (!t || !t->root) {
134  return;
135  }
136 
138  if (!pv) {
139  return;
140  }
141  rz_pvector_reserve(pv, 16);
142  rz_pvector_push(pv, t->root);
143  while (!rz_pvector_empty(pv)) {
145  if (!el) {
146  break;
147  }
148  RTreeNode *n;
149  RzListIter *it;
150 
151  if (vis->pre_visit) {
152  vis->pre_visit(el, vis);
153  }
154 
155  rz_list_foreach (el->children, it, n) {
156  if (vis->discover_child) {
157  vis->discover_child(n, vis);
158  }
159  rz_pvector_push(pv, n);
160  }
161 
162  if (vis->post_visit) {
163  vis->post_visit(el, vis);
164  }
165  }
166 
167  rz_pvector_free(pv);
168 }
static void ** rz_pvector_reserve(RzPVector *vec, size_t capacity)
Definition: rz_vector.h:312
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
static bool rz_pvector_empty(RzPVector *vec)
Definition: rz_vector.h:246
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void * rz_pvector_pop_front(RzPVector *vec)
Definition: vector.c:379
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
void(* discover_child)(RTreeNode *, struct rz_tree_visitor_t *)
Definition: rz_tree.h:24

References rz_tree_node_t::children, rz_tree_visitor_t::discover_child, n, NULL, rz_tree_visitor_t::post_visit, rz_tree_visitor_t::pre_visit, rz_tree_t::root, rz_pvector_empty(), rz_pvector_free(), rz_pvector_new(), rz_pvector_pop_front(), rz_pvector_push(), and rz_pvector_reserve().

Referenced by dot_trace_traverse(), and free_all_children().

◆ rz_tree_dfs()

RZ_API void rz_tree_dfs ( RTree t,
RTreeVisitor vis 
)

Definition at line 124 of file tree.c.

124  {
125  if (!t || !t->root) {
126  return;
127  }
128 
129  tree_dfs_node(t->root, vis);
130 }

References rz_tree_t::root, and tree_dfs_node().

Referenced by trace_traverse().

◆ rz_tree_free()

RZ_API void rz_tree_free ( RTree t)

Definition at line 76 of file tree.c.

76  {
77  if (!t) {
78  return;
79  }
80 
82  free(t);
83 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static void free_all_children(RTree *t)
Definition: tree.c:51

References free(), and free_all_children().

Referenced by rz_debug_free().

◆ rz_tree_new()

RZ_API RTree* rz_tree_new ( void  )

Definition at line 72 of file tree.c.

72  {
73  return RZ_NEW0(RTree);
74 }

References RZ_NEW0.

Referenced by rz_debug_new().

◆ rz_tree_node_free()

static void rz_tree_node_free ( RTreeNode n)
static

Definition at line 39 of file tree.c.

39  {
40  rz_list_free(n->children);
41  if (n->free) {
42  n->free(n->data);
43  }
44  free(n);
45 }
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137

References free(), n, and rz_list_free().

Referenced by node_free().

◆ rz_tree_reset()

RZ_API void rz_tree_reset ( RTree t)

Definition at line 85 of file tree.c.

85  {
86  if (!t) {
87  return;
88  }
89 
91  t->root = NULL;
92 }

References free_all_children(), NULL, and rz_tree_t::root.

Referenced by rz_cmd_debug_traces_reset_handler().

◆ tree_dfs_node()

static void tree_dfs_node ( RTreeNode r,
RTreeVisitor vis 
)
static

Definition at line 7 of file tree.c.

7  {
8  RzStack *s;
9  RzListIter *it;
10  RTreeNode *n;
11 
12  s = rz_stack_new(16);
13  if (!s) {
14  return;
15  }
16  rz_stack_push(s, r);
17  while (!rz_stack_is_empty(s)) {
19 
20  if (vis->pre_visit) {
21  vis->pre_visit(el, vis);
22  }
23 
24  rz_list_foreach_prev(el->children, it, n) {
25  if (vis->discover_child) {
26  vis->discover_child(n, vis);
27  }
28  rz_stack_push(s, n);
29  }
30 
31  if (vis->post_visit) {
32  vis->post_visit(el, vis);
33  }
34  }
35 
37 }
#define r
Definition: crypto_rc6.c:12
static RzSocket * s
Definition: rtr.c:28
RZ_API bool rz_stack_is_empty(RzStack *s)
Definition: stack.c:68
RZ_API void * rz_stack_pop(RzStack *s)
Definition: stack.c:59
RZ_API bool rz_stack_push(RzStack *s, void *el)
Definition: stack.c:42
RZ_API RzStack * rz_stack_new(ut32 n)
Definition: stack.c:6
RZ_API void rz_stack_free(RzStack *s)
Definition: stack.c:29

References rz_tree_node_t::children, rz_tree_visitor_t::discover_child, n, rz_tree_visitor_t::post_visit, rz_tree_visitor_t::pre_visit, r, rz_stack_free(), rz_stack_is_empty(), rz_stack_new(), rz_stack_pop(), rz_stack_push(), and s.

Referenced by rz_tree_add_node(), and rz_tree_dfs().

◆ update_depth()

static void update_depth ( RTreeNode n,
RTreeVisitor vis 
)
static

Definition at line 57 of file tree.c.

57  {
58  n->depth = n->parent ? n->parent->depth + 1 : 0;
59 }

References n.

Referenced by rz_tree_add_node().