}
-/* Delete an element from a tree. The 'old' value does not
- necessarily have to point to the element to be deleted, it must
- just point to a treap structure with the key to be deleted.
- Returns the new root node of the tree. */
+/* Delete an element from a tree, returning the new root node of the tree.
+ The OLD value does not necessarily have to point to the element to be
+ deleted, it must just point to a treap structure with the key to be deleted.
+ The REMOVED argument, if non-null, is set to the removed element from the
+ tree upon return. */
static gfc_bbt *
-delete_treap (gfc_bbt *old, gfc_bbt *t, compare_fn compare)
+delete_treap (gfc_bbt *old, gfc_bbt *t, compare_fn compare, gfc_bbt **removed)
{
int c;
- if (t == NULL)
- return NULL;
+ if (t == nullptr)
+ {
+ if (removed)
+ *removed = nullptr;
+ return nullptr;
+ }
c = (*compare) (old, t);
if (c < 0)
- t->left = delete_treap (old, t->left, compare);
+ t->left = delete_treap (old, t->left, compare, removed);
if (c > 0)
- t->right = delete_treap (old, t->right, compare);
+ t->right = delete_treap (old, t->right, compare, removed);
if (c == 0)
- t = delete_root (t);
+ {
+ if (removed)
+ *removed = t;
+ t = delete_root (t);
+ }
return t;
}
-void
+/* Delete the element from the tree at *ROOT that matches the OLD element
+ according to the COMPARE_FN function. This updates the *ROOT pointer to
+ point to the new tree root (if different from the original) and returns the
+ deleted element. */
+
+void *
gfc_delete_bbt (void *root, void *old, compare_fn compare)
{
gfc_bbt **t;
+ gfc_bbt *removed;
t = (gfc_bbt **) root;
- *t = delete_treap ((gfc_bbt *) old, *t, compare);
+ *t = delete_treap ((gfc_bbt *) old, *t, compare, &removed);
+
+ return (void *) removed;
}
gfc_namespace *gfc_get_namespace (gfc_namespace *, int);
gfc_symtree *gfc_new_symtree (gfc_symtree **, const char *);
gfc_symtree *gfc_find_symtree (gfc_symtree *, const char *);
-void gfc_delete_symtree (gfc_symtree **, const char *);
gfc_symtree *gfc_get_unique_symtree (gfc_namespace *);
gfc_user_op *gfc_get_uop (const char *);
gfc_user_op *gfc_find_uop (const char *, gfc_namespace *);
/* bbt.cc */
typedef int (*compare_fn) (void *, void *);
void gfc_insert_bbt (void *, void *, compare_fn);
-void gfc_delete_bbt (void *, void *, compare_fn);
+void * gfc_delete_bbt (void *, void *, compare_fn);
/* dump-parse-tree.cc */
void gfc_dump_parse_tree (gfc_namespace *, FILE *);
/* Delete a symbol from the tree. Does not free the symbol itself! */
-void
+static void
gfc_delete_symtree (gfc_symtree **root, const char *name)
{
gfc_symtree st, *st0;
else
p = name;
- st0 = gfc_find_symtree (*root, p);
-
st.name = gfc_get_string ("%s", p);
- gfc_delete_bbt (root, &st, compare_symtree);
+ st0 = (gfc_symtree *) gfc_delete_bbt (root, &st, compare_symtree);
free (st0);
}