path FEATURE variables instead of values
Supported now for node-instance-identifier.
diff --git a/src/path.c b/src/path.c
index e455b75..4ee9832 100644
--- a/src/path.c
+++ b/src/path.c
@@ -3,7 +3,7 @@
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief Path functions
*
- * Copyright (c) 2020 CESNET, z.s.p.o.
+ * Copyright (c) 2020 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -11,6 +11,9 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
+
+#define _GNU_SOURCE
+
#include "path.h"
#include <assert.h>
@@ -106,8 +109,14 @@
/* '=' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_OPER_EQUAL), token_error);
- /* Literal or Number */
- LY_CHECK_GOTO(lyxp_next_token2(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL, LYXP_TOKEN_NUMBER), token_error);
+ /* Literal, Number, or VariableReference */
+ if (lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_LITERAL) &&
+ lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_NUMBER) &&
+ lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_VARREF)) {
+ /* error */
+ lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL);
+ goto token_error;
+ }
/* ']' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_BRACK2), token_error);
@@ -528,7 +537,7 @@
LY_ERR
ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const struct lys_module *cur_mod,
const struct lysc_node *ctx_node, const struct lyxp_expr *expr, uint32_t *tok_idx, LY_VALUE_FORMAT format,
- void *prefix_data, struct ly_path_predicate **predicates, enum ly_path_pred_type *pred_type)
+ void *prefix_data, struct ly_path_predicate **predicates)
{
LY_ERR ret = LY_SUCCESS;
struct ly_path_predicate *p;
@@ -540,7 +549,7 @@
LOG_LOCSET(cur_node, NULL, NULL, NULL);
- *pred_type = 0;
+ *predicates = NULL;
if (lyxp_next_token(NULL, expr, tok_idx, LYXP_TOKEN_BRACK1)) {
/* '[', no predicate */
@@ -572,11 +581,7 @@
}
++(*tok_idx);
- if (!*pred_type) {
- /* new predicate */
- *pred_type = LY_PATH_PREDTYPE_LIST;
- }
- assert(*pred_type == LY_PATH_PREDTYPE_LIST);
+ /* new predicate */
LY_ARRAY_NEW_GOTO(ctx, *predicates, p, ret, cleanup);
p->key = key;
@@ -584,28 +589,39 @@
assert(expr->tokens[*tok_idx] == LYXP_TOKEN_OPER_EQUAL);
++(*tok_idx);
- /* Literal or Number */
- assert((expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) || (expr->tokens[*tok_idx] == LYXP_TOKEN_NUMBER));
- if (expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) {
- /* skip quotes */
- val = expr->expr + expr->tok_pos[*tok_idx] + 1;
- val_len = expr->tok_len[*tok_idx] - 2;
+ /* Literal, Number, or VariableReference */
+ if (expr->tokens[*tok_idx] == LYXP_TOKEN_VARREF) {
+ /* store the variable name */
+ p->variable = strndup(expr->expr + expr->tok_pos[*tok_idx], expr->tok_len[*tok_idx]);
+ LY_CHECK_ERR_GOTO(!p->variable, LOGMEM(ctx); ret = LY_EMEM, cleanup);
+
+ p->type = LY_PATH_PREDTYPE_LIST_VAR;
+ ++(*tok_idx);
} else {
- val = expr->expr + expr->tok_pos[*tok_idx];
- val_len = expr->tok_len[*tok_idx];
+ if (expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) {
+ /* skip quotes */
+ val = expr->expr + expr->tok_pos[*tok_idx] + 1;
+ val_len = expr->tok_len[*tok_idx] - 2;
+ } else {
+ assert(expr->tokens[*tok_idx] == LYXP_TOKEN_NUMBER);
+ val = expr->expr + expr->tok_pos[*tok_idx];
+ val_len = expr->tok_len[*tok_idx];
+ }
+
+ /* store the value */
+ LOG_LOCSET(key, NULL, NULL, NULL);
+ ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type, val, val_len, NULL, format,
+ prefix_data, LYD_HINT_DATA, key, NULL);
+ LOG_LOCBACK(key ? 1 : 0, 0, 0, 0);
+ LY_CHECK_ERR_GOTO(ret, p->value.realtype = NULL, cleanup);
+
+ /* "allocate" the type to avoid problems when freeing the value after the type was freed */
+ LY_ATOMIC_INC_BARRIER(((struct lysc_type *)p->value.realtype)->refcount);
+
+ p->type = LY_PATH_PREDTYPE_LIST;
+ ++(*tok_idx);
}
- /* store the value */
- LOG_LOCSET(key, NULL, NULL, NULL);
- ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type, val, val_len, NULL, format,
- prefix_data, LYD_HINT_DATA, key, NULL);
- LOG_LOCBACK(key ? 1 : 0, 0, 0, 0);
- LY_CHECK_ERR_GOTO(ret, p->value.realtype = NULL, cleanup);
- ++(*tok_idx);
-
- /* "allocate" the type to avoid problems when freeing the value after the type was freed */
- LY_ATOMIC_INC_BARRIER(((struct lysc_type *)p->value.realtype)->refcount);
-
/* ']' */
assert(expr->tokens[*tok_idx] == LYXP_TOKEN_BRACK2);
++(*tok_idx);
@@ -622,7 +638,7 @@
/* names (keys) are unique - it was checked when parsing */
LOGVAL(ctx, LYVE_XPATH, "Predicate missing for a key of %s \"%s\" in path.",
lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
- ly_path_predicates_free(ctx, LY_PATH_PREDTYPE_LIST, *predicates);
+ ly_path_predicates_free(ctx, *predicates);
*predicates = NULL;
ret = LY_EVALID;
goto cleanup;
@@ -638,8 +654,8 @@
++(*tok_idx);
/* new predicate */
- *pred_type = LY_PATH_PREDTYPE_LEAFLIST;
LY_ARRAY_NEW_GOTO(ctx, *predicates, p, ret, cleanup);
+ p->type = LY_PATH_PREDTYPE_LEAFLIST;
/* '=' */
assert(expr->tokens[*tok_idx] == LYXP_TOKEN_OPER_EQUAL);
@@ -685,8 +701,8 @@
}
/* new predicate */
- *pred_type = LY_PATH_PREDTYPE_POSITION;
LY_ARRAY_NEW_GOTO(ctx, *predicates, p, ret, cleanup);
+ p->type = LY_PATH_PREDTYPE_POSITION;
/* syntax was already checked */
p->position = strtoull(expr->expr + expr->tok_pos[*tok_idx], (char **)&val, LY_BASE_DEC);
@@ -947,7 +963,7 @@
ret = ly_path_compile_predicate_leafref(ctx_node, cur_node, expr, &tok_idx, format, prefix_data);
} else {
ret = ly_path_compile_predicate(ctx, cur_node, cur_mod, ctx_node, expr, &tok_idx, format, prefix_data,
- &p->predicates, &p->pred_type);
+ &p->predicates);
}
LY_CHECK_GOTO(ret, cleanup);
} while (!lyxp_next_token(NULL, expr, &tok_idx, LYXP_TOKEN_OPER_PATH));
@@ -994,8 +1010,8 @@
}
LY_ERR
-ly_path_eval_partial(const struct ly_path *path, const struct lyd_node *start, LY_ARRAY_COUNT_TYPE *path_idx,
- struct lyd_node **match)
+ly_path_eval_partial(const struct ly_path *path, const struct lyd_node *start, const struct lyxp_var *vars,
+ LY_ARRAY_COUNT_TYPE *path_idx, struct lyd_node **match)
{
LY_ARRAY_COUNT_TYPE u;
struct lyd_node *prev_node = NULL, *elem, *node = NULL, *target;
@@ -1017,35 +1033,37 @@
}
LY_ARRAY_FOR(path, u) {
- switch (path[u].pred_type) {
- case LY_PATH_PREDTYPE_POSITION:
- /* we cannot use hashes and want an instance on a specific position */
- pos = 1;
- node = NULL;
- LYD_LIST_FOR_INST(start, path[u].node, elem) {
- if (pos == path[u].predicates[0].position) {
- node = elem;
- break;
+ if (path[u].predicates) {
+ switch (path[u].predicates[0].type) {
+ case LY_PATH_PREDTYPE_POSITION:
+ /* we cannot use hashes and want an instance on a specific position */
+ pos = 1;
+ node = NULL;
+ LYD_LIST_FOR_INST(start, path[u].node, elem) {
+ if (pos == path[u].predicates[0].position) {
+ node = elem;
+ break;
+ }
+ ++pos;
}
- ++pos;
+ break;
+ case LY_PATH_PREDTYPE_LEAFLIST:
+ /* we will use hashes to find one leaf-list instance */
+ LY_CHECK_RET(lyd_create_term2(path[u].node, &path[u].predicates[0].value, &target));
+ lyd_find_sibling_first(start, target, &node);
+ lyd_free_tree(target);
+ break;
+ case LY_PATH_PREDTYPE_LIST_VAR:
+ case LY_PATH_PREDTYPE_LIST:
+ /* we will use hashes to find one list instance */
+ LY_CHECK_RET(lyd_create_list(path[u].node, path[u].predicates, vars, &target));
+ lyd_find_sibling_first(start, target, &node);
+ lyd_free_tree(target);
+ break;
}
- break;
- case LY_PATH_PREDTYPE_LEAFLIST:
- /* we will use hashes to find one leaf-list instance */
- LY_CHECK_RET(lyd_create_term2(path[u].node, &path[u].predicates[0].value, &target));
- lyd_find_sibling_first(start, target, &node);
- lyd_free_tree(target);
- break;
- case LY_PATH_PREDTYPE_LIST:
- /* we will use hashes to find one list instance */
- LY_CHECK_RET(lyd_create_list(path[u].node, path[u].predicates, &target));
- lyd_find_sibling_first(start, target, &node);
- lyd_free_tree(target);
- break;
- case LY_PATH_PREDTYPE_NONE:
+ } else {
/* we will use hashes to find one any/container/leaf instance */
lyd_find_sibling_val(start, path[u].node, NULL, 0, &node);
- break;
}
if (!node) {
@@ -1092,12 +1110,12 @@
}
LY_ERR
-ly_path_eval(const struct ly_path *path, const struct lyd_node *start, struct lyd_node **match)
+ly_path_eval(const struct ly_path *path, const struct lyd_node *start, const struct lyxp_var *vars, struct lyd_node **match)
{
LY_ERR ret;
struct lyd_node *m;
- ret = ly_path_eval_partial(path, start, NULL, &m);
+ ret = ly_path_eval_partial(path, start, vars, NULL, &m);
if (ret == LY_SUCCESS) {
/* last node was found */
@@ -1129,12 +1147,13 @@
(*dup)[u].node = path[u].node;
if (path[u].predicates) {
LY_ARRAY_CREATE_RET(ctx, (*dup)[u].predicates, LY_ARRAY_COUNT(path[u].predicates), LY_EMEM);
- (*dup)[u].pred_type = path[u].pred_type;
LY_ARRAY_FOR(path[u].predicates, v) {
struct ly_path_predicate *pred = &path[u].predicates[v];
LY_ARRAY_INCREMENT((*dup)[u].predicates);
- switch (path[u].pred_type) {
+ (*dup)[u].predicates[v].type = pred->type;
+
+ switch (pred->type) {
case LY_PATH_PREDTYPE_POSITION:
/* position-predicate */
(*dup)[u].predicates[v].position = pred->position;
@@ -1146,7 +1165,10 @@
pred->value.realtype->plugin->duplicate(ctx, &pred->value, &(*dup)[u].predicates[v].value);
LY_ATOMIC_INC_BARRIER(((struct lysc_type *)pred->value.realtype)->refcount);
break;
- case LY_PATH_PREDTYPE_NONE:
+ case LY_PATH_PREDTYPE_LIST_VAR:
+ /* key-predicate with a variable */
+ (*dup)[u].predicates[v].key = pred->key;
+ (*dup)[u].predicates[v].variable = strdup(pred->variable);
break;
}
}
@@ -1157,7 +1179,7 @@
}
void
-ly_path_predicates_free(const struct ly_ctx *ctx, enum ly_path_pred_type pred_type, struct ly_path_predicate *predicates)
+ly_path_predicates_free(const struct ly_ctx *ctx, struct ly_path_predicate *predicates)
{
LY_ARRAY_COUNT_TYPE u;
struct lysf_ctx fctx = {.ctx = (struct ly_ctx *)ctx};
@@ -1167,9 +1189,8 @@
}
LY_ARRAY_FOR(predicates, u) {
- switch (pred_type) {
+ switch (predicates[u].type) {
case LY_PATH_PREDTYPE_POSITION:
- case LY_PATH_PREDTYPE_NONE:
/* nothing to free */
break;
case LY_PATH_PREDTYPE_LIST:
@@ -1179,6 +1200,9 @@
lysc_type_free(&fctx, (struct lysc_type *)predicates[u].value.realtype);
}
break;
+ case LY_PATH_PREDTYPE_LIST_VAR:
+ free(predicates[u].variable);
+ break;
}
}
LY_ARRAY_FREE(predicates);
@@ -1194,7 +1218,7 @@
}
LY_ARRAY_FOR(path, u) {
- ly_path_predicates_free(ctx, path[u].pred_type, path[u].predicates);
+ ly_path_predicates_free(ctx, path[u].predicates);
}
LY_ARRAY_FREE(path);
}
diff --git a/src/path.h b/src/path.h
index 674dd54..aec1d36 100644
--- a/src/path.h
+++ b/src/path.h
@@ -3,7 +3,7 @@
* @author Michal Vasko <mvasko@cesnet.cz>
* @brief Path structure and manipulation routines.
*
- * Copyright (c) 2020 CESNET, z.s.p.o.
+ * Copyright (c) 2020 - 2023 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -29,24 +29,25 @@
struct lyxp_expr;
enum ly_path_pred_type {
- LY_PATH_PREDTYPE_NONE = 0, /**< no predicate */
LY_PATH_PREDTYPE_POSITION, /**< position predicate - [2] */
LY_PATH_PREDTYPE_LIST, /**< keys predicate - [key1='val1'][key2='val2']... */
- LY_PATH_PREDTYPE_LEAFLIST /**< leaflist value predicate - [.='value'] */
+ LY_PATH_PREDTYPE_LEAFLIST, /**< leaflist value predicate - [.='value'] */
+ LY_PATH_PREDTYPE_LIST_VAR /**< keys predicate with variable instead of value - [key1=$USER]... */
};
/**
* @brief Structure for simple path predicate.
*/
struct ly_path_predicate {
+ enum ly_path_pred_type type; /**< Predicate type (see YANG ABNF) */
union {
- uint64_t position; /**< position value for the position-predicate */
-
+ uint64_t position; /**< position value for the position-predicate */
struct {
- const struct lysc_node *key; /**< key node of the predicate, NULL in
- case of a leaf-list predicate */
- struct lyd_value value; /**< value representation according to the
- key's type, its realtype is allocated */
+ const struct lysc_node *key; /**< key node of the predicate, NULL in case of a leaf-list predicate */
+ union {
+ struct lyd_value value; /**< stored value representation according to the key's type (realtype ref) */
+ char *variable; /**< XPath variable used instead of the value */
+ };
};
};
};
@@ -61,7 +62,6 @@
- is inner node - path is relative */
const struct lysc_ext_instance *ext; /**< Extension instance of @p node, if any */
struct ly_path_predicate *predicates; /**< [Sized array](@ref sizedarrays) of the path segment's predicates */
- enum ly_path_pred_type pred_type; /**< Predicate type (see YANG ABNF) */
};
/**
@@ -87,10 +87,10 @@
* @defgroup path_pred_options Path predicate options.
* @{
*/
-#define LY_PATH_PRED_KEYS 0x0100 /* expected predicate only - [node='value']* */
-#define LY_PATH_PRED_SIMPLE 0x0200 /* expected predicates - [node='value']*; [.='value']; [1] */
-#define LY_PATH_PRED_LEAFREF 0x0400 /* expected predicates only leafref - [node=current()/../../../node/node];
- at least 1 ".." and 1 "node" after */
+#define LY_PATH_PRED_KEYS 0x0100 /** expected predicate only - [node='value']* */
+#define LY_PATH_PRED_SIMPLE 0x0200 /** expected predicates - ( [node='value'] | [node=$VAR] )*; [.='value']; [1] */
+#define LY_PATH_PRED_LEAFREF 0x0400 /** expected predicates only leafref - [node=current()/../../../node/node];
+ at least 1 ".." and 1 "node" after */
/** @} */
/**
@@ -199,18 +199,18 @@
* @param[in] format Format of the path.
* @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_resolve_prefix).
* @param[out] predicates Compiled predicates.
- * @param[out] pred_type Type of the compiled predicate(s).
* @return LY_ERR value.
*/
LY_ERR ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const struct lys_module *cur_mod,
const struct lysc_node *ctx_node, const struct lyxp_expr *expr, uint32_t *tok_idx, LY_VALUE_FORMAT format,
- void *prefix_data, struct ly_path_predicate **predicates, enum ly_path_pred_type *pred_type);
+ void *prefix_data, struct ly_path_predicate **predicates);
/**
* @brief Resolve at least partially the target defined by ly_path structure. Not supported for leafref!
*
* @param[in] path Path structure specifying the target.
* @param[in] start Starting node for relative paths, can be any for absolute paths.
+ * @param[in] vars Array of defined variables to use in predicates, may be NULL.
* @param[out] path_idx Last found path segment index, can be NULL, set to 0 if not found.
* @param[out] match Last found matching node, can be NULL, set to NULL if not found.
* @return LY_ENOTFOUND if no nodes were found,
@@ -218,20 +218,22 @@
* @return LY_SUCCESS when the last node in the path was found,
* @return LY_ERR on another error.
*/
-LY_ERR ly_path_eval_partial(const struct ly_path *path, const struct lyd_node *start, LY_ARRAY_COUNT_TYPE *path_idx,
- struct lyd_node **match);
+LY_ERR ly_path_eval_partial(const struct ly_path *path, const struct lyd_node *start, const struct lyxp_var *vars,
+ LY_ARRAY_COUNT_TYPE *path_idx, struct lyd_node **match);
/**
* @brief Resolve the target defined by ly_path structure. Not supported for leafref!
*
* @param[in] path Path structure specifying the target.
* @param[in] start Starting node for relative paths, can be any for absolute paths.
+ * @param[in] vars Array of defined variables to use in predicates, may be NULL.
* @param[out] match Found matching node, can be NULL, set to NULL if not found.
* @return LY_ENOTFOUND if no nodes were found,
* @return LY_SUCCESS when the last node in the path was found,
* @return LY_ERR on another error.
*/
-LY_ERR ly_path_eval(const struct ly_path *path, const struct lyd_node *start, struct lyd_node **match);
+LY_ERR ly_path_eval(const struct ly_path *path, const struct lyd_node *start, const struct lyxp_var *vars,
+ struct lyd_node **match);
/**
* @brief Duplicate ly_path structure.
@@ -247,11 +249,9 @@
* @brief Free ly_path_predicate structure.
*
* @param[in] ctx libyang context.
- * @param[in] pred_type Predicate type.
* @param[in] predicates Predicates ([sized array](@ref sizedarrays)) to free.
*/
-void ly_path_predicates_free(const struct ly_ctx *ctx, enum ly_path_pred_type pred_type,
- struct ly_path_predicate *predicates);
+void ly_path_predicates_free(const struct ly_ctx *ctx, struct ly_path_predicate *predicates);
/**
* @brief Free ly_path structure.
diff --git a/src/plugins_types/instanceid.c b/src/plugins_types/instanceid.c
index d151d0a..0eef9cc 100644
--- a/src/plugins_types/instanceid.c
+++ b/src/plugins_types/instanceid.c
@@ -84,9 +84,7 @@
LY_ARRAY_FOR(path[u].predicates, v) {
struct ly_path_predicate *pred = &path[u].predicates[v];
- switch (path[u].pred_type) {
- case LY_PATH_PREDTYPE_NONE:
- break;
+ switch (pred->type) {
case LY_PATH_PREDTYPE_POSITION:
/* position predicate */
ret = ly_strcat(&result, "[%" PRIu64 "]", pred->position);
@@ -127,6 +125,10 @@
free((char *)strval);
}
break;
+ case LY_PATH_PREDTYPE_LIST_VAR:
+ LOGINT(path[u].node->module->ctx);
+ ret = LY_EINT;
+ goto cleanup;
}
LY_CHECK_GOTO(ret, cleanup);
@@ -162,7 +164,7 @@
/* compile instance-identifier into path */
if (format == LY_VALUE_LYB) {
- /* The @p value in LYB format is the same as in JSON format. */
+ /* value in LYB format is the same as in JSON format. */
ret = lyplg_type_lypath_new(ctx, value, value_len, options, LY_VALUE_JSON, prefix_data, ctx_node,
unres, &path, err);
} else {
@@ -231,7 +233,7 @@
}
/* find the target in data */
- if ((ret = ly_path_eval(storage->target, tree, NULL))) {
+ if ((ret = ly_path_eval(storage->target, tree, NULL, NULL))) {
value = lyplg_type_print_instanceid(ctx, storage, LY_VALUE_CANON, NULL, NULL, NULL);
path = lyd_path(ctx_node, LYD_PATH_STD, NULL, 0);
return ly_err_new(err, ret, LYVE_DATA, path, strdup("instance-required"), LY_ERRMSG_NOINST, value);
@@ -259,37 +261,43 @@
struct ly_path *s1 = &val1->target[u];
struct ly_path *s2 = &val2->target[u];
- if ((s1->node != s2->node) || (s1->pred_type != s2->pred_type) ||
- (s1->predicates && (LY_ARRAY_COUNT(s1->predicates) != LY_ARRAY_COUNT(s2->predicates)))) {
+ if ((s1->node != s2->node) || (s1->predicates && (LY_ARRAY_COUNT(s1->predicates) != LY_ARRAY_COUNT(s2->predicates)))) {
return LY_ENOT;
}
- if (s1->predicates) {
- LY_ARRAY_FOR(s1->predicates, v) {
- struct ly_path_predicate *pred1 = &s1->predicates[v];
- struct ly_path_predicate *pred2 = &s2->predicates[v];
+ LY_ARRAY_FOR(s1->predicates, v) {
+ struct ly_path_predicate *pred1 = &s1->predicates[v];
+ struct ly_path_predicate *pred2 = &s2->predicates[v];
- switch (s1->pred_type) {
- case LY_PATH_PREDTYPE_NONE:
- break;
- case LY_PATH_PREDTYPE_POSITION:
- /* position predicate */
- if (pred1->position != pred2->position) {
- return LY_ENOT;
- }
- break;
- case LY_PATH_PREDTYPE_LIST:
- /* key-predicate */
- if ((pred1->key != pred2->key) ||
- ((struct lysc_node_leaf *)pred1->key)->type->plugin->compare(&pred1->value, &pred2->value)) {
- return LY_ENOT;
- }
- break;
- case LY_PATH_PREDTYPE_LEAFLIST:
- /* leaf-list predicate */
- if (((struct lysc_node_leaflist *)s1->node)->type->plugin->compare(&pred1->value, &pred2->value)) {
- return LY_ENOT;
- }
+ if (pred1->type != pred2->type) {
+ return LY_ENOT;
+ }
+
+ switch (pred1->type) {
+ case LY_PATH_PREDTYPE_POSITION:
+ /* position predicate */
+ if (pred1->position != pred2->position) {
+ return LY_ENOT;
}
+ break;
+ case LY_PATH_PREDTYPE_LIST:
+ /* key-predicate */
+ if ((pred1->key != pred2->key) ||
+ ((struct lysc_node_leaf *)pred1->key)->type->plugin->compare(&pred1->value, &pred2->value)) {
+ return LY_ENOT;
+ }
+ break;
+ case LY_PATH_PREDTYPE_LEAFLIST:
+ /* leaf-list predicate */
+ if (((struct lysc_node_leaflist *)s1->node)->type->plugin->compare(&pred1->value, &pred2->value)) {
+ return LY_ENOT;
+ }
+ break;
+ case LY_PATH_PREDTYPE_LIST_VAR:
+ /* key-predicate with a variable */
+ if ((pred1->key != pred2->key) || strcmp(pred1->variable, pred2->variable)) {
+ return LY_ENOT;
+ }
+ break;
}
}
}
diff --git a/src/plugins_types/node_instanceid.c b/src/plugins_types/node_instanceid.c
index 04fb164..00cf207 100644
--- a/src/plugins_types/node_instanceid.c
+++ b/src/plugins_types/node_instanceid.c
@@ -90,9 +90,7 @@
LY_ARRAY_FOR(path[u].predicates, v) {
struct ly_path_predicate *pred = &path[u].predicates[v];
- switch (path[u].pred_type) {
- case LY_PATH_PREDTYPE_NONE:
- break;
+ switch (pred->type) {
case LY_PATH_PREDTYPE_POSITION:
/* position predicate */
ret = ly_strcat(&result, "[%" PRIu64 "]", pred->position);
@@ -133,6 +131,16 @@
free((char *)strval);
}
break;
+ case LY_PATH_PREDTYPE_LIST_VAR:
+ /* key-predicate with a variable */
+ if (inherit_prefix) {
+ /* always the same prefix as the parent */
+ ret = ly_strcat(&result, "[%s=$%s]", pred->key->name, pred->variable);
+ } else {
+ ret = ly_strcat(&result, "[%s:%s=$%s]", lyplg_type_get_prefix(pred->key->module, format, prefix_data),
+ pred->key->name, pred->variable);
+ }
+ break;
}
LY_CHECK_GOTO(ret, cleanup);
@@ -193,7 +201,7 @@
ret = ly_path_parse(ctx, ctx_node, value, value_len, 0, LY_PATH_BEGIN_ABSOLUTE, prefix_opt, LY_PATH_PRED_SIMPLE, &exp);
if (ret) {
ret = ly_err_new(err, LY_EVALID, LYVE_DATA, NULL, NULL,
- "Invalid instance-identifier \"%.*s\" value - syntax error.", (int)value_len, (char *)value);
+ "Invalid node-instance-identifier \"%.*s\" value - syntax error.", (int)value_len, (char *)value);
goto cleanup;
}
@@ -209,7 +217,7 @@
LY_VALUE_JSON : format, prefix_data, &path);
if (ret) {
ret = ly_err_new(err, ret, LYVE_DATA, NULL, NULL,
- "Invalid instance-identifier \"%.*s\" value - semantic error.", (int)value_len, (char *)value);
+ "Invalid node-instance-identifier \"%.*s\" value - semantic error.", (int)value_len, (char *)value);
goto cleanup;
}
diff --git a/src/tree_data.c b/src/tree_data.c
index 6c2061d..ecfea86 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1110,11 +1110,9 @@
LIBYANG_API_DEF const struct lyd_node_term *
lyd_target(const struct ly_path *path, const struct lyd_node *tree)
{
- struct lyd_node *target;
+ struct lyd_node *target = NULL;
- if (ly_path_eval(path, tree, &target)) {
- return NULL;
- }
+ lyd_find_target(path, tree, &target);
return (struct lyd_node_term *)target;
}
@@ -2936,7 +2934,7 @@
LY_CHECK_GOTO(ret, cleanup);
/* evaluate the path */
- ret = ly_path_eval_partial(lypath, ctx_node, NULL, match);
+ ret = ly_path_eval_partial(lypath, ctx_node, NULL, NULL, match);
cleanup:
lyxp_expr_free(LYD_CTX(ctx_node), expr);
@@ -2952,7 +2950,7 @@
LY_CHECK_ARG_RET(NULL, path, LY_EINVAL);
- ret = ly_path_eval(path, tree, &m);
+ ret = ly_path_eval(path, tree, NULL, &m);
if (ret) {
if (match) {
*match = NULL;
diff --git a/src/tree_data_common.c b/src/tree_data_common.c
index b39b144..0275ad5 100644
--- a/src/tree_data_common.c
+++ b/src/tree_data_common.c
@@ -220,12 +220,12 @@
return LY_EINVAL;
}
- /* If variable is already defined then change its value. */
- if (*vars && !lyxp_vars_find(*vars, name, 0, &item)) {
+ /* if variable is already defined then change its value */
+ if (*vars && !lyxp_vars_find(NULL, *vars, name, 0, &item)) {
var_value = strdup(value);
LY_CHECK_RET(!var_value, LY_EMEM);
- /* Set new value. */
+ /* update value */
free(item->value);
item->value = var_value;
} else {
@@ -233,7 +233,7 @@
var_value = strdup(value);
LY_CHECK_ERR_GOTO(!var_name || !var_value, ret = LY_EMEM, error);
- /* Add new variable. */
+ /* add new variable */
LY_ARRAY_NEW_GOTO(NULL, *vars, item, ret, error);
item->name = var_name;
item->value = var_value;
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 3cd3d19..40bc562 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -280,11 +280,13 @@
*
* @param[in] schema Schema node of the new data node.
* @param[in] predicates Compiled key list predicates.
+ * @param[in] vars Array of defined variables to use in predicates, may be NULL.
* @param[out] node Created node.
* @return LY_SUCCESS on success.
* @return LY_ERR value if an error occurred.
*/
-LY_ERR lyd_create_list(const struct lysc_node *schema, const struct ly_path_predicate *predicates, struct lyd_node **node);
+LY_ERR lyd_create_list(const struct lysc_node *schema, const struct ly_path_predicate *predicates,
+ const struct lyxp_var *vars, struct lyd_node **node);
/**
* @brief Create a list with all its keys (cannot be used for key-less list).
diff --git a/src/tree_data_new.c b/src/tree_data_new.c
index 864fc9e..d647be3 100644
--- a/src/tree_data_new.c
+++ b/src/tree_data_new.c
@@ -134,10 +134,14 @@
}
LY_ERR
-lyd_create_list(const struct lysc_node *schema, const struct ly_path_predicate *predicates, struct lyd_node **node)
+lyd_create_list(const struct lysc_node *schema, const struct ly_path_predicate *predicates, const struct lyxp_var *vars,
+ struct lyd_node **node)
{
LY_ERR ret = LY_SUCCESS;
struct lyd_node *list = NULL, *key;
+ const struct lyd_value *value;
+ struct lyd_value val = {0};
+ struct lyxp_var *var;
LY_ARRAY_COUNT_TYPE u;
assert((schema->nodetype == LYS_LIST) && !(schema->flags & LYS_KEYLESS));
@@ -149,7 +153,31 @@
/* create and insert all the keys */
LY_ARRAY_FOR(predicates, u) {
- LY_CHECK_GOTO(ret = lyd_create_term2(predicates[u].key, &predicates[u].value, &key), cleanup);
+ if (predicates[u].type == LY_PATH_PREDTYPE_LIST_VAR) {
+ /* find the var */
+ if ((ret = lyxp_vars_find(schema->module->ctx, vars, predicates[u].variable, 0, &var))) {
+ goto cleanup;
+ }
+
+ /* store the value */
+ LOG_LOCSET(predicates[u].key, NULL, NULL, NULL);
+ ret = lyd_value_store(schema->module->ctx, &val, ((struct lysc_node_leaf *)predicates[u].key)->type,
+ var->value, strlen(var->value), NULL, LY_VALUE_JSON, NULL, LYD_HINT_DATA, predicates[u].key, NULL);
+ LOG_LOCBACK(1, 0, 0, 0);
+ LY_CHECK_GOTO(ret, cleanup);
+
+ value = &val;
+ } else {
+ assert(predicates[u].type == LY_PATH_PREDTYPE_LIST);
+ value = &predicates[u].value;
+ }
+
+ ret = lyd_create_term2(predicates[u].key, value, &key);
+ if (val.realtype) {
+ val.realtype->plugin->free(schema->module->ctx, &val);
+ memset(&val, 0, sizeof val);
+ }
+ LY_CHECK_GOTO(ret, cleanup);
lyd_insert_node(list, NULL, key, 0);
}
@@ -172,7 +200,6 @@
LY_ERR ret = LY_SUCCESS;
struct lyxp_expr *expr = NULL;
uint32_t exp_idx = 0;
- enum ly_path_pred_type pred_type = 0;
struct ly_path_predicate *predicates = NULL;
LOG_LOCSET(schema, NULL, NULL, NULL);
@@ -183,15 +210,15 @@
/* compile them */
LY_CHECK_GOTO(ret = ly_path_compile_predicate(schema->module->ctx, NULL, NULL, schema, expr, &exp_idx, LY_VALUE_JSON,
- NULL, &predicates, &pred_type), cleanup);
+ NULL, &predicates), cleanup);
/* create the list node */
- LY_CHECK_GOTO(ret = lyd_create_list(schema, predicates, node), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_list(schema, predicates, NULL, node), cleanup);
cleanup:
LOG_LOCBACK(1, 0, 0, 0);
lyxp_expr_free(schema->module->ctx, expr);
- ly_path_predicates_free(schema->module->ctx, pred_type, predicates);
+ ly_path_predicates_free(schema->module->ctx, predicates);
return ret;
}
@@ -1320,18 +1347,19 @@
schema = path[u].node;
if (lysc_is_dup_inst_list(schema)) {
- if (path[u].pred_type == LY_PATH_PREDTYPE_NONE) {
+ if (!path[u].predicates) {
/* creating a new key-less list or state leaf-list instance */
create = 1;
new_count = u;
- } else if (path[u].pred_type != LY_PATH_PREDTYPE_POSITION) {
+ } else if (path[u].predicates[0].type != LY_PATH_PREDTYPE_POSITION) {
LOG_LOCSET(schema, NULL, NULL, NULL);
LOGVAL(schema->module->ctx, LYVE_XPATH, "Invalid predicate for %s \"%s\" in path \"%s\".",
lys_nodetype2str(schema->nodetype), schema->name, str_path);
LOG_LOCBACK(1, 0, 0, 0);
return LY_EINVAL;
}
- } else if ((schema->nodetype == LYS_LIST) && (path[u].pred_type != LY_PATH_PREDTYPE_LIST)) {
+ } else if ((schema->nodetype == LYS_LIST) &&
+ (!path[u].predicates || (path[u].predicates[0].type != LY_PATH_PREDTYPE_LIST))) {
if ((u < LY_ARRAY_COUNT(path) - 1) || !(options & LYD_NEW_PATH_OPAQ)) {
LOG_LOCSET(schema, NULL, NULL, NULL);
LOGVAL(schema->module->ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path \"%s\".",
@@ -1339,7 +1367,8 @@
LOG_LOCBACK(1, 0, 0, 0);
return LY_EINVAL;
} /* else creating an opaque list */
- } else if ((schema->nodetype == LYS_LEAFLIST) && (path[u].pred_type != LY_PATH_PREDTYPE_LEAFLIST)) {
+ } else if ((schema->nodetype == LYS_LEAFLIST) &&
+ (!path[u].predicates || (path[u].predicates[0].type != LY_PATH_PREDTYPE_LEAFLIST))) {
r = LY_SUCCESS;
if (options & LYD_NEW_PATH_OPAQ) {
r = lyd_value_validate(NULL, schema, value, value_len, NULL, NULL, NULL);
@@ -1351,8 +1380,8 @@
++((struct lysc_type *)val.realtype)->refcount;
/* store the new predicate so that it is used when searching for this instance */
- path[u].pred_type = LY_PATH_PREDTYPE_LEAFLIST;
LY_ARRAY_NEW_RET(schema->module->ctx, path[u].predicates, pred, LY_EMEM);
+ pred->type = LY_PATH_PREDTYPE_LEAFLIST;
pred->value = val;
} /* else we have opaq flag and the value is not valid, leave no predicate and then create an opaque node */
}
@@ -1442,7 +1471,7 @@
/* try to find any existing nodes in the path */
if (parent) {
- ret = ly_path_eval_partial(p, parent, &path_idx, &node);
+ ret = ly_path_eval_partial(p, parent, NULL, &path_idx, &node);
if (ret == LY_SUCCESS) {
if (orig_count == LY_ARRAY_COUNT(p)) {
/* the node exists, are we supposed to update it or is it just a default? */
@@ -1487,15 +1516,14 @@
if (lysc_is_dup_inst_list(schema)) {
/* create key-less list instance */
LY_CHECK_GOTO(ret = lyd_create_inner(schema, &node), cleanup);
- } else if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type == LY_PATH_PREDTYPE_NONE)) {
+ } else if ((options & LYD_NEW_PATH_OPAQ) && !p[path_idx].predicates) {
/* creating opaque list without keys */
LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
schema->module->name, strlen(schema->module->name), NULL, 0, NULL, LY_VALUE_JSON, NULL,
LYD_NODEHINT_LIST, &node), cleanup);
} else {
/* create standard list instance */
- assert(p[path_idx].pred_type == LY_PATH_PREDTYPE_LIST);
- LY_CHECK_GOTO(ret = lyd_create_list(schema, p[path_idx].predicates, &node), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_list(schema, p[path_idx].predicates, NULL, &node), cleanup);
}
break;
case LYS_CONTAINER:
@@ -1505,7 +1533,8 @@
LY_CHECK_GOTO(ret = lyd_create_inner(schema, &node), cleanup);
break;
case LYS_LEAFLIST:
- if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type != LY_PATH_PREDTYPE_LEAFLIST)) {
+ if ((options & LYD_NEW_PATH_OPAQ) &&
+ (!p[path_idx].predicates || (p[path_idx].predicates[0].type != LY_PATH_PREDTYPE_LEAFLIST))) {
/* we have not checked this only for dup-inst lists, otherwise it must be opaque */
r = LY_EVALID;
if (lysc_is_dup_inst_list(schema)) {
@@ -1522,13 +1551,13 @@
}
/* get value to set */
- if (p[path_idx].pred_type == LY_PATH_PREDTYPE_LEAFLIST) {
+ if (p[path_idx].predicates && (p[path_idx].predicates[0].type == LY_PATH_PREDTYPE_LEAFLIST)) {
val = &p[path_idx].predicates[0].value;
}
/* create a leaf-list instance */
if (val) {
- LY_CHECK_GOTO(ret = lyd_create_term2(schema, &p[path_idx].predicates[0].value, &node), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_term2(schema, val, &node), cleanup);
} else {
LY_CHECK_GOTO(ret = lyd_create_term(schema, value, value_len, NULL, format, NULL, LYD_HINT_DATA,
NULL, &node), cleanup);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 3ec4574..26b7c11 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -600,8 +600,8 @@
LY_ARRAY_FOR(path, u) {
/* add nodes from the path */
LY_CHECK_GOTO(ret = ly_set_add(*set, (void *)path[u].node, 0, NULL), cleanup);
- if (path[u].pred_type == LY_PATH_PREDTYPE_LIST) {
- LY_ARRAY_FOR(path[u].predicates, v) {
+ LY_ARRAY_FOR(path[u].predicates, v) {
+ if ((path[u].predicates[v].type == LY_PATH_PREDTYPE_LIST) || (path[u].predicates[v].type == LY_PATH_PREDTYPE_LIST_VAR)) {
/* add all the keys in a predicate */
LY_CHECK_GOTO(ret = ly_set_add(*set, (void *)path[u].predicates[v].key, 0, NULL), cleanup);
}
diff --git a/src/xpath.c b/src/xpath.c
index b83e1cc..77d6c6c 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -4030,7 +4030,7 @@
}
} else {
assert(sleaf->type->basetype == LY_TYPE_INST);
- if (ly_path_eval(leaf->value.target, set->tree, &node)) {
+ if (ly_path_eval(leaf->value.target, set->tree, NULL, &node)) {
LOGERR(set->ctx, LY_EVALID, "Invalid instance-identifier \"%s\" value - required instance not found.",
lyd_get_value(&leaf->node));
return LY_EVALID;
@@ -6144,7 +6144,7 @@
/* create specific data instance if needed */
if (scnode->nodetype == LYS_LIST) {
- LY_CHECK_GOTO(ret = lyd_create_list(scnode, predicates, &inst), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_list(scnode, predicates, NULL, &inst), cleanup);
} else if (scnode->nodetype == LYS_LEAFLIST) {
LY_CHECK_GOTO(ret = lyd_create_term2(scnode, &predicates[0].value, &inst), cleanup);
}
@@ -7705,14 +7705,13 @@
* @param[in] ctx_scnode Found schema node as the context for the predicate.
* @param[in] set Context set.
* @param[out] predicates Parsed predicates.
- * @param[out] pred_type Type of @p predicates.
* @return LY_SUCCESS on success,
* @return LY_ENOT if a predicate could not be compiled.
* @return LY_ERR on any error.
*/
static LY_ERR
eval_name_test_try_compile_predicates(const struct lyxp_expr *exp, uint32_t *tok_idx, const struct lysc_node *ctx_scnode,
- const struct lyxp_set *set, struct ly_path_predicate **predicates, enum ly_path_pred_type *pred_type)
+ const struct lyxp_set *set, struct ly_path_predicate **predicates)
{
LY_ERR rc = LY_SUCCESS;
uint32_t e_idx, val_start_idx, pred_idx = 0, temp_lo = 0, pred_len = 0, nested_pred;
@@ -7851,7 +7850,7 @@
/* compile */
rc = ly_path_compile_predicate(set->ctx, set->cur_node ? set->cur_node->schema : NULL, set->cur_mod, ctx_scnode, exp2,
- &pred_idx, LY_VALUE_JSON, NULL, predicates, pred_type);
+ &pred_idx, LY_VALUE_JSON, NULL, predicates);
LY_CHECK_GOTO(rc, cleanup);
/* success, the predicate must include all the needed information for hash-based search */
@@ -8021,7 +8020,6 @@
const struct lys_module *moveto_mod = NULL;
const struct lysc_node *scnode = NULL;
struct ly_path_predicate *predicates = NULL;
- enum ly_path_pred_type pred_type = 0;
int scnode_skip_pred = 0;
LOGDBG(LY_LDGXPATH, "%-27s %s %s[%u]", __func__, (options & LYXP_SKIP_EXPR ? "skipped" : "parsed"),
@@ -8063,7 +8061,7 @@
if (scnode && (scnode->nodetype & (LYS_LIST | LYS_LEAFLIST))) {
/* try to create the predicates */
- if (eval_name_test_try_compile_predicates(exp, tok_idx, scnode, set, &predicates, &pred_type)) {
+ if (eval_name_test_try_compile_predicates(exp, tok_idx, scnode, set, &predicates)) {
/* hashes cannot be used */
scnode = NULL;
}
@@ -8180,7 +8178,7 @@
}
if (!(options & LYXP_SKIP_EXPR)) {
lydict_remove(set->ctx, ncname_dict);
- ly_path_predicates_free(set->ctx, pred_type, predicates);
+ ly_path_predicates_free(set->ctx, predicates);
}
return rc;
}
@@ -8701,27 +8699,30 @@
}
LY_ERR
-lyxp_vars_find(struct lyxp_var *vars, const char *name, size_t name_len, struct lyxp_var **var)
+lyxp_vars_find(const struct ly_ctx *ctx, const struct lyxp_var *vars, const char *name, size_t name_len,
+ struct lyxp_var **var)
{
- LY_ERR ret = LY_ENOTFOUND;
LY_ARRAY_COUNT_TYPE u;
- assert(vars && name);
+ assert(name);
- name_len = name_len ? name_len : strlen(name);
+ if (!name_len) {
+ name_len = strlen(name);
+ }
LY_ARRAY_FOR(vars, u) {
if (!strncmp(vars[u].name, name, name_len)) {
- ret = LY_SUCCESS;
- break;
+ if (var) {
+ *var = (struct lyxp_var *)&vars[u];
+ }
+ return LY_SUCCESS;
}
}
- if (var && !ret) {
- *var = &vars[u];
+ if (ctx) {
+ LOGERR(ctx, LY_ENOTFOUND, "Variable \"%.*s\" not defined.", (int)name_len, name);
}
-
- return ret;
+ return LY_ENOTFOUND;
}
/**
@@ -8740,17 +8741,14 @@
LY_ERR ret;
const char *name;
struct lyxp_var *var;
- const struct lyxp_var *vars;
struct lyxp_expr *tokens = NULL;
uint32_t token_index, name_len;
- vars = set->vars;
-
/* find out the name and value of the variable */
name = &exp->expr[exp->tok_pos[*tok_idx]];
name_len = exp->tok_len[*tok_idx];
- ret = lyxp_vars_find((struct lyxp_var *)vars, name, name_len, &var);
- LY_CHECK_ERR_RET(ret, LOGERR(set->ctx, ret, "XPath variable \"%.*s\" not defined.", (int)name_len, name), ret);
+ ret = lyxp_vars_find(set->ctx, set->vars, name, name_len, &var);
+ LY_CHECK_RET(ret);
/* parse value */
ret = lyxp_expr_parse(set->ctx, var->value, 0, 1, &tokens);
diff --git a/src/xpath.h b/src/xpath.h
index c34a0f3..803de7d 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -497,15 +497,17 @@
enum lyxp_token want_tok1, enum lyxp_token want_tok2);
/**
- * @brief Find variable named @name in @p vars.
+ * @brief Find variable named @p name in @p vars.
*
+ * @param[in] ctx Context for logging, not logged if NULL.
* @param[in] vars [Sized array](@ref sizedarrays) of XPath variables.
* @param[in] name Name of the variable being searched.
* @param[in] name_len Name length can be set to 0 if @p name is terminated by null byte.
* @param[out] var Variable that was found. The parameter is optional.
* @return LY_SUCCESS if the variable was found, otherwise LY_ENOTFOUND.
*/
-LY_ERR lyxp_vars_find(struct lyxp_var *vars, const char *name, size_t name_len, struct lyxp_var **var);
+LY_ERR lyxp_vars_find(const struct ly_ctx *ctx, const struct lyxp_var *vars, const char *name, size_t name_len,
+ struct lyxp_var **var);
/**
* @brief Frees a parsed XPath expression. @p expr should not be used afterwards.
diff --git a/tests/utests/basic/test_xpath.c b/tests/utests/basic/test_xpath.c
index d28de43..985ecc2 100644
--- a/tests/utests/basic/test_xpath.c
+++ b/tests/utests/basic/test_xpath.c
@@ -900,7 +900,7 @@
LOCAL_SETUP(data, tree);
assert_int_equal(LY_SUCCESS, lyxp_vars_set(&vars, "var1", "\"mstr\""));
assert_int_equal(LY_ENOTFOUND, lyd_find_xpath2(tree, "/foo[text() = $var55]", vars, &set));
- CHECK_LOG_CTX("XPath variable \"var55\" not defined.", NULL);
+ CHECK_LOG_CTX("Variable \"var55\" not defined.", NULL);
LOCAL_TEARDOWN(set, tree, vars);
/* Syntax error in value. */
diff --git a/tests/utests/types/instanceid.c b/tests/utests/types/instanceid.c
index 4c46b64..b41e13e 100644
--- a/tests/utests/types/instanceid.c
+++ b/tests/utests/types/instanceid.c
@@ -79,12 +79,12 @@
test_data_xml(void **state)
{
const char *schema, *schema2;
- const enum ly_path_pred_type val1[] = {LY_PATH_PREDTYPE_NONE, LY_PATH_PREDTYPE_NONE};
- const enum ly_path_pred_type val2[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
+ const enum ly_path_pred_type val1[] = {0, 0};
+ const enum ly_path_pred_type val2[] = {LY_PATH_PREDTYPE_LIST, 0};
const enum ly_path_pred_type val3[] = {LY_PATH_PREDTYPE_LEAFLIST};
- const enum ly_path_pred_type val4[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
- const enum ly_path_pred_type val5[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
- const enum ly_path_pred_type val6[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
+ const enum ly_path_pred_type val4[] = {LY_PATH_PREDTYPE_LIST, 0};
+ const enum ly_path_pred_type val5[] = {LY_PATH_PREDTYPE_LIST, 0};
+ const enum ly_path_pred_type val6[] = {LY_PATH_PREDTYPE_LIST, 0};
/* xml test */
schema = MODULE_CREATE_YANG("mod", "container cont {leaf l2 {type empty;}}");
diff --git a/tests/utests/utests.h b/tests/utests/utests.h
index c2e7733..0e0649d 100644
--- a/tests/utests/utests.h
+++ b/tests/utests/utests.h
@@ -1010,7 +1010,9 @@
LY_ARRAY_COUNT_TYPE arr_size = sizeof(VALUE) / sizeof(VALUE[0]); \
assert_int_equal(arr_size, LY_ARRAY_COUNT((NODE).target)); \
for (LY_ARRAY_COUNT_TYPE it = 0; it < arr_size; it++) { \
- assert_int_equal(VALUE[it], (NODE).target[it].pred_type); \
+ if ((NODE).target[it].predicates) { \
+ assert_int_equal(VALUE[it], (NODE).target[it].predicates[0].type); \
+ } \
} \
}