schema CHANGE support extension instance top-level in ly_path_compile()
For further support of serching schema nodes in extension instance
instead of the standard module tree, we need to extend internal
ly_path_compile().
diff --git a/src/path.c b/src/path.c
index 778beda..209e460 100644
--- a/src/path.c
+++ b/src/path.c
@@ -782,8 +782,8 @@
LY_ERR
ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *ctx_node,
- const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target, LY_PREFIX_FORMAT format,
- void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path)
+ const struct lysc_ext_instance *ext, const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target,
+ LY_PREFIX_FORMAT format, void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path)
{
LY_ERR ret = LY_SUCCESS;
uint16_t tok_idx = 0;
@@ -861,7 +861,11 @@
++tok_idx;
/* find the next node */
- node2 = lys_find_child(ctx_node, mod, name, name_len, 0, getnext_opts);
+ if (!ctx_node && ext) {
+ node2 = lysc_ext_find_node(ext, mod, name, name_len, 0, getnext_opts);
+ } else {
+ node2 = lys_find_child(ctx_node, mod, name, name_len, 0, getnext_opts);
+ }
if (!node2 || (op && (node2->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && (node2 != op))) {
LOGVAL(ctx, LYVE_XPATH, "Not found node \"%.*s\" in path.", (int)name_len, name);
ret = LY_EVALID;
diff --git a/src/path.h b/src/path.h
index a6e8149..9074191 100644
--- a/src/path.h
+++ b/src/path.h
@@ -149,6 +149,9 @@
* @param[in] cur_mod Current module of the path (where it was "instantiated"). Used for nodes without a prefix
* for ::LY_PREF_SCHEMA* format.
* @param[in] ctx_node Optional context node.
+ * @param[in] ext Extension instance containing the definition of the data being created. It is used to find the top-level
+ * node inside the extension instance instead of a module. Note that this is the case not only if the @p ctx_node is NULL,
+ * but also if the relative path starting in @p ctx_node reaches the document root via double dots.
* @param[in] expr Parsed path.
* @param[in] lref Lref option (@ref path_lref_options).
* @param[in] oper Oper option (@ref path_oper_options).
@@ -160,8 +163,8 @@
* @return LY_ERR value.
*/
LY_ERR ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *ctx_node,
- const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target, LY_PREFIX_FORMAT format,
- void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path);
+ const struct lysc_ext_instance *ext, const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target,
+ LY_PREFIX_FORMAT format, void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path);
/**
* @brief Compile predicate into ly_path_predicate structure. Only simple predicates (not leafref) are supported.
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 204b85e..9559608 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -1706,7 +1706,7 @@
}
/* resolve it on schema tree */
- ret = ly_path_compile(ctx, NULL, ctx_node, exp, LY_PATH_LREF_FALSE, (ctx_node->flags & LYS_IS_OUTPUT) ?
+ ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, LY_PATH_LREF_FALSE, (ctx_node->flags & LYS_IS_OUTPUT) ?
LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_SINGLE, format, prefix_data, unres, &path);
if (ret) {
*err = ly_err_msg_create(&ret, LYVE_DATA, NULL, NULL, "Invalid instance-identifier \"%.*s\" value - semantic error.", (int)value_len, value);
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 6d9c606..e98e4f7 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1018,7 +1018,7 @@
assert(node->nodetype & (LYS_LEAF | LYS_LEAFLIST));
/* try to find the target */
- LY_CHECK_RET(ly_path_compile(ctx->ctx, lref->cur_mod, node, lref->path, LY_PATH_LREF_TRUE,
+ LY_CHECK_RET(ly_path_compile(ctx->ctx, lref->cur_mod, node, NULL, lref->path, LY_PATH_LREF_TRUE,
(node->flags & LYS_IS_OUTPUT) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_MANY,
LY_PREF_SCHEMA_RESOLVED, lref->prefixes, unres, &p));
diff --git a/src/tree_data.c b/src/tree_data.c
index e94d8d5..0902b31 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1645,7 +1645,7 @@
LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_SIMPLE, &exp), cleanup);
/* compile path */
- LY_CHECK_GOTO(ret = ly_path_compile(ctx, NULL, parent ? parent->schema : NULL, exp, LY_PATH_LREF_FALSE,
+ LY_CHECK_GOTO(ret = ly_path_compile(ctx, NULL, parent ? parent->schema : NULL, NULL, exp, LY_PATH_LREF_FALSE,
options & LYD_NEW_PATH_OUTPUT ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_MANY, LY_PREF_JSON,
NULL, NULL, &p), cleanup);
@@ -3896,7 +3896,7 @@
LY_CHECK_GOTO(ret, cleanup);
/* compile the path */
- ret = ly_path_compile(LYD_CTX(ctx_node), NULL, ctx_node->schema, expr, LY_PATH_LREF_FALSE,
+ ret = ly_path_compile(LYD_CTX(ctx_node), NULL, ctx_node->schema, NULL, expr, LY_PATH_LREF_FALSE,
output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_SINGLE, LY_PREF_JSON,
(void *)LYD_CTX(ctx_node), NULL, &lypath);
LY_CHECK_GOTO(ret, cleanup);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index f6ee17d..67e4804 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -665,7 +665,7 @@
/* compile */
oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
- ret = ly_path_compile(ctx, NULL, ctx_node, expr, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
+ ret = ly_path_compile(ctx, NULL, ctx_node, NULL, expr, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
LY_PREF_JSON, NULL, NULL, &p);
LY_CHECK_GOTO(ret, cleanup);
@@ -699,7 +699,7 @@
/* compile */
oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
- ret = ly_path_compile(ctx, NULL, ctx_node, exp, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
+ ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
LY_PREF_JSON, NULL, NULL, &p);
LY_CHECK_GOTO(ret, cleanup);
diff --git a/src/xpath.c b/src/xpath.c
index d05107f..6846ef7 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -3714,7 +3714,7 @@
oper = (sleaf->flags & LYS_IS_OUTPUT) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
/* it was already evaluated on schema, it must succeed */
- rc = ly_path_compile(set->ctx, lref->cur_mod, &sleaf->node, lref->path, LY_PATH_LREF_TRUE, oper,
+ rc = ly_path_compile(set->ctx, lref->cur_mod, &sleaf->node, NULL, lref->path, LY_PATH_LREF_TRUE, oper,
LY_PATH_TARGET_MANY, LY_PREF_SCHEMA_RESOLVED, lref->prefixes, NULL, &p);
assert(!rc);
diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c
index 1aab6fc..00cc266 100644
--- a/tests/utests/data/test_tree_data.c
+++ b/tests/utests/data/test_tree_data.c
@@ -227,7 +227,7 @@
CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
assert_int_equal(LY_SUCCESS, ly_path_parse(UTEST_LYCTX, NULL, path_str, strlen(path_str), LY_PATH_BEGIN_EITHER, LY_PATH_LREF_FALSE,
LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_SIMPLE, &exp));
- assert_int_equal(LY_SUCCESS, ly_path_compile(UTEST_LYCTX, NULL, NULL, exp, LY_PATH_LREF_FALSE, LY_PATH_OPER_INPUT,
+ assert_int_equal(LY_SUCCESS, ly_path_compile(UTEST_LYCTX, NULL, NULL, NULL, exp, LY_PATH_LREF_FALSE, LY_PATH_OPER_INPUT,
LY_PATH_TARGET_SINGLE, LY_PREF_JSON, NULL, NULL, &path));
term = lyd_target(path, tree);