* Support for YANG identity and identityref according to RFC 7950 Sec 7.18 and 9.10
* Previous support did no validation of values. * Validation of types and CLI expansion * Example extended with inclusion of iana-if-type RFC 7224 interface identities
This commit is contained in:
parent
ea13727e97
commit
7e4e1d6deb
27 changed files with 2124 additions and 203 deletions
|
|
@ -204,20 +204,49 @@ yang2cli_var_sub(clicon_handle h,
|
|||
}
|
||||
type = ytype?ytype->ys_argument:NULL;
|
||||
cvtypestr = cv_type2str(cvtype);
|
||||
if (strcmp(type, "identityref") == 0)
|
||||
cprintf(cb, "(");
|
||||
cprintf(cb, "<%s:%s", ys->ys_argument, cvtypestr);
|
||||
/* enumeration special case completion */
|
||||
if (type && (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0)){
|
||||
cprintf(cb, " choice:");
|
||||
i = 0;
|
||||
while ((yi = yn_each((yang_node*)ytype, yi)) != NULL){
|
||||
if (yi->ys_keyword != Y_ENUM && yi->ys_keyword != Y_BIT)
|
||||
continue;
|
||||
if (i)
|
||||
cprintf(cb, "|");
|
||||
cprintf(cb, "%s", yi->ys_argument);
|
||||
i++;
|
||||
if (type){
|
||||
if (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0){
|
||||
cprintf(cb, " choice:");
|
||||
i = 0;
|
||||
while ((yi = yn_each((yang_node*)ytype, yi)) != NULL){
|
||||
if (yi->ys_keyword != Y_ENUM && yi->ys_keyword != Y_BIT)
|
||||
continue;
|
||||
if (i)
|
||||
cprintf(cb, "|");
|
||||
cprintf(cb, "%s", yi->ys_argument);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (strcmp(type, "identityref") == 0){
|
||||
yang_stmt *ybaseref;
|
||||
yang_stmt *ybaseid;
|
||||
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);
|
||||
cprintf(cb, "|<%s:%s choice:", ys->ys_argument, cvtypestr);
|
||||
if ((ybaseref = yang_find((yang_node*)ytype, Y_BASE, NULL)) != NULL &&
|
||||
(ybaseid = yang_find_identity(ys, ybaseref->ys_argument)) != NULL){
|
||||
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 (options & YANG_OPTIONS_FRACTION_DIGITS)
|
||||
cprintf(cb, " fraction-digits:%u", fraction_digits);
|
||||
if (options & (YANG_OPTIONS_RANGE|YANG_OPTIONS_LENGTH)){
|
||||
|
|
@ -259,10 +288,12 @@ yang2cli_var_sub(clicon_handle h,
|
|||
}
|
||||
if (options & YANG_OPTIONS_PATTERN)
|
||||
cprintf(cb, " regexp:\"%s\"", pattern);
|
||||
|
||||
cprintf(cb, ">");
|
||||
if (helptext)
|
||||
cprintf(cb, "(\"%s\")", helptext);
|
||||
if (strcmp(type, "identityref") == 0)
|
||||
cprintf(cb, ")");
|
||||
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
@ -385,6 +416,7 @@ yang2cli_var(clicon_handle h,
|
|||
enum cv_type cvtype;
|
||||
int options = 0;
|
||||
int completionp;
|
||||
char *type;
|
||||
|
||||
if (yang_type_get(ys, &origtype, &yrestype,
|
||||
&options, &mincv, &maxcv, &pattern, &fraction_digits) < 0)
|
||||
|
|
@ -413,11 +445,11 @@ yang2cli_var(clicon_handle h,
|
|||
cprintf(cb, ")");
|
||||
}
|
||||
else{
|
||||
char *type;
|
||||
type = yrestype?yrestype->ys_argument:NULL;
|
||||
if (type)
|
||||
completionp = clicon_cli_genmodel_completion(h) &&
|
||||
strcmp(type, "enumeration") != 0 &&
|
||||
strcmp(type, "enumeration") != 0 &&
|
||||
strcmp(type, "identityref") != 0 &&
|
||||
strcmp(type, "bits") != 0;
|
||||
else
|
||||
completionp = clicon_cli_genmodel_completion(h);
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ cli_signal_init (clicon_handle h)
|
|||
|
||||
/*! Interactive CLI command loop
|
||||
* @param[in] h CLICON handle
|
||||
* @retval 0
|
||||
* @retval -1
|
||||
* @see cligen_loop
|
||||
*/
|
||||
static int
|
||||
|
|
@ -124,7 +126,6 @@ cli_interactive(clicon_handle h)
|
|||
new_mode = cli_syntax_mode(h);
|
||||
if ((cmd = clicon_cliread(h)) == NULL) {
|
||||
cligen_exiting_set(cli_cligen(h), 1); /* EOF */
|
||||
retval = -1;
|
||||
goto done;
|
||||
}
|
||||
if ((res = clicon_parse(h, cmd, &new_mode, &result)) < 0)
|
||||
|
|
@ -229,6 +230,7 @@ usage(char *argv0, clicon_handle h)
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int retval = -1;
|
||||
char c;
|
||||
int once;
|
||||
char *tmp;
|
||||
|
|
@ -476,11 +478,19 @@ main(int argc, char **argv)
|
|||
if (restarg != NULL && strlen(restarg)){
|
||||
char *mode = cli_syntax_mode(h);
|
||||
int result;
|
||||
clicon_parse(h, restarg, &mode, &result);
|
||||
|
||||
/* */
|
||||
if (clicon_parse(h, restarg, &mode, &result) != 1){
|
||||
goto done;
|
||||
}
|
||||
if (result < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Go into event-loop unless -1 command-line */
|
||||
if (!once)
|
||||
cli_interactive(h);
|
||||
retval = cli_interactive(h);
|
||||
else
|
||||
retval = 0;
|
||||
done:
|
||||
if (treename)
|
||||
free(treename);
|
||||
|
|
@ -491,6 +501,5 @@ main(int argc, char **argv)
|
|||
clicon_log(LOG_NOTICE, "%s: %u Terminated\n", __PROGRAM__, getpid());
|
||||
if (h)
|
||||
cli_terminate(h);
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,6 +481,7 @@ clicon_eval(clicon_handle h,
|
|||
* @param[out] result -2 On eof (shouldnt happen)
|
||||
* -1 On parse error
|
||||
* >=0 Number of matches
|
||||
* @retval 0 XXX How does this relate to result???
|
||||
*/
|
||||
int
|
||||
clicon_parse(clicon_handle h,
|
||||
|
|
@ -490,7 +491,7 @@ clicon_parse(clicon_handle h,
|
|||
{
|
||||
char *modename;
|
||||
char *modename0;
|
||||
int res = -1;
|
||||
int retval = -1;
|
||||
int r;
|
||||
cli_syntax_t *stx = NULL;
|
||||
cli_syntaxmode_t *smode;
|
||||
|
|
@ -511,10 +512,11 @@ clicon_parse(clicon_handle h,
|
|||
else {
|
||||
if ((smode = syntax_mode_find(stx, modename, 0)) == NULL) {
|
||||
cli_output(f, "Can't find syntax mode '%s'\n", modename);
|
||||
return -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
while(smode) {
|
||||
if (smode)
|
||||
while(1) {
|
||||
modename0 = NULL;
|
||||
if ((pt = cligen_tree_active_get(cli_cligen(h))) != NULL)
|
||||
modename0 = pt->pt_name;
|
||||
|
|
@ -530,24 +532,24 @@ clicon_parse(clicon_handle h,
|
|||
clicon_err(OE_UNIX, errno, "cvec_new");
|
||||
goto done;;
|
||||
}
|
||||
res = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv);
|
||||
if (res != CG_MATCH)
|
||||
retval = cliread_parse(cli_cligen(h), cmd, pt, &match_obj, cvv);
|
||||
if (retval != CG_MATCH)
|
||||
pt_expand_cleanup_1(pt); /* XXX change to pt_expand_treeref_cleanup */
|
||||
if (modename0){
|
||||
cligen_tree_active_set(cli_cligen(h), modename0);
|
||||
modename0 = NULL;
|
||||
}
|
||||
switch (res) {
|
||||
switch (retval) {
|
||||
case CG_EOF: /* eof */
|
||||
case CG_ERROR:
|
||||
cli_output(f, "CLI parse error: %s\n", cmd);
|
||||
goto done;
|
||||
case CG_NOMATCH: /* no match */
|
||||
smode = NULL;
|
||||
/* clicon_err(OE_CFG, 0, "CLI syntax error: \"%s\": %s",
|
||||
cmd, cli_nomatch(h));*/
|
||||
cli_output(f, "CLI syntax error: \"%s\": %s\n",
|
||||
cmd, cli_nomatch(h));
|
||||
goto done;
|
||||
break;
|
||||
case CG_MATCH:
|
||||
if (strcmp(modename, *modenamep)){ /* Command in different mode */
|
||||
|
|
@ -565,12 +567,12 @@ clicon_parse(clicon_handle h,
|
|||
cli_output(f, "CLI syntax error: \"%s\" is ambiguous\n", cmd);
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* switch retval */
|
||||
} /* while smode */
|
||||
done:
|
||||
if (cvv)
|
||||
cvec_free(cvv);
|
||||
return res;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Read command from CLIgen's cliread() using current syntax mode.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue