schema tree: CHANGE: resolve_nodeid special augment, uses, choice treatment
diff --git a/src/tree.c b/src/tree.c
index 7937f42..515a481 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -260,9 +260,14 @@
/*
* id - schema-nodeid
+ *
+ * node_type - LY_NODE_AUGMENT (searches also RPCs and notifications)
+ * - LY_NODE_USES (the caller is actually either an augment or refine in a uses, only
+ * descendant-schema-nodeid allowed, ".." not allowed)
+ * - LY_NODE_CHOICE (search only start->child, only descendant-schema-nodeid allowed)
*/
struct ly_mnode *
-resolve_schema_nodeid(const char *id, struct ly_mnode *start, struct ly_module *mod)
+resolve_schema_nodeid(const char *id, struct ly_mnode *start, struct ly_module *mod, LY_NODE_TYPE node_type)
{
const char *name, *prefix, *ptr;
struct ly_mnode *sibling;
@@ -273,6 +278,9 @@
assert(id);
if (id[0] == '/') {
+ if (node_type & (LY_NODE_USES | LY_NODE_CHOICE)) {
+ return NULL;
+ }
ptr = strchr(id+1, '/');
prefix = id+1;
} else {
@@ -346,7 +354,8 @@
if (!strcmp(name, ".")) {
/* this node - start does not change */
} else if (!strcmp(name, "..")) {
- if (!start) {
+ /* ".." is not allowed in refines and augment sin uses, there is no need for it there */
+ if (!start || (node_type == LY_NODE_USES)) {
return NULL;
}
start = start->parent;
@@ -358,6 +367,11 @@
/* prefix check, it's not our own */
if (prefix && strncmp(sibling->module->prefix, prefix, pref_len)) {
+ /* in choice and the prefix is not ours, error for sure */
+ if (node_type == LY_NODE_CHOICE) {
+ return NULL;
+ }
+
/* import prefix check */
for (i = 0; i < sibling->module->imp_size; i++) {
if (!strncmp(sibling->module->imp[i].prefix, prefix, pref_len)
@@ -406,8 +420,34 @@
}
}
+ /* we did not find the case in direct siblings */
+ if (node_type == LY_NODE_CHOICE) {
+ return NULL;
+ }
+
/* no match */
if (!sibling) {
+ /* on augment search also RPCs and notifications, if we are in top-level */
+ if ((node_type == LY_NODE_AUGMENT) && !start->parent) {
+ /* we have searched all the data nodes */
+ if (start == start->module->data) {
+ start = start->module->rpc;
+ if (start) {
+ continue;
+ }
+ }
+ /* we have searched all the RPCs */
+ if (start == start->module->rpc) {
+ start = start->module->notif;
+ if (start) {
+ continue;
+ }
+ }
+ /* we have searched all the notifications, nothing else to search in */
+ if (start == start->module->notif) {
+ return NULL;
+ }
+ }
return NULL;
}
}