data tree BUGFIX validation in case of having nested choices
modify mandatory nodes checking and data nodes from different choice cases
checking in case the schema has a choice inside a case statement (nested
choices).
diff --git a/src/validation.c b/src/validation.c
index d63b4a0..795423d 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -166,28 +166,47 @@
}
/* check that there are no data from different choice case */
- if (!(options & LYD_OPT_FILTER) && schema->parent && (schema->parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
- if (schema->parent->nodetype == LYS_CHOICE) {
- cs = NULL;
- ch = schema->parent;
- } else { /* schema->parent->nodetype == LYS_CASE */
- cs = schema->parent;
- ch = schema->parent->parent;
- }
- if (ch->parent && ch->parent->nodetype == LYS_CASE) {
- /* TODO check schemas with a choice inside a case */
- LOGWRN("Not checking parent branches of nested choice");
- }
- for (diter = start; diter; diter = diter->next) {
- if (diter == node) {
- continue;
+ if (!(options & LYD_OPT_FILTER)) {
+ /* init loop condition */
+ ch = schema;
+
+ while (ch->parent && (ch->parent->nodetype & (LYS_CASE | LYS_CHOICE))) {
+ if (ch->parent->nodetype == LYS_CHOICE) {
+ cs = NULL;
+ ch = ch->parent;
+ } else { /* ch->parent->nodetype == LYS_CASE */
+ cs = ch->parent;
+ ch = ch->parent->parent;
}
- if ((diter->schema->parent->nodetype == LYS_CHOICE && diter->schema->parent == ch) ||
- (diter->schema->parent->nodetype == LYS_CASE && !cs) ||
- (diter->schema->parent->nodetype == LYS_CASE && cs && diter->schema->parent != cs && diter->schema->parent->parent == ch)) {
- LOGVAL(LYE_MCASEDATA, line, ch->name);
- return EXIT_FAILURE;
+ for (diter = start; diter; diter = diter->next) {
+ if (diter == node) {
+ continue;
+ }
+
+ /* find correct level to compare */
+ for (siter = diter->schema->parent; siter; siter = siter->parent) {
+ if (siter->nodetype == LYS_CHOICE) {
+ if (siter == ch) {
+ LOGVAL(LYE_MCASEDATA, line, ch->name);
+ return EXIT_FAILURE;
+ } else {
+ continue;
+ }
+ }
+
+ if (siter->nodetype == LYS_CASE) {
+ if (siter->parent != ch) {
+ continue;
+ } else if (!cs || cs != siter) {
+ LOGVAL(LYE_MCASEDATA, line, ch->name);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* diter is from something else choice (subtree) */
+ break;
+ }
}
}
}