Changed YANG uses/grouping to keep uses statement and flag it with YANG_FLAG_USES_EXP
Updated yang code headers
This commit is contained in:
parent
e0cbc10fad
commit
d48442960e
4 changed files with 172 additions and 146 deletions
|
|
@ -148,6 +148,7 @@ ys_grouping_module_resolve(yang_stmt *ymod,
|
|||
}
|
||||
|
||||
/*! Resolve a grouping name from a point in the yang tree
|
||||
*
|
||||
* @param[in] ys Yang statement of "uses" statement doing the lookup
|
||||
* @param[in] prefix Prefix of grouping to look for
|
||||
* @param[in] name Name of grouping to look for
|
||||
|
|
@ -409,6 +410,7 @@ yang_augment_module(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Given a refine node, perform the refinement action on the target refine node
|
||||
*
|
||||
* The RFC is somewhat complicate in the rules for refine.
|
||||
* Most nodes will be replaced, but some are added
|
||||
* @param[in] yr Refine node
|
||||
|
|
@ -477,6 +479,7 @@ ys_do_refine(yang_stmt *yr,
|
|||
}
|
||||
|
||||
/*! Check if Yang node y is a leaf in yang node list yp
|
||||
*
|
||||
* Could be made to a generic function used elsewhere as well
|
||||
* @param[in] y Yang leaf
|
||||
* @param[in] yp Yang list parent
|
||||
|
|
@ -507,15 +510,17 @@ ys_iskey(yang_stmt *y,
|
|||
}
|
||||
|
||||
/*! Helper function to yang_expand_grouping
|
||||
*
|
||||
* @param[in] yn Yang parent node of uses ststement
|
||||
* @param[in] ys Uses statement
|
||||
* @param[in] i
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
yang_expand_uses_node(yang_stmt *yn,
|
||||
yang_stmt *ys,
|
||||
int i)
|
||||
int i)
|
||||
{
|
||||
int retval = -1;
|
||||
char *id = NULL;
|
||||
|
|
@ -555,12 +560,12 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
goto done;
|
||||
}
|
||||
} while((yp = yang_parent_get(yp)) != NULL);
|
||||
if (yang_flag_get(ygrouping, YANG_FLAG_MARK) == 0){
|
||||
if (yang_flag_get(ygrouping, YANG_FLAG_GROUPING) == 0){
|
||||
/* Check mark flag to see if this grouping has been expanded before,
|
||||
* here below in the traverse section
|
||||
* A mark could be completely normal (several uses) or it could be a recursion.
|
||||
*/
|
||||
yang_flag_set(ygrouping, YANG_FLAG_MARK); /* Mark as (being) expanded */
|
||||
yang_flag_set(ygrouping, YANG_FLAG_GROUPING); /* Mark as (being) expanded */
|
||||
if (yang_expand_grouping(ygrouping) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -584,18 +589,22 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
* yn is parent: the children of ygrouping replaces ys.
|
||||
* Is there a case when glen == 0? YES AND THIS BREAKS
|
||||
*/
|
||||
if (glen != 1){
|
||||
if (glen > 0){
|
||||
int oldbuflen = yn->ys_len;
|
||||
/* size of existing elements up from i+1 (not uses-stmt) */
|
||||
size = (yang_len_get(yn) - i - 1)*sizeof(struct yang_stmt *);
|
||||
yn->ys_len += glen - 1;
|
||||
if (glen && (yn->ys_stmt = realloc(yn->ys_stmt, (yang_len_get(yn))*sizeof(yang_stmt *))) == 0){
|
||||
yn->ys_len += glen;
|
||||
if ((yn->ys_stmt = realloc(yn->ys_stmt, (yang_len_get(yn))*sizeof(yang_stmt *))) == 0){
|
||||
clicon_err(OE_YANG, errno, "realloc");
|
||||
goto done;
|
||||
}
|
||||
/* Then move all existing elements up from i+1 (not uses-stmt) */
|
||||
/* Here, glen last elements are not initialized.
|
||||
* Zeroed here but will be assigned later in the "j" loop below
|
||||
*/
|
||||
memset(&yn->ys_stmt[oldbuflen], 0, glen*sizeof(yang_stmt *));
|
||||
/* Move existing elements if any */
|
||||
if (size)
|
||||
memmove(&yn->ys_stmt[i+glen],
|
||||
&yn->ys_stmt[i+1],
|
||||
size);
|
||||
memmove(&yn->ys_stmt[i+glen+1], &yn->ys_stmt[i+1], size);
|
||||
}
|
||||
/* Find when statement, if present */
|
||||
if ((ywhen = yang_find(ys, Y_WHEN, NULL)) != NULL){
|
||||
|
|
@ -604,6 +613,7 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
goto done;
|
||||
}
|
||||
/* Note: yang_desc_schema_nodeid() requires ygrouping2 to be in yspec tree,
|
||||
* due to correct module prefixes etc.
|
||||
* cannot be dangling, insert into tree here and then prune immediately after while loop
|
||||
*/
|
||||
if (yn_insert(yang_parent_get(ygrouping), ygrouping2) < 0)
|
||||
|
|
@ -667,16 +677,13 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
/* This is for extensions that allow list keys to be optional, see restconf_main_extension_cb */
|
||||
if (yang_flag_get(ys, YANG_FLAG_NOKEY))
|
||||
yang_flag_set(yg, YANG_FLAG_NOKEY);
|
||||
yn->ys_stmt[i+k] = yg;
|
||||
yn->ys_stmt[i+k+1] = yg;
|
||||
yg->ys_parent = yn;
|
||||
k++;
|
||||
}
|
||||
/* Remove 'uses' node */
|
||||
ys_free(ys);
|
||||
/* Remove the grouping copy */
|
||||
ygrouping2->ys_len = 0; /* Cant do with get access function */
|
||||
ys_free(ygrouping2);
|
||||
|
||||
retval = 0;
|
||||
done:
|
||||
if (wnsc)
|
||||
|
|
@ -689,8 +696,8 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Macro expansion of grouping/uses done in step 2 of yang parsing
|
||||
* RFC7950:
|
||||
* Identifiers appearing inside the grouping are resolved
|
||||
*
|
||||
* RFC7950: Identifiers appearing inside the grouping are resolved
|
||||
* relative to the scope in which the grouping is defined, not where it is
|
||||
* used. Prefix mappings, type names, grouping names, and extension usage are
|
||||
* evaluated in the hierarchy where the "grouping" statement appears.
|
||||
|
|
@ -698,9 +705,9 @@ yang_expand_uses_node(yang_stmt *yn,
|
|||
* until the contents of the grouping are added to the schema tree via a
|
||||
* "uses" statement that does not appear inside a "grouping" statement,
|
||||
* at which point they are bound to the namespace of the current module.
|
||||
* @param[in] yn Yang node for recursive iteration
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @param[in] yn Yang node for recursive iteration
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
yang_expand_grouping(yang_stmt *yn)
|
||||
|
|
@ -715,29 +722,35 @@ yang_expand_grouping(yang_stmt *yn)
|
|||
ys = yn->ys_stmt[i];
|
||||
switch (yang_keyword_get(ys)){
|
||||
case Y_USES:
|
||||
if (yang_expand_uses_node(yn, ys, i) < 0)
|
||||
goto done;
|
||||
break; /* Note same child is re-iterated since it may be changed */
|
||||
if (yang_flag_get(ys, YANG_FLAG_GROUPING) == 0){
|
||||
if (yang_expand_uses_node(yn, ys, i) < 0)
|
||||
goto done;
|
||||
yang_flag_set(ys, YANG_FLAG_GROUPING);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* Second pass since length may have changed */
|
||||
for (i=0; i<yang_len_get(yn); i++){
|
||||
ys = yn->ys_stmt[i];
|
||||
if (yang_keyword_get(ys) == Y_GROUPING){
|
||||
/* Check mark flag to see if this grouping has been expanded before, here or in the
|
||||
* 'uses' section
|
||||
/* This is for expanding uses under groupings in place, not after expansio n
|
||||
* Check mark flag to see if this grouping has been expanded before, here or in the
|
||||
* 'uses' section.
|
||||
* A mark could be completely normal (several uses) or it could be a recursion.
|
||||
*/
|
||||
if (yang_flag_get(ys, YANG_FLAG_MARK) == 0){
|
||||
yang_flag_set(ys, YANG_FLAG_MARK); /* Mark as (being) expanded */
|
||||
if (yang_flag_get(ys, YANG_FLAG_GROUPING) == 0){
|
||||
yang_flag_set(ys, YANG_FLAG_GROUPING); /* Mark as (being) expanded */
|
||||
if (yang_expand_grouping(ys) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else{
|
||||
else
|
||||
|
||||
{
|
||||
if (yang_expand_grouping(ys) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -811,6 +824,7 @@ yang_parse_str(char *str,
|
|||
}
|
||||
|
||||
/*! Parse yang spec from an open file descriptor
|
||||
*
|
||||
* @param[in] fd File descriptor containing the YANG file as ASCII characters
|
||||
* @param[in] name For debug, eg filename
|
||||
* @param[in] yspec Yang specification. Should have been created by caller using yspec_new
|
||||
|
|
@ -863,6 +877,7 @@ yang_parse_file(FILE *fp,
|
|||
}
|
||||
|
||||
/*! Given a yang filename, extract the revision as an integer as YYYYMMDD
|
||||
*
|
||||
* @param[in] filename Filename on the form: name [+ @rev ] + .yang
|
||||
* @param[out] basep "Base" filename, stripped: [+ @rev ] + .yang (malloced)
|
||||
* @param[out] revp Revision as YYYYMMDD (0 if not found)
|
||||
|
|
@ -901,6 +916,7 @@ filename2revision(const char *filename,
|
|||
}
|
||||
|
||||
/*! No specific revision give. Match a yang file given module
|
||||
*
|
||||
* @param[in] h CLICON handle
|
||||
* @param[in] module Name of main YANG module.
|
||||
* @param[in] revision Revision or NULL
|
||||
|
|
@ -1016,8 +1032,8 @@ done:
|
|||
* @param[in] h Clixon handle (can be NULL, but then no callbacks)
|
||||
* @param[in] filename Name of file
|
||||
* @param[in] yspec Yang specification. Should have been created by caller using yspec_new
|
||||
* @retval ymod Top-level yang (sub)module
|
||||
* @retval NULL Error encountered
|
||||
* @retval ymod Top-level yang (sub)module
|
||||
* @retval NULL Error encountered
|
||||
|
||||
* The database symbols are inserted in alphabetical order.
|
||||
* See top of file for diagram of calling order
|
||||
|
|
@ -1213,71 +1229,8 @@ yang_parse_recurse(clicon_handle h,
|
|||
return retval; /* top-level (sub)module */
|
||||
}
|
||||
|
||||
/*!
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] dummy Necessary for called in yang_apply
|
||||
* @see yang_applyfn_t
|
||||
*/
|
||||
static int
|
||||
ys_schemanode_check(yang_stmt *ys,
|
||||
void *dummy)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *yres = NULL;
|
||||
yang_stmt *yp;
|
||||
char *arg;
|
||||
enum rfc_6020 keyword;
|
||||
char **vec = NULL;
|
||||
char *v;
|
||||
int nvec;
|
||||
int i;
|
||||
|
||||
yp = yang_parent_get(ys);
|
||||
arg = yang_argument_get(ys);
|
||||
keyword = yang_keyword_get(ys);
|
||||
switch (yang_keyword_get(ys)){
|
||||
case Y_AUGMENT:
|
||||
if (yang_keyword_get(yp) == Y_MODULE || /* Not top-level */
|
||||
yang_keyword_get(yp) == Y_SUBMODULE)
|
||||
break;
|
||||
/* fallthru */
|
||||
case Y_REFINE:
|
||||
if (yang_desc_schema_nodeid(yp, arg, &yres) < 0)
|
||||
goto done;
|
||||
if (yres == NULL){
|
||||
clicon_err(OE_YANG, 0, "schemanode sanity check of %s %s",
|
||||
yang_key2str(keyword), arg);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case Y_UNIQUE:{
|
||||
/* Unique: Sec 7.8.3 It takes as an argument a string that contains a space-
|
||||
separated list of schema node identifiers */
|
||||
if ((vec = clicon_strsep(arg, " \t\n", &nvec)) == NULL)
|
||||
goto done;
|
||||
for (i=0; i<nvec; i++){
|
||||
v = vec[i];
|
||||
if (yang_desc_schema_nodeid(yp, v, &yres) < 0)
|
||||
goto done;
|
||||
if (yres == NULL){
|
||||
clicon_err(OE_YANG, 0, "schemanode sanity check of %s %s",
|
||||
yang_key2str(yang_keyword_get(ys)), v);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (vec)
|
||||
free(vec);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Check lists: config lists MUST have keys
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ys Yang statement
|
||||
* Verify the following rule:
|
||||
|
|
@ -1333,6 +1286,7 @@ ys_list_check(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Depth-first topological sort
|
||||
*
|
||||
* Topological sort of a DAG
|
||||
* @param[in] yn Yang module node
|
||||
* @param[out] ylist Result list of sorted nodes with "least significant" first
|
||||
|
|
@ -1402,6 +1356,7 @@ ys_visit(struct yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Sort module/submodules according to import/include order and cycle detect
|
||||
*
|
||||
* Topological sort of a DAG
|
||||
* @param[in] yspec Yang specification.
|
||||
* @param[in] modmin Start of interval of yspec:s module children
|
||||
|
|
@ -1421,7 +1376,6 @@ yang_sort_modules(yang_stmt *yspec,
|
|||
int i;
|
||||
struct yang_stmt *yn;
|
||||
|
||||
|
||||
for (i=modmin; i<modmax; i++){
|
||||
yn = yang_child_i(yspec, i);
|
||||
/* select an unmarked node n */
|
||||
|
|
@ -1518,13 +1472,15 @@ yang_parse_post(clicon_handle h,
|
|||
* single tree as they are used.
|
||||
*/
|
||||
|
||||
/* 6: Macro expansion of all grouping/uses pairs. Expansion needs marking */
|
||||
/* 6: Macro expansion of all uses/grouping pairs.
|
||||
* All uses expansion is made "in-place", ie not after expansion.
|
||||
* Exanded nodes are marked with "GROUPING" flag
|
||||
* This alters the original YANG: after this all YANG uses have been expanded
|
||||
*/
|
||||
for (i=0; i<ylen; i++){
|
||||
if (yang_expand_grouping(ylist[i]) < 0)
|
||||
goto done;
|
||||
yang_apply(ylist[i], -1, (yang_applyfn_t*)yang_flag_reset, 1, (void*)YANG_FLAG_MARK);
|
||||
}
|
||||
|
||||
/* 7: Top-level augmentation of all modules.
|
||||
* Note: Clixon does not implement augment in USES
|
||||
* Note: There is an ordering problem, where an augment in one module depends on an augment in
|
||||
|
|
@ -1552,9 +1508,6 @@ yang_parse_post(clicon_handle h,
|
|||
|
||||
/* 10: sanity checks of expanded yangs need more here */
|
||||
for (i=0; i<ylen; i++){
|
||||
/* Check schemanode references */
|
||||
if (yang_apply(ylist[i], -1, ys_schemanode_check, 1, NULL) < 0)
|
||||
goto done;
|
||||
/* Check list key values */
|
||||
if (ys_list_check(h, ylist[i]) < 0)
|
||||
goto done;
|
||||
|
|
@ -1571,6 +1524,7 @@ yang_parse_post(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Parse yang specification and its dependencies recursively given module
|
||||
*
|
||||
* @param[in] h clicon handle
|
||||
* @param[in] module Module name, or absolute filename (including dir)
|
||||
* @param[in] revision Revision, or NULL
|
||||
|
|
@ -1616,6 +1570,7 @@ yang_spec_parse_module(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Parse yang specification and its dependencies recursively given filename
|
||||
*
|
||||
* @param[in] h clicon handle
|
||||
* @param[in] filename Actual filename (including dir and revision)
|
||||
* @param[in] yspec Modules parse are added to this yangspec
|
||||
|
|
@ -1662,6 +1617,7 @@ yang_spec_parse_file(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Load all yang modules in directory
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] dir Load all yang modules in this directory
|
||||
* @param[in] yspec Modules parse are added to this yangspec
|
||||
|
|
@ -1791,6 +1747,7 @@ yang_spec_load_dir(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! parse yang date-arg string and return a uint32 useful for arithmetics
|
||||
*
|
||||
* @param[in] datearg yang revision string as "YYYY-MM-DD"
|
||||
* @param[out] dateint Integer version as YYYYMMDD
|
||||
* @retval 0 OK
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue