diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c
index 811467cb..8be21f88 100644
--- a/apps/cli/cli_show.c
+++ b/apps/cli/cli_show.c
@@ -111,6 +111,7 @@ expand_dbvar(void *h,
cxobj *xtop = NULL; /* xpath root */
cxobj *xbot = NULL; /* xpath, NULL if datastore */
yang_stmt *y = NULL; /* yang spec of xpath */
+ yang_stmt *yp;
yang_stmt *ytype;
yang_stmt *ypath;
cxobj *xcur;
@@ -167,11 +168,13 @@ expand_dbvar(void *h,
xbot = xtop;
/* This is primarily to get "y",
* xpath2xml would have worked!!
+ * XXX: but y is just the first in this list, there could be other y:s?
*/
if (api_path && api_path2xml(api_path, yspec, xtop, YC_DATANODE, 0, &xbot, &y) < 1)
goto done;
if (y==NULL)
goto ok;
+
if ((nsc = xml_nsctx_init(NULL, namespace)) == NULL)
goto done;
@@ -203,7 +206,12 @@ expand_dbvar(void *h,
}
if (xpath_vec_nsc(xcur, nsc, "%s", &xvec, &xlen, xpathcur) < 0)
goto done;
- bodystr0 = NULL; /* Assume sorted XML where duplicates are adjacent */
+ /* Loop for inserting into commands cvec.
+ * Detect duplicates: for ordered-by system assume list is ordered, so you need
+ * just remember previous
+ * but for ordered-by system, check the whole list
+ */
+ bodystr0 = NULL;
for (i = 0; i < xlen; i++) {
x = xvec[i];
if (xml_type(x) == CX_BODY)
@@ -212,11 +220,27 @@ expand_dbvar(void *h,
bodystr = xml_body(x);
if (bodystr == NULL)
continue; /* no body, cornercase */
- if (bodystr0 && strcmp(bodystr, bodystr0) == 0)
- continue; /* duplicate, assume sorted */
- /* RFC3986 decode */
- cvec_add_string(commands, NULL, bodystr);
- bodystr0 = bodystr;
+ if ((y = xml_spec(x)) != NULL &&
+ (yp = yang_parent_get(y)) != NULL &&
+ yang_keyword_get(yp) == Y_LIST &&
+ yang_find(yp, Y_ORDERED_BY, "user") != NULL){
+ /* Detect duplicates linearly in existing values */
+ {
+ cg_var *cv = NULL;
+ while ((cv = cvec_each(commands, cv)) != NULL)
+ if (strcmp(cv_string_get(cv), bodystr) == 0)
+ break;
+ if (cv == NULL)
+ cvec_add_string(commands, NULL, bodystr);
+ }
+ }
+ else{
+ if (bodystr0 && strcmp(bodystr, bodystr0) == 0)
+ continue; /* duplicate, assume sorted */
+ bodystr0 = bodystr;
+ /* RFC3986 decode */
+ cvec_add_string(commands, NULL, bodystr);
+ }
}
ok:
retval = 0;
diff --git a/test/test_cli_multikey.sh b/test/test_cli_multikey.sh
index 331ef1f4..e674ae1a 100755
--- a/test/test_cli_multikey.sh
+++ b/test/test_cli_multikey.sh
@@ -1,5 +1,6 @@
#!/bin/bash
# CLI test for multi-key lists
+# Had bugs in duplicate detection
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
@@ -49,6 +50,20 @@ module $APPNAME{
}
}
}
+ list y{
+ key "a b" ;
+ ordered-by user;
+ leaf a {
+ type string;
+ }
+ leaf b {
+ type enumeration{
+ enum v1;
+ enum v2;
+ enum v3;
+ }
+ }
+ }
}
}
EOF
@@ -91,6 +106,26 @@ expectfn "$clixon_cli -1 -f $cfg set ex x a 1 b v2" 0 ""
new "show conf"
expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^1v11v21v32v12v22v3]]>]]>$'
+
+# ordered-by user
+new "set 1 v1"
+expectfn "$clixon_cli -1 -f $cfg set ex y a 1 b v1" 0 ""
+
+new "set 2 v1"
+expectfn "$clixon_cli -1 -f $cfg set ex y a 2 b v1" 0 ""
+
+new "set 1 v2"
+expectfn "$clixon_cli -1 -f $cfg set ex y a 1 b v2" 0 ""
+
+new "set 1 v3"
+expectfn "$clixon_cli -1 -f $cfg set ex y a 1 b v3" 0 ""
+
+new "set 2 v2"
+expectfn "$clixon_cli -1 -f $cfg set ex y a 2 b v2" 0 ""
+
+new "show conf"
+expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^1v11v21v32v12v22v31v12v11v21v32v2]]>]]>$'
+
if [ $BE -eq 0 ]; then
exit # BE
fi