data FEATURE add helpers functions to work with data trees (sized arrays)
Adds lyd_trees_new() and lyd_trees_free() and unifies work with the data
trees in validation functions.
diff --git a/src/parser_xml.c b/src/parser_xml.c
index e94e4f5..75e3c55 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -306,18 +306,16 @@
/* finish incompletely validated terminal values */
for (unsigned int u = 0; u < xmlctx.incomplete_type_validation.count; u++) {
struct lyd_node_term *node = (struct lyd_node_term*)xmlctx.incomplete_type_validation.objs[u];
- struct lyd_node **trees = NULL;
+ const struct lyd_node **trees = NULL;
/* prepare sized array for validator */
if (*result) {
- struct lyd_node **tree;
- LY_ARRAY_NEW_RET(ctx, trees, tree, LY_EMEM);
- *tree = *result;
+ trees = lyd_trees_new(1, *result);
}
/* validate and store the value of the node */
ret = lyd_value_parse(node, node->value.canonized, node->value.canonized ? strlen(node->value.canonized) : 0, 0, 1,
lydxml_resolve_prefix, ctx, LYD_XML, trees);
- LY_ARRAY_FREE(trees);
+ lyd_trees_free(trees, 0);
if (ret) {
lyd_free_all(*result);
*result = NULL;
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 9658afd..736f173 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -405,7 +405,7 @@
static LY_ERR
ly_type_store_int(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
LY_ERR ret;
@@ -468,7 +468,7 @@
static LY_ERR
ly_type_store_uint(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
LY_ERR ret;
@@ -529,7 +529,7 @@
static LY_ERR
ly_type_store_decimal64(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
int64_t d;
@@ -601,7 +601,7 @@
static LY_ERR
ly_type_store_binary(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
size_t start = 0, stop = 0, count = 0, u, termination = 0;
@@ -704,7 +704,7 @@
static LY_ERR
ly_type_store_string(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
@@ -747,7 +747,7 @@
static LY_ERR
ly_type_store_bits(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
LY_ERR ret = LY_EVALID;
@@ -915,7 +915,7 @@
static LY_ERR
ly_type_store_enum(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
unsigned int u, v;
@@ -983,7 +983,7 @@
static LY_ERR
ly_type_store_boolean(struct ly_ctx *ctx, struct lysc_type *UNUSED(type), const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
int8_t i;
@@ -1031,7 +1031,7 @@
static LY_ERR
ly_type_store_empty(struct ly_ctx *ctx, struct lysc_type *UNUSED(type), const char *value, size_t value_len, int options,
ly_clb_resolve_prefix UNUSED(get_prefix), void *UNUSED(parser), LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
if (options & LY_TYPE_OPTS_SECOND_CALL) {
@@ -1088,7 +1088,7 @@
static LY_ERR
ly_type_store_identityref(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT UNUSED(format),
- const void *UNUSED(context_node), struct lyd_node **UNUSED(trees),
+ const void *UNUSED(context_node), const struct lyd_node **UNUSED(trees),
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
struct lysc_type_identityref *type_ident = (struct lysc_type_identityref *)type;
@@ -1219,7 +1219,7 @@
ly_type_store_instanceid_checknodeid(const char *orig, size_t orig_len, int options, int require_instance,
const char **token, struct lyd_value_prefix *prefixes, LYD_FORMAT format,
const struct lysc_node **node_s, const struct lyd_node **node_d,
- struct lyd_node **trees, char **errmsg)
+ const struct lyd_node **trees, char **errmsg)
{
const char *id, *prefix;
size_t id_len, prefix_len;
@@ -1405,7 +1405,7 @@
static LY_ERR
ly_type_store_instanceid(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
- const void *context_node, struct lyd_node **trees,
+ const void *context_node, const struct lyd_node **trees,
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
LY_ERR ret = LY_EVALID;
@@ -1807,7 +1807,7 @@
static LY_ERR
ly_type_store_leafref(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
- const void *context_node, struct lyd_node **trees,
+ const void *context_node, const struct lyd_node **trees,
struct lyd_value *storage, const char **canonized, struct ly_err_item **err)
{
LY_ERR ret;
diff --git a/src/plugins_types.h b/src/plugins_types.h
index e3c2356..4b13f1f 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -116,7 +116,7 @@
*/
typedef LY_ERR (*ly_type_store_clb)(struct ly_ctx *ctx, struct lysc_type *type, const char *value, size_t value_len, int options,
ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,
- const void *context_node, struct lyd_node **trees,
+ const void *context_node, const struct lyd_node **trees,
struct lyd_value *storage, const char **canonized, struct ly_err_item **err);
/**
diff --git a/src/tree_data.c b/src/tree_data.c
index 87c1569..c9ef10f 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -29,6 +29,66 @@
#include "tree_data_internal.h"
#include "tree_schema.h"
+API void
+lyd_trees_free(const struct lyd_node **trees, int free_data)
+{
+ if (!trees) {
+ return;
+ }
+
+ if (free_data) {
+ unsigned int u;
+ LY_ARRAY_FOR(trees, u) {
+ lyd_free_all((struct lyd_node *)trees[u]);
+ }
+ }
+ LY_ARRAY_FREE(trees);
+}
+
+static const struct lyd_node *
+lyd_trees_getstart(const struct lyd_node *tree)
+{
+ if (!tree) {
+ return NULL;
+ }
+ while (tree->prev->next) {
+ tree = tree->prev;
+ }
+ return tree;
+}
+
+API const struct lyd_node **
+lyd_trees_new(size_t count, const struct lyd_node *tree, ...)
+{
+ LY_ERR ret;
+ const struct lyd_node **trees = NULL;
+ va_list ap;
+
+ LY_CHECK_ARG_RET(NULL, tree, count > 0, NULL);
+
+ va_start(ap, tree);
+
+ LY_ARRAY_CREATE_GOTO(tree->schema->module->ctx, trees, count, ret, error);
+ /* first, mandatory, tree to insert */
+ trees[0] = lyd_trees_getstart(tree);
+ LY_ARRAY_INCREMENT(trees);
+
+ /* variable arguments */
+ for (unsigned int u = 1; u < count; ++u) {
+ trees[u] = lyd_trees_getstart(va_arg(ap, const struct lyd_node *));
+ LY_ARRAY_INCREMENT(trees);
+ }
+
+ va_end(ap);
+ return trees;
+
+error:
+ (void)ret; /* unused */
+ lyd_trees_free(trees, 1);
+ va_end(ap);
+ return NULL;
+}
+
static int
cmp_str(const char *refstr, const char *str, size_t str_len)
{
@@ -90,7 +150,7 @@
LY_ERR
lyd_value_parse(struct lyd_node_term *node, const char *value, size_t value_len, int dynamic, int second,
- ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format, struct lyd_node **trees)
+ ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format, const struct lyd_node **trees)
{
LY_ERR ret = LY_SUCCESS, rc;
struct ly_err_item *err = NULL;
@@ -161,7 +221,7 @@
API LY_ERR
lyd_value_validate(struct ly_ctx *ctx, const struct lyd_node_term *node, const char *value, size_t value_len,
- ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, struct lyd_node **trees)
+ ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, const struct lyd_node **trees)
{
LY_ERR rc;
struct ly_err_item *err = NULL;
@@ -192,7 +252,7 @@
API LY_ERR
lyd_value_compare(const struct lyd_node_term *node, const char *value, size_t value_len,
- ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, struct lyd_node **trees)
+ ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, const struct lyd_node **trees)
{
LY_ERR ret = LY_SUCCESS, rc;
struct ly_err_item *err = NULL;
@@ -397,7 +457,7 @@
}
API const struct lyd_node_term *
-lyd_target(struct lyd_value_path *path, struct lyd_node **trees)
+lyd_target(struct lyd_value_path *path, const struct lyd_node **trees)
{
unsigned int u, v, x;
const struct lyd_node *node = NULL, *parent = NULL, *start_search;
diff --git a/src/tree_data.h b/src/tree_data.h
index 84021b5..060f869 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -592,6 +592,24 @@
void lyd_free_attr(struct ly_ctx *ctx, struct lyd_attr *attr, int recursive);
/**
+ * @brief Prepare ([sized array](@ref sizedarrays)) of data trees required by various (mostly validation) functions.
+ *
+ * @param[in] count Number of trees to include (including the mandatory @p tree).
+ * @param[in] tree First (and mandatory) tree to be included into the resulting ([sized array](@ref sizedarrays)).
+ * @return NULL in case of memory allocation failure or invalid argument, prepared ([sized array](@ref sizedarrays)) otherwise.
+ */
+const struct lyd_node **lyd_trees_new(size_t count, const struct lyd_node *tree, ...);
+
+/**
+ * @brief Free the trees ([sized array](@ref sizedarrays)).
+ *
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees.
+ * @param[in] free_data Flag to free also the particular trees in the @p trees ([sized array](@ref sizedarrays)).
+ * If set to zero, only the trees envelope is freed and data are untouched.
+ */
+void lyd_trees_free(const struct lyd_node **trees, int free_data);
+
+/**
* @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value.
*
* The given node is not modified in any way - it is just checked if the @p value can be set to the node.
@@ -608,13 +626,13 @@
* @param[in] format Input format of the data.
* @param[in] trees ([Sized array](@ref sizedarrays)) of data trees (e.g. when validating RPC/Notification) where the required
* data instance (leafref target, instance-identifier) can be placed. NULL in case the data tree are not yet complete,
- * then LY_EINCOMPLETE can be returned.
+ * then LY_EINCOMPLETE can be returned. To simply prepare this structure, use lyd_trees_new().
* @return LY_SUCCESS on success
* @return LY_EINCOMPLETE in case the @p trees is not provided and it was needed to finish the validation (e.g. due to require-instance).
* @return LY_ERR value if an error occurred.
*/
LY_ERR lyd_value_validate(struct ly_ctx *ctx, const struct lyd_node_term *node, const char *value, size_t value_len,
- ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, struct lyd_node **trees);
+ ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, const struct lyd_node **trees);
/**
* @brief Compare the node's value with the given string value. The string value is first validated according to the node's type.
@@ -628,17 +646,25 @@
* @param[in] format Input format of the data.
* @param[in] trees ([Sized array](@ref sizedarrays)) of data trees (e.g. when validating RPC/Notification) where the required
* data instance (leafref target, instance-identifier) can be placed. NULL in case the data tree are not yet complete,
- * then LY_EINCOMPLETE can be returned in case the validation was not completed, but values matches.
+ * then LY_EINCOMPLETE can be returned in case the validation was not completed, but values matches. To simply prepare
+ * this structure, use lyd_trees_new(). To simply prepare this structure, use lyd_trees_new().
* @return LY_SUCCESS on success
* @return LY_EINCOMPLETE in case of success when the @p trees is not provided and it was needed to finish the validation of
* the given string @p value (e.g. due to require-instance).
* @return LY_ERR value if an error occurred.
*/
LY_ERR lyd_value_compare(const struct lyd_node_term *node, const char *value, size_t value_len,
- ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, struct lyd_node **trees);
+ ly_clb_resolve_prefix get_prefix, void *get_prefix_data, LYD_FORMAT format, const struct lyd_node **trees);
-
-const struct lyd_node_term *lyd_target(struct lyd_value_path *path, struct lyd_node **trees);
+/**
+ * @brief Resolve instance-identifier defined by lyd_value_path structure.
+ *
+ * @param[in] path Path structure specifying the instance-identifier target.
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees to be searched.
+ * To simply prepare this structure, use lyd_trees_new().
+ * @return Target node of the instance-identifier present in the given data @p trees.
+ */
+const struct lyd_node_term *lyd_target(struct lyd_value_path *path, const struct lyd_node **trees);
#ifdef __cplusplus
}
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index a9ff2e6..75ef8f3 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -57,7 +57,7 @@
* @return LY_ERR value if an error occurred.
*/
LY_ERR lyd_value_parse(struct lyd_node_term *node, const char *value, size_t value_len, int dynamic, int second,
- ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format,struct lyd_node **trees);
+ ly_clb_resolve_prefix get_prefix, void *parser, LYD_FORMAT format, const struct lyd_node **trees);
/**
* @brief Parse XML string as YANG data tree.