data tree NEW opaque data node
Used for unknown anyxml/anydata nodes.
Some refactoring including making context
const for cases when only the dictionary
is modified or replacing unsigned int with
uint32_t.
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index 7aa63ae..beb1f40 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -26,7 +26,7 @@
#include "plugins_types.h"
void
-lyd_value_free_path(struct ly_ctx *ctx, struct lyd_value_path *path)
+lyd_value_free_path(const struct ly_ctx *ctx, struct lyd_value_path *path)
{
unsigned int u, v;
@@ -43,7 +43,7 @@
}
API void
-lyd_free_meta(struct ly_ctx *ctx, struct lyd_meta *meta, int recursive)
+lyd_free_meta(const struct ly_ctx *ctx, struct lyd_meta *meta, int recursive)
{
struct lyd_meta *iter;
@@ -75,7 +75,7 @@
meta->next = NULL;
}
- for(iter = meta; iter; ) {
+ for (iter = meta; iter; ) {
meta = iter;
iter = iter->next;
@@ -85,52 +85,128 @@
}
}
+API void
+ly_free_attr(const struct ly_ctx *ctx, struct ly_attr *attr, int recursive)
+{
+ struct ly_attr *iter;
+ uint32_t u;
+
+ LY_CHECK_ARG_RET(NULL, ctx, );
+ if (!attr) {
+ return;
+ }
+
+ if (attr->parent) {
+ if (attr->parent->attr == attr) {
+ if (recursive) {
+ attr->parent->attr = NULL;
+ } else {
+ attr->parent->attr = attr->next;
+ }
+ } else {
+ for (iter = attr->parent->attr; iter->next != attr; iter = iter->next);
+ if (iter->next) {
+ if (recursive) {
+ iter->next = NULL;
+ } else {
+ iter->next = attr->next;
+ }
+ }
+ }
+ }
+
+ if (!recursive) {
+ attr->next = NULL;
+ }
+
+ for (iter = attr; iter; ) {
+ attr = iter;
+ iter = iter->next;
+
+ LY_ARRAY_FOR(attr->val_prefs, u) {
+ FREE_STRING(ctx, attr->val_prefs[u].pref);
+ FREE_STRING(ctx, attr->val_prefs[u].ns);
+ }
+ LY_ARRAY_FREE(attr->val_prefs);
+ FREE_STRING(ctx, attr->name);
+ FREE_STRING(ctx, attr->value);
+ FREE_STRING(ctx, attr->prefix.pref);
+ FREE_STRING(ctx, attr->prefix.ns);
+ free(attr);
+ }
+}
+
/**
* @brief Free Data (sub)tree.
- * @param[in] ctx libyang context.
* @param[in] node Data node to be freed.
* @param[in] top Recursion flag to unlink the root of the subtree being freed.
*/
static void
-lyd_free_subtree(struct ly_ctx *ctx, struct lyd_node *node, int top)
+lyd_free_subtree(struct lyd_node *node, int top)
{
struct lyd_node *iter, *next;
struct lyd_node *children;
+ struct lyd_node_opaq *opaq;
+ uint32_t u;
assert(node);
- /* remove children hash table in case of inner data node */
- if (node->schema->nodetype & LYD_NODE_INNER) {
- lyht_free(((struct lyd_node_inner*)node)->children_ht);
- ((struct lyd_node_inner*)node)->children_ht = NULL;
+ if (!node->schema) {
+ opaq = (struct lyd_node_opaq *)node;
/* free the children */
- children = (struct lyd_node*)lyd_node_children(node);
+ children = (struct lyd_node *)lyd_node_children(node);
LY_LIST_FOR_SAFE(children, next, iter) {
- lyd_free_subtree(ctx, iter, 0);
+ lyd_free_subtree(iter, 0);
+ }
+
+ FREE_STRING(LYD_NODE_CTX(opaq), opaq->name);
+ FREE_STRING(LYD_NODE_CTX(opaq), opaq->prefix.pref);
+ FREE_STRING(LYD_NODE_CTX(opaq), opaq->prefix.ns);
+ if (opaq->val_prefs) {
+ LY_ARRAY_FOR(opaq->val_prefs, u) {
+ FREE_STRING(LYD_NODE_CTX(opaq), opaq->val_prefs[u].pref);
+ FREE_STRING(LYD_NODE_CTX(opaq), opaq->val_prefs[u].ns);
+ }
+ LY_ARRAY_FREE(opaq->val_prefs);
+ }
+ FREE_STRING(LYD_NODE_CTX(opaq), opaq->value);
+ } else if (node->schema->nodetype & LYD_NODE_INNER) {
+ /* remove children hash table in case of inner data node */
+ lyht_free(((struct lyd_node_inner *)node)->children_ht);
+ ((struct lyd_node_inner *)node)->children_ht = NULL;
+
+ /* free the children */
+ children = (struct lyd_node *)lyd_node_children(node);
+ LY_LIST_FOR_SAFE(children, next, iter) {
+ lyd_free_subtree(iter, 0);
}
} else if (node->schema->nodetype & LYD_NODE_ANY) {
- switch (((struct lyd_node_any*)node)->value_type) {
+ switch (((struct lyd_node_any *)node)->value_type) {
case LYD_ANYDATA_DATATREE:
- lyd_free_all(((struct lyd_node_any*)node)->value.tree);
+ lyd_free_all(((struct lyd_node_any *)node)->value.tree);
break;
case LYD_ANYDATA_STRING:
case LYD_ANYDATA_XML:
case LYD_ANYDATA_JSON:
- FREE_STRING(node->schema->module->ctx, ((struct lyd_node_any*)node)->value.str);
+ FREE_STRING(LYD_NODE_CTX(node), ((struct lyd_node_any *)node)->value.str);
break;
#if 0 /* TODO LYB format */
case LYD_ANYDATA_LYB:
- free(((struct lyd_node_any*)node)->value.mem);
+ free(((struct lyd_node_any *)node)->value.mem);
break;
#endif
}
} else if (node->schema->nodetype & LYD_NODE_TERM) {
- ((struct lysc_node_leaf*)node->schema)->type->plugin->free(ctx, &((struct lyd_node_term*)node)->value);
+ ((struct lysc_node_leaf *)node->schema)->type->plugin->free(LYD_NODE_CTX(node), &((struct lyd_node_term *)node)->value);
}
- /* free the node's metadata */
- lyd_free_meta(ctx, node->meta, 1);
+ if (!node->schema) {
+ ly_free_attr(LYD_NODE_CTX(node), opaq->attr, 1);
+ } else {
+ /* free the node's metadata */
+ lyd_free_meta(LYD_NODE_CTX(node), node->meta, 1);
+ }
/* unlink only the nodes from the first level, nodes in subtree are freed all, so no unlink is needed */
if (top) {
@@ -147,7 +223,7 @@
return;
}
- lyd_free_subtree(node->schema->module->ctx, node, 1);
+ lyd_free_subtree(node, 1);
}
static void
@@ -161,7 +237,7 @@
/* get the first (top-level) sibling */
if (top) {
- for (; node->parent; node = (struct lyd_node*)node->parent);
+ for (; node->parent; node = (struct lyd_node *)node->parent);
}
while (node->prev->next) {
node = node->prev;
@@ -169,7 +245,7 @@
LY_LIST_FOR_SAFE(node, next, iter) {
/* in case of the top-level nodes (node->parent is NULL), no unlinking needed */
- lyd_free_subtree(iter->schema->module->ctx, iter, iter->parent ? 1 : 0);
+ lyd_free_subtree(iter, iter->parent ? 1 : 0);
}
}