xpath BUGFIX pass xcontext explicitly
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 3c403f1..bea306e 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -1919,7 +1919,8 @@
int rc;
/* find all target data instances */
- ret = lyxp_eval(lref->path, lref->cur_mod, LY_PREF_SCHEMA_RESOLVED, lref->prefixes, node, tree, &set, 0);
+ ret = lyxp_eval(lref->cur_mod->ctx, lref->path, lref->cur_mod, LY_PREF_SCHEMA_RESOLVED, lref->prefixes, node, tree,
+ &set, 0);
if (ret) {
ret = LY_ENOTFOUND;
val_str = lref->plugin->print(value, LY_PREF_JSON, NULL, &dynamic);
diff --git a/src/schema_compile.c b/src/schema_compile.c
index f7ce1f8..c35aaca 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -798,8 +798,8 @@
LOG_LOCSET(node, NULL, NULL, NULL);
LY_ARRAY_FOR(node->when, u) {
when = node->when[u];
- ret = lyxp_atomize(when->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when->prefixes, when->context,
- &tmp_set, LYXP_SCNODE_SCHEMA);
+ ret = lyxp_atomize(set->ctx, when->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when->prefixes,
+ when->context, &tmp_set, LYXP_SCNODE_SCHEMA);
if (ret != LY_SUCCESS) {
LOGVAL(set->ctx, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when->cond->expr);
goto cleanup;
@@ -997,8 +997,8 @@
}
/* check "when" */
- ret = lyxp_atomize(when[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes, when[u]->context,
- &tmp_set, opts);
+ ret = lyxp_atomize(ctx->ctx, when[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes,
+ when[u]->context, &tmp_set, opts);
if (ret) {
LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when[u]->cond->expr);
goto cleanup;
@@ -1047,7 +1047,8 @@
}
/* check "must" */
- ret = lyxp_atomize(musts[u].cond, node->module, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes, node, &tmp_set, opts);
+ ret = lyxp_atomize(ctx->ctx, musts[u].cond, node->module, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes, node,
+ &tmp_set, opts);
if (ret) {
LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid must restriction \"%s\".", musts[u].cond->expr);
goto cleanup;
diff --git a/src/tree_data.c b/src/tree_data.c
index 8eee401..0aa1063 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -3491,7 +3491,7 @@
LY_CHECK_GOTO(ret, cleanup);
/* evaluate expression */
- ret = lyxp_eval(exp, NULL, LY_PREF_JSON, NULL, ctx_node, ctx_node, &xp_set, LYXP_IGNORE_WHEN);
+ ret = lyxp_eval(LYD_CTX(ctx_node), exp, NULL, LY_PREF_JSON, NULL, ctx_node, ctx_node, &xp_set, LYXP_IGNORE_WHEN);
LY_CHECK_GOTO(ret, cleanup);
/* allocate return set */
diff --git a/src/tree_schema.c b/src/tree_schema.c
index b3b6582..1c5cd3b 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -333,7 +333,7 @@
LY_CHECK_GOTO(ret, cleanup);
/* atomize expression */
- ret = lyxp_atomize(exp, NULL, LY_PREF_JSON, NULL, ctx_node, &xp_set, options);
+ ret = lyxp_atomize(ctx, exp, NULL, LY_PREF_JSON, NULL, ctx_node, &xp_set, options);
LY_CHECK_GOTO(ret, cleanup);
/* allocate return set */
@@ -372,7 +372,7 @@
}
/* atomize expression */
- ret = lyxp_atomize(expr, cur_mod, LY_PREF_SCHEMA_RESOLVED, (void *)prefixes, ctx_node, &xp_set, options);
+ ret = lyxp_atomize(cur_mod->ctx, expr, cur_mod, LY_PREF_SCHEMA_RESOLVED, (void *)prefixes, ctx_node, &xp_set, options);
LY_CHECK_GOTO(ret, cleanup);
/* allocate return set */
@@ -409,7 +409,6 @@
LY_ERR ret = LY_SUCCESS;
struct lyxp_set xp_set = {0};
struct lyxp_expr *exp = NULL;
- const struct lys_module *yanglib_mod;
uint32_t i;
LY_CHECK_ARG_RET(NULL, ctx || ctx_node, xpath, set, LY_EINVAL);
@@ -419,18 +418,13 @@
if (!ctx) {
ctx = ctx_node->module->ctx;
}
- if (!ctx_node) {
- yanglib_mod = ctx->list.objs[5];
- assert(!strcmp(yanglib_mod->name, "ietf-yang-library"));
- ctx_node = yanglib_mod->compiled->data;
- }
/* compile expression */
ret = lyxp_expr_parse(ctx, xpath, 0, 1, &exp);
LY_CHECK_GOTO(ret, cleanup);
/* atomize expression */
- ret = lyxp_atomize(exp, NULL, LY_PREF_JSON, NULL, ctx_node, &xp_set, options);
+ ret = lyxp_atomize(ctx, exp, NULL, LY_PREF_JSON, NULL, ctx_node, &xp_set, options);
LY_CHECK_GOTO(ret, cleanup);
/* allocate return set */
diff --git a/src/validation.c b/src/validation.c
index 20894f8..b9b8570 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -128,8 +128,8 @@
/* evaluate when */
memset(&xp_set, 0, sizeof xp_set);
- ret = lyxp_eval(when->cond, schema->module, LY_PREF_SCHEMA_RESOLVED, when->prefixes, ctx_node, tree,
- &xp_set, LYXP_SCHEMA);
+ ret = lyxp_eval(LYD_CTX(node), when->cond, schema->module, LY_PREF_SCHEMA_RESOLVED, when->prefixes,
+ ctx_node, tree, &xp_set, LYXP_SCHEMA);
lyxp_set_cast(&xp_set, LYXP_SET_BOOLEAN);
/* return error or LY_EINCOMPLETE for dependant unresolved when */
@@ -1211,8 +1211,8 @@
memset(&xp_set, 0, sizeof xp_set);
/* evaluate must */
- LY_CHECK_RET(lyxp_eval(musts[u].cond, node->schema->module, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes, node,
- tree, &xp_set, LYXP_SCHEMA));
+ LY_CHECK_RET(lyxp_eval(LYD_CTX(node), musts[u].cond, node->schema->module, LY_PREF_SCHEMA_RESOLVED,
+ musts[u].prefixes, node, tree, &xp_set, LYXP_SCHEMA));
/* check the result */
lyxp_set_cast(&xp_set, LYXP_SET_BOOLEAN);
diff --git a/src/xpath.c b/src/xpath.c
index 2e2e314..0002ac9 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -8453,13 +8453,14 @@
}
LY_ERR
-lyxp_eval(const struct lyxp_expr *exp, const struct lys_module *cur_mod, LY_PREFIX_FORMAT format, void *prefix_data,
- const struct lyd_node *ctx_node, const struct lyd_node *tree, struct lyxp_set *set, uint32_t options)
+lyxp_eval(const struct ly_ctx *ctx, const struct lyxp_expr *exp, const struct lys_module *cur_mod,
+ LY_PREFIX_FORMAT format, void *prefix_data, const struct lyd_node *ctx_node, const struct lyd_node *tree,
+ struct lyxp_set *set, uint32_t options)
{
uint16_t tok_idx = 0;
LY_ERR rc;
- LY_CHECK_ARG_RET(NULL, exp, set, LY_EINVAL);
+ LY_CHECK_ARG_RET(ctx, ctx, exp, set, LY_EINVAL);
if (!cur_mod && ((format == LY_PREF_SCHEMA) || (format == LY_PREF_SCHEMA_RESOLVED))) {
LOGARG(NULL, "Current module must be set if schema format is used.");
return LY_EINVAL;
@@ -8479,7 +8480,7 @@
set->root_type = lyxp_get_root_type(ctx_node, NULL, options);
set_insert_node(set, (struct lyd_node *)ctx_node, 0, ctx_node ? LYXP_NODE_ELEM : set->root_type, 0);
- set->ctx = (struct ly_ctx *)(cur_mod ? cur_mod->ctx : (ctx_node ? LYD_CTX(ctx_node) : (tree ? LYD_CTX(tree) : NULL)));
+ set->ctx = (struct ly_ctx *)ctx;
set->cur_node = ctx_node;
for (set->context_op = ctx_node ? ctx_node->schema : NULL;
set->context_op && !(set->context_op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF));
@@ -8730,13 +8731,14 @@
}
LY_ERR
-lyxp_atomize(const struct lyxp_expr *exp, const struct lys_module *cur_mod, LY_PREFIX_FORMAT format, void *prefix_data,
- const struct lysc_node *ctx_scnode, struct lyxp_set *set, uint32_t options)
+lyxp_atomize(const struct ly_ctx *ctx, const struct lyxp_expr *exp, const struct lys_module *cur_mod,
+ LY_PREFIX_FORMAT format, void *prefix_data, const struct lysc_node *ctx_scnode, struct lyxp_set *set,
+ uint32_t options)
{
LY_ERR ret;
uint16_t tok_idx = 0;
- LY_CHECK_ARG_RET(NULL, exp, set, LY_EINVAL);
+ LY_CHECK_ARG_RET(ctx, ctx, exp, set, LY_EINVAL);
if (!cur_mod && ((format == LY_PREF_SCHEMA) || (format == LY_PREF_SCHEMA_RESOLVED))) {
LOGARG(NULL, "Current module must be set if schema format is used.");
return LY_EINVAL;
@@ -8749,7 +8751,7 @@
LY_CHECK_RET(lyxp_set_scnode_insert_node(set, ctx_scnode, ctx_scnode ? LYXP_NODE_ELEM : set->root_type, NULL));
set->val.scnodes[0].in_ctx = LYXP_SET_SCNODE_START;
- set->ctx = cur_mod ? cur_mod->ctx : (ctx_scnode ? ctx_scnode->module->ctx : NULL);
+ set->ctx = (struct ly_ctx *)ctx;
set->cur_scnode = ctx_scnode;
for (set->context_op = ctx_scnode;
set->context_op && !(set->context_op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF));
diff --git a/src/xpath.h b/src/xpath.h
index 8278fb8..4f13699 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -279,6 +279,7 @@
* @brief Evaluate an XPath expression on data. Be careful when using this function, the result can often
* be confusing without thorough understanding of XPath evaluation rules defined in RFC 7950.
*
+ * @param[in] ctx libyang context to use.
* @param[in] exp Parsed XPath expression to be evaluated.
* @param[in] cur_mod Current module for the expression (where it was "instantiated").
* @param[in] format Format of the XPath expression (more specifcally, of any used prefixes).
@@ -292,12 +293,14 @@
* @return LY_EINCOMPLETE for unresolved when,
* @return LY_EINVAL, LY_EMEM, LY_EINT for other errors.
*/
-LY_ERR lyxp_eval(const struct lyxp_expr *exp, const struct lys_module *cur_mod, LY_PREFIX_FORMAT format, void *prefix_data,
- const struct lyd_node *ctx_node, const struct lyd_node *tree, struct lyxp_set *set, uint32_t options);
+LY_ERR lyxp_eval(const struct ly_ctx *ctx, const struct lyxp_expr *exp, const struct lys_module *cur_mod,
+ LY_PREFIX_FORMAT format, void *prefix_data, const struct lyd_node *ctx_node, const struct lyd_node *tree,
+ struct lyxp_set *set, uint32_t options);
/**
* @brief Get all the partial XPath nodes (atoms) that are required for @p exp to be evaluated.
*
+ * @param[in] ctx libyang context to use.
* @param[in] exp Parsed XPath expression to be evaluated.
* @param[in] cur_mod Current module for the expression (where it was "instantiated").
* @param[in] format Format of the XPath expression (more specifcally, of any used prefixes).
@@ -307,8 +310,9 @@
* @param[in] options Whether to apply some evaluation restrictions, one flag must always be used.
* @return LY_ERR (same as ::lyxp_eval()).
*/
-LY_ERR lyxp_atomize(const struct lyxp_expr *exp, const struct lys_module *cur_mod, LY_PREFIX_FORMAT format, void *prefix_data,
- const struct lysc_node *ctx_scnode, struct lyxp_set *set, uint32_t options);
+LY_ERR lyxp_atomize(const struct ly_ctx *ctx, const struct lyxp_expr *exp, const struct lys_module *cur_mod,
+ LY_PREFIX_FORMAT format, void *prefix_data, const struct lysc_node *ctx_scnode, struct lyxp_set *set,
+ uint32_t options);
/* used only internally, maps with @ref findxpathoptions */
#define LYXP_IGNORE_WHEN 0x01 /**< Ignore unevaluated when in data nodes and do not return ::LY_EINCOMPLETE. */
diff --git a/tests/utests/basic/test_xpath.c b/tests/utests/basic/test_xpath.c
index 0da6f7b..8be1fbf 100644
--- a/tests/utests/basic/test_xpath.c
+++ b/tests/utests/basic/test_xpath.c
@@ -299,20 +299,19 @@
assert_non_null(mod);
/* some random paths just making sure the API function works */
- assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(NULL, mod->compiled->data, "/a:*", 0, &set));
+ assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:*", 0, &set));
assert_int_equal(4, set->count);
ly_set_free(set, NULL);
/* all nodes from all modules (including internal, which can change easily, so check just the test modules) */
- assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(NULL, mod->compiled->data, "//.", 0, &set));
+ assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "//.", 0, &set));
assert_in_range(set->count, 16, UINT32_MAX);
ly_set_free(set, NULL);
- assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(NULL, mod->compiled->data->next->next, "/a:c/ll[a='val1']/ll[a='val2']/b",
- 0, &set));
- assert_int_equal(7, set->count);
+ assert_int_equal(LY_SUCCESS, lys_find_xpath_atoms(UTEST_LYCTX, NULL, "/a:c/ll[a='val1']/ll[a='val2']/b", 0, &set));
+ assert_int_equal(6, set->count);
ly_set_free(set, NULL);
}