* Partially corrected: [yang type range statement does not support multiple values](https://github.com/clicon/clixon/issues/59).
* Should work for netconf and restconf, but not for CLI. * Fixed again: [Range parsing is not RFC 7950 compliant](https://github.com/clicon/clixon/issues/71)
This commit is contained in:
parent
f718c716b6
commit
19343c2b21
6 changed files with 329 additions and 202 deletions
|
|
@ -143,6 +143,9 @@
|
||||||
* <!DOCTYPE (ie DTD) is not supported.
|
* <!DOCTYPE (ie DTD) is not supported.
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
* Partially corrected: [yang type range statement does not support multiple values](https://github.com/clicon/clixon/issues/59).
|
||||||
|
* Should work for netconf and restconf, but not for CLI.
|
||||||
|
* Fixed again: [Range parsing is not RFC 7950 compliant](https://github.com/clicon/clixon/issues/71)
|
||||||
* xml_cmp() compares numeric nodes based on string value [https://github.com/clicon/clixon/issues/64]
|
* xml_cmp() compares numeric nodes based on string value [https://github.com/clicon/clixon/issues/64]
|
||||||
* xml_cmp() respects 'ordered-by user' for state nodes, which violates RFC 7950 [https://github.com/clicon/clixon/issues/63]. (Thanks JDL)
|
* xml_cmp() respects 'ordered-by user' for state nodes, which violates RFC 7950 [https://github.com/clicon/clixon/issues/63]. (Thanks JDL)
|
||||||
* XML<>JSON conversion problems [https://github.com/clicon/clixon/issues/66]
|
* XML<>JSON conversion problems [https://github.com/clicon/clixon/issues/66]
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <syslog.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <math.h> /* For pow() kludge in cvtype_max2str_dup2 */
|
#include <math.h> /* For pow() kludge in cvtype_max2str_dup2 */
|
||||||
|
|
||||||
|
|
@ -162,6 +163,98 @@ cli_callback_generate(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Generate identityref statements for CLI variables
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] ytype Yang union type being resolved
|
||||||
|
* @param[in] helptext CLI help text
|
||||||
|
* @param[out] cb Buffer where cligen code is written
|
||||||
|
* @see yang2cli_var_sub Its sub-function
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
yang2cli_var_identityref(yang_stmt *ys,
|
||||||
|
yang_stmt *ytype,
|
||||||
|
char *cvtypestr,
|
||||||
|
char *helptext,
|
||||||
|
cbuf *cb)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
yang_stmt *ybaseref;
|
||||||
|
yang_stmt *ybaseid;
|
||||||
|
cg_var *cv = NULL;
|
||||||
|
char *name;
|
||||||
|
char *id;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Add a wildchar string first -let validate take it for default prefix */
|
||||||
|
cprintf(cb, ">");
|
||||||
|
if (helptext)
|
||||||
|
cprintf(cb, "(\"%s\")", helptext);
|
||||||
|
if ((ybaseref = yang_find((yang_node*)ytype, Y_BASE, NULL)) != NULL &&
|
||||||
|
(ybaseid = yang_find_identity(ys, ybaseref->ys_argument)) != NULL){
|
||||||
|
if (cvec_len(ybaseid->ys_cvec) > 0){
|
||||||
|
cprintf(cb, "|<%s:%s choice:", ys->ys_argument, cvtypestr);
|
||||||
|
i = 0;
|
||||||
|
while ((cv = cvec_each(ybaseid->ys_cvec, cv)) != NULL){
|
||||||
|
if (i++)
|
||||||
|
cprintf(cb, "|");
|
||||||
|
name = strdup(cv_name_get(cv));
|
||||||
|
if ((id=strchr(name, ':')) != NULL)
|
||||||
|
*id = '\0';
|
||||||
|
cprintf(cb, "%s:%s", name, id+1);
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
// done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Generate range check statements for CLI variables
|
||||||
|
* @param[out] cb Buffer where cligen code is written
|
||||||
|
* @see yang2cli_var_sub Its sub-function
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
yang2cli_var_range(yang_stmt *ys,
|
||||||
|
cvec *cvv,
|
||||||
|
int options,
|
||||||
|
cbuf *cb)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int i;
|
||||||
|
cg_var *cv;
|
||||||
|
|
||||||
|
/* Loop through range_min and range_min..range_max */
|
||||||
|
i = 0;
|
||||||
|
while (i<cvec_len(cvv)){
|
||||||
|
if (i){
|
||||||
|
// clicon_log(LOG_NOTICE, "%s: Warning %s has more ranges, ignoring", __FUNCTION__, ys->ys_argument);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cv = cvec_i(cvv, i++);
|
||||||
|
if (strcmp(cv_name_get(cv),"range_min") == 0){
|
||||||
|
cprintf(cb, " %s[", (options&YANG_OPTIONS_RANGE)?"range":"length");
|
||||||
|
cv2cbuf(cv, cb);
|
||||||
|
cprintf(cb,":");
|
||||||
|
/* probe next */
|
||||||
|
if (i<cvec_len(cvv) &&
|
||||||
|
(cv = cvec_i(cvv, i)) != NULL &&
|
||||||
|
strcmp(cv_name_get(cv),"range_max") == 0){
|
||||||
|
i++;
|
||||||
|
cv2cbuf(cv, cb);
|
||||||
|
}
|
||||||
|
else /* If not, it is a single number range [x:x]*/
|
||||||
|
cv2cbuf(cv, cb);
|
||||||
|
cprintf(cb,"]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
// done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/* Forward */
|
/* Forward */
|
||||||
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys, cbuf *cb,
|
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys, cbuf *cb,
|
||||||
enum genmodel_type gt, int level);
|
enum genmodel_type gt, int level);
|
||||||
|
|
@ -175,7 +268,7 @@ static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, char *origtype,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] ys Yang statement
|
* @param[in] ys Yang statement
|
||||||
* @param[in] ytype Yang union type being resolved
|
* @param[in] ytype Yang union type being resolved
|
||||||
* @param[in] cb Buffer where cligen code is written
|
* @param[out] cb Buffer where cligen code is written
|
||||||
* @param[in] helptext CLI help text
|
* @param[in] helptext CLI help text
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -196,7 +289,6 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
yang_stmt *yi = NULL;
|
yang_stmt *yi = NULL;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char *cvtypestr;
|
char *cvtypestr;
|
||||||
cg_var *cv;
|
|
||||||
|
|
||||||
if (cvtype == CGV_VOID){
|
if (cvtype == CGV_VOID){
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -223,61 +315,16 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(type, "identityref") == 0){
|
else if (strcmp(type, "identityref") == 0){
|
||||||
yang_stmt *ybaseref;
|
if (yang2cli_var_identityref(ys, ytype, cvtypestr, helptext, cb) < 0)
|
||||||
yang_stmt *ybaseid;
|
goto done;
|
||||||
cg_var *cv = NULL;
|
|
||||||
char *name;
|
|
||||||
char *id;
|
|
||||||
/* Add a wildchar string first -let validate take it for default prefix */
|
|
||||||
cprintf(cb, ">");
|
|
||||||
if (helptext)
|
|
||||||
cprintf(cb, "(\"%s\")", helptext);
|
|
||||||
if ((ybaseref = yang_find((yang_node*)ytype, Y_BASE, NULL)) != NULL &&
|
|
||||||
(ybaseid = yang_find_identity(ys, ybaseref->ys_argument)) != NULL){
|
|
||||||
if (cvec_len(ybaseid->ys_cvec) > 0){
|
|
||||||
cprintf(cb, "|<%s:%s choice:", ys->ys_argument, cvtypestr);
|
|
||||||
i = 0;
|
|
||||||
while ((cv = cvec_each(ybaseid->ys_cvec, cv)) != NULL){
|
|
||||||
if (i++)
|
|
||||||
cprintf(cb, "|");
|
|
||||||
name = strdup(cv_name_get(cv));
|
|
||||||
if ((id=strchr(name, ':')) != NULL)
|
|
||||||
*id = '\0';
|
|
||||||
cprintf(cb, "%s:%s", name, id+1);
|
|
||||||
if (name)
|
|
||||||
free(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options & YANG_OPTIONS_FRACTION_DIGITS)
|
if (options & YANG_OPTIONS_FRACTION_DIGITS)
|
||||||
cprintf(cb, " fraction-digits:%u", fraction_digits);
|
cprintf(cb, " fraction-digits:%u", fraction_digits);
|
||||||
|
|
||||||
if (options & (YANG_OPTIONS_RANGE|YANG_OPTIONS_LENGTH)){
|
if (options & (YANG_OPTIONS_RANGE|YANG_OPTIONS_LENGTH)){
|
||||||
/* Loop through range_min and range_min..rang_max */
|
if (yang2cli_var_range(ys, cvv, options, cb) < 0)
|
||||||
i = 0;
|
goto done;
|
||||||
while (i<cvec_len(cvv)){
|
|
||||||
// if (i)
|
|
||||||
// clicon_log(LOG_NOTICE, "%s: Warning %s has more ranges, ignoring", __FUNCTION__, ys->ys_argument);
|
|
||||||
cv = cvec_i(cvv, i++);
|
|
||||||
if (strcmp(cv_name_get(cv),"range_min") == 0){
|
|
||||||
cprintf(cb, " %s[", (options&YANG_OPTIONS_RANGE)?"range":"length");
|
|
||||||
cv2cbuf(cv, cb);
|
|
||||||
cprintf(cb,":");
|
|
||||||
/* probe next */
|
|
||||||
if (i<cvec_len(cvv) &&
|
|
||||||
(cv = cvec_i(cvv, i)) != NULL &&
|
|
||||||
strcmp(cv_name_get(cv),"range_max") == 0){
|
|
||||||
i++;
|
|
||||||
cv2cbuf(cv, cb);
|
|
||||||
}
|
|
||||||
else /* If not, it is a single number range [x:x]*/
|
|
||||||
cv2cbuf(cv, cb);
|
|
||||||
cprintf(cb,"]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (options & YANG_OPTIONS_PATTERN){
|
if (options & YANG_OPTIONS_PATTERN){
|
||||||
char *posix = NULL;
|
char *posix = NULL;
|
||||||
|
|
@ -292,7 +339,6 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
cprintf(cb, "(\"%s\")", helptext);
|
cprintf(cb, "(\"%s\")", helptext);
|
||||||
if (type && strcmp(type, "identityref") == 0)
|
if (type && strcmp(type, "identityref") == 0)
|
||||||
cprintf(cb, ")");
|
cprintf(cb, ")");
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -624,13 +624,14 @@ clixon_trim(char *str)
|
||||||
char *s = str;
|
char *s = str;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while (strlen(s) && isblank(s[0]))
|
while (strlen(s) && isblank(s[0])) /* trim from front */
|
||||||
s++;
|
s++;
|
||||||
for (i=0; i<strlen(s); i++)
|
for (i=strlen(s)-1; i>=0; i--){ /* trim from rear */
|
||||||
if (isblank(s[i])){
|
if (isblank(s[i]))
|
||||||
s[i] = '\0';
|
s[i] = '\0';
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1152,9 +1152,7 @@ bound_add(yang_stmt *ys,
|
||||||
enum cv_type cvtype,
|
enum cv_type cvtype,
|
||||||
char *name,
|
char *name,
|
||||||
char *val,
|
char *val,
|
||||||
int options,
|
uint8_t fraction_digits)
|
||||||
uint8_t fraction_digits
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
|
|
@ -1169,7 +1167,7 @@ bound_add(yang_stmt *ys,
|
||||||
clicon_err(OE_YANG, errno, "cv_name_set(%s)", name);
|
clicon_err(OE_YANG, errno, "cv_name_set(%s)", name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (options & YANG_OPTIONS_FRACTION_DIGITS && cvtype == CGV_DEC64)
|
if (cvtype == CGV_DEC64)
|
||||||
cv_dec64_n_set(cv, fraction_digits);
|
cv_dec64_n_set(cv, fraction_digits);
|
||||||
if (strcmp(val, "min") == 0)
|
if (strcmp(val, "min") == 0)
|
||||||
cv_min_set(cv);
|
cv_min_set(cv);
|
||||||
|
|
@ -1189,6 +1187,43 @@ bound_add(yang_stmt *ys,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Common range length parsing of "x .. y | z..w " statements
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
range_parse(yang_stmt *ys,
|
||||||
|
enum cv_type cvtype,
|
||||||
|
uint8_t fraction_digits)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char **vec = NULL;
|
||||||
|
int nvec;
|
||||||
|
int i;
|
||||||
|
char *v;
|
||||||
|
char *v2;
|
||||||
|
|
||||||
|
if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL)
|
||||||
|
goto done;
|
||||||
|
for (i=0; i<nvec; i++){
|
||||||
|
v = vec[i];
|
||||||
|
if ((v2 = strstr(v, "..")) != NULL){
|
||||||
|
*v2 = '\0';
|
||||||
|
v2 += 2;
|
||||||
|
v2 = clixon_trim(v2); /* trim blanks */
|
||||||
|
}
|
||||||
|
v = clixon_trim(v); /* trim blanks */
|
||||||
|
if (bound_add(ys, cvtype, "range_min", v, fraction_digits) < 0)
|
||||||
|
goto done;
|
||||||
|
if (v2)
|
||||||
|
if (bound_add(ys, cvtype, "range_max", v2, fraction_digits) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (vec)
|
||||||
|
free(vec);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Populate string built-in range statement
|
/*! Populate string built-in range statement
|
||||||
*
|
*
|
||||||
* Create cvec variables "range_min" and "range_max". Assume parent is type.
|
* Create cvec variables "range_min" and "range_max". Assume parent is type.
|
||||||
|
|
@ -1213,11 +1248,6 @@ ys_populate_range(yang_stmt *ys,
|
||||||
int options = 0x0;
|
int options = 0x0;
|
||||||
uint8_t fraction_digits;
|
uint8_t fraction_digits;
|
||||||
enum cv_type cvtype = CGV_ERR;
|
enum cv_type cvtype = CGV_ERR;
|
||||||
char **vec = NULL;
|
|
||||||
char *v;
|
|
||||||
char *v2;
|
|
||||||
int nvec;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
yparent = ys->ys_parent; /* Find parent: type */
|
yparent = ys->ys_parent; /* Find parent: type */
|
||||||
if (yparent->yn_keyword != Y_TYPE){
|
if (yparent->yn_keyword != Y_TYPE){
|
||||||
|
|
@ -1232,28 +1262,10 @@ ys_populate_range(yang_stmt *ys,
|
||||||
/* This handles non-resolved also */
|
/* This handles non-resolved also */
|
||||||
if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
|
if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL)
|
if (range_parse(ys, cvtype, fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<nvec; i++){
|
|
||||||
v = vec[i++];
|
|
||||||
v = clixon_trim(v); /* trim blanks */
|
|
||||||
if ((v2 = strstr(v, "..")) != NULL){
|
|
||||||
*v2 = '\0';
|
|
||||||
v2 += 2;
|
|
||||||
v2 = clixon_trim(v2); /* trim blanks */
|
|
||||||
}
|
|
||||||
if (bound_add(ys, cvtype, "range_min", v,
|
|
||||||
options, fraction_digits) < 0)
|
|
||||||
goto done;
|
|
||||||
if (v2)
|
|
||||||
if (bound_add(ys, cvtype, "range_max",v2,
|
|
||||||
options, fraction_digits) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (vec)
|
|
||||||
free(vec);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1276,11 +1288,6 @@ ys_populate_length(yang_stmt *ys,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_node *yparent; /* type */
|
yang_node *yparent; /* type */
|
||||||
enum cv_type cvtype = CGV_ERR;
|
enum cv_type cvtype = CGV_ERR;
|
||||||
char **vec = NULL;
|
|
||||||
char *v;
|
|
||||||
int nvec;
|
|
||||||
int i;
|
|
||||||
char *v2;
|
|
||||||
|
|
||||||
yparent = ys->ys_parent; /* Find parent: type */
|
yparent = ys->ys_parent; /* Find parent: type */
|
||||||
if (yparent->yn_keyword != Y_TYPE){
|
if (yparent->yn_keyword != Y_TYPE){
|
||||||
|
|
@ -1288,27 +1295,10 @@ ys_populate_length(yang_stmt *ys,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cvtype = CGV_UINT64;
|
cvtype = CGV_UINT64;
|
||||||
if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL)
|
if (range_parse(ys, cvtype, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i=0; i<nvec; i++){
|
|
||||||
|
|
||||||
v = vec[i++];
|
|
||||||
v = clixon_trim(v); /* trim blanks */
|
|
||||||
if ((v2 = strstr(v, "..")) != NULL){
|
|
||||||
*v2 = '\0';
|
|
||||||
v2 += 2;
|
|
||||||
v2 = clixon_trim(v2); /* trim blanks */
|
|
||||||
}
|
|
||||||
if (bound_add(ys, cvtype, "range_min", v, 0, 0) < 0)
|
|
||||||
goto done;
|
|
||||||
if (v2)
|
|
||||||
if (bound_add(ys, cvtype, "range_max",v2, 0, 0) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (vec)
|
|
||||||
free(vec);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,9 @@ cv_validate1(cg_var *cv,
|
||||||
uint64_t uu = 0;
|
uint64_t uu = 0;
|
||||||
int64_t ii = 0;
|
int64_t ii = 0;
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int reti; /* must keep signed, unsigned and string retval */
|
||||||
|
int retu; /* separated due to different error handling */
|
||||||
|
int rets;
|
||||||
|
|
||||||
if (reason && *reason){
|
if (reason && *reason){
|
||||||
free(*reason);
|
free(*reason);
|
||||||
|
|
@ -384,89 +386,86 @@ cv_validate1(cg_var *cv,
|
||||||
(options & YANG_OPTIONS_LENGTH) != 0){
|
(options & YANG_OPTIONS_LENGTH) != 0){
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i<cvec_len(cvv)){
|
while (i<cvec_len(cvv)){
|
||||||
cv1 = cvec_i(cvv, i++);
|
cv1 = cvec_i(cvv, i++); /* Increment to check for max pair */
|
||||||
if (strcmp(cv_name_get(cv1),"range_min") == 0){
|
if (strcmp(cv_name_get(cv1),"range_min") != 0){
|
||||||
if (i<cvec_len(cvv) &&
|
clicon_err(OE_YANG, EINVAL, "Internal error, expected range_min");
|
||||||
(cv2 = cvec_i(cvv, i)) != NULL &&
|
goto done;
|
||||||
strcmp(cv_name_get(cv2),"range_max") == 0){
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cv2 = cv1;
|
|
||||||
ret = 0;
|
|
||||||
switch (cvtype){
|
|
||||||
case CGV_INT8:
|
|
||||||
ii = cv_int8_get(cv);
|
|
||||||
ret = range_check(ii, cv1, cv2, int8);
|
|
||||||
break;
|
|
||||||
case CGV_INT16:
|
|
||||||
ii = cv_int16_get(cv);
|
|
||||||
ret = range_check(ii, cv1, cv2, int16);
|
|
||||||
break;
|
|
||||||
case CGV_INT32:
|
|
||||||
ii = cv_int32_get(cv);
|
|
||||||
ret = range_check(ii, cv1, cv2, int32);
|
|
||||||
break;
|
|
||||||
case CGV_DEC64: /* XXX look at fraction-digit? */
|
|
||||||
case CGV_INT64:
|
|
||||||
ii = cv_int64_get(cv);
|
|
||||||
ret = range_check(ii, cv1, cv2, int64);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret){
|
|
||||||
if (reason)
|
|
||||||
*reason = cligen_reason("Number out of range: %" PRId64, ii);
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
switch (cvtype){
|
|
||||||
case CGV_UINT8:
|
|
||||||
uu = cv_uint8_get(cv);
|
|
||||||
ret = range_check(uu, cv1, cv2, uint8);
|
|
||||||
break;
|
|
||||||
case CGV_UINT16:
|
|
||||||
uu = cv_uint16_get(cv);
|
|
||||||
ret = range_check(uu, cv1, cv2, uint16);
|
|
||||||
break;
|
|
||||||
case CGV_UINT32:
|
|
||||||
uu = cv_uint32_get(cv);
|
|
||||||
ret = range_check(uu, cv1, cv2, uint32);
|
|
||||||
break;
|
|
||||||
case CGV_UINT64:
|
|
||||||
uu = cv_uint32_get(cv);
|
|
||||||
ret = range_check(uu, cv1, cv2, uint64);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ret){
|
|
||||||
if (reason)
|
|
||||||
*reason = cligen_reason("Number out of range: %" PRIu64, uu);
|
|
||||||
goto fail;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
switch (cvtype){
|
|
||||||
case CGV_STRING:
|
|
||||||
case CGV_REST:
|
|
||||||
if ((str = cv_string_get(cv)) == NULL)
|
|
||||||
break;
|
|
||||||
uu = strlen(str);
|
|
||||||
if (range_check(uu, cv1, cv2, uint64)){
|
|
||||||
if (reason)
|
|
||||||
*reason = cligen_reason("string length out of range: %" PRIu64, uu);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (i<cvec_len(cvv) &&
|
||||||
|
(cv2 = cvec_i(cvv, i)) != NULL &&
|
||||||
|
strcmp(cv_name_get(cv2),"range_max") == 0){
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cv2 = cv1;
|
||||||
|
reti = 0; retu = 0; rets = 0;
|
||||||
|
switch (cvtype){
|
||||||
|
case CGV_INT8:
|
||||||
|
ii = cv_int8_get(cv);
|
||||||
|
reti = range_check(ii, cv1, cv2, int8);
|
||||||
|
break;
|
||||||
|
case CGV_INT16:
|
||||||
|
ii = cv_int16_get(cv);
|
||||||
|
reti = range_check(ii, cv1, cv2, int16);
|
||||||
|
break;
|
||||||
|
case CGV_INT32:
|
||||||
|
ii = cv_int32_get(cv);
|
||||||
|
reti = range_check(ii, cv1, cv2, int32);
|
||||||
|
break;
|
||||||
|
case CGV_DEC64: /* XXX look at fraction-digit? */
|
||||||
|
case CGV_INT64:
|
||||||
|
ii = cv_int64_get(cv);
|
||||||
|
reti = range_check(ii, cv1, cv2, int64);
|
||||||
|
break;
|
||||||
|
case CGV_UINT8:
|
||||||
|
uu = cv_uint8_get(cv);
|
||||||
|
retu = range_check(uu, cv1, cv2, uint8);
|
||||||
|
break;
|
||||||
|
case CGV_UINT16:
|
||||||
|
uu = cv_uint16_get(cv);
|
||||||
|
retu = range_check(uu, cv1, cv2, uint16);
|
||||||
|
break;
|
||||||
|
case CGV_UINT32:
|
||||||
|
uu = cv_uint32_get(cv);
|
||||||
|
retu = range_check(uu, cv1, cv2, uint32);
|
||||||
|
break;
|
||||||
|
case CGV_UINT64:
|
||||||
|
uu = cv_uint32_get(cv);
|
||||||
|
retu = range_check(uu, cv1, cv2, uint64);
|
||||||
|
break;
|
||||||
|
case CGV_STRING:
|
||||||
|
case CGV_REST:
|
||||||
|
if ((str = cv_string_get(cv)) == NULL)
|
||||||
|
break;
|
||||||
|
uu = strlen(str);
|
||||||
|
rets = range_check(uu, cv1, cv2, uint64);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Error handling for signed and unsigned, strings in switch
|
||||||
|
* OK: if check OK
|
||||||
|
* Failure: check fails and it is the last
|
||||||
|
*/
|
||||||
|
if ((reti==0 && retu==0 && rets == 0))
|
||||||
|
goto step1ok;
|
||||||
|
/* Check fails */
|
||||||
|
if (i==cvec_len(cvv)){ /* And it is last */
|
||||||
|
if (reason){
|
||||||
|
if (reti)
|
||||||
|
*reason = cligen_reason("Number out of range: %"
|
||||||
|
PRId64, ii);
|
||||||
|
else if (retu)
|
||||||
|
*reason = cligen_reason("Number out of range: %"
|
||||||
|
PRIu64, uu);
|
||||||
|
else
|
||||||
|
*reason = cligen_reason("string length out of range: %" PRIu64, uu);
|
||||||
|
}
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
} /* while i<cvec_len(cvv) */
|
||||||
}
|
}
|
||||||
|
step1ok:
|
||||||
/* then check options for others */
|
/* then check options for others */
|
||||||
switch (cvtype){
|
switch (cvtype){
|
||||||
case CGV_STRING:
|
case CGV_STRING:
|
||||||
|
|
|
||||||
|
|
@ -129,9 +129,9 @@ module example{
|
||||||
range "1";
|
range "1";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaf num2 {
|
leaf num2 { /* range and blanks */
|
||||||
type int32 {
|
type int32 {
|
||||||
range "4..4000";
|
range " 4 .. 4000 ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaf num3 {
|
leaf num3 {
|
||||||
|
|
@ -139,9 +139,9 @@ module example{
|
||||||
range "min..max";
|
range "min..max";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaf num4 { /* XXX multiple ranges not supported yet - only first*/
|
leaf num4 {
|
||||||
type uint8 {
|
type uint8 {
|
||||||
range "1 .. 2 | 42";
|
range "1..2 | 42";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaf len1 {
|
leaf len1 {
|
||||||
|
|
@ -151,7 +151,7 @@ module example{
|
||||||
}
|
}
|
||||||
leaf len2 {
|
leaf len2 {
|
||||||
type string {
|
type string {
|
||||||
length "4..4000";
|
length " 4 .. 4000 ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leaf len3 {
|
leaf len3 {
|
||||||
|
|
@ -304,7 +304,7 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><can
|
||||||
new "cli bits validate"
|
new "cli bits validate"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang validate" 0 "^$"
|
||||||
|
|
||||||
#----------------int ranges---------------------
|
#-------- num1 single range (1)
|
||||||
|
|
||||||
new "cli range test num1 1 OK"
|
new "cli range test num1 1 OK"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num1 1" 0 "^$"
|
||||||
|
|
@ -321,24 +321,97 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><can
|
||||||
new "netconf validate num1 -1 wrong"
|
new "netconf validate num1 -1 wrong"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: -1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num1</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: -1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
new "cli range test num2 1000 ok"
|
new "netconf discard-changes"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 "^$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
#-------- num2 range and blanks
|
||||||
|
|
||||||
new "cli range test num2 3 error"
|
new "cli range test num2 3 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 3" 255 "^$"
|
||||||
|
|
||||||
|
new "cli range test num2 1000 ok"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 1000" 0 "^$"
|
||||||
|
|
||||||
new "cli range test num2 5000 error"
|
new "cli range test num2 5000 error"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num2 5000" 255 "^$"
|
||||||
|
|
||||||
|
new "netconf range set num2 3 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">3</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num2 3 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 3</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf range set num2 1000 ok"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">1000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num2 1000 ok"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf range set num2 5000 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num2 xmlns="urn:example:clixon">5000</num2></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num2 5000 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num2</bad-element></error-info><error-severity>error</error-severity><error-message>Number out of range: 5000</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf discard-changes"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
#-------- num3 min max range
|
||||||
|
|
||||||
new "cli range test num3 42 ok"
|
new "cli range test num3 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 42" 0 "^$"
|
||||||
|
|
||||||
new "cli range test num3 260 error"
|
new "cli range test num3 260 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 260" 255 "^$"
|
||||||
|
|
||||||
#----------------string ranges---------------------
|
new "cli range test num3 -1 fail"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num3 -1" 255 "^$"
|
||||||
|
|
||||||
new "cli length test len1 1 error"
|
new "netconf range set num3 260 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num3 xmlns="urn:example:clixon">260</num3></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num3 260 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>num3</bad-element></error-info><error-severity>error</error-severity><error-message>260 is out of range(type is uint8)</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf discard-changes"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
#-------- num4 multiple ranges 1..2 | 42
|
||||||
|
|
||||||
|
new "cli range test num4 multiple 2 ok"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l e -y $fyang set num4 2" 0 "^$"
|
||||||
|
|
||||||
|
new "cli range test num4 multiple 99 fail"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 99" 255 "^$"
|
||||||
|
|
||||||
|
# See https://github.com/clicon/clixon/issues/59
|
||||||
|
#new "cli range test num4 multiple 42 ok"
|
||||||
|
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set num4 42" 0 "^$"
|
||||||
|
|
||||||
|
new "netconf range set num4 multiple 2"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num4 OK"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf range set num4 multiple 20"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num4 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf range set num4 multiple 42"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><num4 xmlns="urn:example:clixon">42</num4></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf validate num4 fail"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
new "netconf discard-changes"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
#----------------string ranges---------------------
|
||||||
|
#-------- len1 single range (2)
|
||||||
|
new "cli length test len1 1 fail"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 x" 255 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len1 x" 255 "^$"
|
||||||
|
|
||||||
new "cli length test len1 2 OK"
|
new "cli length test len1 2 OK"
|
||||||
|
|
@ -356,18 +429,33 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><can
|
||||||
new "netconf validate len1 1 wrong"
|
new "netconf validate len1 1 wrong"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>len1</bad-element></error-info><error-severity>error</error-severity><error-message>string length out of range: 1</error-message></rpc-error></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
|
#-------- len2 range and blanks
|
||||||
|
|
||||||
|
new "cli length test len2 3 error"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 "^$"
|
||||||
|
|
||||||
new "cli length test len2 42 ok"
|
new "cli length test len2 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 "^$"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli length test len2 3 error"
|
#-------- len3 min max range
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len2 ab" 255 "^$"
|
|
||||||
|
|
||||||
new "cli range test len3 42 ok"
|
new "cli range test len3 42 ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len3 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$"
|
||||||
|
|
||||||
|
#-------- len4 multiple ranges 1..2 | 42 (only first range)
|
||||||
|
new "cli length test len4 3 error"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 abc" 255 "^$"
|
||||||
|
|
||||||
|
new "cli length test len4 2 ok"
|
||||||
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 ab" 255 "^$"
|
||||||
|
|
||||||
|
# See https://github.com/clicon/clixon/issues/59
|
||||||
|
#new "cli length test len4 42 ok"
|
||||||
|
#expectfn "$clixon_cli -1f $cfg -l o -y $fyang set len4 hsakjdhkjsahdkjsahdksahdksajdhsakjhd" 0 "^$"
|
||||||
|
|
||||||
# XSD schema -> POSIX ECE translation
|
# XSD schema -> POSIX ECE translation
|
||||||
new "cli yang pattern \d ok"
|
new "cli yang pattern \d ok"
|
||||||
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 "^$"
|
expectfn "$clixon_cli -1f $cfg -l o -y $fyang set digit4 0123" 0 "^$"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue