Fixed again: [Nested YANG choice does not work #342](https://github.com/clicon/clixon/issues/342)
Previous fix only for some sub-cases. New fix should work for all reecursive cases
This commit is contained in:
parent
657ddf9e87
commit
9537596a67
3 changed files with 128 additions and 82 deletions
|
|
@ -274,58 +274,66 @@ check_when_condition(cxobj *x0p,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Given choice/case, remove all other cases.
|
||||
/*! Get cloxest yang case and choice, if any
|
||||
*/
|
||||
static int
|
||||
choice_delete_existing_children(cxobj *x0,
|
||||
yang_stmt *y1c,
|
||||
yang_stmt *y1case,
|
||||
yang_stmt *y1choice)
|
||||
choice_case_get(yang_stmt *yc,
|
||||
yang_stmt **ycase,
|
||||
yang_stmt **ychoice)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *x0c;
|
||||
yang_stmt *y0c;
|
||||
yang_stmt *y0case;
|
||||
yang_stmt *y0choice;
|
||||
cxobj *x0prev;
|
||||
yang_stmt *y0p;
|
||||
|
||||
/* Now traverse existing tree and compare with choice yang structure of added tree */
|
||||
x0prev = NULL;
|
||||
x0c = NULL;
|
||||
while ((x0c = xml_child_each(x0, x0c, CX_ELMNT)) != NULL) {
|
||||
if ((y0c = xml_spec(x0c)) == NULL ||
|
||||
yang_parent_get(y0c) == NULL){
|
||||
x0prev = x0c;
|
||||
continue;
|
||||
}
|
||||
y0p = yang_parent_get(y0c);
|
||||
if (yang_keyword_get(y0p) == Y_CASE){
|
||||
y0case = y0p;
|
||||
y0choice = yang_parent_get(y0case);
|
||||
}
|
||||
else if (yang_keyword_get(y0p) == Y_CHOICE){
|
||||
y0case = NULL;
|
||||
y0choice = y0p;
|
||||
}
|
||||
else{
|
||||
x0prev = x0c;
|
||||
continue;
|
||||
}
|
||||
if (y0choice == y1choice){
|
||||
if ((y0case == NULL && y0c != y1c) ||
|
||||
y0case != y1case){
|
||||
if (xml_purge(x0c) < 0)
|
||||
goto done;
|
||||
x0c = x0prev;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
x0prev = x0c;
|
||||
yang_stmt *yp;
|
||||
|
||||
if ((yp = yang_parent_get(yc)) == NULL)
|
||||
return 0;
|
||||
if (yang_keyword_get(yp) == Y_CASE){
|
||||
*ycase = yp;
|
||||
*ychoice = yang_parent_get(yp);
|
||||
return 1;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
else if (yang_keyword_get(yp) == Y_CHOICE){
|
||||
*ycase = NULL;
|
||||
*ychoice = yp;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Check if x0/y0 is part of other choice/case than y1 recursively , if so purge
|
||||
* @retval 0 No, y0 it is not in other case than y1
|
||||
* @retval 1 yes, y0 is in other case than y1
|
||||
*/
|
||||
static int
|
||||
choice_is_other(yang_stmt *y0c,
|
||||
yang_stmt *y0case,
|
||||
yang_stmt *y0choice,
|
||||
yang_stmt *y1c,
|
||||
yang_stmt *y1case,
|
||||
yang_stmt *y1choice)
|
||||
{
|
||||
yang_stmt *ycase;
|
||||
yang_stmt *ychoice;
|
||||
|
||||
if (y0choice == y1choice){
|
||||
if ((y0case == NULL && y0c != y1c) ||
|
||||
y0case != y1case){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* First recurse y0 */
|
||||
if (choice_case_get(y0choice, &ycase, &ychoice)){
|
||||
if (choice_is_other(y0choice, ycase, ychoice,
|
||||
y1c, y1case, y1choice) == 1)
|
||||
return 1;
|
||||
}
|
||||
/* Second recurse y1 */
|
||||
if (choice_case_get(y1choice, &ycase, &ychoice)){
|
||||
if (choice_is_other(y0choice, y0case, y0choice,
|
||||
y1choice, ycase, ychoice) == 1)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Check if choice nodes and implicitly remove all other cases.
|
||||
|
|
@ -346,31 +354,41 @@ choice_delete_existing_children(cxobj *x0,
|
|||
* other cases inside the choice.
|
||||
*/
|
||||
static int
|
||||
check_delete_existing_case(cxobj *x0,
|
||||
yang_stmt *y1c)
|
||||
choice_delete_other(cxobj *x0,
|
||||
yang_stmt *y1c)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *yp;
|
||||
yang_stmt *y1case;
|
||||
yang_stmt *y1choice;
|
||||
|
||||
if ((yp = yang_parent_get(y1c)) == NULL)
|
||||
cxobj *x0c;
|
||||
cxobj *x0prev;
|
||||
yang_stmt *y0c;
|
||||
yang_stmt *y0case;
|
||||
yang_stmt *y0choice;
|
||||
yang_stmt *y1case = NULL;
|
||||
yang_stmt *y1choice = NULL;
|
||||
|
||||
if (choice_case_get(y1c, &y1case, &y1choice) == 0)
|
||||
goto ok;
|
||||
if (yang_keyword_get(yp) == Y_CASE){
|
||||
y1case = yp;
|
||||
y1choice = yang_parent_get(y1case);
|
||||
x0prev = NULL;
|
||||
x0c = NULL;
|
||||
while ((x0c = xml_child_each(x0, x0c, CX_ELMNT)) != NULL) {
|
||||
if ((y0c = xml_spec(x0c)) == NULL ||
|
||||
yang_parent_get(y0c) == NULL){
|
||||
x0prev = x0c;
|
||||
continue;
|
||||
}
|
||||
if (choice_case_get(y0c, &y0case, &y0choice) == 0){
|
||||
x0prev = x0c;
|
||||
continue;
|
||||
}
|
||||
/* Check if x0/y0 is part of other choice/case than y1 recursively , if so purge */
|
||||
if (choice_is_other(y0c, y0case, y0choice, y1c, y1case, y1choice) == 1){
|
||||
if (xml_purge(x0c) < 0)
|
||||
goto done;
|
||||
x0c = x0prev;
|
||||
continue;
|
||||
}
|
||||
x0prev = x0c;
|
||||
}
|
||||
else if (yang_keyword_get(yp) == Y_CHOICE){
|
||||
y1case = NULL;
|
||||
y1choice = yp;
|
||||
}
|
||||
else
|
||||
goto ok;
|
||||
if (choice_delete_existing_children(x0, y1c, y1case, y1choice) < 0)
|
||||
goto done;
|
||||
/* Recursive call */
|
||||
if (check_delete_existing_case(x0, y1choice) < 0)
|
||||
goto done;
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -827,8 +845,8 @@ text_modify(clicon_handle h,
|
|||
x1cname, yang_find_mynamespace(y0));
|
||||
goto done;
|
||||
}
|
||||
/* Check if existing case should be deleted */
|
||||
if (check_delete_existing_case(x0, yc) < 0)
|
||||
/* Check if existing choice/case should be deleted */
|
||||
if (choice_delete_other(x0, yc) < 0)
|
||||
goto done;
|
||||
/* See if there is a corresponding node in the base tree */
|
||||
x0c = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue