1
0
Fork 0

Merging upstream version 3.7.8.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 08:08:50 +01:00
parent 099007bbc4
commit a3c6363c26
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
52 changed files with 13518 additions and 998 deletions

View file

@ -1243,14 +1243,15 @@ lyd_new_attr2(struct lyd_node *parent, const char *module_ns, const char *name,
*
* Reinserting ensures that the node is in the correct position and the data instances remain properly ordered.
*
* @param[in] term Term node to change. If it is a key, the parental list is inserted again.
* @param[in] term Term node to change. If it is a key, the parent list is reinserted.
* @param[in] val New value for @p term.
* @return LY_SUCCESS on success.
* @param[in] use_val Whether @p val can be used and spent or should only be duplicated.
* @return LY_ERR value.
*/
static LY_ERR
lyd_change_node_value(struct lyd_node_term *term, struct lyd_value *val)
lyd_change_node_value(struct lyd_node_term *term, struct lyd_value *val, ly_bool use_val)
{
LY_ERR ret = LY_SUCCESS;
LY_ERR rc = LY_SUCCESS;
struct lyd_node *target, *first;
if (term->schema->nodetype == LYS_LEAFLIST) {
@ -1260,33 +1261,115 @@ lyd_change_node_value(struct lyd_node_term *term, struct lyd_value *val)
} else {
/* just change the value */
term->value.realtype->plugin->free(LYD_CTX(term), &term->value);
term->value = *val;
if (use_val) {
term->value = *val;
} else {
rc = ((struct lysc_node_leaf *)term->schema)->type->plugin->duplicate(LYD_CTX(term), val, &term->value);
}
/* leaf that is not a key, its value is not used for its hash so it does not change */
return LY_SUCCESS;
return rc;
}
if (!LYD_NODE_IS_ALONE(target) && lyds_is_supported(target)) {
/* changing the value may cause a change in the order */
first = lyd_first_sibling(target);
first = first == target ? first->next : first;
/* unlink hash and unlink the target node in the lyds tree */
lyd_unlink_tree(target);
/* change value */
term->value.realtype->plugin->free(LYD_CTX(term), &term->value);
term->value = *val;
if (use_val) {
term->value = *val;
} else {
rc = ((struct lysc_node_leaf *)term->schema)->type->plugin->duplicate(LYD_CTX(term), val, &term->value);
}
/* reinserting */
lyd_insert_node(NULL, &first, target, LYD_INSERT_NODE_DEFAULT);
} else {
/* unlink hash */
lyd_unlink_hash(target);
/* change value */
term->value.realtype->plugin->free(LYD_CTX(term), &term->value);
term->value = *val;
if (use_val) {
term->value = *val;
} else {
rc = ((struct lysc_node_leaf *)term->schema)->type->plugin->duplicate(LYD_CTX(term), val, &term->value);
}
}
lyd_hash(target);
ret = lyd_insert_hash(target);
return ret;
lyd_hash(target);
rc = lyd_insert_hash(target);
return rc;
}
LY_ERR
lyd_change_term_val(struct lyd_node *term, struct lyd_value *val, ly_bool use_val, ly_bool is_dflt)
{
LY_ERR rc = LY_SUCCESS;
struct lysc_type *type;
struct lyd_node_term *t;
ly_bool dflt_change, val_change;
t = (struct lyd_node_term *)term;
type = ((struct lysc_node_leaf *)term->schema)->type;
/* compare original and new value */
if (type->plugin->compare(LYD_CTX(term), &t->value, val)) {
/* since they are different, they cannot both be default */
assert(!(term->flags & LYD_DEFAULT) || !is_dflt);
/* values differ, switch them */
LY_CHECK_RET(lyd_change_node_value(t, val, use_val));
val_change = 1;
} else {
/* same values, free the new stored one */
if (use_val) {
type->plugin->free(LYD_CTX(term), val);
}
val_change = 0;
}
/* clear links to leafref nodes */
if (val_change && (ly_ctx_get_options(LYD_CTX(term)) & LY_CTX_LEAFREF_LINKING)) {
lyd_free_leafref_nodes(t);
}
/* update flags */
if (val_change) {
term->flags |= LYD_NEW;
}
if ((term->flags & LYD_DEFAULT) && !is_dflt) {
/* remove dflt flag */
term->flags &= ~LYD_DEFAULT;
/* remove parent dflt flag */
lyd_np_cont_dflt_del(lyd_parent(term));
dflt_change = 1;
} else if (!(term->flags & LYD_DEFAULT) && is_dflt) {
/* add dflt flag */
term->flags |= LYD_DEFAULT;
/* add parent dflt flag */
lyd_np_cont_dflt_set(lyd_parent(term));
dflt_change = 1;
} else {
dflt_change = 0;
}
if (!val_change) {
/* only default flag change or no change */
rc = dflt_change ? LY_EEXIST : LY_ENOT;
} /* else value changed, LY_SUCCESS */
return rc;
}
/**
@ -1307,68 +1390,20 @@ lyd_change_node_value(struct lyd_node_term *term, struct lyd_value *val)
static LY_ERR
_lyd_change_term(struct lyd_node *term, const void *value, size_t value_len, LY_VALUE_FORMAT format)
{
LY_ERR ret = LY_SUCCESS;
struct lysc_type *type;
struct lyd_node_term *t;
struct lyd_node *parent;
LY_ERR r;
struct lyd_value val;
ly_bool dflt_change, val_change;
assert(term && term->schema && (term->schema->nodetype & LYD_NODE_TERM));
t = (struct lyd_node_term *)term;
type = ((struct lysc_node_leaf *)term->schema)->type;
/* parse the new value */
LOG_LOCSET(term->schema, term);
ret = lyd_value_store(LYD_CTX(term), &val, type, value, value_len, 0, 0, NULL, format, NULL, LYD_HINT_DATA,
term->schema, NULL);
r = lyd_value_store(LYD_CTX(term), &val, ((struct lysc_node_leaf *)term->schema)->type, value, value_len, 0, 0,
NULL, format, NULL, LYD_HINT_DATA, term->schema, NULL);
LOG_LOCBACK(1, 1);
LY_CHECK_GOTO(ret, cleanup);
LY_CHECK_RET(r);
/* compare original and new value */
if (type->plugin->compare(LYD_CTX(term), &t->value, &val)) {
/* values differ, switch them */
lyd_change_node_value(t, &val);
/* make the node non-validated */
term->flags &= LYD_NEW;
val_change = 1;
} else {
/* same values, free the new stored one */
type->plugin->free(LYD_CTX(term), &val);
val_change = 0;
}
/* clear links to leafref nodes */
if (ly_ctx_get_options(LYD_CTX(term)) & LY_CTX_LEAFREF_LINKING) {
lyd_free_leafref_nodes(t);
}
/* always clear the default flag */
if (term->flags & LYD_DEFAULT) {
for (parent = term; parent; parent = lyd_parent(parent)) {
parent->flags &= ~LYD_DEFAULT;
}
/* make the node non-validated */
term->flags &= LYD_NEW;
dflt_change = 1;
} else {
dflt_change = 0;
}
/* return value */
if (!val_change) {
if (dflt_change) {
/* only default flag change */
ret = LY_EEXIST;
} else {
/* no change */
ret = LY_ENOT;
}
} /* else value changed, LY_SUCCESS */
cleanup:
return ret;
/* change it */
return lyd_change_term_val(term, &val, 1, 0);
}
LIBYANG_API_DEF LY_ERR
@ -1623,13 +1658,14 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
LY_ERR ret = LY_SUCCESS, r;
struct lyxp_expr *exp = NULL;
struct ly_path *p = NULL;
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent;
struct lyd_node *nparent = NULL, *nnode = NULL, *node = NULL, *cur_parent, *iter;
const struct lysc_node *schema;
const struct lyd_value *val = NULL;
ly_bool store_only = (options & LYD_NEW_VAL_STORE_ONLY) ? 1 : 0;
ly_bool any_use_value = (options & LYD_NEW_ANY_USE_VALUE) ? 1 : 0;
LY_ARRAY_COUNT_TYPE path_idx = 0, orig_count = 0;
LY_VALUE_FORMAT format;
uint32_t hints;
uint32_t hints, count;
assert(parent || ctx);
assert(path && ((path[0] == '/') || parent));
@ -1676,7 +1712,7 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
goto cleanup;
} /* else we were not searching for the whole path */
} else if (r == LY_EINCOMPLETE) {
/* some nodes were found, adjust the iterator to the next segment */
/* some nodes were found, adjust the iterator to the next segment to be created */
++path_idx;
} else if (r == LY_ENOTFOUND) {
/* we will create the nodes from top-level, default behavior (absolute path), or from the parent (relative path) */
@ -1695,6 +1731,29 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
LY_ARRAY_INCREMENT(p);
}
if ((path_idx < LY_ARRAY_COUNT(p)) && lysc_is_dup_inst_list(p[path_idx].node) && p[path_idx].predicates &&
(p[path_idx].predicates[0].type == LY_PATH_PREDTYPE_POSITION)) {
/* check the used position of a key-less list or state leaf-list */
count = 0;
LYD_LIST_FOR_INST(node ? lyd_child(node) : parent, p[path_idx].node, iter) {
++count;
}
if (count + 1 < p[path_idx].predicates[0].position) {
if (count) {
LOGVAL(ctx, LYVE_REFERENCE,
"Cannot create \"%s\" on position %" PRIu64 ", only %" PRIu32 " instance%s exist%s.",
p[path_idx].node->name, p[path_idx].predicates[0].position, count, (count > 1) ? "s" : "",
(count > 1) ? "" : "s");
} else {
LOGVAL(ctx, LYVE_REFERENCE, "Cannot create \"%s\" on position %" PRIu64 ", no instances exist.",
p[path_idx].node->name, p[path_idx].predicates[0].position);
}
ret = LY_EINVAL;
goto cleanup;
}
}
/* create all the non-existing nodes in a loop */
for ( ; path_idx < LY_ARRAY_COUNT(p); ++path_idx) {
cur_parent = node;
@ -1789,7 +1848,7 @@ lyd_new_path_(struct lyd_node *parent, const struct ly_ctx *ctx, const struct ly
break;
case LYS_ANYDATA:
case LYS_ANYXML:
LY_CHECK_GOTO(ret = lyd_create_any(schema, value, value_type, 0, &node), cleanup);
LY_CHECK_GOTO(ret = lyd_create_any(schema, value, value_type, any_use_value, &node), cleanup);
break;
default:
LOGINT(ctx);
@ -1875,16 +1934,16 @@ lyd_new_ext_path(struct lyd_node *parent, const struct lysc_ext_instance *ext, c
}
LY_ERR
lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
lyd_new_implicit(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
const struct lys_module *mod, struct ly_set *node_when, struct ly_set *node_types, struct ly_set *ext_node,
uint32_t impl_opts, struct lyd_node **diff)
uint32_t impl_opts, struct ly_ht *getnext_ht, struct lyd_node **diff)
{
LY_ERR ret;
const struct lysc_node *iter = NULL;
const struct lysc_node *snode, **choices, **snodes;
struct lyd_node *node = NULL;
struct lyd_value **dflts;
LY_ARRAY_COUNT_TYPE u;
uint32_t getnext_opts;
uint32_t i;
assert(first && (parent || sparent || mod));
@ -1892,40 +1951,51 @@ lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struc
sparent = parent->schema;
}
getnext_opts = LYS_GETNEXT_WITHCHOICE;
if (impl_opts & LYD_IMPLICIT_OUTPUT) {
getnext_opts |= LYS_GETNEXT_OUTPUT;
}
/* get cached getnext schema nodes */
LY_CHECK_RET(lyd_val_getnext_get(sparent, mod, NULL, impl_opts & LYD_IMPLICIT_OUTPUT, getnext_ht, &choices, &snodes));
while ((iter = lys_getnext(iter, sparent, mod ? mod->compiled : NULL, getnext_opts))) {
if ((impl_opts & LYD_IMPLICIT_NO_STATE) && (iter->flags & LYS_CONFIG_R)) {
/* choice nodes */
for (i = 0; choices && choices[i]; ++i) {
snode = choices[i];
if ((impl_opts & LYD_IMPLICIT_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
continue;
} else if ((impl_opts & LYD_IMPLICIT_NO_CONFIG) && (iter->flags & LYS_CONFIG_W)) {
} else if ((impl_opts & LYD_IMPLICIT_NO_CONFIG) && (snode->flags & LYS_CONFIG_W)) {
continue;
}
switch (iter->nodetype) {
case LYS_CHOICE:
node = lys_getnext_data(NULL, *first, NULL, iter, NULL);
if (!node && ((struct lysc_node_choice *)iter)->dflt) {
/* create default case data */
LY_CHECK_RET(lyd_new_implicit_r(parent, first, &((struct lysc_node_choice *)iter)->dflt->node,
NULL, node_when, node_types, ext_node, impl_opts, diff));
} else if (node) {
/* create any default data in the existing case */
assert(node->schema->parent->nodetype == LYS_CASE);
LY_CHECK_RET(lyd_new_implicit_r(parent, first, node->schema->parent, NULL, node_when, node_types,
ext_node, impl_opts, diff));
}
break;
node = lys_getnext_data(NULL, *first, NULL, snode, NULL);
if (!node && ((struct lysc_node_choice *)snode)->dflt) {
/* create default case data */
LY_CHECK_RET(lyd_new_implicit(parent, first, &((struct lysc_node_choice *)snode)->dflt->node,
NULL, node_when, node_types, ext_node, impl_opts, getnext_ht, diff));
} else if (node) {
/* create any default data in the existing case */
assert(node->schema->parent->nodetype == LYS_CASE);
LY_CHECK_RET(lyd_new_implicit(parent, first, node->schema->parent, NULL, node_when, node_types, ext_node,
impl_opts, getnext_ht, diff));
}
}
/* container, leaf, leaf-list nodes */
for (i = 0; snodes && snodes[i]; ++i) {
snode = snodes[i];
if ((impl_opts & LYD_IMPLICIT_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
continue;
} else if ((impl_opts & LYD_IMPLICIT_NO_CONFIG) && (snode->flags & LYS_CONFIG_W)) {
continue;
}
switch (snode->nodetype) {
case LYS_CONTAINER:
if (!(iter->flags & LYS_PRESENCE) && lyd_find_sibling_val(*first, iter, NULL, 0, NULL)) {
if (!(snode->flags & LYS_PRESENCE) && lyd_find_sibling_val(*first, snode, NULL, 0, NULL)) {
/* create default NP container */
LY_CHECK_RET(lyd_create_inner(iter, &node));
node->flags = LYD_DEFAULT | (lysc_has_when(iter) ? LYD_WHEN_TRUE : 0);
LY_CHECK_RET(lyd_create_inner(snode, &node));
node->flags = LYD_DEFAULT | (lysc_has_when(snode) ? LYD_WHEN_TRUE : 0);
lyd_insert_node(parent, first, node, LYD_INSERT_NODE_DEFAULT);
if (lysc_has_when(iter) && node_when) {
if (lysc_has_when(snode) && node_when) {
/* remember to resolve when */
LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
}
@ -1937,17 +2007,13 @@ lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struc
/* add into diff */
LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_CREATE, diff));
}
/* create any default children */
LY_CHECK_RET(lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, node_when, node_types,
ext_node, impl_opts, diff));
}
break;
case LYS_LEAF:
if (!(impl_opts & LYD_IMPLICIT_NO_DEFAULTS) && ((struct lysc_node_leaf *)iter)->dflt &&
lyd_find_sibling_val(*first, iter, NULL, 0, NULL)) {
if (!(impl_opts & LYD_IMPLICIT_NO_DEFAULTS) && ((struct lysc_node_leaf *)snode)->dflt &&
lyd_find_sibling_val(*first, snode, NULL, 0, NULL)) {
/* create default leaf */
ret = lyd_create_term2(iter, ((struct lysc_node_leaf *)iter)->dflt, &node);
ret = lyd_create_term2(snode, ((struct lysc_node_leaf *)snode)->dflt, &node);
if (ret == LY_EINCOMPLETE) {
if (node_types) {
/* remember to resolve type */
@ -1956,10 +2022,10 @@ lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struc
} else if (ret) {
return ret;
}
node->flags = LYD_DEFAULT | (lysc_has_when(iter) ? LYD_WHEN_TRUE : 0);
node->flags = LYD_DEFAULT | (lysc_has_when(snode) ? LYD_WHEN_TRUE : 0);
lyd_insert_node(parent, first, node, LYD_INSERT_NODE_DEFAULT);
if (lysc_has_when(iter) && node_when) {
if (lysc_has_when(snode) && node_when) {
/* remember to resolve when */
LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
}
@ -1974,12 +2040,12 @@ lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struc
}
break;
case LYS_LEAFLIST:
if (!(impl_opts & LYD_IMPLICIT_NO_DEFAULTS) && ((struct lysc_node_leaflist *)iter)->dflts &&
lyd_find_sibling_val(*first, iter, NULL, 0, NULL)) {
if (!(impl_opts & LYD_IMPLICIT_NO_DEFAULTS) && ((struct lysc_node_leaflist *)snode)->dflts &&
lyd_find_sibling_val(*first, snode, NULL, 0, NULL)) {
/* create all default leaf-lists */
dflts = ((struct lysc_node_leaflist *)iter)->dflts;
dflts = ((struct lysc_node_leaflist *)snode)->dflts;
LY_ARRAY_FOR(dflts, u) {
ret = lyd_create_term2(iter, dflts[u], &node);
ret = lyd_create_term2(snode, dflts[u], &node);
if (ret == LY_EINCOMPLETE) {
if (node_types) {
/* remember to resolve type */
@ -1988,10 +2054,10 @@ lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struc
} else if (ret) {
return ret;
}
node->flags = LYD_DEFAULT | (lysc_has_when(iter) ? LYD_WHEN_TRUE : 0);
node->flags = LYD_DEFAULT | (lysc_has_when(snode) ? LYD_WHEN_TRUE : 0);
lyd_insert_node(parent, first, node, LYD_INSERT_NODE_DEFAULT);
if (lysc_has_when(iter) && node_when) {
if (lysc_has_when(snode) && node_when) {
/* remember to resolve when */
LY_CHECK_RET(ly_set_add(node_when, node, 1, NULL));
}
@ -2015,38 +2081,64 @@ lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struc
return LY_SUCCESS;
}
LY_ERR
lyd_new_implicit_r(struct lyd_node *parent, struct lyd_node **first, const struct lysc_node *sparent,
const struct lys_module *mod, struct ly_set *node_when, struct ly_set *node_types, struct ly_set *ext_node,
uint32_t impl_opts, struct ly_ht *getnext_ht, struct lyd_node **diff)
{
struct lyd_node *child;
/* parent children */
LY_CHECK_RET(lyd_new_implicit(parent, first, sparent, mod, node_when, node_types, ext_node, impl_opts, getnext_ht, diff));
LY_LIST_FOR(parent ? lyd_child_no_keys(parent) : *first, child) {
/* recursively for all the containers */
if ((child->flags & LYD_DEFAULT) && (child->schema->nodetype == LYS_CONTAINER)) {
LY_CHECK_RET(lyd_new_implicit_r(child, lyd_node_child_p(child), NULL, mod, node_when, node_types, ext_node,
impl_opts, getnext_ht, diff));
}
}
return LY_SUCCESS;
}
LIBYANG_API_DEF LY_ERR
lyd_new_implicit_tree(struct lyd_node *tree, uint32_t implicit_options, struct lyd_node **diff)
{
LY_ERR ret = LY_SUCCESS;
LY_ERR rc = LY_SUCCESS;
struct lyd_node *node;
struct ly_set node_when = {0};
struct ly_ht *getnext_ht = NULL;
LY_CHECK_ARG_RET(NULL, tree, LY_EINVAL);
if (diff) {
*diff = NULL;
}
/* create the getnext hash table */
LY_CHECK_GOTO(rc = lyd_val_getnext_ht_new(&getnext_ht), cleanup);
LYD_TREE_DFS_BEGIN(tree, node) {
if (node->schema && (node->schema->nodetype & LYD_NODE_INNER)) {
LY_CHECK_GOTO(ret = lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, &node_when, NULL,
NULL, implicit_options, diff), cleanup);
LY_CHECK_GOTO(rc = lyd_new_implicit(node, lyd_node_child_p(node), NULL, NULL, &node_when, NULL,
NULL, implicit_options, getnext_ht, diff), cleanup);
}
LYD_TREE_DFS_END(tree, node);
}
/* resolve when and remove any invalid defaults */
ret = lyd_validate_unres(&tree, NULL, 0, &node_when, LYXP_IGNORE_WHEN, NULL, NULL, NULL, NULL, 0, diff);
LY_CHECK_GOTO(ret, cleanup);
rc = lyd_validate_unres(&tree, NULL, 0, &node_when, LYXP_IGNORE_WHEN, NULL, NULL, NULL, NULL, 0, diff);
LY_CHECK_GOTO(rc, cleanup);
cleanup:
ly_set_erase(&node_when, NULL);
if (ret && diff) {
lyd_val_getnext_ht_free(getnext_ht);
if (rc && diff) {
lyd_free_all(*diff);
*diff = NULL;
}
return ret;
return rc;
}
LIBYANG_API_DEF LY_ERR
@ -2055,7 +2147,7 @@ lyd_new_implicit_all(struct lyd_node **tree, const struct ly_ctx *ctx, uint32_t
const struct lys_module *mod;
struct lyd_node *d = NULL;
uint32_t i = 0;
LY_ERR ret = LY_SUCCESS;
LY_ERR rc = LY_SUCCESS;
LY_CHECK_ARG_RET(ctx, tree, *tree || ctx, LY_EINVAL);
LY_CHECK_CTX_EQUAL_RET(*tree ? LYD_CTX(*tree) : NULL, ctx, LY_EINVAL);
@ -2072,7 +2164,7 @@ lyd_new_implicit_all(struct lyd_node **tree, const struct ly_ctx *ctx, uint32_t
continue;
}
LY_CHECK_GOTO(ret = lyd_new_implicit_module(tree, mod, implicit_options, diff ? &d : NULL), cleanup);
LY_CHECK_GOTO(rc = lyd_new_implicit_module(tree, mod, implicit_options, diff ? &d : NULL), cleanup);
if (d) {
/* merge into one diff */
lyd_insert_sibling(*diff, d, diff);
@ -2082,20 +2174,21 @@ lyd_new_implicit_all(struct lyd_node **tree, const struct ly_ctx *ctx, uint32_t
}
cleanup:
if (ret && diff) {
if (rc && diff) {
lyd_free_all(*diff);
*diff = NULL;
}
return ret;
return rc;
}
LIBYANG_API_DEF LY_ERR
lyd_new_implicit_module(struct lyd_node **tree, const struct lys_module *module, uint32_t implicit_options,
struct lyd_node **diff)
{
LY_ERR ret = LY_SUCCESS;
LY_ERR rc = LY_SUCCESS;
struct lyd_node *root, *d = NULL;
struct ly_set node_when = {0};
struct ly_ht *getnext_ht = NULL;
LY_CHECK_ARG_RET(NULL, tree, module, LY_EINVAL);
LY_CHECK_CTX_EQUAL_RET(*tree ? LYD_CTX(*tree) : NULL, module ? module->ctx : NULL, LY_EINVAL);
@ -2103,17 +2196,20 @@ lyd_new_implicit_module(struct lyd_node **tree, const struct lys_module *module,
*diff = NULL;
}
/* create the getnext hash table for this module */
LY_CHECK_GOTO(rc = lyd_val_getnext_ht_new(&getnext_ht), cleanup);
/* add all top-level defaults for this module */
LY_CHECK_GOTO(ret = lyd_new_implicit_r(NULL, tree, NULL, module, &node_when, NULL, NULL, implicit_options, diff),
cleanup);
rc = lyd_new_implicit(NULL, tree, NULL, module, &node_when, NULL, NULL, implicit_options, getnext_ht, diff);
LY_CHECK_GOTO(rc, cleanup);
/* resolve when and remove any invalid defaults */
LY_CHECK_GOTO(ret = lyd_validate_unres(tree, module, 0, &node_when, LYXP_IGNORE_WHEN, NULL, NULL, NULL, NULL,
LY_CHECK_GOTO(rc = lyd_validate_unres(tree, module, 0, &node_when, LYXP_IGNORE_WHEN, NULL, NULL, NULL, NULL,
0, diff), cleanup);
/* process nested nodes */
/* process top-level (and nested) nodes */
LY_LIST_FOR(*tree, root) {
LY_CHECK_GOTO(ret = lyd_new_implicit_tree(root, implicit_options, diff ? &d : NULL), cleanup);
LY_CHECK_GOTO(rc = lyd_new_implicit_tree(root, implicit_options, diff ? &d : NULL), cleanup);
if (d) {
/* merge into one diff */
@ -2124,9 +2220,10 @@ lyd_new_implicit_module(struct lyd_node **tree, const struct lys_module *module,
cleanup:
ly_set_erase(&node_when, NULL);
if (ret && diff) {
lyd_val_getnext_ht_free(getnext_ht);
if (rc && diff) {
lyd_free_all(*diff);
*diff = NULL;
}
return ret;
return rc;
}