libyang REFACTOR return values and options changes
Unified, all functions that return a variety
of errors return LY_ERR. Any options such as
NOSIBLINGS, WITHSIBLINGS and so on were replaced
by function variants with suffixes _single, _all,
_tree, and _siblings.
diff --git a/src/context.c b/src/context.c
index 302638e..b2637ff 100644
--- a/src/context.c
+++ b/src/context.c
@@ -257,10 +257,9 @@
/* load internal modules */
for (i = 0; i < ((options & LY_CTX_NOYANGLIBRARY) ? (LY_INTERNAL_MODS_COUNT - 2) : LY_INTERNAL_MODS_COUNT); i++) {
ly_in_memory(in, internal_modules[i].data);
- module = (struct lys_module *)lys_parse_mem_module(ctx, in, internal_modules[i].format,
- internal_modules[i].implemented, NULL, NULL);
- LY_CHECK_ERR_GOTO(!module, rc = ly_errcode(ctx), error);
- LY_CHECK_GOTO((rc = lys_compile(&module, 0)), error);
+ LY_CHECK_GOTO(rc = lys_parse_mem_module(ctx, in, internal_modules[i].format, internal_modules[i].implemented,
+ NULL, NULL, &module), error);
+ LY_CHECK_GOTO(rc = lys_compile(&module, 0), error);
}
ly_in_free(in, 0);
@@ -551,7 +550,6 @@
ylib_feature(struct lyd_node *parent, const struct lys_module *cur_mod)
{
LY_ARRAY_COUNT_TYPE i;
- struct lyd_node *node;
if (!cur_mod->implemented) {
/* no features can be enabled */
@@ -563,8 +561,7 @@
continue;
}
- node = lyd_new_term(parent, NULL, "feature", cur_mod->compiled->features[i].name);
- LY_CHECK_RET(!node, LY_EOTHER);
+ LY_CHECK_RET(lyd_new_term(parent, NULL, "feature", cur_mod->compiled->features[i].name, NULL));
}
return LY_SUCCESS;
@@ -574,7 +571,6 @@
ylib_deviation(struct lyd_node *parent, const struct lys_module *cur_mod, int bis)
{
LY_ARRAY_COUNT_TYPE i;
- struct lyd_node *node;
struct lys_module *mod;
if (!cur_mod->implemented) {
@@ -586,11 +582,10 @@
mod = cur_mod->compiled->deviated_by[i];
if (bis) {
- node = lyd_new_term(parent, NULL, "deviation", mod->name);
- LY_CHECK_RET(!node, LY_EOTHER);
+ LY_CHECK_RET(lyd_new_term(parent, NULL, "deviation", mod->name, NULL));
} else {
- node = lyd_new_list(parent, NULL, "deviation", mod->name, (mod->parsed->revs ? mod->parsed->revs[0].date : ""));
- LY_CHECK_RET(!node, LY_EOTHER);
+ LY_CHECK_RET(lyd_new_list(parent, NULL, "deviation", NULL, mod->name,
+ (mod->parsed->revs ? mod->parsed->revs[0].date : "")));
}
}
@@ -600,35 +595,34 @@
static LY_ERR
ylib_submodules(struct lyd_node *parent, const struct lys_module *cur_mod, int bis)
{
+ LY_ERR ret;
LY_ARRAY_COUNT_TYPE i;
- struct lyd_node *node, *cont;
+ struct lyd_node *cont;
struct lysp_submodule *submod;
- int ret;
+ int r;
char *str;
LY_ARRAY_FOR(cur_mod->parsed->includes, i) {
submod = cur_mod->parsed->includes[i].submodule;
if (bis) {
- cont = lyd_new_list(parent, NULL, "submodule", submod->name);
- LY_CHECK_RET(!cont, LY_EOTHER);
+ LY_CHECK_RET(lyd_new_list(parent, NULL, "submodule", &cont, submod->name));
if (submod->revs) {
- node = lyd_new_term(cont, NULL, "revision", submod->revs[0].date);
- LY_CHECK_RET(!node, LY_EOTHER);
+ LY_CHECK_RET(lyd_new_term(cont, NULL, "revision", submod->revs[0].date, NULL));
}
} else {
- cont = lyd_new_list(parent, NULL, "submodule", submod->name, (submod->revs ? submod->revs[0].date : ""));
- LY_CHECK_RET(!cont, LY_EOTHER);
+ LY_CHECK_RET(lyd_new_list(parent, NULL, "submodule", &cont, submod->name,
+ (submod->revs ? submod->revs[0].date : "")));
}
if (submod->filepath) {
- ret = asprintf(&str, "file://%s", submod->filepath);
- LY_CHECK_ERR_RET(ret == -1, LOGMEM(cur_mod->ctx), LY_EMEM);
+ r = asprintf(&str, "file://%s", submod->filepath);
+ LY_CHECK_ERR_RET(r == -1, LOGMEM(cur_mod->ctx), LY_EMEM);
- node = lyd_new_term(cont, NULL, bis ? "location" : "schema", str);
- LY_CHECK_RET(!node, LY_EOTHER);
+ ret = lyd_new_term(cont, NULL, bis ? "location" : "schema", str, NULL);
free(str);
+ LY_CHECK_RET(ret);
}
}
@@ -641,19 +635,20 @@
return ctx->module_set_id;
}
-API struct lyd_node *
-ly_ctx_get_yanglib_data(const struct ly_ctx *ctx)
+API LY_ERR
+ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct lyd_node **root_p)
{
+ LY_ERR ret;
uint32_t i;
- int bis = 0, ret;
+ int bis = 0, r;
char id[8], *str;
const struct lys_module *mod;
- struct lyd_node *root = NULL, *root_bis = NULL, *cont, *set_bis = NULL, *node;
+ struct lyd_node *root = NULL, *root_bis = NULL, *cont, *set_bis = NULL;
- LY_CHECK_ARG_RET(ctx, ctx, NULL);
+ LY_CHECK_ARG_RET(ctx, ctx, root_p, LY_EINVAL);
mod = ly_ctx_get_module_implemented(ctx, "ietf-yang-library");
- LY_CHECK_ERR_RET(!mod, LOGERR(ctx, LY_EINVAL, "Module \"ietf-yang-library\" is not implemented."), NULL);
+ LY_CHECK_ERR_RET(!mod, LOGERR(ctx, LY_EINVAL, "Module \"ietf-yang-library\" is not implemented."), LY_EINVAL);
if (mod->parsed->revs && !strcmp(mod->parsed->revs[0].date, "2016-06-21")) {
bis = 0;
@@ -661,18 +656,14 @@
bis = 1;
} else {
LOGERR(ctx, LY_EINVAL, "Incompatible ietf-yang-library version in context.");
- return NULL;
+ return LY_EINVAL;
}
- root = lyd_new_inner(NULL, mod, "modules-state");
- LY_CHECK_GOTO(!root, error);
+ LY_CHECK_GOTO(ret = lyd_new_inner(NULL, mod, "modules-state", &root), error);
if (bis) {
- root_bis = lyd_new_inner(NULL, mod, "yang-library");
- LY_CHECK_GOTO(!root_bis, error);
-
- set_bis = lyd_new_list(root_bis, NULL, "module-set", "complete");
- LY_CHECK_GOTO(!set_bis, error);
+ LY_CHECK_GOTO(ret = lyd_new_inner(NULL, mod, "yang-library", &root_bis), error);
+ LY_CHECK_GOTO(ret = lyd_new_list(root_bis, NULL, "module-set", &set_bis, "complete"), error);
}
for (i = 0; i < ctx->list.count; ++i) {
@@ -681,35 +672,34 @@
/*
* deprecated legacy
*/
- cont = lyd_new_list(root, NULL, "module", mod->name, (mod->parsed->revs ? mod->parsed->revs[0].date : ""));
- LY_CHECK_GOTO(!cont, error);
+ LY_CHECK_GOTO(ret = lyd_new_list(root, NULL, "module", &cont, mod->name,
+ (mod->parsed->revs ? mod->parsed->revs[0].date : "")), error);
/* schema */
if (mod->filepath) {
- ret = asprintf(&str, "file://%s", mod->filepath);
- LY_CHECK_ERR_GOTO(ret == -1, LOGMEM(ctx), error);
+ r = asprintf(&str, "file://%s", mod->filepath);
+ LY_CHECK_ERR_GOTO(r == -1, LOGMEM(ctx); ret = LY_EMEM, error);
- node = lyd_new_term(cont, NULL, "schema", str);
+ ret = lyd_new_term(cont, NULL, "schema", str, NULL);
free(str);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret, error);
}
/* namespace */
- node = lyd_new_term(cont, NULL, "namespace", mod->ns);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(cont, NULL, "namespace", mod->ns, NULL), error);
/* feature leaf-list */
- LY_CHECK_GOTO(ylib_feature(cont, mod), error);
+ LY_CHECK_GOTO(ret = ylib_feature(cont, mod), error);
/* deviation list */
- LY_CHECK_GOTO(ylib_deviation(cont, mod, 0), error);
+ LY_CHECK_GOTO(ret = ylib_deviation(cont, mod, 0), error);
/* conformance-type */
- node = lyd_new_term(cont, NULL, "conformance-type", (mod->implemented ? "implement" : "import"));
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(cont, NULL, "conformance-type", mod->implemented ? "implement" : "import",
+ NULL), error);
/* submodule list */
- LY_CHECK_GOTO(ylib_submodules(cont, mod, 0), error);
+ LY_CHECK_GOTO(ret = ylib_submodules(cont, mod, 0), error);
/*
* current revision
@@ -717,60 +707,52 @@
if (bis) {
/* name and revision */
if (mod->implemented) {
- cont = lyd_new_list(set_bis, NULL, "module", mod->name);
- LY_CHECK_GOTO(!cont, error);
+ LY_CHECK_GOTO(ret = lyd_new_list(set_bis, NULL, "module", &cont, mod->name), error);
if (mod->parsed->revs) {
- node = lyd_new_term(cont, NULL, "revision", mod->parsed->revs[0].date);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(cont, NULL, "revision", mod->parsed->revs[0].date, NULL), error);
}
} else {
- cont = lyd_new_list(set_bis, NULL, "import-only-module", mod->name,
- (mod->parsed->revs ? mod->parsed->revs[0].date : ""));
- LY_CHECK_GOTO(!cont, error);
+ LY_CHECK_GOTO(ret = lyd_new_list(set_bis, NULL, "import-only-module", &cont, mod->name,
+ (mod->parsed->revs ? mod->parsed->revs[0].date : "")), error);
}
/* namespace */
- node = lyd_new_term(cont, NULL, "namespace", mod->ns);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(cont, NULL, "namespace", mod->ns, NULL), error);
/* location */
if (mod->filepath) {
- ret = asprintf(&str, "file://%s", mod->filepath);
- LY_CHECK_ERR_GOTO(ret == -1, LOGMEM(ctx), error);
+ r = asprintf(&str, "file://%s", mod->filepath);
+ LY_CHECK_ERR_GOTO(r == -1, LOGMEM(ctx); ret = LY_EMEM, error);
- node = lyd_new_term(cont, NULL, "schema", str);
+ ret = lyd_new_term(cont, NULL, "schema", str, NULL);
free(str);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret, error);
}
/* submodule list */
- LY_CHECK_GOTO(ylib_submodules(cont, mod, 1), error);
+ LY_CHECK_GOTO(ret = ylib_submodules(cont, mod, 1), error);
/* feature list */
- LY_CHECK_GOTO(ylib_feature(cont, mod), error);
+ LY_CHECK_GOTO(ret = ylib_feature(cont, mod), error);
/* deviation */
- LY_CHECK_GOTO(ylib_deviation(cont, mod, 1), error);
+ LY_CHECK_GOTO(ret = ylib_deviation(cont, mod, 1), error);
}
}
/* IDs */
sprintf(id, "%u", ctx->module_set_id);
- node = lyd_new_term(root, NULL, "module-set-id", id);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(root, NULL, "module-set-id", id, NULL), error);
if (bis) {
/* create one complete schema */
- cont = lyd_new_list(root_bis, NULL, "schema", "complete");
- LY_CHECK_GOTO(!cont, error);
+ LY_CHECK_GOTO(ret = lyd_new_list(root_bis, NULL, "schema", &cont, "complete"), error);
- node = lyd_new_term(cont, NULL, "module-set", "complete");
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(cont, NULL, "module-set", "complete", NULL), error);
/* content-id */
- node = lyd_new_term(root_bis, NULL, "content-id", id);
- LY_CHECK_GOTO(!node, error);
+ LY_CHECK_GOTO(ret = lyd_new_term(root_bis, NULL, "content-id", id, NULL), error);
}
if (root_bis) {
@@ -781,16 +763,15 @@
root_bis = 0;
}
- if (lyd_validate(&root, NULL, LYD_VALIDATE_PRESENT, NULL)) {
- goto error;
- }
+ LY_CHECK_GOTO(ret = lyd_validate_all(&root, NULL, LYD_VALIDATE_PRESENT, NULL), error);
- return root;
+ *root_p = root;
+ return LY_SUCCESS;
error:
lyd_free_all(root);
lyd_free_all(root_bis);
- return NULL;
+ return ret;
}
API void
diff --git a/src/context.h b/src/context.h
index 9dc3f57..cdd5ced 100644
--- a/src/context.h
+++ b/src/context.h
@@ -24,6 +24,7 @@
extern "C" {
#endif
+struct lyd_node;
struct lysc_node;
/**
@@ -446,10 +447,10 @@
* ietf-yang-library module must be loaded.
*
* @param[in] ctx Context with the modules.
- * @return Generated data, must be freed,
- * @return NULL on error.
+ * @param[out] root Generated yang-library data.
+ * @return LY_ERR value
*/
-struct lyd_node *ly_ctx_get_yanglib_data(const struct ly_ctx *ctx);
+LY_ERR ly_ctx_get_yanglib_data(const struct ly_ctx *ctx, struct lyd_node **root);
/**
* @brief Free all internal structures of the specified context.
diff --git a/src/diff.c b/src/diff.c
index e69f52a..cef0713 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -102,8 +102,8 @@
}
/* duplicate the subtree (and connect to the diff if possible) */
- dup = lyd_dup(node, (struct lyd_node_inner *)diff_parent, LYD_DUP_RECURSIVE | LYD_DUP_NO_META | LYD_DUP_WITH_PARENTS);
- LY_CHECK_RET(!dup, LY_EMEM);
+ LY_CHECK_RET(lyd_dup_single(node, (struct lyd_node_inner *)diff_parent,
+ LYD_DUP_RECURSIVE | LYD_DUP_NO_META | LYD_DUP_WITH_PARENTS, &dup));
/* find the first duplicated parent */
if (!diff_parent) {
@@ -139,38 +139,36 @@
assert(!strcmp(yang_mod->name, "yang"));
/* add parent operation, if any */
- if (diff_parent && (diff_parent != dup) && !lyd_new_meta(diff_parent, yang_mod, "operation", "none")) {
- return LY_EMEM;
+ if (diff_parent && (diff_parent != dup)) {
+ LY_CHECK_RET(lyd_new_meta(diff_parent, yang_mod, "operation", "none", NULL));
}
/* add subtree operation */
- if (!lyd_new_meta(dup, yang_mod, "operation", lyd_diff_op2str(op))) {
- return LY_EMEM;
- }
+ LY_CHECK_RET(lyd_new_meta(dup, yang_mod, "operation", lyd_diff_op2str(op), NULL));
/* orig-default */
- if (orig_default && !lyd_new_meta(dup, yang_mod, "orig-default", orig_default)) {
- return LY_EMEM;
+ if (orig_default) {
+ LY_CHECK_RET(lyd_new_meta(dup, yang_mod, "orig-default", orig_default, NULL));
}
/* orig-value */
- if (orig_value && !lyd_new_meta(dup, yang_mod, "orig-value", orig_value)) {
- return LY_EMEM;
+ if (orig_value) {
+ LY_CHECK_RET(lyd_new_meta(dup, yang_mod, "orig-value", orig_value, NULL));
}
/* key */
- if (key && !lyd_new_meta(dup, yang_mod, "key", key)) {
- return LY_EMEM;
+ if (key) {
+ LY_CHECK_RET(lyd_new_meta(dup, yang_mod, "key", key, NULL));
}
/* value */
- if (value && !lyd_new_meta(dup, yang_mod, "value", value)) {
- return LY_EMEM;
+ if (value) {
+ LY_CHECK_RET(lyd_new_meta(dup, yang_mod, "value", value, NULL));
}
/* orig-key */
- if (orig_key && !lyd_new_meta(dup, yang_mod, "orig-key", orig_key)) {
- return LY_EMEM;
+ if (orig_key) {
+ LY_CHECK_RET(lyd_new_meta(dup, yang_mod, "orig-key", orig_key, NULL));
}
return LY_SUCCESS;
@@ -290,7 +288,7 @@
if (lyd_compare(second, userord_item->inst[second_pos], 0)) {
/* in first, there is a different instance on the second position, we are going to move 'first' node */
*op = LYD_DIFF_OP_REPLACE;
- } else if ((options & LYD_DIFF_WITHDEFAULTS) && ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
+ } else if ((options & LYD_DIFF_DEFAULTS) && ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
/* default flag change */
*op = LYD_DIFF_OP_NONE;
} else {
@@ -304,7 +302,7 @@
*/
/* orig-default */
- if ((options & LYD_DIFF_WITHDEFAULTS) && (schema->nodetype == LYS_LEAFLIST)
+ if ((options & LYD_DIFF_DEFAULTS) && (schema->nodetype == LYS_LEAFLIST)
&& ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_NONE))
&& ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
if (first->flags & LYD_DEFAULT) {
@@ -440,7 +438,7 @@
return LY_ENOT;
case LYS_LIST:
case LYS_LEAFLIST:
- if ((options & LYD_DIFF_WITHDEFAULTS) && ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
+ if ((options & LYD_DIFF_DEFAULTS) && ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
/* default flag change */
*op = LYD_DIFF_OP_NONE;
} else {
@@ -454,7 +452,7 @@
if (lyd_compare(first, second, 0)) {
/* different values */
*op = LYD_DIFF_OP_REPLACE;
- } else if ((options & LYD_DIFF_WITHDEFAULTS) && ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
+ } else if ((options & LYD_DIFF_DEFAULTS) && ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
/* default flag change */
*op = LYD_DIFF_OP_NONE;
} else {
@@ -472,7 +470,7 @@
*/
/* orig-default */
- if ((options & LYD_DIFF_WITHDEFAULTS) && (schema->nodetype & LYD_NODE_TERM)
+ if ((options & LYD_DIFF_DEFAULTS) && (schema->nodetype & LYD_NODE_TERM)
&& ((*op == LYD_DIFF_OP_REPLACE) || (*op == LYD_DIFF_OP_NONE))
&& ((first->flags & LYD_DEFAULT) != (second->flags & LYD_DEFAULT))) {
if (first->flags & LYD_DEFAULT) {
@@ -532,32 +530,27 @@
* @param[in] first First tree first sibling.
* @param[in] second Second tree first sibling.
* @param[in] options Diff options.
+ * @param[in] nosiblings Whether to skip following siblings.
* @param[in,out] diff Diff to append to.
* @return LY_ERR value.
*/
static LY_ERR
-lyd_diff_siblings_r(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff)
+lyd_diff_siblings_r(const struct lyd_node *first, const struct lyd_node *second, int options, int nosiblings,
+ struct lyd_node **diff)
{
LY_ERR ret = LY_SUCCESS;
const struct lyd_node *iter_first, *iter_second;
struct lyd_node *match_second, *match_first;
- int nosiblings = 0;
struct lyd_diff_userord *userord = NULL;
LY_ARRAY_COUNT_TYPE u;
enum lyd_diff_op op;
const char *orig_default;
char *orig_value, *key, *value, *orig_key;
- if (options & LYD_DIFF_NOSIBLINGS) {
- /* remember it for this function call only, should not be passed recursively */
- nosiblings = 1;
- options &= ~LYD_DIFF_NOSIBLINGS;
- }
-
/* compare first tree to the second tree - delete, replace, none */
LY_LIST_FOR(first, iter_first) {
assert(!(iter_first->schema->flags & LYS_KEY));
- if ((iter_first->flags & LYD_DEFAULT) && !(options & LYD_DIFF_WITHDEFAULTS)) {
+ if ((iter_first->flags & LYD_DEFAULT) && !(options & LYD_DIFF_DEFAULTS)) {
/* skip default nodes */
continue;
}
@@ -570,7 +563,7 @@
lyd_find_sibling_val(second, iter_first->schema, NULL, 0, &match_second);
}
- if (match_second && (match_second->flags & LYD_DEFAULT) && !(options & LYD_DIFF_WITHDEFAULTS)) {
+ if (match_second && (match_second->flags & LYD_DEFAULT) && !(options & LYD_DIFF_DEFAULTS)) {
/* ignore default nodes */
match_second = NULL;
}
@@ -617,7 +610,7 @@
/* check descendants, if any, recursively */
if (match_second) {
- LY_CHECK_GOTO(lyd_diff_siblings_r(LYD_CHILD(iter_first), LYD_CHILD(match_second), options, diff), cleanup);
+ LY_CHECK_GOTO(lyd_diff_siblings_r(LYD_CHILD(iter_first), LYD_CHILD(match_second), options, 0, diff), cleanup);
}
if (nosiblings) {
@@ -633,7 +626,7 @@
/* compare second tree to the first tree - create, user-ordered move */
LY_LIST_FOR(second, iter_second) {
assert(!(iter_second->schema->flags & LYS_KEY));
- if ((iter_second->flags & LYD_DEFAULT) && !(options & LYD_DIFF_WITHDEFAULTS)) {
+ if ((iter_second->flags & LYD_DEFAULT) && !(options & LYD_DIFF_DEFAULTS)) {
/* skip default nodes */
continue;
}
@@ -644,7 +637,7 @@
lyd_find_sibling_val(first, iter_second->schema, NULL, 0, &match_first);
}
- if (match_first && (match_first->flags & LYD_DEFAULT) && !(options & LYD_DIFF_WITHDEFAULTS)) {
+ if (match_first && (match_first->flags & LYD_DEFAULT) && !(options & LYD_DIFF_DEFAULTS)) {
/* ignore default nodes */
match_first = NULL;
}
@@ -693,8 +686,8 @@
return ret;
}
-API LY_ERR
-lyd_diff(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff)
+static LY_ERR
+lyd_diff(const struct lyd_node *first, const struct lyd_node *second, int options, int nosiblings, struct lyd_node **diff)
{
const struct ly_ctx *ctx;
@@ -715,7 +708,19 @@
*diff = NULL;
- return lyd_diff_siblings_r(first, second, options, diff);
+ return lyd_diff_siblings_r(first, second, options, nosiblings, diff);
+}
+
+API LY_ERR
+lyd_diff_tree(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff)
+{
+ return lyd_diff(first, second, options, 1, diff);
+}
+
+API LY_ERR
+lyd_diff_siblings(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff)
+{
+ return lyd_diff(first, second, options, 0, diff);
}
/**
@@ -886,9 +891,8 @@
/* find the node (we must have some siblings because the node was only moved) */
lyd_diff_find_node(*first_node, diff_node, &match);
} else {
- /* duplicate the node(s) */
- match = lyd_dup(diff_node, NULL, LYD_DUP_NO_META);
- LY_CHECK_RET(!match, LY_EMEM);
+ /* duplicate the node */
+ LY_CHECK_RET(lyd_dup_single(diff_node, NULL, LYD_DUP_NO_META, &match));
}
/* get "key" or "value" metadata string value */
@@ -937,8 +941,7 @@
break;
case LYD_DIFF_OP_CREATE:
/* duplicate the node */
- match = lyd_dup(diff_node, NULL, LYD_DUP_NO_META);
- LY_CHECK_RET(!match, LY_EMEM);
+ LY_CHECK_RET(lyd_dup_single(diff_node, NULL, LYD_DUP_NO_META, &match));
/* insert it at the end */
ret = 0;
@@ -1026,7 +1029,7 @@
}
API LY_ERR
-lyd_diff_apply(struct lyd_node **data, const struct lyd_node *diff)
+lyd_diff_apply_all(struct lyd_node **data, const struct lyd_node *diff)
{
return lyd_diff_apply_module(data, diff, NULL, NULL, NULL);
}
@@ -1073,7 +1076,7 @@
LY_LIST_FOR(node->meta, meta) {
if (!strcmp(meta->name, name) && !strcmp(meta->annotation->module->name, "yang")) {
- lyd_free_meta(LYD_NODE_CTX(node), meta, 0);
+ lyd_free_meta_single(meta);
return;
}
}
@@ -1095,15 +1098,12 @@
LY_LIST_FOR(node->meta, meta) {
if (!strcmp(meta->name, "operation") && !strcmp(meta->annotation->module->name, "yang")) {
- lyd_free_meta(LYD_NODE_CTX(node), meta, 0);
+ lyd_free_meta_single(meta);
break;
}
}
- if (!lyd_new_meta(node, NULL, "yang:operation", lyd_diff_op2str(op))) {
- return LY_EINT;
- }
- return LY_SUCCESS;
+ return lyd_new_meta(node, NULL, "yang:operation", lyd_diff_op2str(op), NULL);
}
/**
@@ -1142,9 +1142,7 @@
lyd_diff_del_meta(diff_match, meta_name);
meta = lyd_find_meta(src_diff->meta, mod, meta_name);
LY_CHECK_ERR_RET(!meta, LOGINT(LYD_NODE_CTX(src_diff)), LY_EINT);
- if (!lyd_dup_meta(meta, diff_match)) {
- return LY_EINT;
- }
+ LY_CHECK_RET(lyd_dup_meta_single(meta, diff_match, NULL));
break;
case LYS_LEAF:
/* replaced with the exact same value, impossible */
@@ -1175,7 +1173,7 @@
}
if (!ret) {
/* values are the same, remove orig-value meta and set oper to NONE */
- lyd_free_meta(LYD_NODE_CTX(diff_match), meta, 0);
+ lyd_free_meta_single(meta);
LY_CHECK_RET(lyd_diff_change_op(diff_match, LYD_DIFF_OP_NONE));
}
@@ -1208,15 +1206,11 @@
/* set orig-key and key metadata */
meta = lyd_find_meta(src_diff->meta, mod, "orig-key");
LY_CHECK_ERR_RET(!meta, LOGINT(LYD_NODE_CTX(src_diff)), LY_EINT);
- if (!lyd_dup_meta(meta, diff_match)) {
- return LY_EINT;
- }
+ LY_CHECK_RET(lyd_dup_meta_single(meta, diff_match, NULL));
meta = lyd_find_meta(src_diff->meta, mod, "key");
LY_CHECK_ERR_RET(!meta, LOGINT(LYD_NODE_CTX(src_diff)), LY_EINT);
- if (!lyd_dup_meta(meta, diff_match)) {
- return LY_EINT;
- }
+ LY_CHECK_RET(lyd_dup_meta_single(meta, diff_match, NULL));
break;
default:
/* delete operation is not valid */
@@ -1238,7 +1232,6 @@
lyd_diff_merge_create(struct lyd_node *diff_match, enum lyd_diff_op cur_op, const struct lyd_node *src_diff)
{
struct lyd_node *child;
- struct lyd_meta *meta;
const char *str_val;
int dynamic;
LY_ERR ret;
@@ -1252,9 +1245,8 @@
if (diff_match->schema->nodetype & LYD_NODE_TERM) {
/* add orig-dflt metadata */
- if (!lyd_new_meta(diff_match, NULL, "yang:orig-default", diff_match->flags & LYD_DEFAULT ? "true" : "false")) {
- return LY_EINT;
- }
+ LY_CHECK_RET(lyd_new_meta(diff_match, NULL, "yang:orig-default",
+ diff_match->flags & LYD_DEFAULT ? "true" : "false", NULL));
}
} else {
assert(diff_match->schema->nodetype == LYS_LEAF);
@@ -1263,11 +1255,11 @@
/* current value is the previous one (meta) */
str_val = lyd_value2str((struct lyd_node_term *)diff_match, &dynamic);
- meta = lyd_new_meta(diff_match, NULL, "yang:orig-value", str_val);
+ ret = lyd_new_meta(diff_match, NULL, "yang:orig-value", str_val, NULL);
if (dynamic) {
free((char *)str_val);
}
- LY_CHECK_RET(!meta, LY_EINT);
+ LY_CHECK_RET(ret);
/* update the value itself */
str_val = lyd_value2str((struct lyd_node_term *)src_diff, &dynamic);
@@ -1320,9 +1312,8 @@
if (diff_match->schema->nodetype & LYD_NODE_TERM) {
/* add orig-default meta because it is expected */
- if (!lyd_new_meta(diff_match, NULL, "yang:orig-default", diff_match->flags & LYD_DEFAULT ? "true" : "false")) {
- return LY_EINT;
- }
+ LY_CHECK_RET(lyd_new_meta(diff_match, NULL, "yang:orig-default",
+ diff_match->flags & LYD_DEFAULT ? "true" : "false", NULL));
} else {
/* keep operation for all descendants (for now) */
LY_LIST_FOR(LYD_CHILD(diff_match), child) {
@@ -1384,8 +1375,8 @@
if (!lyd_compare_meta(orig_val_meta, val_meta)) {
/* there is actually no move */
- lyd_free_meta(LYD_NODE_CTX(diff), orig_val_meta, 0);
- lyd_free_meta(LYD_NODE_CTX(diff), val_meta, 0);
+ lyd_free_meta_single(orig_val_meta);
+ lyd_free_meta_single(val_meta);
if (child) {
/* change operation to NONE, we have siblings */
lyd_diff_change_op(diff, LYD_DIFF_OP_NONE);
@@ -1486,8 +1477,7 @@
}
} else {
/* add new diff node with all descendants */
- diff_node = lyd_dup(src_diff, (struct lyd_node_inner *)diff_parent, LYD_DUP_RECURSIVE);
- LY_CHECK_RET(!diff_node, LY_EINT);
+ LY_CHECK_RET(lyd_dup_single(src_diff, (struct lyd_node_inner *)diff_parent, LYD_DUP_RECURSIVE, &diff_node));
/* insert node into diff if not already */
if (!diff_parent) {
@@ -1541,7 +1531,7 @@
}
API LY_ERR
-lyd_diff_merge(const struct lyd_node *src_diff, struct lyd_node **diff)
+lyd_diff_merge_all(const struct lyd_node *src_diff, struct lyd_node **diff)
{
return lyd_diff_merge_module(src_diff, NULL, NULL, NULL, diff);
}
@@ -1662,8 +1652,7 @@
}
/* duplicate diff */
- *diff = lyd_dup(src_diff, NULL, LYD_DUP_WITH_SIBLINGS | LYD_DUP_RECURSIVE);
- LY_CHECK_RET(!*diff, LY_EMEM);
+ LY_CHECK_RET(lyd_dup_siblings(src_diff, NULL, LYD_DUP_RECURSIVE, diff));
/* find module with metadata needed for later */
mod = ly_ctx_get_module_latest(LYD_NODE_CTX(src_diff), "yang");
diff --git a/src/parser_data.h b/src/parser_data.h
index 7bf68b2..a8ec4d5 100644
--- a/src/parser_data.h
+++ b/src/parser_data.h
@@ -131,7 +131,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
-LY_ERR lyd_parse_data(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree);
+LY_ERR lyd_parse_data(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, int parse_options,
+ int validate_options, struct lyd_node **tree);
/**
* @brief Parse (and validate) input data as a YANG data tree.
@@ -148,7 +149,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
-LY_ERR lyd_parse_data_mem(const struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree);
+LY_ERR lyd_parse_data_mem(const struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int parse_options,
+ int validate_options, struct lyd_node **tree);
/**
* @brief Parse (and validate) input data as a YANG data tree.
@@ -165,7 +167,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
-LY_ERR lyd_parse_data_fd(const struct ly_ctx *ctx, int fd, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree);
+LY_ERR lyd_parse_data_fd(const struct ly_ctx *ctx, int fd, LYD_FORMAT format, int parse_options, int validate_options,
+ struct lyd_node **tree);
/**
* @brief Parse (and validate) input data as a YANG data tree.
@@ -182,7 +185,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
-LY_ERR lyd_parse_data_path(const struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree);
+LY_ERR lyd_parse_data_path(const struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int parse_options,
+ int validate_options, struct lyd_node **tree);
/**
* @brief Parse (and validate) data from the input handler as a YANG RPC/action invocation.
@@ -201,7 +205,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
-LY_ERR lyd_parse_rpc(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree, struct lyd_node **op);
+LY_ERR lyd_parse_rpc(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree,
+ struct lyd_node **op);
/**
* @brief Parse (and validate) data from the input handler as a YANG RPC/action reply.
@@ -221,7 +226,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the request's context using ly_err* functions.
*/
-LY_ERR lyd_parse_reply(const struct lyd_node *request, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree, struct lyd_node **op);
+LY_ERR lyd_parse_reply(const struct lyd_node *request, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree,
+ struct lyd_node **op);
/**
* @brief Parse XML string as YANG notification.
@@ -238,7 +244,8 @@
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
-LY_ERR lyd_parse_notif(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree, struct lyd_node **ntf);
+LY_ERR lyd_parse_notif(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree,
+ struct lyd_node **ntf);
/**
* @brief Fully validate a data tree.
@@ -250,7 +257,7 @@
* @return LY_SUCCESS on success.
* @return LY_ERR error on error.
*/
-LY_ERR lyd_validate(struct lyd_node **tree, const struct ly_ctx *ctx, int val_opts, struct lyd_node **diff);
+LY_ERR lyd_validate_all(struct lyd_node **tree, const struct ly_ctx *ctx, int val_opts, struct lyd_node **diff);
/**
* @brief Fully validate a data tree of a module.
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 1965afb..95ff05a 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -379,7 +379,7 @@
cleanup:
free(meta_name);
if (ret) {
- lyd_free_meta(lybctx->ctx, *meta, 1);
+ lyd_free_meta_siblings(*meta);
*meta = NULL;
}
return ret;
@@ -518,7 +518,7 @@
}
ly_free_val_prefs(lybctx->ctx, val_prefs);
if (ret) {
- ly_free_attr(lybctx->ctx, *attr, 1);
+ ly_free_attr_siblings(lybctx->ctx, *attr);
*attr = NULL;
}
return ret;
@@ -910,8 +910,8 @@
}
ly_free_val_prefs(lybctx->ctx, val_prefs);
- lyd_free_meta(lybctx->ctx, meta, 1);
- ly_free_attr(lybctx->ctx, attr, 1);
+ lyd_free_meta_siblings(meta);
+ ly_free_attr_siblings(lybctx->ctx, attr);
lyd_free_tree(node);
return ret;
}
@@ -1208,8 +1208,8 @@
}
/* duplicate request OP with parents */
- rep_op = lyd_dup(req_op, NULL, LYD_DUP_WITH_PARENTS);
- LY_CHECK_ERR_GOTO(!rep_op, ret = LY_EMEM, cleanup);
+ ret = lyd_dup_single(req_op, NULL, LYD_DUP_WITH_PARENTS, &rep_op);
+ LY_CHECK_GOTO(ret, cleanup);
/* read magic number */
ret = lyb_parse_magic_number(&lybctx);
diff --git a/src/parser_schema.h b/src/parser_schema.h
index 82bdd9b..9e3985a 100644
--- a/src/parser_schema.h
+++ b/src/parser_schema.h
@@ -20,6 +20,7 @@
#endif
struct ly_in;
+struct lys_module;
/**
* @addtogroup schematree
@@ -41,9 +42,10 @@
* @param[in] ctx libyang context where to process the data model.
* @param[in] in The input handle to provide the dumped data model in the specified format.
* @param[in] format Format of the schema to parse.
- * @return Pointer to the data model structure or NULL on error.
+ * @param[out] module Optional parsed module.
+ * @return LY_ERR value.
*/
-struct lys_module *lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format);
+LY_ERR lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const struct lys_module **module);
/**
* @brief Load a schema into the specified context.
@@ -52,12 +54,12 @@
* consider use of lys_parse() with a standalone input handler.
*
* @param[in] ctx libyang context where to process the data model.
- * @param[in] data The string containing the dumped data model in the specified
- * format.
+ * @param[in] data The string containing the dumped data model in the specified format.
* @param[in] format Format of the input data (YANG or YIN).
- * @return Pointer to the data model structure or NULL on error.
+ * @param[out] module Optional parsed module.
+ * @return LY_ERR value.
*/
-struct lys_module *lys_parse_mem(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format);
+LY_ERR lys_parse_mem(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, const struct lys_module **module);
/**
* @brief Read a schema from file descriptor into the specified context.
@@ -71,9 +73,10 @@
* @param[in] fd File descriptor of a regular file (e.g. sockets are not supported) containing the schema
* in the specified format.
* @param[in] format Format of the input data (YANG or YIN).
- * @return Pointer to the data model structure or NULL on error.
+ * @param[out] module Optional parsed module.
+ * @return LY_ERR value.
*/
-struct lys_module *lys_parse_fd(struct ly_ctx *ctx, int fd, LYS_INFORMAT format);
+LY_ERR lys_parse_fd(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, const struct lys_module **module);
/**
* @brief Load a schema into the specified context from a file.
@@ -84,9 +87,10 @@
* @param[in] ctx libyang context where to process the data model.
* @param[in] path Path to the file with the model in the specified format.
* @param[in] format Format of the input data (YANG or YIN).
- * @return Pointer to the data model structure or NULL on error.
+ * @param[out] module Optional parsed module.
+ * @return LY_ERR value.
*/
-struct lys_module *lys_parse_path(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format);
+LY_ERR lys_parse_path(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format, const struct lys_module **module);
/**
* @brief Search for the schema file in the specified searchpaths.
@@ -103,7 +107,8 @@
* file suffix.
* @return LY_ERR value (LY_SUCCESS is returned even if the file is not found, then the *localfile is NULL).
*/
-LY_ERR lys_search_localfile(const char * const *searchpaths, int cwd, const char *name, const char *revision, char **localfile, LYS_INFORMAT *format);
+LY_ERR lys_search_localfile(const char * const *searchpaths, int cwd, const char *name, const char *revision,
+ char **localfile, LYS_INFORMAT *format);
/** @} schematree */
diff --git a/src/parser_xml.c b/src/parser_xml.c
index c382a78..eb73a8f 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -139,7 +139,7 @@
cleanup:
if (ret) {
- lyd_free_meta(xmlctx->ctx, *meta, 1);
+ lyd_free_meta_siblings(*meta);
*meta = NULL;
}
return ret;
@@ -203,7 +203,7 @@
cleanup:
if (ret) {
- ly_free_attr(xmlctx->ctx, *attr, 1);
+ ly_free_attr_siblings(xmlctx->ctx, *attr);
*attr = NULL;
}
return ret;
@@ -662,8 +662,8 @@
ret = LY_SUCCESS;
cleanup:
- lyd_free_meta(ctx, meta, 1);
- ly_free_attr(ctx, attr, 1);
+ lyd_free_meta_siblings(meta);
+ ly_free_attr_siblings(ctx, attr);
lyd_free_tree(cur);
if (ret && *first) {
lyd_free_siblings(*first);
@@ -799,7 +799,7 @@
attr = NULL;
cleanup:
- ly_free_attr(xmlctx->ctx, attr, 1);
+ ly_free_attr_siblings(xmlctx->ctx, attr);
return ret;
}
@@ -982,7 +982,7 @@
cleanup:
if (ret) {
lyd_free_tree(*envp);
- ly_free_attr(xmlctx->ctx, attr, 1);
+ ly_free_attr_siblings(xmlctx->ctx, attr);
}
return ret;
}
@@ -1080,11 +1080,11 @@
}
/* duplicate request OP with parents */
- rep_op = lyd_dup(req_op, NULL, LYD_DUP_WITH_PARENTS);
- LY_CHECK_ERR_GOTO(!rep_op, ret = LY_EMEM, cleanup);
+ LY_CHECK_GOTO(ret = lyd_dup_single(req_op, NULL, LYD_DUP_WITH_PARENTS, &rep_op), cleanup);
/* parse "rpc-reply", if any */
- LY_CHECK_GOTO(ret = lydxml_envelope(lydctx.xmlctx, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0", &rpcr_e), cleanup);
+ LY_CHECK_GOTO(ret = lydxml_envelope(lydctx.xmlctx, "rpc-reply", "urn:ietf:params:xml:ns:netconf:base:1.0", &rpcr_e),
+ cleanup);
/* parse the rest of data normally but connect them to the duplicated operation */
LY_CHECK_GOTO(ret = lydxml_data_r(&lydctx, (struct lyd_node_inner *)rep_op, lyd_node_children_p(rep_op)), cleanup);
diff --git a/src/path.c b/src/path.c
index f4829e3..eb72c2f 100644
--- a/src/path.c
+++ b/src/path.c
@@ -424,7 +424,7 @@
key = lys_find_child(ctx_node, mod, name, name_len, 0, LYS_GETNEXT_NOSTATECHECK);
if (!key) {
LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
- return LY_EVALID;
+ return LY_ENOTFOUND;
} else if ((key->nodetype != LYS_LEAF) || !(key->flags & LYS_KEY)) {
LOGVAL(ctx, LY_VLOG_LYSC, key, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
lys_nodetype2str(key->nodetype), key->name);
diff --git a/src/printer_data.c b/src/printer_data.c
index bbb2eda..3d78d3b 100644
--- a/src/printer_data.c
+++ b/src/printer_data.c
@@ -23,15 +23,10 @@
#include "printer_internal.h"
#include "tree_data.h"
-API LY_ERR
-lyd_print(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options)
+static LY_ERR
+lyd_print_(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options)
{
- LY_ERR ret = LY_EINVAL;
-
- LY_CHECK_ARG_RET(NULL, out, root, LY_EINVAL);
-
- /* reset number of printed bytes */
- out->func_printed = 0;
+ LY_ERR ret = LY_SUCCESS;
switch (format) {
case LYD_XML:
@@ -54,22 +49,46 @@
return ret;
}
-static LY_ERR
-lyd_print_(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options)
+API LY_ERR
+lyd_print_all(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options)
{
- LY_ERR ret;
+ LY_CHECK_ARG_RET(NULL, out, root, !(options & LYD_PRINT_WITHSIBLINGS), LY_EINVAL);
- LY_CHECK_ARG_RET(NULL, out, LY_EINVAL);
+ /* reset the number of printed bytes */
+ out->func_printed = 0;
- ret = lyd_print(out, root, format, options);
+ /* get first top-level sibling */
+ while (root->parent) {
+ root = (struct lyd_node *)root->parent;
+ }
+ while (root->prev->next) {
+ root = root->prev;
+ }
- ly_out_free(out, NULL, 0);
- return ret;
+ /* print each top-level sibling */
+ LY_CHECK_RET(lyd_print_(out, root, format, options | LYD_PRINT_WITHSIBLINGS));
+
+ return LY_SUCCESS;
+}
+
+API LY_ERR
+lyd_print_tree(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+ LY_CHECK_ARG_RET(NULL, out, root, !(options & LYD_PRINT_WITHSIBLINGS), LY_EINVAL);
+
+ /* reset the number of printed bytes */
+ out->func_printed = 0;
+
+ /* print the subtree */
+ LY_CHECK_RET(lyd_print_(out, root, format, options));
+
+ return LY_SUCCESS;
}
API LY_ERR
lyd_print_mem(char **strp, const struct lyd_node *root, LYD_FORMAT format, int options)
{
+ LY_ERR ret;
struct ly_out *out;
LY_CHECK_ARG_RET(NULL, strp, root, LY_EINVAL);
@@ -78,50 +97,64 @@
*strp = NULL;
LY_CHECK_RET(ly_out_new_memory(strp, 0, &out));
- return lyd_print_(out, root, format, options);
+ ret = lyd_print_(out, root, format, options);
+ ly_out_free(out, NULL, 0);
+ return ret;
}
API LY_ERR
lyd_print_fd(int fd, const struct lyd_node *root, LYD_FORMAT format, int options)
{
+ LY_ERR ret;
struct ly_out *out;
LY_CHECK_ARG_RET(NULL, fd != -1, root, LY_EINVAL);
LY_CHECK_RET(ly_out_new_fd(fd, &out));
- return lyd_print_(out, root, format, options);
+ ret = lyd_print_(out, root, format, options);
+ ly_out_free(out, NULL, 0);
+ return ret;
}
API LY_ERR
lyd_print_file(FILE *f, const struct lyd_node *root, LYD_FORMAT format, int options)
{
+ LY_ERR ret;
struct ly_out *out;
LY_CHECK_ARG_RET(NULL, f, root, LY_EINVAL);
LY_CHECK_RET(ly_out_new_file(f, &out));
- return lyd_print_(out, root, format, options);
+ ret = lyd_print_(out, root, format, options);
+ ly_out_free(out, NULL, 0);
+ return ret;
}
API LY_ERR
lyd_print_path(const char *path, const struct lyd_node *root, LYD_FORMAT format, int options)
{
+ LY_ERR ret;
struct ly_out *out;
LY_CHECK_ARG_RET(NULL, path, root, LY_EINVAL);
LY_CHECK_RET(ly_out_new_filepath(path, &out));
- return lyd_print_(out, root, format, options);
+ ret = lyd_print_(out, root, format, options);
+ ly_out_free(out, NULL, 0);
+ return ret;
}
API LY_ERR
lyd_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg,
const struct lyd_node *root, LYD_FORMAT format, int options)
{
+ LY_ERR ret;
struct ly_out *out;
LY_CHECK_ARG_RET(NULL, writeclb, root, LY_EINVAL);
LY_CHECK_RET(ly_out_new_clb(writeclb, arg, &out));
- return lyd_print_(out, root, format, options);
+ ret = lyd_print_(out, root, format, options);
+ ly_out_free(out, NULL, 0);
+ return ret;
}
diff --git a/src/printer_data.h b/src/printer_data.h
index afe0418..09fe8f5 100644
--- a/src/printer_data.h
+++ b/src/printer_data.h
@@ -57,15 +57,26 @@
*/
/**
- * @brief Common YANG data printer.
+ * @brief Print the whole data tree of the root, including all the siblings.
*
* @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.
- * @param[in] root The root element of the (sub)tree to print.
+ * @param[in] root The root element of the tree to print, can be any sibling.
* @param[in] format Output format.
- * @param[in] options [Data printer flags](@ref dataprinterflags).
+ * @param[in] options [Data printer flags](@ref dataprinterflags) except ::LYD_PRINT_WITHSIBLINGS.
* @return LY_ERR value.
*/
-LY_ERR lyd_print(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options);
+LY_ERR lyd_print_all(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options);
+
+/**
+ * @brief Print the selected data subtree.
+ *
+ * @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.
+ * @param[in] root The root element of the subtree to print.
+ * @param[in] format Output format.
+ * @param[in] options [Data printer flags](@ref dataprinterflags) except ::LYD_PRINT_WITHSIBLINGS.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_print_tree(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options);
/**
* @brief Print data tree in the specified format.
diff --git a/src/tree_data.c b/src/tree_data.c
index 3b7e1a3..7780c97 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -657,30 +657,36 @@
return LY_SUCCESS;
}
-API struct lyd_node *
-lyd_new_inner(struct lyd_node *parent, const struct lys_module *module, const char *name)
+API LY_ERR
+lyd_new_inner(struct lyd_node *parent, const struct lys_module *module, const char *name, struct lyd_node **node)
{
struct lyd_node *ret = NULL;
const struct lysc_node *schema;
struct ly_ctx *ctx = parent ? parent->schema->module->ctx : (module ? module->ctx : NULL);
- LY_CHECK_ARG_RET(ctx, parent || module, name, NULL);
+ LY_CHECK_ARG_RET(ctx, parent || module, name, LY_EINVAL);
if (!module) {
module = parent->schema->module;
}
- schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0, LYS_CONTAINER | LYS_NOTIF | LYS_RPC | LYS_ACTION, 0);
- LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Inner node (and not a list) \"%s\" not found.", name), NULL);
+ schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0,
+ LYS_CONTAINER | LYS_NOTIF | LYS_RPC | LYS_ACTION, 0);
+ LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Inner node (and not a list) \"%s\" not found.", name), LY_ENOTFOUND);
- if (!lyd_create_inner(schema, &ret) && parent) {
+ LY_CHECK_RET(lyd_create_inner(schema, &ret));
+ if (parent) {
lyd_insert_node(parent, NULL, ret);
}
- return ret;
+
+ if (node) {
+ *node = ret;
+ }
+ return LY_SUCCESS;
}
-API struct lyd_node *
-lyd_new_list(struct lyd_node *parent, const struct lys_module *module, const char *name, ...)
+API LY_ERR
+lyd_new_list(struct lyd_node *parent, const struct lys_module *module, const char *name, struct lyd_node **node, ...)
{
struct lyd_node *ret = NULL, *key;
const struct lysc_node *schema, *key_s;
@@ -689,19 +695,19 @@
const char *key_val;
LY_ERR rc = LY_SUCCESS;
- LY_CHECK_ARG_RET(ctx, parent || module, name, NULL);
+ LY_CHECK_ARG_RET(ctx, parent || module, name, LY_EINVAL);
if (!module) {
module = parent->schema->module;
}
schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0, LYS_LIST, 0);
- LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "List node \"%s\" not found.", name), NULL);
+ LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "List node \"%s\" not found.", name), LY_ENOTFOUND);
/* create list inner node */
- LY_CHECK_RET(lyd_create_inner(schema, &ret), NULL);
+ LY_CHECK_RET(lyd_create_inner(schema, &ret));
- va_start(ap, name);
+ va_start(ap, node);
/* create and insert all the keys */
for (key_s = lysc_node_children(schema, 0); key_s && (key_s->flags & LYS_KEY); key_s = key_s->next) {
@@ -713,30 +719,30 @@
lyd_insert_node(ret, NULL, key);
}
- /* hash having all the keys */
- lyd_hash(ret);
-
if (parent) {
lyd_insert_node(parent, NULL, ret);
}
cleanup:
+ va_end(ap);
if (rc) {
lyd_free_tree(ret);
ret = NULL;
+ } else if (node) {
+ *node = ret;
}
- va_end(ap);
- return ret;
+ return rc;
}
-API struct lyd_node *
-lyd_new_list2(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *keys)
+API LY_ERR
+lyd_new_list2(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *keys,
+ struct lyd_node **node)
{
struct lyd_node *ret = NULL;
const struct lysc_node *schema;
struct ly_ctx *ctx = parent ? parent->schema->module->ctx : (module ? module->ctx : NULL);
- LY_CHECK_ARG_RET(ctx, parent || module, name, NULL);
+ LY_CHECK_ARG_RET(ctx, parent || module, name, LY_EINVAL);
if (!module) {
module = parent->schema->module;
@@ -747,69 +753,81 @@
/* find schema node */
schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0, LYS_LIST, 0);
- LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "List node \"%s\" not found.", name), NULL);
+ LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "List node \"%s\" not found.", name), LY_ENOTFOUND);
if ((schema->flags & LYS_KEYLESS) && !keys[0]) {
/* key-less list */
- LY_CHECK_RET(lyd_create_inner(schema, &ret), NULL);
+ LY_CHECK_RET(lyd_create_inner(schema, &ret));
} else {
/* create the list node */
- LY_CHECK_RET(lyd_create_list2(schema, keys, strlen(keys), &ret), NULL);
+ LY_CHECK_RET(lyd_create_list2(schema, keys, strlen(keys), &ret));
}
-
if (parent) {
lyd_insert_node(parent, NULL, ret);
}
- return ret;
+
+ if (node) {
+ *node = ret;
+ }
+ return LY_SUCCESS;
}
-API struct lyd_node *
-lyd_new_term(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str)
+API LY_ERR
+lyd_new_term(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str,
+ struct lyd_node **node)
{
LY_ERR rc;
struct lyd_node *ret = NULL;
const struct lysc_node *schema;
struct ly_ctx *ctx = parent ? parent->schema->module->ctx : (module ? module->ctx : NULL);
- LY_CHECK_ARG_RET(ctx, parent || module, name, NULL);
+ LY_CHECK_ARG_RET(ctx, parent || module, name, LY_EINVAL);
if (!module) {
module = parent->schema->module;
}
schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0, LYD_NODE_TERM, 0);
- LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Term node \"%s\" not found.", name), NULL);
+ LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Term node \"%s\" not found.", name), LY_ENOTFOUND);
rc = lyd_create_term(schema, val_str, val_str ? strlen(val_str) : 0, NULL, lydjson_resolve_prefix, NULL, LYD_JSON, &ret);
- LY_CHECK_RET(rc && (rc != LY_EINCOMPLETE), NULL);
-
+ LY_CHECK_RET(rc && (rc != LY_EINCOMPLETE), rc);
if (parent) {
lyd_insert_node(parent, NULL, ret);
}
- return ret;
+
+ if (node) {
+ *node = ret;
+ }
+ return LY_SUCCESS;
}
-API struct lyd_node *
+API LY_ERR
lyd_new_any(struct lyd_node *parent, const struct lys_module *module, const char *name, const void *value,
- LYD_ANYDATA_VALUETYPE value_type)
+ LYD_ANYDATA_VALUETYPE value_type, struct lyd_node **node)
{
struct lyd_node *ret = NULL;
const struct lysc_node *schema;
struct ly_ctx *ctx = parent ? parent->schema->module->ctx : (module ? module->ctx : NULL);
- LY_CHECK_ARG_RET(ctx, parent || module, name, NULL);
+ LY_CHECK_ARG_RET(ctx, parent || module, name, LY_EINVAL);
if (!module) {
module = parent->schema->module;
}
schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0, LYD_NODE_ANY, 0);
- LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Any node \"%s\" not found.", name), NULL);
+ LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Any node \"%s\" not found.", name), LY_ENOTFOUND);
- if (!lyd_create_any(schema, value, value_type, &ret) && parent) {
+ LY_CHECK_RET(lyd_create_any(schema, value, value_type, &ret));
+ if (parent) {
lyd_insert_node(parent, NULL, ret);
}
- return ret;
+
+ if (node) {
+ *node = ret;
+ }
+ return LY_SUCCESS;
}
/**
@@ -885,8 +903,9 @@
return ret;
}
-API struct lyd_meta *
-lyd_new_meta(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str)
+API LY_ERR
+lyd_new_meta(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str,
+ struct lyd_meta **meta)
{
struct lyd_meta *ret = NULL;
const struct ly_ctx *ctx;
@@ -894,7 +913,7 @@
char *str;
size_t pref_len, name_len;
- LY_CHECK_ARG_RET(NULL, parent, name, module || strchr(name, ':'), NULL);
+ LY_CHECK_ARG_RET(NULL, parent, name, module || strchr(name, ':'), LY_EINVAL);
ctx = LYD_NODE_CTX(parent);
@@ -902,7 +921,7 @@
tmp = name;
if (ly_parse_nodeid(&tmp, &prefix, &pref_len, &name, &name_len) || tmp[0]) {
LOGERR(ctx, LY_EINVAL, "Metadata name \"%s\" is not valid.", name);
- return NULL;
+ return LY_EVALID;
}
/* find the module */
@@ -910,7 +929,7 @@
str = strndup(prefix, pref_len);
module = ly_ctx_get_module_implemented(ctx, str);
free(str);
- LY_CHECK_ERR_RET(!module, LOGERR(ctx, LY_EINVAL, "Module \"%.*s\" not found.", pref_len, prefix), NULL);
+ LY_CHECK_ERR_RET(!module, LOGERR(ctx, LY_EINVAL, "Module \"%.*s\" not found.", pref_len, prefix), LY_ENOTFOUND);
}
/* set value if none */
@@ -918,18 +937,22 @@
val_str = "";
}
- lyd_create_meta(parent, &ret, module, name, name_len, val_str, strlen(val_str), NULL, lydjson_resolve_prefix, NULL,
- LYD_JSON, parent->schema);
- return ret;
+ LY_CHECK_RET(lyd_create_meta(parent, &ret, module, name, name_len, val_str, strlen(val_str), NULL,
+ lydjson_resolve_prefix, NULL, LYD_JSON, parent->schema));
+
+ if (meta) {
+ *meta = ret;
+ }
+ return LY_SUCCESS;
}
-API struct lyd_node *
+API LY_ERR
lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
- const char *module_name)
+ const char *module_name, struct lyd_node **node)
{
struct lyd_node *ret = NULL;
- LY_CHECK_ARG_RET(ctx, parent || ctx, name, module_name, NULL);
+ LY_CHECK_ARG_RET(ctx, parent || ctx, name, module_name, LY_EINVAL);
if (!ctx) {
ctx = LYD_NODE_CTX(parent);
@@ -938,22 +961,28 @@
value = "";
}
- if (!lyd_create_opaq(ctx, name, strlen(name), value, strlen(value), NULL, LYD_JSON, NULL, NULL, 0, module_name, &ret)
- && parent) {
+ LY_CHECK_RET(lyd_create_opaq(ctx, name, strlen(name), value, strlen(value), NULL, LYD_JSON, NULL, NULL, 0,
+ module_name, &ret));
+ if (parent) {
lyd_insert_node(parent, NULL, ret);
}
- return ret;
+
+ if (node) {
+ *node = ret;
+ }
+ return LY_SUCCESS;
}
-API struct ly_attr *
-lyd_new_attr(struct lyd_node *parent, const char *module_name, const char *name, const char *val_str)
+API LY_ERR
+lyd_new_attr(struct lyd_node *parent, const char *module_name, const char *name, const char *val_str,
+ struct ly_attr **attr)
{
struct ly_attr *ret = NULL;
const struct ly_ctx *ctx;
const char *prefix, *tmp;
size_t pref_len, name_len;
- LY_CHECK_ARG_RET(NULL, parent, !parent->schema, name, NULL);
+ LY_CHECK_ARG_RET(NULL, parent, !parent->schema, name, LY_EINVAL);
ctx = LYD_NODE_CTX(parent);
@@ -961,7 +990,7 @@
tmp = name;
if (ly_parse_nodeid(&tmp, &prefix, &pref_len, &name, &name_len) || tmp[0]) {
LOGERR(ctx, LY_EINVAL, "Metadata name \"%s\" is not valid.", name);
- return NULL;
+ return LY_EVALID;
}
/* set value if none */
@@ -969,9 +998,13 @@
val_str = "";
}
- ly_create_attr(parent, &ret, ctx, name, name_len, val_str, strlen(val_str), NULL, LYD_JSON, NULL, prefix,
- pref_len, module_name);
- return ret;
+ LY_CHECK_RET(ly_create_attr(parent, &ret, ctx, name, name_len, val_str, strlen(val_str), NULL, LYD_JSON, NULL,
+ prefix, pref_len, module_name));
+
+ if (attr) {
+ *attr = ret;
+ }
+ return LY_SUCCESS;
}
API LY_ERR
@@ -1092,23 +1125,11 @@
return ret;
}
-API struct lyd_node *
-lyd_new_path(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const char *value, int options)
+API LY_ERR
+lyd_new_path(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const char *value, int options,
+ struct lyd_node **node)
{
- struct lyd_node *new_parent = NULL;
-
- lyd_new_path2(parent, ctx, path, value, 0, options, &new_parent, NULL);
- return new_parent;
-}
-
-API struct lyd_node *
-lyd_new_path_any(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const void *value,
- LYD_ANYDATA_VALUETYPE value_type, int options)
-{
- struct lyd_node *new_parent = NULL;
-
- lyd_new_path2(parent, ctx, path, value, value_type, options, &new_parent, NULL);
- return new_parent;
+ return lyd_new_path2(parent, ctx, path, value, 0, options, node, NULL);
}
API LY_ERR
@@ -2106,8 +2127,8 @@
* @return LY_ERR value
*/
static LY_ERR
-lyd_dup_recursive(const struct lyd_node *node, struct lyd_node *parent, struct lyd_node **first, int options,
- struct lyd_node **dup_p)
+lyd_dup_r(const struct lyd_node *node, struct lyd_node *parent, struct lyd_node **first, int options,
+ struct lyd_node **dup_p)
{
LY_ERR ret;
struct lyd_node *dup = NULL;
@@ -2155,10 +2176,7 @@
/* duplicate metadata */
if (!(options & LYD_DUP_NO_META)) {
LY_LIST_FOR(node->meta, meta) {
- if (!lyd_dup_meta(meta, dup)) {
- ret = LY_EINT;
- goto error;
- }
+ LY_CHECK_GOTO(ret = lyd_dup_meta_single(meta, dup, NULL), error);
}
}
@@ -2171,7 +2189,7 @@
if (options & LYD_DUP_RECURSIVE) {
/* duplicate all the children */
LY_LIST_FOR(orig->child, child) {
- LY_CHECK_GOTO(ret = lyd_dup_recursive(child, dup, NULL, options, NULL), error);
+ LY_CHECK_GOTO(ret = lyd_dup_r(child, dup, NULL, options, NULL), error);
}
}
opaq->name = lydict_insert(LYD_NODE_CTX(node), orig->name, 0);
@@ -2207,7 +2225,7 @@
if (options & LYD_DUP_RECURSIVE) {
/* duplicate all the children */
LY_LIST_FOR(orig->child, child) {
- LY_CHECK_GOTO(ret = lyd_dup_recursive(child, dup, NULL, options, NULL), error);
+ LY_CHECK_GOTO(ret = lyd_dup_r(child, dup, NULL, options, NULL), error);
}
} else if (dup->schema->nodetype == LYS_LIST && !(dup->schema->flags & LYS_KEYLESS)) {
/* always duplicate keys of a list */
@@ -2223,7 +2241,7 @@
* but there can be also some non-key nodes */
continue;
}
- LY_CHECK_GOTO(ret = lyd_dup_recursive(child, dup, NULL, options, NULL), error);
+ LY_CHECK_GOTO(ret = lyd_dup_r(child, dup, NULL, options, NULL), error);
child = child->next;
}
}
@@ -2247,86 +2265,92 @@
return ret;
}
-API struct lyd_node *
-lyd_dup(const struct lyd_node *node, struct lyd_node_inner *parent, int options)
+static LY_ERR
+lyd_dup_get_local_parent(const struct lyd_node *node, const struct lyd_node_inner *parent, struct lyd_node **dup_parent,
+ struct lyd_node_inner **local_parent)
{
+ const struct lyd_node_inner *orig_parent, *iter;
+ int repeat = 1;
+
+ *dup_parent = NULL;
+ *local_parent = NULL;
+
+ for (orig_parent = node->parent; repeat && orig_parent; orig_parent = orig_parent->parent) {
+ if (parent && (parent->schema == orig_parent->schema)) {
+ /* stop creating parents, connect what we have into the provided parent */
+ iter = parent;
+ repeat = 0;
+ } else {
+ iter = NULL;
+ LY_CHECK_RET(lyd_dup_r((struct lyd_node *)orig_parent, NULL, (struct lyd_node **)&iter, 0,
+ (struct lyd_node **)&iter));
+ }
+ if (!*local_parent) {
+ *local_parent = (struct lyd_node_inner *)iter;
+ }
+ if (iter->child) {
+ /* 1) list - add after keys
+ * 2) provided parent with some children */
+ iter->child->prev->next = *dup_parent;
+ if (*dup_parent) {
+ (*dup_parent)->prev = iter->child->prev;
+ iter->child->prev = *dup_parent;
+ }
+ } else {
+ ((struct lyd_node_inner *)iter)->child = *dup_parent;
+ }
+ if (*dup_parent) {
+ (*dup_parent)->parent = (struct lyd_node_inner *)iter;
+ }
+ *dup_parent = (struct lyd_node *)iter;
+ }
+
+ if (repeat && parent) {
+ /* given parent and created parents chain actually do not interconnect */
+ LOGERR(LYD_NODE_CTX(node), LY_EINVAL,
+ "Invalid argument parent (%s()) - does not interconnect with the created node's parents chain.", __func__);
+ return LY_EINVAL;
+ }
+
+ return LY_SUCCESS;
+}
+
+static LY_ERR
+lyd_dup(const struct lyd_node *node, struct lyd_node_inner *parent, int options, int nosiblings, struct lyd_node **dup)
+{
+ LY_ERR rc;
const struct lyd_node *orig; /* original node to be duplicated */
struct lyd_node *first = NULL; /* the first duplicated node, this is returned */
struct lyd_node *top = NULL; /* the most higher created node */
struct lyd_node_inner *local_parent = NULL; /* the direct parent node for the duplicated node(s) */
- int keyless_parent_list = 0;
- LY_CHECK_ARG_RET(NULL, node, NULL);
+ LY_CHECK_ARG_RET(NULL, node, LY_EINVAL);
if (options & LYD_DUP_WITH_PARENTS) {
- struct lyd_node_inner *orig_parent, *iter;
- int repeat = 1;
- for (top = NULL, orig_parent = node->parent; repeat && orig_parent; orig_parent = orig_parent->parent) {
- if (parent && parent->schema == orig_parent->schema) {
- /* stop creating parents, connect what we have into the provided parent */
- iter = parent;
- repeat = 0;
- /* get know if there is a keyless list which we will have to rehash */
- for (struct lyd_node_inner *piter = parent; piter; piter = piter->parent) {
- if (piter->schema->nodetype == LYS_LIST && (piter->schema->flags & LYS_KEYLESS)) {
- keyless_parent_list = 1;
- break;
- }
- }
- } else {
- iter = NULL;
- LY_CHECK_GOTO(lyd_dup_recursive((struct lyd_node *)orig_parent, NULL, (struct lyd_node **)&iter, 0,
- (struct lyd_node **)&iter), error);
- }
- if (!local_parent) {
- local_parent = iter;
- }
- if (iter->child) {
- /* 1) list - add after keys
- * 2) provided parent with some children */
- iter->child->prev->next = top;
- if (top) {
- top->prev = iter->child->prev;
- iter->child->prev = top;
- }
- } else {
- iter->child = top;
- if (iter->schema->nodetype == LYS_LIST) {
- /* keyless list - we will need to rehash it since we are going to add nodes into it */
- keyless_parent_list = 1;
- }
- }
- if (top) {
- top->parent = iter;
- }
- top = (struct lyd_node*)iter;
- }
- if (repeat && parent) {
- /* given parent and created parents chain actually do not interconnect */
- LOGERR(LYD_NODE_CTX(node), LY_EINVAL,
- "Invalid argument parent (%s()) - does not interconnect with the created node's parents chain.", __func__);
- goto error;
- }
+ LY_CHECK_GOTO(rc = lyd_dup_get_local_parent(node, parent, &top, &local_parent), error);
} else {
local_parent = parent;
}
LY_LIST_FOR(node, orig) {
/* if there is no local parent, it will be inserted into first */
- LY_CHECK_GOTO(lyd_dup_recursive(orig, (struct lyd_node *)local_parent, &first, options, first ? NULL : &first), error);
- if (!(options & LYD_DUP_WITH_SIBLINGS)) {
+ LY_CHECK_GOTO(rc = lyd_dup_r(orig, (struct lyd_node *)local_parent, &first, options, first ? NULL : &first), error);
+ if (nosiblings) {
break;
}
}
- if (keyless_parent_list) {
- /* rehash */
- for (; local_parent; local_parent = local_parent->parent) {
- if (local_parent->schema->nodetype == LYS_LIST && (local_parent->schema->flags & LYS_KEYLESS)) {
- lyd_hash((struct lyd_node*)local_parent);
- }
+
+ /* rehash if needed */
+ for (; local_parent; local_parent = local_parent->parent) {
+ if (local_parent->schema->nodetype == LYS_LIST && (local_parent->schema->flags & LYS_KEYLESS)) {
+ lyd_hash((struct lyd_node *)local_parent);
}
}
- return first;
+
+ if (dup) {
+ *dup = first;
+ }
+ return LY_SUCCESS;
error:
if (top) {
@@ -2334,25 +2358,37 @@
} else {
lyd_free_siblings(first);
}
- return NULL;
+ return rc;
}
-API struct lyd_meta *
-lyd_dup_meta(const struct lyd_meta *meta, struct lyd_node *node)
+API LY_ERR
+lyd_dup_single(const struct lyd_node *node, struct lyd_node_inner *parent, int options, struct lyd_node **dup)
+{
+ return lyd_dup(node, parent, options, 1, dup);
+}
+
+API LY_ERR
+lyd_dup_siblings(const struct lyd_node *node, struct lyd_node_inner *parent, int options, struct lyd_node **dup)
+{
+ return lyd_dup(node, parent, options, 0, dup);
+}
+
+API LY_ERR
+lyd_dup_meta_single(const struct lyd_meta *meta, struct lyd_node *node, struct lyd_meta **dup)
{
LY_ERR ret;
struct lyd_meta *mt, *last;
- LY_CHECK_ARG_RET(NULL, meta, node, NULL);
+ LY_CHECK_ARG_RET(NULL, meta, node, LY_EINVAL);
/* create a copy */
mt = calloc(1, sizeof *mt);
- LY_CHECK_ERR_RET(!mt, LOGMEM(LYD_NODE_CTX(node)), NULL);
+ LY_CHECK_ERR_RET(!mt, LOGMEM(LYD_NODE_CTX(node)), LY_EMEM);
mt->parent = node;
mt->annotation = meta->annotation;
mt->value.realtype = meta->value.realtype;
ret = mt->value.realtype->plugin->duplicate(LYD_NODE_CTX(node), &meta->value, &mt->value);
- LY_CHECK_ERR_RET(ret, LOGERR(LYD_NODE_CTX(node), LY_EINT, "Value duplication failed."), NULL);
+ LY_CHECK_ERR_RET(ret, LOGERR(LYD_NODE_CTX(node), LY_EINT, "Value duplication failed."), ret);
mt->name = lydict_insert(LYD_NODE_CTX(node), meta->name, 0);
/* insert as the last attribute */
@@ -2363,7 +2399,10 @@
node->meta = mt;
}
- return mt;
+ if (dup) {
+ *dup = mt;
+ }
+ return LY_SUCCESS;
}
/**
@@ -2401,8 +2440,8 @@
/* since they are different, they cannot both be default */
assert(!(sibling_src->flags & LYD_DEFAULT) || !(match_trg->flags & LYD_DEFAULT));
- /* update value (or only LYD_DEFAULT flag) only if no flag set or the source node is not default */
- if (!(options & LYD_MERGE_EXPLICIT) || !(sibling_src->flags & LYD_DEFAULT)) {
+ /* update value (or only LYD_DEFAULT flag) only if flag set or the source node is not default */
+ if ((options & LYD_MERGE_DEFAULTS) || !(sibling_src->flags & LYD_DEFAULT)) {
type = ((struct lysc_node_leaf *)match_trg->schema)->type;
type->plugin->free(LYD_NODE_CTX(match_trg), &((struct lyd_node_term *)match_trg)->value);
LY_CHECK_RET(type->plugin->duplicate(LYD_NODE_CTX(match_trg), &((struct lyd_node_term *)sibling_src)->value,
@@ -2418,8 +2457,7 @@
/* spend it */
*sibling_src_p = NULL;
} else {
- dup_src = lyd_dup(sibling_src, NULL, 0);
- LY_CHECK_RET(!dup_src, LY_EMEM);
+ LY_CHECK_RET(lyd_dup_single(sibling_src, NULL, 0, &dup_src));
}
/* just switch values */
tmp_val_type = ((struct lyd_node_any *)match_trg)->value_type;
@@ -2448,8 +2486,7 @@
/* spend it */
*sibling_src_p = NULL;
} else {
- dup_src = lyd_dup(sibling_src, NULL, LYD_DUP_RECURSIVE | LYD_DUP_WITH_FLAGS);
- LY_CHECK_RET(!dup_src, LY_EMEM);
+ LY_CHECK_RET(lyd_dup_single(sibling_src, NULL, LYD_DUP_RECURSIVE | LYD_DUP_WITH_FLAGS, &dup_src));
}
/* set LYD_NEW for all the new nodes, required for validation */
@@ -2464,8 +2501,8 @@
return LY_SUCCESS;
}
-API LY_ERR
-lyd_merge(struct lyd_node **target, const struct lyd_node *source, int options)
+static LY_ERR
+lyd_merge(struct lyd_node **target, const struct lyd_node *source, int options, int nosiblings)
{
const struct lyd_node *sibling_src, *tmp;
int first;
@@ -2490,7 +2527,7 @@
source = tmp;
}
- if (options & LYD_MERGE_NOSIBLINGS) {
+ if (nosiblings) {
break;
}
}
@@ -2503,6 +2540,18 @@
return LY_SUCCESS;
}
+API LY_ERR
+lyd_merge_tree(struct lyd_node **target, const struct lyd_node *source, int options)
+{
+ return lyd_merge(target, source, options, 1);
+}
+
+API LY_ERR
+lyd_merge_siblings(struct lyd_node **target, const struct lyd_node *source, int options)
+{
+ return lyd_merge(target, source, options, 0);
+}
+
static LY_ERR
lyd_path_str_enlarge(char **buffer, size_t *buflen, size_t reqlen, int is_static)
{
diff --git a/src/tree_data.h b/src/tree_data.h
index 9991eec..ea44fe7 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -475,10 +475,10 @@
* @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
* @param[in] module Module of the node being created. If NULL, @p parent module will be used.
* @param[in] name Schema node name of the new data node. The node can be #LYS_CONTAINER, #LYS_NOTIF, #LYS_RPC, or #LYS_ACTION.
- * @return New created node.
- * @return NULL on error.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_inner(struct lyd_node *parent, const struct lys_module *module, const char *name);
+LY_ERR lyd_new_inner(struct lyd_node *parent, const struct lys_module *module, const char *name, struct lyd_node **node);
/**
* @brief Create a new list node in the data tree.
@@ -486,13 +486,13 @@
* @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
* @param[in] module Module of the node being created. If NULL, @p parent module will be used.
* @param[in] name Schema node name of the new data node. The node must be #LYS_LIST.
+ * @param[out] node Optional created node.
* @param[in] ... Ordered key values of the new list instance, all must be set. In case of an instance-identifier
* or identityref value, the JSON format is expected (module names instead of prefixes). No keys are expected for
* key-less lists.
- * @return New created node.
- * @return NULL on error.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_list(struct lyd_node *parent, const struct lys_module *module, const char *name, ...);
+LY_ERR lyd_new_list(struct lyd_node *parent, const struct lys_module *module, const char *name, struct lyd_node **node, ...);
/**
* @brief Create a new list node in the data tree.
@@ -503,10 +503,11 @@
* @param[in] keys All key values predicate in the form of "[key1='val1'][key2='val2']...", they do not have to be ordered.
* In case of an instance-identifier or identityref value, the JSON format is expected (module names instead of prefixes).
* Use NULL or string of length 0 in case of key-less list.
- * @return New created node.
- * @return NULL on error.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_list2(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *keys);
+LY_ERR lyd_new_list2(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *keys,
+ struct lyd_node **node);
/**
* @brief Create a new term node in the data tree.
@@ -516,10 +517,11 @@
* @param[in] name Schema node name of the new data node. The node can be #LYS_LEAF or #LYS_LEAFLIST.
* @param[in] val_str String form of the value of the node being created. In case of an instance-identifier or identityref
* value, the JSON format is expected (module names instead of prefixes).
- * @return New created node.
- * @return NULL on error.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_term(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str);
+LY_ERR lyd_new_term(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str,
+ struct lyd_node **node);
/**
* @brief Create a new any node in the data tree.
@@ -529,11 +531,11 @@
* @param[in] name Schema node name of the new data node. The node can be #LYS_ANYDATA or #LYS_ANYXML.
* @param[in] value Value to be directly assigned to the node. Expected type is determined by @p value_type.
* @param[in] value_type Type of the provided value in @p value.
- * @return New created node.
- * @return NULL on error.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_any(struct lyd_node *parent, const struct lys_module *module, const char *name,
- const void *value, LYD_ANYDATA_VALUETYPE value_type);
+LY_ERR lyd_new_any(struct lyd_node *parent, const struct lys_module *module, const char *name, const void *value,
+ LYD_ANYDATA_VALUETYPE value_type, struct lyd_node **node);
/**
* @brief Create new metadata for a data node.
@@ -544,11 +546,11 @@
* If the prefix is specified it is always used but if not specified, @p module must be set.
* @param[in] val_str String form of the value of the metadata. In case of an instance-identifier or identityref
* value, the JSON format is expected (module names instead of prefixes).
- * @return New created metadata of @p parent.
- * @return NULL on error.
+ * @param[out] meta Optional created metadata.
+ * @return LY_ERR value.
*/
-struct lyd_meta *lyd_new_meta(struct lyd_node *parent, const struct lys_module *module, const char *name,
- const char *val_str);
+LY_ERR lyd_new_meta(struct lyd_node *parent, const struct lys_module *module, const char *name, const char *val_str,
+ struct lyd_meta **meta);
/**
* @brief Create a new opaque node in the data tree.
@@ -558,11 +560,11 @@
* @param[in] name Node name.
* @param[in] value Node value, may be NULL.
* @param[in] module_name Node module name.
- * @return New created node.
- * @return NULL on error.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
- const char *module_name);
+LY_ERR lyd_new_opaq(struct lyd_node *parent, const struct ly_ctx *ctx, const char *name, const char *value,
+ const char *module_name, struct lyd_node **node);
/**
* @brief Create new attribute for an opaque data node.
@@ -571,10 +573,11 @@
* @param[in] module Module name of the attribute being created. There may be none.
* @param[in] name Attribute name. It can include the module name as the prefix.
* @param[in] val_str String value of the attribute. Is stored directly.
- * @return New created attribute of @p parent.
- * @return NULL on error.
+ * @param[out] attr Optional created attribute.
+ * @return LY_ERR value.
*/
-struct ly_attr *lyd_new_attr(struct lyd_node *parent, const char *module_name, const char *name, const char *val_str);
+LY_ERR lyd_new_attr(struct lyd_node *parent, const char *module_name, const char *name, const char *val_str,
+ struct ly_attr **attr);
/**
* @defgroup pathoptions Data path creation options
@@ -614,11 +617,11 @@
* @param[in] path Path to create (TODO ref path).
* @param[in] value Value of the new leaf/leaf-list. For other node types, it is ignored.
* @param[in] options Bitmask of options, see @ref pathoptions.
- * @return First created node.
- * @return NULL on error.
+ * @param[out] node Optional first created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_path(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const char *value,
- int options);
+LY_ERR lyd_new_path(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const char *value,
+ int options, struct lyd_node **node);
/**
* @brief Create a new node in the data tree based on a path. All node types can be created.
@@ -633,11 +636,11 @@
* @param[in] value Value of the new leaf/leaf-list/anyxml/anydata. For other node types, it is ignored.
* @param[in] value_type Anyxml/anydata node @p value type.
* @param[in] options Bitmask of options, see @ref pathoptions.
- * @return First created node.
- * @return NULL on error.
+ * @param[out] node Optional first created node.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_new_path_any(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const void *value,
- LYD_ANYDATA_VALUETYPE value_type, int options);
+LY_ERR lyd_new_path_any(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const void *value,
+ LYD_ANYDATA_VALUETYPE value_type, int options, struct lyd_node **node);
/**
* @brief Create a new node in the data tree based on a path. All node types can be created.
@@ -652,8 +655,8 @@
* @param[in] value Value of the new leaf/leaf-list/anyxml/anydata. For other node types, it is ignored.
* @param[in] value_type Anyxml/anydata node @p value type.
* @param[in] options Bitmask of options, see @ref pathoptions.
- * @param[out] new_parent First parent node created, can be NULL. If only one node was created, equals to @p new_node.
- * @param[out] new_node Last node created, can be NULL.
+ * @param[out] new_parent Optional first parent node created. If only one node was created, equals to @p new_node.
+ * @param[out] new_node Optional last node created.
* @return LY_ERR value.
*/
LY_ERR lyd_new_path2(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const void *value,
@@ -753,7 +756,7 @@
void lyd_free_all(struct lyd_node *node);
/**
- * @brief Free all the sibling nodes.
+ * @brief Free all the sibling nodes (preceding as well as succeeding).
*
* @param[in] node Any of the sibling nodes to free.
*/
@@ -767,24 +770,34 @@
void lyd_free_tree(struct lyd_node *node);
/**
- * @brief Destroy metadata.
+ * @brief Free a single metadata instance.
*
- * @param[in] ctx Context where the metadata was created.
- * @param[in] meta Metadata to destroy
- * @param[in] recursive Zero to destroy only the single metadata (the metadata list is corrected),
- * non-zero to destroy also all the subsequent metadata in the list.
+ * @param[in] meta Metadata to free.
*/
-void lyd_free_meta(const struct ly_ctx *ctx, struct lyd_meta *meta, int recursive);
+void lyd_free_meta_single(struct lyd_meta *meta);
/**
- * @brief Destroy attributes.
+ * @brief Free the metadata instance with any following instances.
+ *
+ * @param[in] meta Metadata to free.
+ */
+void lyd_free_meta_siblings(struct lyd_meta *meta);
+
+/**
+ * @brief Free a single attribute.
*
* @param[in] ctx Context where the attributes were created.
- * @param[in] attr Attributes to destroy.
- * @param[in] recursive Zero to destroy only the single attribute (the attribute list is corrected),
- * non-zero to destroy also all the subsequent attributes in the list.
+ * @param[in] attr Attribute to free.
*/
-void ly_free_attr(const struct ly_ctx *ctx, struct ly_attr *attr, int recursive);
+void ly_free_attr_single(const struct ly_ctx *ctx, struct ly_attr *attr);
+
+/**
+ * @brief Free the attribute with any following attributes.
+ *
+ * @param[in] ctx Context where the attributes were created.
+ * @param[in] attr First attribute to free.
+ */
+void ly_free_attr_siblings(const struct ly_ctx *ctx, struct ly_attr *attr);
/**
* @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value.
@@ -877,7 +890,7 @@
*
* Default behavior:
* - only the specified node is duplicated without siblings, parents, or children.
- * - all the attributes of the duplicated nodes are also duplicated.
+ * - all the metadata of the duplicated nodes are also duplicated.
* @{
*/
@@ -886,8 +899,7 @@
#define LYD_DUP_NO_META 0x02 /**< Do not duplicate metadata of any node. */
#define LYD_DUP_WITH_PARENTS 0x04 /**< If a nested node is being duplicated, duplicate also all the parents.
Keys are also duplicated for lists. Return value does not change! */
-#define LYD_DUP_WITH_SIBLINGS 0x08 /**< Duplicate also all the sibling of the given node. */
-#define LYD_DUP_WITH_FLAGS 0x10 /**< Also copy any data node flags. That will cause the duplicated data to preserve
+#define LYD_DUP_WITH_FLAGS 0x08 /**< Also copy any data node flags. That will cause the duplicated data to preserve
its validation/default node state. */
/** @} dupoptions */
@@ -897,24 +909,38 @@
*
* @param[in] node Data tree node to be duplicated.
* @param[in] parent Optional parent node where to connect the duplicated node(s).
- * If set in combination with LYD_DUP_WITH_PARENTS, the parents chain is duplicated until it comes to and connect with the @p parent
- * (if the parents chain does not match at some node the schema node of the provided @p parent, duplication fails).
+ * If set in combination with LYD_DUP_WITH_PARENTS, the parents chain is duplicated until it comes to and connects with
+ * the @p parent.
* @param[in] options Bitmask of options flags, see @ref dupoptions.
- * @return Created copy of the provided data \p node (the first of the duplicated siblings when LYD_DUP_WITH_SIBLINGS used).
- * Note that in case the parents chain is duplicated for the duplicated node(s) (when LYD_DUP_WITH_PARENTS used), the first duplicated node
- * is still returned, not a pointer to the duplicated parents.
+ * @param[out] dup Optional created copy of the node. Note that in case the parents chain is duplicated for the duplicated
+ * node(s) (when LYD_DUP_WITH_PARENTS used), the first duplicated node is still returned.
+ * @return LY_ERR value.
*/
-struct lyd_node *lyd_dup(const struct lyd_node *node, struct lyd_node_inner *parent, int options);
+LY_ERR lyd_dup_single(const struct lyd_node *node, struct lyd_node_inner *parent, int options, struct lyd_node **dup);
+
+/**
+ * @brief Create a copy of the specified data tree \p node with any following siblings. Schema references are kept the same.
+ *
+ * @param[in] node Data tree node to be duplicated.
+ * @param[in] parent Optional parent node where to connect the duplicated node(s).
+ * If set in combination with LYD_DUP_WITH_PARENTS, the parents chain is duplicated until it comes to and connects with
+ * the @p parent.
+ * @param[in] options Bitmask of options flags, see @ref dupoptions.
+ * @param[out] dup Optional created copy of the node. Note that in case the parents chain is duplicated for the duplicated
+ * node(s) (when LYD_DUP_WITH_PARENTS used), the first duplicated node is still returned.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_dup_siblings(const struct lyd_node *node, struct lyd_node_inner *parent, int options, struct lyd_node **dup);
/**
* @brief Create a copy of the metadata.
*
* @param[in] meta Metadata to copy.
- * @param[in] node Node where to append the new metadata.
- * @return Created metadata copy,
- * @return NULL on error.
+ * @param[in] parent Node where to append the new metadata.
+ * @param[out] dup Optional created metadata copy.
+ * @return LY_ERR value.
*/
-struct lyd_meta *lyd_dup_meta(const struct lyd_meta *meta, struct lyd_node *node);
+LY_ERR lyd_dup_meta_single(const struct lyd_meta *meta, struct lyd_node *parent, struct lyd_meta **dup);
/**
* @defgroup mergeoptions Data merge options.
@@ -924,20 +950,17 @@
*
* Default behavior:
* - source data tree is not modified in any way,
- * - source data tree is merged with any succeeding siblings,
- * - any default nodes from source replace explicit nodes in the target.
+ * - any default nodes in the source are ignored if there are explicit nodes in the target.
* @{
*/
#define LYD_MERGE_DESTRUCT 0x01 /**< Spend source data tree in the function, it cannot be used afterwards! */
-#define LYD_MERGE_NOSIBLINGS 0x02 /**< Merge only the single source data tree, no siblings. */
-#define LYD_MERGE_EXPLICIT 0x04 /**< Default nodes in the source tree are ignored if there are explicit nodes
- in the target tree. */
+#define LYD_MERGE_DEFAULTS 0x02 /**< Default nodes in the source tree replace even explicit nodes in the target. */
/** @} mergeoptions */
/**
- * @brief Merge the source data tree into the target data tree. Merge may not be complete until validation
+ * @brief Merge the source data subtree into the target data tree. Merge may not be complete until validation
* is called on the resulting data tree (data from more cases may be present, default and non-default values).
*
* @param[in,out] target Target data tree to merge into, must be a top-level tree.
@@ -946,7 +969,20 @@
* @return LY_SUCCESS on success,
* @return LY_ERR value on error.
*/
-LY_ERR lyd_merge(struct lyd_node **target, const struct lyd_node *source, int options);
+LY_ERR lyd_merge_tree(struct lyd_node **target, const struct lyd_node *source, int options);
+
+/**
+ * @brief Merge the source data tree with any following siblings into the target data tree. Merge may not be
+ * complete until validation called on the resulting data tree (data from more cases may be present, default
+ * and non-default values).
+ *
+ * @param[in,out] target Target data tree to merge into, must be a top-level tree.
+ * @param[in] source Source data tree to merge, must be a top-level tree.
+ * @param[in] options Bitmask of option flags, see @ref mergeoptions.
+ * @return LY_SUCCESS on success,
+ * @return LY_ERR value on error.
+ */
+LY_ERR lyd_merge_siblings(struct lyd_node **target, const struct lyd_node *source, int options);
/**
* @defgroup diffoptions Data diff options.
@@ -955,15 +991,13 @@
* Various options to change lyd_diff() behavior.
*
* Default behavior:
- * - data trees are compared with all the siblings,
* - any default nodes are treated as non-existent and ignored.
* @{
*/
-#define LYD_DIFF_NOSIBLINGS 0x01 /**< Only the single subtree is compared, no siblings. */
-#define LYD_DIFF_WITHDEFAULTS 0x02 /**< Default nodes in the trees are not ignored but treated similarly to explicit
- nodes. Also, leaves and leaf-lists are added into diff even in case only their
- default flag (state) was changed. */
+#define LYD_DIFF_DEFAULTS 0x01 /**< Default nodes in the trees are not ignored but treated similarly to explicit
+ nodes. Also, leaves and leaf-lists are added into diff even in case only their
+ default flag (state) was changed. */
/** @} diffoptions */
@@ -992,7 +1026,19 @@
* @return LY_SUCCESS on success,
* @return LY_ERR on error.
*/
-LY_ERR lyd_diff(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff);
+LY_ERR lyd_diff_tree(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff);
+
+/**
+ * @brief Learn the differences between 2 data trees including all the following siblings.
+ *
+ * @param[in] first First data tree.
+ * @param[in] second Second data tree.
+ * @param[in] options Bitmask of options flags, see @ref diffoptions.
+ * @param[out] diff Generated diff.
+ * @return LY_SUCCESS on success,
+ * @return LY_ERR on error.
+ */
+LY_ERR lyd_diff_siblings(const struct lyd_node *first, const struct lyd_node *second, int options, struct lyd_node **diff);
/**
* @brief Callback for diff nodes.
@@ -1005,7 +1051,7 @@
typedef LY_ERR (*lyd_diff_cb)(const struct lyd_node *diff_node, struct lyd_node *data_node, void *cb_data);
/**
- * @brief Apply a difference on a data tree but restrict the operation to one module.
+ * @brief Apply the whole diff on a data tree but restrict the operation to one module.
*
* @param[in,out] data Data to apply the diff on.
* @param[in] diff Diff to apply.
@@ -1019,14 +1065,14 @@
lyd_diff_cb diff_cb, void *cb_data);
/**
- * @brief Apply a difference on a data tree.
+ * @brief Apply the whole diff tree on a data tree.
*
* @param[in,out] data Data to apply the diff on.
* @param[in] diff Diff to apply.
* @return LY_SUCCESS on success,
* @return LY_ERR on error.
*/
-LY_ERR lyd_diff_apply(struct lyd_node **data, const struct lyd_node *diff);
+LY_ERR lyd_diff_apply_all(struct lyd_node **data, const struct lyd_node *diff);
/**
* @brief Merge 2 diffs into each other but restrict the operation to one module.
@@ -1060,7 +1106,7 @@
* @return LY_SUCCESS on success,
* @return LY_ERR on error.
*/
-LY_ERR lyd_diff_merge(const struct lyd_node *src_diff, struct lyd_node **diff);
+LY_ERR lyd_diff_merge_all(const struct lyd_node *src_diff, struct lyd_node **diff);
/**
* @brief Reverse a diff and make the opposite changes. Meaning change create to delete, delete to create,
@@ -1071,7 +1117,7 @@
* @return LY_SUCCESS on success.
* @return LY_ERR on error.
*/
-LY_ERR lyd_diff_reverse(const struct lyd_node *src_diff, struct lyd_node **diff);
+LY_ERR lyd_diff_reverse_all(const struct lyd_node *src_diff, struct lyd_node **diff);
/**
* @brief Find the target in data of a compiled ly_path structure (instance-identifier).
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index 9cb946e..7cd1283 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -23,19 +23,18 @@
#include "tree_data_internal.h"
#include "plugins_types.h"
-API void
-lyd_free_meta(const struct ly_ctx *ctx, struct lyd_meta *meta, int recursive)
+static void
+lyd_free_meta(struct lyd_meta *meta, int siblings)
{
struct lyd_meta *iter;
- LY_CHECK_ARG_RET(NULL, ctx, );
if (!meta) {
return;
}
if (meta->parent) {
if (meta->parent->meta == meta) {
- if (recursive) {
+ if (siblings) {
meta->parent->meta = NULL;
} else {
meta->parent->meta = meta->next;
@@ -43,7 +42,7 @@
} else {
for (iter = meta->parent->meta; iter->next != meta; iter = iter->next);
if (iter->next) {
- if (recursive) {
+ if (siblings) {
iter->next = NULL;
} else {
iter->next = meta->next;
@@ -52,7 +51,7 @@
}
}
- if (!recursive) {
+ if (!siblings) {
meta->next = NULL;
}
@@ -60,14 +59,26 @@
meta = iter;
iter = iter->next;
- FREE_STRING(ctx, meta->name);
- meta->value.realtype->plugin->free(ctx, &meta->value);
+ FREE_STRING(meta->annotation->module->ctx, meta->name);
+ meta->value.realtype->plugin->free(meta->annotation->module->ctx, &meta->value);
free(meta);
}
}
API void
-ly_free_attr(const struct ly_ctx *ctx, struct ly_attr *attr, int recursive)
+lyd_free_meta_single(struct lyd_meta *meta)
+{
+ lyd_free_meta(meta, 0);
+}
+
+API void
+lyd_free_meta_siblings(struct lyd_meta *meta)
+{
+ lyd_free_meta(meta, 1);
+}
+
+static void
+ly_free_attr(const struct ly_ctx *ctx, struct ly_attr *attr, int siblings)
{
struct ly_attr *iter;
LY_ARRAY_COUNT_TYPE u;
@@ -79,7 +90,7 @@
if (attr->parent) {
if (attr->parent->attr == attr) {
- if (recursive) {
+ if (siblings) {
attr->parent->attr = NULL;
} else {
attr->parent->attr = attr->next;
@@ -87,7 +98,7 @@
} else {
for (iter = attr->parent->attr; iter->next != attr; iter = iter->next);
if (iter->next) {
- if (recursive) {
+ if (siblings) {
iter->next = NULL;
} else {
iter->next = attr->next;
@@ -96,7 +107,7 @@
}
}
- if (!recursive) {
+ if (!siblings) {
attr->next = NULL;
}
@@ -117,6 +128,18 @@
}
}
+API void
+ly_free_attr_single(const struct ly_ctx *ctx, struct ly_attr *attr)
+{
+ ly_free_attr(ctx, attr, 0);
+}
+
+API void
+ly_free_attr_siblings(const struct ly_ctx *ctx, struct ly_attr *attr)
+{
+ ly_free_attr(ctx, attr, 1);
+}
+
void
ly_free_val_prefs(const struct ly_ctx *ctx, struct ly_prefix *val_prefs)
{
@@ -175,10 +198,10 @@
}
if (!node->schema) {
- ly_free_attr(LYD_NODE_CTX(node), opaq->attr, 1);
+ ly_free_attr_siblings(LYD_NODE_CTX(node), opaq->attr);
} else {
/* free the node's metadata */
- lyd_free_meta(LYD_NODE_CTX(node), node->meta, 1);
+ lyd_free_meta_siblings(node->meta);
}
/* unlink only the nodes from the first level, nodes in subtree are freed all, so no unlink is needed */
diff --git a/src/tree_data_helpers.c b/src/tree_data_helpers.c
index e11815b..7551667 100644
--- a/src/tree_data_helpers.c
+++ b/src/tree_data_helpers.c
@@ -198,7 +198,7 @@
} else {
*meta = (*meta)->next;
}
- lyd_free_meta(LYD_NODE_CTX(node), meta2, 0);
+ lyd_free_meta_single(meta2);
break;
}
@@ -242,8 +242,7 @@
switch (value_type) {
case LYD_ANYDATA_DATATREE:
if (value->tree) {
- t->value.tree = lyd_dup(value->tree, NULL, LYD_DUP_RECURSIVE | LYD_DUP_WITH_SIBLINGS);
- LY_CHECK_RET(!t->value.tree, LY_EINT);
+ LY_CHECK_RET(lyd_dup_siblings(value->tree, NULL, LYD_DUP_RECURSIVE, &t->value.tree));
}
break;
case LYD_ANYDATA_STRING:
diff --git a/src/tree_schema.c b/src/tree_schema.c
index b958df4..e89cd01 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -749,17 +749,18 @@
return lys_set_implemented_internal(mod, 1);
}
-struct lysp_submodule *
+LY_ERR
lys_parse_mem_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, struct lys_parser_ctx *main_ctx,
- LY_ERR (*custom_check)(const struct ly_ctx*, struct lysp_module*, struct lysp_submodule*, void*), void *check_data)
+ LY_ERR (*custom_check)(const struct ly_ctx*, struct lysp_module*, struct lysp_submodule*, void*),
+ void *check_data, struct lysp_submodule **submodule)
{
- LY_ERR ret = LY_EINVAL;
+ LY_ERR ret;
struct lysp_submodule *submod = NULL, *latest_sp;
struct lys_yang_parser_ctx *yangctx = NULL;
struct lys_yin_parser_ctx *yinctx = NULL;
struct lys_parser_ctx *pctx;
- LY_CHECK_ARG_RET(ctx, ctx, in, NULL);
+ LY_CHECK_ARG_RET(ctx, ctx, in, LY_EINVAL);
switch (format) {
case LYS_IN_YIN:
@@ -802,7 +803,7 @@
}
if (custom_check) {
- LY_CHECK_GOTO(custom_check(PARSER_CTX(pctx), NULL, submod, check_data), error);
+ LY_CHECK_GOTO(ret = custom_check(PARSER_CTX(pctx), NULL, submod, check_data), error);
}
if (latest_sp) {
@@ -818,7 +819,8 @@
} else {
yin_parser_ctx_free(yinctx);
}
- return submod;
+ *submodule = submod;
+ return LY_SUCCESS;
error:
lysp_submodule_free(ctx, submod);
@@ -827,27 +829,28 @@
} else {
yin_parser_ctx_free(yinctx);
}
- return NULL;
+ return ret;
}
-struct lys_module *
+LY_ERR
lys_parse_mem_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, int implement,
- LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
- void *check_data)
+ LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod,
+ struct lysp_submodule *submod, void *data), void *check_data,
+ struct lys_module **module)
{
struct lys_module *mod = NULL, *latest, *mod_dup;
struct lysp_import *imp;
struct lysp_include *inc;
- LY_ERR ret = LY_EINVAL;
+ LY_ERR ret;
LY_ARRAY_COUNT_TYPE u, v;
struct lys_yang_parser_ctx *yangctx = NULL;
struct lys_yin_parser_ctx *yinctx = NULL;
struct lys_parser_ctx *pctx = NULL;
- LY_CHECK_ARG_RET(ctx, ctx, in, NULL);
+ LY_CHECK_ARG_RET(ctx, ctx, in, LY_EINVAL);
mod = calloc(1, sizeof *mod);
- LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), NULL);
+ LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), LY_EMEM);
mod->ctx = ctx;
switch (format) {
@@ -861,6 +864,7 @@
break;
default:
LOGERR(ctx, LY_EINVAL, "Invalid schema input format.");
+ ret = LY_EINVAL;
break;
}
LY_CHECK_GOTO(ret, error);
@@ -893,13 +897,14 @@
}
if (custom_check) {
- LY_CHECK_GOTO(custom_check(ctx, mod->parsed, NULL, check_data), error);
+ LY_CHECK_GOTO(ret = custom_check(ctx, mod->parsed, NULL, check_data), error);
}
if (implement) {
/* mark the loaded module implemented */
if (ly_ctx_get_module_implemented(ctx, mod->name)) {
LOGERR(ctx, LY_EDENIED, "Module \"%s\" is already implemented in the context.", mod->name);
+ ret = LY_EDENIED;
goto error;
}
mod->implemented = 1;
@@ -917,6 +922,7 @@
LOGERR(ctx, LY_EEXIST, "Module \"%s\" with no revision is already present in the context.",
mod->name);
}
+ ret = LY_EEXIST;
goto error;
} else {
/* add the parsed data to the currently compiled-only module in the context */
@@ -931,8 +937,8 @@
if (!mod->implemented) {
/* pre-compile features and identities of the module */
- LY_CHECK_GOTO(lys_feature_precompile(NULL, ctx, mod, mod->parsed->features, &mod->dis_features), error);
- LY_CHECK_GOTO(lys_identity_precompile(NULL, ctx, mod, mod->parsed->identities, &mod->dis_identities), error);
+ LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, mod->parsed->features, &mod->dis_features), error);
+ LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, mod->parsed->identities, &mod->dis_identities), error);
}
if (latest) {
@@ -947,39 +953,44 @@
mod->parsed->parsing = 1;
LY_ARRAY_FOR(mod->parsed->imports, u) {
imp = &mod->parsed->imports[u];
- if (!imp->module && lysp_load_module(ctx, imp->name, imp->rev[0] ? imp->rev : NULL, 0, 0, &imp->module)) {
- goto error_ctx;
+ if (!imp->module) {
+ LY_CHECK_GOTO(ret = lysp_load_module(ctx, imp->name, imp->rev[0] ? imp->rev : NULL, 0, 0, &imp->module),
+ error_ctx);
}
/* check for importing the same module twice */
for (v = 0; v < u; ++v) {
if (imp->module == mod->parsed->imports[v].module) {
- LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Single revision of the module \"%s\" referred twice.", imp->name);
+ LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Single revision of the module \"%s\" referred twice.",
+ imp->name);
+ ret = LY_EVALID;
goto error_ctx;
}
}
}
LY_ARRAY_FOR(mod->parsed->includes, u) {
inc = &mod->parsed->includes[u];
- if (!inc->submodule && lysp_load_submodule(pctx, mod->parsed, inc)) {
- goto error_ctx;
+ if (!inc->submodule) {
+ LY_CHECK_GOTO(ret = lysp_load_submodule(pctx, mod->parsed, inc), error_ctx);
}
if (!mod->implemented) {
/* pre-compile features and identities of the submodule */
- LY_CHECK_GOTO(lys_feature_precompile(NULL, ctx, mod, inc->submodule->features, &mod->dis_features), error);
- LY_CHECK_GOTO(lys_identity_precompile(NULL, ctx, mod, inc->submodule->identities, &mod->dis_identities), error);
+ LY_CHECK_GOTO(ret = lys_feature_precompile(NULL, ctx, mod, inc->submodule->features, &mod->dis_features), error);
+ LY_CHECK_GOTO(ret = lys_identity_precompile(NULL, ctx, mod, inc->submodule->identities, &mod->dis_identities),
+ error);
}
}
mod->parsed->parsing = 0;
/* check name collisions - typedefs and TODO groupings */
- LY_CHECK_GOTO(lysp_check_typedefs(pctx, mod->parsed), error_ctx);
+ LY_CHECK_GOTO(ret = lysp_check_typedefs(pctx, mod->parsed), error_ctx);
if (format == LYS_IN_YANG) {
yang_parser_ctx_free(yangctx);
} else {
yin_parser_ctx_free(yinctx);
}
- return mod;
+ *module = mod;
+ return LY_SUCCESS;
error_ctx:
ly_set_rm(&ctx->list, mod, NULL);
@@ -994,23 +1005,25 @@
yin_parser_ctx_free(yinctx);
}
- return NULL;
+ return ret;
}
-API struct lys_module *
-lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format)
+API LY_ERR
+lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const struct lys_module **module)
{
struct lys_module *mod;
char *filename, *rev, *dot;
size_t len;
- LY_CHECK_ARG_RET(NULL, ctx, in, format > LYS_IN_UNKNOWN, NULL);
+ if (module) {
+ *module = NULL;
+ }
+ LY_CHECK_ARG_RET(NULL, ctx, in, format > LYS_IN_UNKNOWN, LY_EINVAL);
/* remember input position */
in->func_start = in->current;
- mod = lys_parse_mem_module(ctx, in, format, 1, NULL, NULL);
- LY_CHECK_RET(!mod, NULL);
+ LY_CHECK_RET(lys_parse_mem_module(ctx, in, format, 1, NULL, NULL, &mod));
switch (in->type) {
case LY_IN_FILEPATH:
@@ -1045,65 +1058,66 @@
/* nothing special to do */
break;
default:
- LOGINT(ctx);
+ LOGINT_RET(ctx);
break;
}
lys_parser_fill_filepath(ctx, in, &mod->filepath);
- lys_compile(&mod, 0);
+ LY_CHECK_RET(lys_compile(&mod, 0));
- return mod;
+ if (module) {
+ *module = mod;
+ }
+ return LY_SUCCESS;
}
-API struct lys_module *
-lys_parse_mem(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format)
+API LY_ERR
+lys_parse_mem(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, const struct lys_module **module)
{
LY_ERR ret;
struct ly_in *in = NULL;
- struct lys_module *result = NULL;
- LY_CHECK_ARG_RET(ctx, data, format != LYS_IN_UNKNOWN, NULL);
+ LY_CHECK_ARG_RET(ctx, data, format != LYS_IN_UNKNOWN, LY_EINVAL);
- LY_CHECK_ERR_RET(ret = ly_in_new_memory(data, &in), LOGERR(ctx, ret, "Unable to create input handler."), NULL);
+ LY_CHECK_ERR_RET(ret = ly_in_new_memory(data, &in), LOGERR(ctx, ret, "Unable to create input handler."), ret);
- result = lys_parse(ctx, in, format);
+ ret = lys_parse(ctx, in, format, module);
ly_in_free(in, 0);
- return result;
+ return ret;
}
-API struct lys_module *
-lys_parse_fd(struct ly_ctx *ctx, int fd, LYS_INFORMAT format)
+API LY_ERR
+lys_parse_fd(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, const struct lys_module **module)
{
LY_ERR ret;
struct ly_in *in = NULL;
- struct lys_module *result = NULL;
- LY_CHECK_ARG_RET(ctx, fd != -1, format != LYS_IN_UNKNOWN, NULL);
+ LY_CHECK_ARG_RET(ctx, fd > -1, format != LYS_IN_UNKNOWN, LY_EINVAL);
- LY_CHECK_ERR_RET(ret = ly_in_new_fd(fd, &in), LOGERR(ctx, ret, "Unable to create input handler."), NULL);
+ LY_CHECK_ERR_RET(ret = ly_in_new_fd(fd, &in), LOGERR(ctx, ret, "Unable to create input handler."), ret);
- result = lys_parse(ctx, in, format);
+ ret = lys_parse(ctx, in, format, module);
ly_in_free(in, 0);
- return result;
+ return ret;
}
-API struct lys_module *
-lys_parse_path(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format)
+API LY_ERR
+lys_parse_path(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format, const struct lys_module **module)
{
LY_ERR ret;
struct ly_in *in = NULL;
- struct lys_module *result = NULL;
- LY_CHECK_ARG_RET(ctx, path, format != LYS_IN_UNKNOWN, NULL);
+ LY_CHECK_ARG_RET(ctx, path, format != LYS_IN_UNKNOWN, LY_EINVAL);
- LY_CHECK_ERR_RET(ret = ly_in_new_filepath(path, 0, &in), LOGERR(ctx, ret, "Unable to create input handler for filepath %s.", path), NULL);
+ LY_CHECK_ERR_RET(ret = ly_in_new_filepath(path, 0, &in),
+ LOGERR(ctx, ret, "Unable to create input handler for filepath %s.", path), ret);
- result = lys_parse(ctx, in, format);
+ ret = lys_parse(ctx, in, format, module);
ly_in_free(in, 0);
- return result;
+ return ret;
}
API LY_ERR
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index d62473b..ca53a39 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -911,7 +911,7 @@
static LY_ERR
lys_compile_import(struct lysc_ctx *ctx, struct lysp_import *imp_p, struct lysc_import *imp)
{
- struct lys_module *mod = NULL;
+ const struct lys_module *mod = NULL;
LY_ERR ret = LY_SUCCESS;
DUP_STRING(ctx->ctx, imp_p->prefix, imp->prefix);
@@ -928,16 +928,18 @@
if (ly_in_new_filepath(imp->module->filepath, 0, &in)) {
LOGINT(ctx->ctx);
} else {
- mod = lys_parse(ctx->ctx, in, !strcmp(&imp->module->filepath[strlen(imp->module->filepath - 4)], ".yin") ? LYS_IN_YIN : LYS_IN_YANG);
+ LY_CHECK_RET(lys_parse(ctx->ctx, in, !strcmp(&imp->module->filepath[strlen(imp->module->filepath - 4)],
+ ".yin") ? LYS_IN_YIN : LYS_IN_YANG, &mod));
if (mod != imp->module) {
- LOGERR(ctx->ctx, LY_EINT, "Filepath \"%s\" of the module \"%s\" does not match.", imp->module->filepath, imp->module->name);
+ LOGERR(ctx->ctx, LY_EINT, "Filepath \"%s\" of the module \"%s\" does not match.",
+ imp->module->filepath, imp->module->name);
mod = NULL;
}
}
ly_in_free(in, 1);
}
if (!mod) {
- if (lysp_load_module(ctx->ctx, imp->module->name, imp->module->revision, 0, 1, &mod)) {
+ if (lysp_load_module(ctx->ctx, imp->module->name, imp->module->revision, 0, 1, (struct lys_module **)&mod)) {
LOGERR(ctx->ctx, LY_ENOTFOUND, "Unable to reload \"%s\" module to import it into \"%s\", source data not found.",
imp->module->name, ctx->mod->name);
return LY_ENOTFOUND;
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index e079640..bedf795 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -755,34 +755,42 @@
LY_CHECK_RET(lys_search_localfile(ly_ctx_get_searchdirs(ctx), !(ctx->flags & LY_CTX_DISABLE_SEARCHDIR_CWD), name, revision,
&filepath, &format));
- LY_CHECK_ERR_RET(!filepath, if (required) {LOGERR(ctx, LY_ENOTFOUND, "Data model \"%s%s%s\" not found in local searchdirs.",
- name, revision ? "@" : "", revision ? revision : "");}, LY_ENOTFOUND);
+ if (!filepath) {
+ if (required) {
+ LOGERR(ctx, LY_ENOTFOUND, "Data model \"%s%s%s\" not found in local searchdirs.", name, revision ? "@" : "",
+ revision ? revision : "");
+ }
+ return LY_ENOTFOUND;
+ }
LOGVRB("Loading schema from \"%s\" file.", filepath);
/* get the (sub)module */
- LY_CHECK_ERR_GOTO(ret = ly_in_new_filepath(filepath, 0, &in), LOGERR(ctx, ret, "Unable to create input handler for filepath %s.", filepath), cleanup);
+ LY_CHECK_ERR_GOTO(ret = ly_in_new_filepath(filepath, 0, &in),
+ LOGERR(ctx, ret, "Unable to create input handler for filepath %s.", filepath), cleanup);
check_data.name = name;
check_data.revision = revision;
check_data.path = filepath;
check_data.submoduleof = main_name;
if (main_ctx) {
- mod = lys_parse_mem_submodule(ctx, in, format, main_ctx, lysp_load_module_check, &check_data);
+ ret = lys_parse_mem_submodule(ctx, in, format, main_ctx, lysp_load_module_check, &check_data,
+ (struct lysp_submodule **)&mod);
} else {
- mod = lys_parse_mem_module(ctx, in, format, implement, lysp_load_module_check, &check_data);
+ ret = lys_parse_mem_module(ctx, in, format, implement, lysp_load_module_check, &check_data,
+ (struct lys_module **)&mod);
}
- LY_CHECK_ERR_GOTO(!mod, ly_in_free(in, 1);ly_errcode(ctx), cleanup);
+ LY_CHECK_ERR_GOTO(ret, ly_in_free(in, 1), cleanup);
if (main_ctx) {
- lys_parser_fill_filepath(ctx, in, &((struct lysp_submodule*)mod)->filepath);
+ lys_parser_fill_filepath(ctx, in, &((struct lysp_submodule *)mod)->filepath);
} else {
- lys_parser_fill_filepath(ctx, in, &((struct lys_module*)mod)->filepath);
+ lys_parser_fill_filepath(ctx, in, &((struct lys_module *)mod)->filepath);
}
ly_in_free(in, 1);
if (mod && implement) {
- lys_compile((struct lys_module**)&mod, 0);
+ lys_compile((struct lys_module **)&mod, 0);
}
*result = mod;
@@ -794,7 +802,8 @@
}
LY_ERR
-lysp_load_module(struct ly_ctx *ctx, const char *name, const char *revision, int implement, int require_parsed, struct lys_module **mod)
+lysp_load_module(struct ly_ctx *ctx, const char *name, const char *revision, int implement, int require_parsed,
+ struct lys_module **mod)
{
const char *module_data = NULL;
LYS_INFORMAT format = LYS_IN_UNKNOWN;
@@ -848,7 +857,7 @@
LY_CHECK_RET(ly_in_new_memory(module_data, &in));
check_data.name = name;
check_data.revision = revision;
- *mod = lys_parse_mem_module(ctx, in, format, implement, lysp_load_module_check, &check_data);
+ lys_parse_mem_module(ctx, in, format, implement, lysp_load_module_check, &check_data, mod);
ly_in_free(in, 0);
if (module_data_free) {
module_data_free((void*)module_data, ctx->imp_clb_data);
@@ -970,7 +979,7 @@
check_data.name = inc->name;
check_data.revision = inc->rev[0] ? inc->rev : NULL;
check_data.submoduleof = mod->mod->name;
- submod = lys_parse_mem_submodule(ctx, in, format, pctx, lysp_load_module_check, &check_data);
+ lys_parse_mem_submodule(ctx, in, format, pctx, lysp_load_module_check, &check_data, &submod);
ly_in_free(in, 0);
if (submodule_data_free) {
submodule_data_free((void*)submodule_data, ctx->imp_clb_data);
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 880a297..2952413 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -520,7 +520,8 @@
*/
const char *lys_datatype2str(LY_DATA_TYPE basetype);
-typedef LY_ERR (*lys_custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *check_data);
+typedef LY_ERR (*lys_custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod,
+ void *check_data);
/**
* @brief Parse module from a string.
@@ -533,10 +534,11 @@
* @param[in] implement Flag if the schema is supposed to be marked as implemented.
* @param[in] custom_check Callback to check the parsed schema before it is accepted.
* @param[in] check_data Caller's data to pass to the custom_check callback.
- * @return Pointer to the data model structure or NULL on error.
+ * @param[out] module Parsed module.
+ * @return LY_ERR value.
*/
-struct lys_module *lys_parse_mem_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, int implement,
- lys_custom_check custom_check, void *check_data);
+LY_ERR lys_parse_mem_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, int implement,
+ lys_custom_check custom_check, void *check_data, struct lys_module **module);
/**
* @brief Parse submodule from a string.
@@ -549,11 +551,12 @@
* @param[in] main_ctx Parser context of the main module.
* @param[in] custom_check Callback to check the parsed schema before it is accepted.
* @param[in] check_data Caller's data to pass to the custom_check callback.
- * @return Pointer to the data model structure or NULL on error.
+ * @param[out] submodule Parsed submodule.
+ * @return LY_ERR value.
*/
-struct lysp_submodule *lys_parse_mem_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format,
- struct lys_parser_ctx *main_ctx, lys_custom_check custom_check,
- void *check_data);
+LY_ERR lys_parse_mem_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format,
+ struct lys_parser_ctx *main_ctx, lys_custom_check custom_check,
+ void *check_data, struct lysp_submodule **submodule);
/**
* @brief Fill filepath value if available in input handler @p in
diff --git a/src/validation.c b/src/validation.c
index 631fde6..437ce21 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -117,7 +117,7 @@
LY_CHECK_RET(lyd_diff_add(node, op, NULL, NULL, NULL, NULL, NULL, &new_diff));
/* merge into existing diff */
- ret = lyd_diff_merge(new_diff, diff);
+ ret = lyd_diff_merge_all(new_diff, diff);
lyd_free_tree(new_diff);
return ret;
@@ -1256,7 +1256,7 @@
* @return LY_ERR value.
*/
static LY_ERR
-_lyd_validate(struct lyd_node **tree, const struct lys_module *module, const struct ly_ctx *ctx, int val_opts,
+lyd_validate(struct lyd_node **tree, const struct lys_module *module, const struct ly_ctx *ctx, int val_opts,
struct lyd_node **diff)
{
LY_ERR ret = LY_SUCCESS;
@@ -1319,15 +1319,15 @@
}
API LY_ERR
-lyd_validate(struct lyd_node **tree, const struct ly_ctx *ctx, int val_opts, struct lyd_node **diff)
+lyd_validate_all(struct lyd_node **tree, const struct ly_ctx *ctx, int val_opts, struct lyd_node **diff)
{
- return _lyd_validate(tree, NULL, ctx, val_opts, diff);
+ return lyd_validate(tree, NULL, ctx, val_opts, diff);
}
API LY_ERR
lyd_validate_module(struct lyd_node **tree, const struct lys_module *module, int val_opts, struct lyd_node **diff)
{
- return _lyd_validate(tree, module, NULL, val_opts, diff);
+ return lyd_validate(tree, module, NULL, val_opts, diff);
}
/**
diff --git a/src/xpath.c b/src/xpath.c
index 3a1f3df..55a0f6b 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -431,7 +431,7 @@
break;
case LYD_ANYDATA_DATATREE:
LY_CHECK_RET(ly_out_new_memory(&buf, 0, &out));
- rc = lyd_print(out, any->value.tree, LYD_XML, LYD_PRINT_WITHSIBLINGS);
+ rc = lyd_print_all(out, any->value.tree, LYD_XML, 0);
ly_out_free(out, NULL, 0);
LY_CHECK_RET(rc < 0, -rc);
break;