Merging upstream version 3.7.8.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
099007bbc4
commit
a3c6363c26
52 changed files with 13518 additions and 998 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue