yang resolve union
This commit is contained in:
parent
fd2a5db31b
commit
0c065dc026
4 changed files with 171 additions and 91 deletions
|
|
@ -161,21 +161,29 @@ cli_callback_generate(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys,
|
/* Forward */
|
||||||
cbuf *cb0,
|
static int yang2cli_stmt(clicon_handle h, yang_stmt *ys, cbuf *cb,
|
||||||
enum genmodel_type gt,
|
enum genmodel_type gt, int level);
|
||||||
int level);
|
|
||||||
|
|
||||||
/*! Check for completion (of already existent values), ranges (eg range[min:max]) and
|
static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, char *origtype,
|
||||||
|
yang_stmt *ytype, cbuf *cb, char *helptext);
|
||||||
|
|
||||||
|
/*! Generate CLI code for Yang leaf statement to CLIgen variable of specific type
|
||||||
|
* Check for completion (of already existent values), ranges (eg range[min:max]) and
|
||||||
* patterns, (eg regexp:"[0.9]*").
|
* patterns, (eg regexp:"[0.9]*").
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] ytype Yang union type being resolved
|
||||||
|
* @param[in] cb Buffer where cligen code is written
|
||||||
|
* @param[in] helptext CLI help text
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
yang2cli_var_sub(clicon_handle h,
|
yang2cli_var_sub(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
cbuf *cb0,
|
yang_stmt *ytype, /* resolved type */
|
||||||
|
cbuf *cb,
|
||||||
char *helptext,
|
char *helptext,
|
||||||
enum cv_type cvtype,
|
enum cv_type cvtype,
|
||||||
yang_stmt *ytype, /* resolved type */
|
|
||||||
int options,
|
int options,
|
||||||
cg_var *mincv,
|
cg_var *mincv,
|
||||||
cg_var *maxcv,
|
cg_var *maxcv,
|
||||||
|
|
@ -196,31 +204,31 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
}
|
}
|
||||||
type = ytype?ytype->ys_argument:NULL;
|
type = ytype?ytype->ys_argument:NULL;
|
||||||
cvtypestr = cv_type2str(cvtype);
|
cvtypestr = cv_type2str(cvtype);
|
||||||
cprintf(cb0, "<%s:%s", ys->ys_argument, cvtypestr);
|
cprintf(cb, "<%s:%s", ys->ys_argument, cvtypestr);
|
||||||
/* enumeration special case completion */
|
/* enumeration special case completion */
|
||||||
if (type && (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0)){
|
if (type && (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0)){
|
||||||
cprintf(cb0, " choice:");
|
cprintf(cb, " choice:");
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((yi = yn_each((yang_node*)ytype, yi)) != NULL){
|
while ((yi = yn_each((yang_node*)ytype, yi)) != NULL){
|
||||||
if (yi->ys_keyword != Y_ENUM && yi->ys_keyword != Y_BIT)
|
if (yi->ys_keyword != Y_ENUM && yi->ys_keyword != Y_BIT)
|
||||||
continue;
|
continue;
|
||||||
if (i)
|
if (i)
|
||||||
cprintf(cb0, "|");
|
cprintf(cb, "|");
|
||||||
cprintf(cb0, "%s", yi->ys_argument);
|
cprintf(cb, "%s", yi->ys_argument);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options & YANG_OPTIONS_FRACTION_DIGITS)
|
if (options & YANG_OPTIONS_FRACTION_DIGITS)
|
||||||
cprintf(cb0, " 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)){
|
||||||
assert(mincv || maxcv);
|
assert(mincv || maxcv);
|
||||||
cprintf(cb0, " %s[", (options&YANG_OPTIONS_RANGE)?"range":"length");
|
cprintf(cb, " %s[", (options&YANG_OPTIONS_RANGE)?"range":"length");
|
||||||
if (mincv){
|
if (mincv){
|
||||||
if ((r = cv2str_dup(mincv)) == NULL){
|
if ((r = cv2str_dup(mincv)) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "cv2str_dup");
|
clicon_err(OE_UNIX, errno, "cv2str_dup");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cb0, "%s:", r);
|
cprintf(cb, "%s:", r);
|
||||||
free(r);
|
free(r);
|
||||||
r = NULL;
|
r = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -237,32 +245,37 @@ yang2cli_var_sub(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cprintf(cb0, "%s]", r);
|
cprintf(cb, "%s]", r);
|
||||||
free(r);
|
free(r);
|
||||||
r = NULL;
|
r = NULL;
|
||||||
}
|
}
|
||||||
if (options & YANG_OPTIONS_PATTERN)
|
if (options & YANG_OPTIONS_PATTERN)
|
||||||
cprintf(cb0, " regexp:\"%s\"", pattern);
|
cprintf(cb, " regexp:\"%s\"", pattern);
|
||||||
|
|
||||||
cprintf(cb0, ">");
|
cprintf(cb, ">");
|
||||||
if (helptext)
|
if (helptext)
|
||||||
cprintf(cb0, "(\"%s\")", helptext);
|
cprintf(cb, "(\"%s\")", helptext);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* forward */
|
/*! Resolve a single Yang union and generate code
|
||||||
static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, cbuf *cb0,
|
* Part of generating CLI code for Yang leaf statement to CLIgen variable
|
||||||
char *helptext, yang_stmt *yrestype, char *type);
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement (caller of type)
|
||||||
|
* @param[in] origtype Name of original type in the call
|
||||||
|
* @param[in] ytsub Yang type invocation, a sub-type of a resolved union type
|
||||||
|
* @param[in] cb Buffer where cligen code is written
|
||||||
|
* @param[in] helptext CLI help text
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
yang2cli_var_union_one(clicon_handle h,
|
yang2cli_var_union_one(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
cbuf *cb0,
|
char *origtype,
|
||||||
char *helptext,
|
yang_stmt *ytsub,
|
||||||
char *type,
|
cbuf *cb,
|
||||||
yang_stmt *yt)
|
char *helptext)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
|
|
@ -271,22 +284,24 @@ yang2cli_var_union_one(clicon_handle h,
|
||||||
char *pattern = NULL;
|
char *pattern = NULL;
|
||||||
uint8_t fraction_digits = 0;
|
uint8_t fraction_digits = 0;
|
||||||
enum cv_type cvtype;
|
enum cv_type cvtype;
|
||||||
yang_stmt *yrestype;
|
yang_stmt *ytype; /* resolved type */
|
||||||
char *restype;
|
char *restype;
|
||||||
|
|
||||||
if (yang_type_resolve(ys, yt, &yrestype,
|
/* Resolve the sub-union type to a resolved type */
|
||||||
&options, &mincv, &maxcv, &pattern, &fraction_digits) < 0)
|
if (yang_type_resolve(ys, ytsub, /* in */
|
||||||
|
&ytype, &options, /* resolved type */
|
||||||
|
&mincv, &maxcv, &pattern, &fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrestype?yrestype->ys_argument:NULL;
|
restype = ytype?ytype->ys_argument:NULL;
|
||||||
|
|
||||||
if (restype && strcmp(restype, "union") == 0){ /* recursive union */
|
if (restype && strcmp(restype, "union") == 0){ /* recursive union */
|
||||||
if (yang2cli_var_union(h, ys, cb0, helptext, yrestype, type) < 0)
|
if (yang2cli_var_union(h, ys, origtype, ytype, cb, helptext) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (clicon_type2cv(type, restype, &cvtype) < 0)
|
if (clicon_type2cv(origtype, restype, &cvtype) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((retval = yang2cli_var_sub(h, ys, cb0, helptext, cvtype, yrestype,
|
if ((retval = yang2cli_var_sub(h, ys, ytype, cb, helptext, cvtype,
|
||||||
options, mincv, maxcv, pattern, fraction_digits)) < 0)
|
options, mincv, maxcv, pattern, fraction_digits)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -295,25 +310,39 @@ yang2cli_var_union_one(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Loop over all sub-types of a Yang union
|
||||||
|
* Part of generating CLI code for Yang leaf statement to CLIgen variable
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement (caller)
|
||||||
|
* @param[in] origtype Name of original type in the call
|
||||||
|
* @param[in] ytype Yang resolved type (a union in this case)
|
||||||
|
* @param[in] type Name of type
|
||||||
|
* @param[in] cb Buffer where cligen code is written
|
||||||
|
* @param[in] helptext CLI help text
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
yang2cli_var_union(clicon_handle h,
|
yang2cli_var_union(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
cbuf *cb0,
|
char *origtype,
|
||||||
char *helptext,
|
yang_stmt *ytype,
|
||||||
yang_stmt *yrestype,
|
cbuf *cb,
|
||||||
char *type)
|
char *helptext)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *yt = NULL;
|
yang_stmt *ytsub = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((yt = yn_each((yang_node*)yrestype, yt)) != NULL){
|
/* Loop over all sub-types in the resolved union type, note these are
|
||||||
if (yt->ys_keyword != Y_TYPE)
|
* not resolved types (unless they are built-in, but the resolve call is
|
||||||
|
* made in the union_one call.
|
||||||
|
*/
|
||||||
|
while ((ytsub = yn_each((yang_node*)ytype, ytsub)) != NULL){
|
||||||
|
if (ytsub->ys_keyword != Y_TYPE)
|
||||||
continue;
|
continue;
|
||||||
if (i++)
|
if (i++)
|
||||||
cprintf(cb0, "|");
|
cprintf(cb, "|");
|
||||||
if (yang2cli_var_union_one(h, ys, cb0, helptext, type, yt) < 0)
|
if (yang2cli_var_union_one(h, ys, origtype, ytsub, cb, helptext) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -321,7 +350,12 @@ yang2cli_var_union(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Translate a yang leaf to cligen variable
|
/*! Generate CLI code for Yang leaf statement to CLIgen variable
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] cb Buffer where cligen code is written
|
||||||
|
* @param[in] helptext CLI help text
|
||||||
|
*
|
||||||
* Make a type lookup and complete a cligen variable expression such as <a:string>.
|
* Make a type lookup and complete a cligen variable expression such as <a:string>.
|
||||||
* One complication is yang union, that needs a recursion since it consists of sub-types.
|
* One complication is yang union, that needs a recursion since it consists of sub-types.
|
||||||
* eg type union{ type int32; type string } --> (<x:int32>| <x:string>)
|
* eg type union{ type int32; type string } --> (<x:int32>| <x:string>)
|
||||||
|
|
@ -329,11 +363,11 @@ yang2cli_var_union(clicon_handle h,
|
||||||
static int
|
static int
|
||||||
yang2cli_var(clicon_handle h,
|
yang2cli_var(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
cbuf *cb0,
|
cbuf *cb,
|
||||||
char *helptext)
|
char *helptext)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
char *type; /* orig type */
|
char *origtype;
|
||||||
yang_stmt *yrestype; /* resolved type */
|
yang_stmt *yrestype; /* resolved type */
|
||||||
char *restype; /* resolved type */
|
char *restype; /* resolved type */
|
||||||
cg_var *mincv = NULL;
|
cg_var *mincv = NULL;
|
||||||
|
|
@ -344,7 +378,7 @@ yang2cli_var(clicon_handle h,
|
||||||
int options = 0;
|
int options = 0;
|
||||||
int completionp;
|
int completionp;
|
||||||
|
|
||||||
if (yang_type_get(ys, &type, &yrestype,
|
if (yang_type_get(ys, &origtype, &yrestype,
|
||||||
&options, &mincv, &maxcv, &pattern, &fraction_digits) < 0)
|
&options, &mincv, &maxcv, &pattern, &fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
restype = yrestype?yrestype->ys_argument:NULL;
|
restype = yrestype?yrestype->ys_argument:NULL;
|
||||||
|
|
@ -353,24 +387,22 @@ yang2cli_var(clicon_handle h,
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (clicon_type2cv(origtype, restype, &cvtype) < 0)
|
||||||
if (clicon_type2cv(type, restype, &cvtype) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Note restype can be NULL here for example with unresolved hardcoded uuid */
|
/* Note restype can be NULL here for example with unresolved hardcoded uuid */
|
||||||
if (restype && strcmp(restype, "union") == 0){
|
if (restype && strcmp(restype, "union") == 0){
|
||||||
/* Union: loop over resolved type's sub-types (can also be recursive unions) */
|
/* Union: loop over resolved type's sub-types (can also be recursive unions) */
|
||||||
cprintf(cb0, "(");
|
cprintf(cb, "(");
|
||||||
if (yang2cli_var_union(h, ys, cb0, helptext, yrestype, type) < 0)
|
if (yang2cli_var_union(h, ys, origtype, yrestype, cb, helptext) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_cli_genmodel_completion(h)){
|
if (clicon_cli_genmodel_completion(h)){
|
||||||
if (cli_expand_var_generate(h, ys, cvtype, cb0,
|
if (cli_expand_var_generate(h, ys, cvtype, cb,
|
||||||
options, fraction_digits) < 0)
|
options, fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (helptext)
|
if (helptext)
|
||||||
cprintf(cb0, "(\"%s\")", helptext);
|
cprintf(cb, "(\"%s\")", helptext);
|
||||||
}
|
}
|
||||||
cprintf(cb0, ")");
|
cprintf(cb, ")");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
char *type;
|
char *type;
|
||||||
|
|
@ -382,17 +414,17 @@ yang2cli_var(clicon_handle h,
|
||||||
else
|
else
|
||||||
completionp = clicon_cli_genmodel_completion(h);
|
completionp = clicon_cli_genmodel_completion(h);
|
||||||
if (completionp)
|
if (completionp)
|
||||||
cprintf(cb0, "(");
|
cprintf(cb, "(");
|
||||||
if ((retval = yang2cli_var_sub(h, ys, cb0, helptext, cvtype, yrestype,
|
if ((retval = yang2cli_var_sub(h, ys, yrestype, cb, helptext, cvtype,
|
||||||
options, mincv, maxcv, pattern, fraction_digits)) < 0)
|
options, mincv, maxcv, pattern, fraction_digits)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (completionp){
|
if (completionp){
|
||||||
if (cli_expand_var_generate(h, ys, cvtype, cb0,
|
if (cli_expand_var_generate(h, ys, cvtype, cb,
|
||||||
options, fraction_digits) < 0)
|
options, fraction_digits) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (helptext)
|
if (helptext)
|
||||||
cprintf(cb0, "(\"%s\")", helptext);
|
cprintf(cb, "(\"%s\")", helptext);
|
||||||
cprintf(cb0, ")");
|
cprintf(cb, ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -400,8 +432,12 @@ yang2cli_var(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*! Generate CLI code for Yang leaf statement
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] cbuf Buffer where cligen code is written
|
||||||
|
* @param[in] gt CLI Generate style
|
||||||
|
* @param[in] level Indentation level
|
||||||
* @param[in] callback If set, include a "; cli_set()" callback, otherwise not.
|
* @param[in] callback If set, include a "; cli_set()" callback, otherwise not.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -449,6 +485,13 @@ yang2cli_leaf(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Generate CLI code for Yang container statement
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] cbuf Buffer where cligen code is written
|
||||||
|
* @param[in] gt CLI Generate style
|
||||||
|
* @param[in] level Indentation level
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
yang2cli_container(clicon_handle h,
|
yang2cli_container(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
|
|
@ -488,6 +531,13 @@ yang2cli_container(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Generate CLI code for Yang list statement
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] cbuf Buffer where cligen code is written
|
||||||
|
* @param[in] gt CLI Generate style
|
||||||
|
* @param[in] level Indentation level
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
yang2cli_list(clicon_handle h,
|
yang2cli_list(clicon_handle h,
|
||||||
yang_stmt *ys,
|
yang_stmt *ys,
|
||||||
|
|
@ -568,13 +618,20 @@ yang2cli_list(clicon_handle h,
|
||||||
cvec_free(cvk);
|
cvec_free(cvk);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
/*! Generate cli code for yang choice statement
|
|
||||||
|
|
||||||
Example:
|
/*! Generate CLI code for Yang choice statement
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] cbuf Buffer where cligen code is written
|
||||||
|
* @param[in] gt CLI Generate style
|
||||||
|
* @param[in] level Indentation level
|
||||||
|
@example
|
||||||
choice interface-type {
|
choice interface-type {
|
||||||
container ethernet { ... }
|
container ethernet { ... }
|
||||||
container fddi { ... }
|
container fddi { ... }
|
||||||
}
|
}
|
||||||
|
@example.end
|
||||||
@Note Removes 'meta-syntax' from cli syntax. They are not shown when xml is
|
@Note Removes 'meta-syntax' from cli syntax. They are not shown when xml is
|
||||||
translated to cli. and therefore input-syntax != output syntax. Which is bad
|
translated to cli. and therefore input-syntax != output syntax. Which is bad
|
||||||
*/
|
*/
|
||||||
|
|
@ -611,8 +668,12 @@ yang2cli_choice(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Generate CLI code for Yang statement
|
||||||
/*! Translate yang-stmt to CLIgen syntax.
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] cbuf Buffer where cligen code is written
|
||||||
|
* @param[in] gt CLI Generate style
|
||||||
|
* @param[in] level Indentation level
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
yang2cli_stmt(clicon_handle h,
|
yang2cli_stmt(clicon_handle h,
|
||||||
|
|
@ -665,17 +726,20 @@ yang2cli_stmt(clicon_handle h,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Translate from a yang specification into a CLIgen syntax.
|
/*! Generate CLI code for Yang specification
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] yspec Yang specification
|
||||||
|
* @param[out] ptnew CLIgen parse-tree
|
||||||
|
* @param[in] gt CLI Generate style
|
||||||
*
|
*
|
||||||
* Print a CLIgen syntax to cbuf string, then parse it.
|
* Code generation styles:
|
||||||
* @param gt - how to generate CLI:
|
* VARS: generate keywords for regular vars only not index
|
||||||
* VARS: generate keywords for regular vars only not index
|
* ALL: generate keywords for all variables including index
|
||||||
* ALL: generate keywords for all variables including index
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
yang2cli(clicon_handle h,
|
yang2cli(clicon_handle h,
|
||||||
yang_spec *yspec,
|
yang_spec *yspec,
|
||||||
parse_tree *ptnew,
|
parse_tree *ptnew,
|
||||||
enum genmodel_type gt)
|
enum genmodel_type gt)
|
||||||
{
|
{
|
||||||
cbuf *cbuf;
|
cbuf *cbuf;
|
||||||
|
|
|
||||||
|
|
@ -1533,17 +1533,26 @@ yang_parse(clicon_handle h,
|
||||||
/* Add top module name as dbspec-name */
|
/* Add top module name as dbspec-name */
|
||||||
clicon_dbspec_name_set(h, ymod->ys_argument);
|
clicon_dbspec_name_set(h, ymod->ys_argument);
|
||||||
|
|
||||||
/* Resolve all types */
|
/* Step 2: Go through parse tree and populate it with cv types */
|
||||||
|
if (yang_apply((yang_node*)ysp, -1, ys_populate, NULL) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Step 3: Resolve all types: populate type caches. Requires eg length/range cvecs
|
||||||
|
* from ys_populate step
|
||||||
|
*/
|
||||||
yang_apply((yang_node*)ysp, Y_TYPE, ys_resolve_type, NULL);
|
yang_apply((yang_node*)ysp, Y_TYPE, ys_resolve_type, NULL);
|
||||||
|
|
||||||
/* Step 2: Macro expansion of all grouping/uses pairs. Expansion needs marking */
|
/* Up to here resolving is made in the context they are defined, rather than the
|
||||||
|
context they are used. Like static scoping. After this we expand all
|
||||||
|
grouping/uses and unfold all macros into a single tree as they are used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Step 4: Macro expansion of all grouping/uses pairs. Expansion needs marking */
|
||||||
if (yang_expand((yang_node*)ysp) < 0)
|
if (yang_expand((yang_node*)ysp) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
yang_apply((yang_node*)ymod, -1, ys_flag_reset, (void*)YANG_FLAG_MARK);
|
yang_apply((yang_node*)ymod, -1, ys_flag_reset, (void*)YANG_FLAG_MARK);
|
||||||
|
|
||||||
/* Step 3: Go through parse tree and populate it with cv types */
|
|
||||||
if (yang_apply((yang_node*)ysp, -1, ys_populate, NULL) < 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Step 4: Top-level augmentation of all modules */
|
/* Step 4: Top-level augmentation of all modules */
|
||||||
if (yang_augment_spec(ysp) < 0)
|
if (yang_augment_spec(ysp) < 0)
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,11 @@ yang_type_cache_free(yang_type_cache *ycache)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Resolve types: populate type caches */
|
/*! Resolve types: populate type caches
|
||||||
|
* @param[in] ys This is a type statement
|
||||||
|
* @param[in] arg Not used
|
||||||
|
* Typically only called once when loading te yang type system.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
ys_resolve_type(yang_stmt *ys,
|
ys_resolve_type(yang_stmt *ys,
|
||||||
void *arg)
|
void *arg)
|
||||||
|
|
@ -218,6 +222,7 @@ ys_resolve_type(yang_stmt *ys,
|
||||||
uint8_t fraction = 0;
|
uint8_t fraction = 0;
|
||||||
yang_stmt *resolved = NULL;
|
yang_stmt *resolved = NULL;
|
||||||
|
|
||||||
|
assert(ys->ys_keyword == Y_TYPE);
|
||||||
if (yang_type_resolve((yang_stmt*)ys->ys_parent, ys, &resolved,
|
if (yang_type_resolve((yang_stmt*)ys->ys_parent, ys, &resolved,
|
||||||
&options, &mincv, &maxcv, &pattern, &fraction) < 0)
|
&options, &mincv, &maxcv, &pattern, &fraction) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -327,9 +332,10 @@ cv2yang_type(enum cv_type cv_type)
|
||||||
* handle case where yang resolve did not succedd (rtype=NULL) and then try
|
* handle case where yang resolve did not succedd (rtype=NULL) and then try
|
||||||
* to find special cligen types such as ipv4addr.
|
* to find special cligen types such as ipv4addr.
|
||||||
* not true yang types
|
* not true yang types
|
||||||
* @param[in] origtype
|
* @param[in] origtype Name of original type
|
||||||
* @param[in] restype
|
* @param[in] restype Resolved type. may be null, in that case origtype is used
|
||||||
* @param[out] cvtype
|
* @param[out] cvtype Translation from resolved type
|
||||||
|
* @note Thereis a kludge for handling direct translations of native cligen types
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_type2cv(char *origtype,
|
clicon_type2cv(char *origtype,
|
||||||
|
|
@ -854,7 +860,7 @@ resolve_restrictions(yang_stmt *yrange,
|
||||||
/*! Recursively resolve a yang type to built-in type with optional restrictions
|
/*! Recursively resolve a yang type to built-in type with optional restrictions
|
||||||
* @param [in] ys yang-stmt from where the current search is based
|
* @param [in] ys yang-stmt from where the current search is based
|
||||||
* @param [in] ytype yang-stmt object containing currently resolving type
|
* @param [in] ytype yang-stmt object containing currently resolving type
|
||||||
* @param [out] yrestype resolved type. return built-in type or NULL. mandatory
|
* @param [out] yrestype resolved type. return built-in type or NULL. mandatory
|
||||||
* @param [out] options pointer to flags field of optional values. optional
|
* @param [out] options pointer to flags field of optional values. optional
|
||||||
* @param [out] mincv pointer to cv with min range or length. If options&YANG_OPTIONS_RANGE
|
* @param [out] mincv pointer to cv with min range or length. If options&YANG_OPTIONS_RANGE
|
||||||
* @param [out] maxcv pointer to cv with max range or length. If options&YANG_OPTIONS_RANGE
|
* @param [out] maxcv pointer to cv with max range or length. If options&YANG_OPTIONS_RANGE
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ module example{
|
||||||
type string {
|
type string {
|
||||||
pattern
|
pattern
|
||||||
'(([e-f])\.){3}[e-f]';
|
'(([e-f])\.){3}[e-f]';
|
||||||
|
length "1..253";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typedef ad {
|
typedef ad {
|
||||||
|
|
@ -42,8 +43,8 @@ module example{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list list {
|
list list {
|
||||||
key k;
|
key ip;
|
||||||
leaf k {
|
leaf ip {
|
||||||
type af;
|
type af;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,19 +87,19 @@ new "cli commit"
|
||||||
expectfn "$clixon_cli -1f $clixon_cf -l o -y /tmp/type.yang -l o commit" "^$"
|
expectfn "$clixon_cli -1f $clixon_cf -l o -y /tmp/type.yang -l o commit" "^$"
|
||||||
|
|
||||||
new "netconf validate ok"
|
new "netconf validate ok"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/type.yang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf set ab fail"
|
new "netconf set ab wrong"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><edit-config><target><candidate/></target><config><list><k>a.b&c.d</k></list></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/type.yang" "<rpc><edit-config><target><candidate/></target><config><list><ip>a.b&c.d</ip></list></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf validate"
|
new "netconf validate"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/type.yang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/type.yang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $clixon_cf" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/type.yang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if still alive
|
# Check if still alive
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue