diff --git a/librz/include/rz_util/rz_intervaltree.h b/librz/include/rz_util/rz_intervaltree.h index 72ab5cf5ea..94c7f92e91 100644 --- a/librz/include/rz_util/rz_intervaltree.h +++ b/librz/include/rz_util/rz_intervaltree.h @@ -42,8 +42,7 @@ typedef struct rz_interval_tree_t { RZ_API void rz_interval_tree_init(RzIntervalTree *tree, RzIntervalNodeFree free); RZ_API void rz_interval_tree_fini(RzIntervalTree *tree); -// return false if the insertion failed. -RZ_API bool rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, void *data); +RZ_API RZ_NULLABLE RzIntervalNode *rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, void *data); // Removes a given node from the tree. The node will be freed. // If free is true, the data in the node is freed as well. diff --git a/librz/util/intervaltree.c b/librz/util/intervaltree.c index 9bc2578eaa..6e7e541827 100644 --- a/librz/util/intervaltree.c +++ b/librz/util/intervaltree.c @@ -118,8 +118,14 @@ RZ_API void rz_interval_tree_fini(RzIntervalTree *tree) { rz_rbtree_free(&tree->root->node, interval_node_free, tree->free); } -RZ_API bool rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, void *data) { - rz_return_val_if_fail(end >= start, false); +/** + * \brief Insert an element into the interval tree + * \param start Lowest value covered by the element + * \param end May be the inclusive or exclusive end of the interval. This is determined only by how it is queried later. + * \return The newly created node or NULL if the insertion failed. + */ +RZ_API RZ_NULLABLE RzIntervalNode *rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, void *data) { + rz_return_val_if_fail(tree && end >= start, false); RzIntervalNode *node = RZ_NEW0(RzIntervalNode); if (!node) { return false; @@ -132,8 +138,9 @@ RZ_API bool rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, tree->root = unwrap(root); if (!r) { free(node); + return NULL; } - return r; + return node; } RZ_API bool rz_interval_tree_delete(RzIntervalTree *tree, RzIntervalNode *node, bool free) { @@ -152,7 +159,7 @@ RZ_API bool rz_interval_tree_resize(RzIntervalTree *tree, RzIntervalNode *node, if (!rz_interval_tree_delete(tree, node, false)) { return false; } - return rz_interval_tree_insert(tree, new_start, new_end, data); + return rz_interval_tree_insert(tree, new_start, new_end, data) != NULL; } if (node->end != new_end) { // Only end change just needs the updated augmented max value to be propagated upwards diff --git a/test/unit/test_intervaltree.c b/test/unit/test_intervaltree.c index 6ac0bc8b84..29afd2e39b 100644 --- a/test/unit/test_intervaltree.c +++ b/test/unit/test_intervaltree.c @@ -44,7 +44,8 @@ bool test_rz_interval_tree_insert_at() { rz_interval_tree_insert(&tree, 5, 123, NULL); rz_interval_tree_insert(&tree, 6, 54, NULL); rz_interval_tree_insert(&tree, 4, 5, NULL); - rz_interval_tree_insert(&tree, 3, 9, (void *)0x1337); + RzIntervalNode *node3 = rz_interval_tree_insert(&tree, 3, 9, (void *)0x1337); + mu_assert_notnull(node3, "inserted node"); rz_interval_tree_insert(&tree, 4, 11, NULL); rz_interval_tree_insert(&tree, 1, 42, NULL); @@ -53,7 +54,7 @@ bool test_rz_interval_tree_insert_at() { } RzIntervalNode *node = rz_interval_tree_node_at(&tree, 3); - mu_assert_notnull(node, "at not null"); + mu_assert_ptreq(node, node3, "node at return"); mu_assert_ptreq(node->data, (void *)0x1337, "at node data"); mu_assert_eq_fmt(node->start, (ut64)3, "at node start", "0x%" PFMT64x); mu_assert_eq_fmt(node->end, (ut64)9, "at node end", "0x%" PFMT64x);