List-pagination sort-by parameter
This commit is contained in:
parent
ad5312d824
commit
36f3c95768
10 changed files with 415 additions and 98 deletions
|
|
@ -279,7 +279,7 @@ typedef int (datastore_upgrade_t)(clixon_handle h, const char *db, cxobj *xt, mo
|
|||
/*! YANG schema mount
|
||||
*
|
||||
* Given an XML mount-point xt, return XML yang-lib modules-set
|
||||
* Return yanglib as XML tree on the RFC8525 form:
|
||||
* Return yanglib as XML tree on the RFC8528 form:
|
||||
* <yang-library>
|
||||
* <module-set>
|
||||
* <module>...</module>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@
|
|||
* Prototypes
|
||||
*/
|
||||
int xml_cmp(cxobj *x1, cxobj *x2, int same, int skip1, char *expl);
|
||||
int xml_sort(cxobj *x0);
|
||||
int xml_sort(cxobj *x);
|
||||
int xml_sort_by(cxobj *x, char *indexvar);
|
||||
int xml_sort_recurse(cxobj *xn);
|
||||
int xml_insert(cxobj *xp, cxobj *xc, enum insert_type ins, char *key_val, cvec *nsckey);
|
||||
int xml_sort_verify(cxobj *x, void *arg);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#define __USE_GNU /* for qsort_r */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -166,7 +167,7 @@ xml_cv_cache_clear(cxobj *xt)
|
|||
* @param[in] same If set, x1 and x2 are member of same parent & enumeration
|
||||
* is used (see explanation below)
|
||||
* @param[in] skip1 Key matching skipped for keys not in x1 (see explanation)
|
||||
* @param[in] explicit For list nodes, use explicit index variables, not keys
|
||||
* @param[in] indexvar For (leaf)list nodes, use explicit index variable xpaths
|
||||
* @retval 0 If equal
|
||||
* @retval <0 If x1 is less than x2
|
||||
* @retval >0 If x1 is greater than x2
|
||||
|
|
@ -273,6 +274,7 @@ xml_cmp(cxobj *x1,
|
|||
* existing list.
|
||||
*/
|
||||
if (same &&
|
||||
indexvar == NULL &&
|
||||
(
|
||||
#ifndef STATE_ORDERED_BY_SYSTEM
|
||||
yang_config(y1)==0 ||
|
||||
|
|
@ -283,8 +285,25 @@ xml_cmp(cxobj *x1,
|
|||
}
|
||||
switch (yang_keyword_get(y1)){
|
||||
case Y_LEAF_LIST: /* Match with name and value */
|
||||
#ifdef XML_EXPLICIT_INDEX
|
||||
if (indexvar){
|
||||
if ((x1b = xpath_first(x1, 0, "%s", indexvar)) != NULL)
|
||||
b1 = xml_body(x1b);
|
||||
else
|
||||
b1 = NULL;
|
||||
if ((x2b = xpath_first(x2, 0, "%s", indexvar)) != NULL)
|
||||
b2 = xml_body(x2b);
|
||||
else
|
||||
b2 = NULL;
|
||||
}
|
||||
else {
|
||||
b1 = xml_body(x1);
|
||||
b2 = xml_body(x2);
|
||||
}
|
||||
#else
|
||||
b1 = xml_body(x1);
|
||||
b2 = xml_body(x2);
|
||||
#endif
|
||||
if (b1 == NULL && b2 == NULL)
|
||||
;
|
||||
else if (b1 == NULL)
|
||||
|
|
@ -309,8 +328,8 @@ xml_cmp(cxobj *x1,
|
|||
case Y_LIST: /* Match with key values */
|
||||
if (indexvar != NULL){
|
||||
#ifdef XML_EXPLICIT_INDEX
|
||||
x1b = xml_find(x1, indexvar);
|
||||
x2b = xml_find(x2, indexvar);
|
||||
x1b = xpath_first(x1, 0, "%s", indexvar);
|
||||
x2b = xpath_first(x2, 0, "%s", indexvar);
|
||||
if (x1b == NULL && x2b == NULL)
|
||||
;
|
||||
else if (x1b == NULL)
|
||||
|
|
@ -396,19 +415,35 @@ xml_cmp(cxobj *x1,
|
|||
* @note args are pointer to pointers, to fit into qsort cmp function
|
||||
*/
|
||||
static int
|
||||
xml_cmp_qsort(const void* arg1,
|
||||
const void* arg2)
|
||||
xml_cmp_qsort(const void *arg1,
|
||||
const void *arg2,
|
||||
void *indexvar)
|
||||
{
|
||||
return xml_cmp(*(struct xml**)arg1, *(struct xml**)arg2, 1, 0, NULL);
|
||||
return xml_cmp(*(struct xml**)arg1, *(struct xml**)arg2, 1, 0, indexvar);
|
||||
}
|
||||
|
||||
/*! Sort children of an XML node using an index
|
||||
*
|
||||
* @param[in] x XML node
|
||||
* @param[in] indexvar Descendant-schema-nodeid
|
||||
* @retval 0 OK, all nodes traversed (subparts may have been skipped)
|
||||
*/
|
||||
int
|
||||
xml_sort_by(cxobj *x,
|
||||
char *indexvar)
|
||||
{
|
||||
xml_enumerate_children(x); /* This is to make sorting "stable", ie not change existing order */
|
||||
qsort_r(xml_childvec_get(x), xml_child_nr(x), sizeof(cxobj *), xml_cmp_qsort, indexvar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Sort children of an XML node
|
||||
*
|
||||
* Assume populated by yang spec.
|
||||
* @param[in] x0 XML node
|
||||
* @retval 1 OK, aborted on first fn returned 1
|
||||
* @retval 0 OK, all nodes traversed (subparts may have been skipped)
|
||||
* @retval -1 Error, aborted at first error encounter
|
||||
* @param[in] x XML node
|
||||
* @retval 1 OK, aborted on first fn returned 1
|
||||
* @retval 0 OK, all nodes traversed (subparts may have been skipped)
|
||||
* @retval -1 Error, aborted at first error encounter
|
||||
* @see xml_apply - typically called by recursive apply function
|
||||
* @see xml_sort_verify
|
||||
*/
|
||||
|
|
@ -423,7 +458,7 @@ xml_sort(cxobj *x)
|
|||
return 1;
|
||||
#endif
|
||||
xml_enumerate_children(x); /* This is to make sorting "stable", ie not change existing order */
|
||||
qsort(xml_childvec_get(x), xml_child_nr(x), sizeof(cxobj *), xml_cmp_qsort);
|
||||
qsort_r(xml_childvec_get(x), xml_child_nr(x), sizeof(cxobj *), xml_cmp_qsort, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
***** END LICENSE BLOCK *****
|
||||
|
||||
* Clixon XML object vectors
|
||||
* Note these are used only occasionally, instead the more primitive cxobj** is mostly used.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ yang_when_nsc_set(yang_stmt *ys,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Get yang filename for error/debug purpose
|
||||
/*! Get yang filename for error/debug purpose (only modules)
|
||||
*
|
||||
* @param[in] ys Yang statement
|
||||
* @retval filename
|
||||
|
|
@ -3053,7 +3053,7 @@ ys_populate2(yang_stmt *ys,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
/* RFC 8525 Yang schema mount flag for optimization */
|
||||
/* RFC 8528 Yang schema mount flag for optimization */
|
||||
if ((ret = yang_schema_mount_point0(ys)) < 0)
|
||||
goto done;
|
||||
if (ret == 1)
|
||||
|
|
|
|||
|
|
@ -527,7 +527,6 @@ ys_iskey(yang_stmt *y,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Helper function to yang_expand_grouping
|
||||
*
|
||||
* @param[in] yn Yang parent node of uses ststement
|
||||
|
|
@ -549,6 +548,7 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
yang_stmt *yg; /* grouping child */
|
||||
yang_stmt *yr; /* refinement */
|
||||
yang_stmt *yp;
|
||||
yang_stmt *ym;
|
||||
int glen;
|
||||
size_t size;
|
||||
int j;
|
||||
|
|
@ -564,8 +564,13 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
if (ys_grouping_resolve(ys, prefix, id, &ygrouping) < 0)
|
||||
goto done;
|
||||
if (ygrouping == NULL){
|
||||
clixon_log(NULL, LOG_NOTICE, "%s: Yang error : grouping \"%s\" not found in module \"%s\"",
|
||||
__FUNCTION__, yang_argument_get(ys), yang_argument_get(ys_module(ys)));
|
||||
if ((ym = ys_module(yn)) != NULL)
|
||||
clixon_err(OE_YANG, 0, "Yang error : grouping \"%s\" not found in module \"%s\" in file: %s:%d",
|
||||
yang_argument_get(ys), yang_argument_get(ys_module(ys)),
|
||||
yang_filename_get(ym), yang_linenum_get(yn));
|
||||
else
|
||||
clixon_err(OE_YANG, 0, "Yang error : grouping \"%s\" not found in module \"%s\"",
|
||||
yang_argument_get(ys), yang_argument_get(ys_module(ys)));
|
||||
goto done;
|
||||
}
|
||||
/* Check so that this uses statement is not a descendant of the grouping
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
* RFC 8525 Yang schema mount support
|
||||
* RFC 8528 Yang schema mount support
|
||||
*
|
||||
* Extend a container with ietf-yang-schema-mount:mount-point.
|
||||
* Structure of mount-points in YANG anc config:
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
#include "clixon_xml_nsctx.h"
|
||||
#include "clixon_yang_schema_mount.h"
|
||||
|
||||
/*! Check if YANG node is a RFC 8525 YANG schema mount
|
||||
/*! Check if YANG node is a RFC 8528 YANG schema mount
|
||||
*
|
||||
* Check if:
|
||||
* - y is CONTAINER or LIST, AND
|
||||
|
|
@ -126,7 +126,7 @@
|
|||
* - the extension label matches y (see note below)
|
||||
* If so, then return 1
|
||||
* @param[in] y Yang statement
|
||||
* @retval 1 Yes, y is a RFC 8525 YANG mount-point
|
||||
* @retval 1 Yes, y is a RFC 8528 YANG mount-point
|
||||
* @retval 0 No, y is not
|
||||
* @retval -1 Error
|
||||
* @note That this may be a restriction on the usage of "label". The RFC is somewhat unclear.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue