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
|
|
@ -72,6 +72,7 @@ Developers may need to change their code
|
|||
|
||||
### Minor features
|
||||
|
||||
* Changed YANG uses/grouping to keep uses statement and flag it with YANG_FLAG_USES_EXP
|
||||
* Removed extras/ and build-root/ build code since they are not properly maintained
|
||||
* Refactored cli-syntax code to use cligen pt_head instead (long overdue)
|
||||
* Modified backend exit strategy so that 2nd ^C actually exits
|
||||
|
|
|
|||
|
|
@ -70,6 +70,19 @@
|
|||
* Transformed to ANYDATA but some code may need to check
|
||||
* why it is an ANYDATA
|
||||
*/
|
||||
#define YANG_FLAG_GROUPING 0x80 /* Mark node as uses/grouping expansion:
|
||||
* 1) for uses: this uses is expanded
|
||||
* 2) for grouping: all uses below are expanded
|
||||
* 3) other nodes: expanded from previous uses
|
||||
* container x {
|
||||
* ...
|
||||
* uses y; YANG_FLAG_GROUPING (1)
|
||||
* leaf z; YANG_FLAG_GROUPING (3)
|
||||
* ...
|
||||
* group y { YANG_FLAG_GROUPING (2)
|
||||
* leaf z;
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Types
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ static int yang_type_cache_cp(yang_stmt *ynew, yang_stmt *yold);
|
|||
*/
|
||||
|
||||
/*! Get Number of children yang statements
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
*/
|
||||
int
|
||||
|
|
@ -189,6 +190,7 @@ yang_len_get(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Get Specific Yang statement child
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
* @param[in] i Return this child
|
||||
*/
|
||||
|
|
@ -200,6 +202,7 @@ yang_child_i(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Get yang statement parent
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
*/
|
||||
yang_stmt *
|
||||
|
|
@ -209,6 +212,7 @@ yang_parent_get(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Get yang statement keyword
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
*/
|
||||
enum rfc_6020
|
||||
|
|
@ -218,6 +222,7 @@ yang_keyword_get(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Get yang statement context-dependent argument
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
*/
|
||||
char*
|
||||
|
|
@ -236,6 +241,7 @@ yang_argument_get(yang_stmt *ys)
|
|||
* 2d. type: leafref types: derived instances.
|
||||
*/
|
||||
/*! Set yang argument, not not copied
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
* @param[in] arg Argument, note must be malloced
|
||||
* Typically only done at parsing / initiation
|
||||
|
|
@ -249,6 +255,7 @@ yang_argument_set(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Get yang statement CLIgen variable
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
*/
|
||||
cg_var*
|
||||
|
|
@ -258,6 +265,7 @@ yang_cv_get(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Set yang statement CLIgen variable
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
* @param[in] cv cligen variable
|
||||
* @note: Frees on replace, not if cv is NULL. This is for some ys_cp/ys_dup cases, which means
|
||||
|
|
@ -274,6 +282,7 @@ yang_cv_set(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Get yang statement CLIgen variable vector
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
* @note To add entries, use yang_cvec_add(), since this function may return NULL
|
||||
*/
|
||||
|
|
@ -284,6 +293,7 @@ yang_cvec_get(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Set yang statement CLIgen variable vector
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
* @param[in] cvec CLIgen vector
|
||||
* @retval 0 OK
|
||||
|
|
@ -334,6 +344,7 @@ yang_cvec_add(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Get yang stmt flags, used for internal algorithms
|
||||
*
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] flag Flags value(s) to get, see YANG_FLAG_*
|
||||
* @retval value Flags value masked by "flag" parameter, see YANG_FLAG_*
|
||||
|
|
@ -346,6 +357,7 @@ yang_flag_get(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Set yang stmt flags, used for internal algorithms
|
||||
*
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] flag Flag value(s) to set, see YANG_FLAG_*
|
||||
*/
|
||||
|
|
@ -358,6 +370,7 @@ yang_flag_set(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Reset yang stmt flags, used for internal algorithms
|
||||
*
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] flag Flag value(s) to reset, see YANG_FLAG_*
|
||||
*/
|
||||
|
|
@ -376,7 +389,7 @@ yang_flag_reset(yang_stmt *ys,
|
|||
* @param[in] ys Yang statement
|
||||
* @retval xpath xpath should evaluate to true at validation
|
||||
* @retval NULL Not set
|
||||
* Note xpath context is PARENT which is different from when actual when child which is
|
||||
* @note xpath context is PARENT which is different from when actual when child which is
|
||||
* child itself
|
||||
*/
|
||||
char*
|
||||
|
|
@ -525,6 +538,7 @@ yang_stats_global(uint64_t *nr)
|
|||
}
|
||||
|
||||
/*! Return the alloced memory of a single YANG obj
|
||||
*
|
||||
* @param[in] y YANG object
|
||||
* @param[out] szp Size of this YANG obj
|
||||
* @retval 0 OK
|
||||
|
|
@ -566,6 +580,7 @@ yang_stats_one(yang_stmt *y,
|
|||
}
|
||||
|
||||
/*! Return statistics of an YANG-stmt tree recursively
|
||||
*
|
||||
* @param[in] yt YANG object
|
||||
* @param[out] nrp Number of YANG objects recursively
|
||||
* @param[out] szp Size of this YANG stmt recursively
|
||||
|
|
@ -604,6 +619,7 @@ yang_stats(yang_stmt *yt,
|
|||
/* stats end */
|
||||
|
||||
/*! Create new yang specification
|
||||
*
|
||||
* @retval yspec Free with ys_free()
|
||||
* @retval NULL Error
|
||||
*/
|
||||
|
|
@ -623,6 +639,7 @@ yspec_new(void)
|
|||
}
|
||||
|
||||
/*! Create new yang node/statement
|
||||
*
|
||||
* @retval ys Free with ys_free()
|
||||
* @retval NULL Error
|
||||
*/
|
||||
|
|
@ -703,10 +720,11 @@ ys_free1(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Remove child i from parent yp (dont free)
|
||||
*
|
||||
* @param[in] yp Parent node
|
||||
* @param[in] i Order of child to remove
|
||||
* @retval NULL No such node, nothing done
|
||||
* @retval yc returned orphaned yang node
|
||||
* @retval NULL No such node, nothing done
|
||||
* @see ys_free Deallocate yang node
|
||||
* @see ys_prune_self Prune child itself
|
||||
* @note Do not call this in a loop of yang children (unless you know what you are doing)
|
||||
|
|
@ -733,7 +751,8 @@ ys_prune(yang_stmt *yp,
|
|||
return yc;
|
||||
}
|
||||
|
||||
/*! Remove yang node from parent (dont free
|
||||
/*! Remove yang node from parent (dont free)
|
||||
*
|
||||
* @param[in] ys Yang node to remove
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
|
|
@ -769,6 +788,7 @@ ys_prune_self(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Free all yang children tree recursively
|
||||
*
|
||||
* @param[in] ys Yang node to its children recursively
|
||||
*/
|
||||
static int
|
||||
|
|
@ -790,6 +810,7 @@ ys_freechildren(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Free a yang statement tree recursively
|
||||
*
|
||||
* @param[in] ys Yang node to remove and all its children recursively
|
||||
* @note does not remove yang node from tree
|
||||
* @see ys_prune Remove from parent
|
||||
|
|
@ -802,7 +823,8 @@ ys_free(yang_stmt *ys)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Allocate larger yang statement vector adding empty field last */
|
||||
/*! Allocate larger yang statement vector adding empty field last
|
||||
*/
|
||||
static int
|
||||
yn_realloc(yang_stmt *yn)
|
||||
{
|
||||
|
|
@ -817,6 +839,7 @@ yn_realloc(yang_stmt *yn)
|
|||
}
|
||||
|
||||
/*! Copy yang statement recursively from old to new
|
||||
*
|
||||
* @param[in] ynew New empty (but created) yang statement (to)
|
||||
* @param[in] yold Old existing yang statement (from)
|
||||
* @retval 0 OK
|
||||
|
|
@ -893,6 +916,7 @@ ys_cp(yang_stmt *ynew,
|
|||
}
|
||||
|
||||
/*! Create a new yang node and copy the contents recursively from the original. *
|
||||
*
|
||||
* @param[in] old Old existing yang statement (from)
|
||||
* @retval NULL Error
|
||||
* @retval nw New created yang statement
|
||||
|
|
@ -1190,6 +1214,7 @@ yang_find_datanode(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Find child schema node with matching argument (container, leaf, etc)
|
||||
*
|
||||
* @param[in] yn Yang node, current context node.
|
||||
* @param[in] argument if NULL, match any(first) argument.
|
||||
* @note XXX unify code with yang_find_datanode?
|
||||
|
|
@ -1270,8 +1295,8 @@ yang_find_schemanode(yang_stmt *yn,
|
|||
/*! Given a yang statement, or module itself, find the prefix associated to this module
|
||||
*
|
||||
* @param[in] ys Yang statement in module tree (or module itself)
|
||||
* @retval NULL No prefix found. This is an error
|
||||
* @retval prefix OK: Prefix as char* pointer into yang tree
|
||||
* @retval NULL No prefix found. This is an error
|
||||
* @code
|
||||
* char *myprefix;
|
||||
* myprefix = yang_find_myprefix(ys);
|
||||
|
|
@ -1303,8 +1328,8 @@ yang_find_myprefix(yang_stmt *ys)
|
|||
/*! Given a yang statement, find the namespace URI associated to this module
|
||||
*
|
||||
* @param[in] ys Yang statement in module tree (or module itself)
|
||||
* @retval NULL Error: No namespace found. This is an error
|
||||
* @retval ns Namspace URI as char* pointer into yang tree
|
||||
* @retval NULL Error: No namespace found. This is an error
|
||||
* @code
|
||||
* char *myns = yang_find_mynamespace(ys);
|
||||
* @endcode
|
||||
|
|
@ -1329,15 +1354,16 @@ yang_find_mynamespace(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Given a yang statement and namespace, find local prefix valid in module
|
||||
*
|
||||
* This is useful if you want to make a "reverse" lookup, you know the
|
||||
* (global) namespace of a module, but you do not know the local prefix
|
||||
* used to access it in XML.
|
||||
* @param[in] ys Yang statement in module tree (or module itself)
|
||||
* @param[in] ns Namespace URI as char* pointer into yang tree
|
||||
* @param[out] prefix Local prefix to access module with (direct pointer)
|
||||
* @retval -1 Error
|
||||
* @retval 0 Not found
|
||||
* @retval 1 Found
|
||||
* @retval 0 Not found
|
||||
* @retval -1 Error
|
||||
* @note prefix NULL is not returned, if own module, then return its prefix
|
||||
* @code
|
||||
* char *prefix = NULL;
|
||||
|
|
@ -1404,9 +1430,9 @@ yang_find_prefix_by_namespace(yang_stmt *ys,
|
|||
* @param[in] ys Yang statement in module tree (or module itself)
|
||||
* @param[in] prefix Local prefix to access module with (direct pointer)
|
||||
* @param[out] ns Namespace URI as char* pointer into yang tree
|
||||
* @retval -1 Error
|
||||
* @retval 0 Not found
|
||||
* @retval 1 Found
|
||||
* @retval 0 Not found
|
||||
* @retval -1 Error
|
||||
* @note prefix NULL is not returned, if own module, then return its prefix
|
||||
* @code
|
||||
* char *ns = NULL;
|
||||
|
|
@ -1515,11 +1541,12 @@ yang_choice(yang_stmt *y)
|
|||
}
|
||||
|
||||
/*! Find matching y in yp:s children, "yang order" of y when y is choice
|
||||
*
|
||||
* @param[in] yp Choice node
|
||||
* @param[in] y Yang datanode to find
|
||||
* @param[out] index Index of y in yp:s list of children
|
||||
* @retval 0 not found (must be datanode)
|
||||
* @retval 1 found
|
||||
* @retval 0 not found (must be datanode)
|
||||
* @see order1 the main function
|
||||
* There are two distinct cases, either (1) the choice has case statements, or
|
||||
* (2) it uses shortcut mode without case statements.
|
||||
|
|
@ -1571,6 +1598,7 @@ yang_order1_choice(yang_stmt *yp,
|
|||
}
|
||||
|
||||
/*! Find matching y in yp:s children, return "yang order" of y or -1 if not found
|
||||
*
|
||||
* @param[in] yp Parent
|
||||
* @param[in] y Yang datanode to find
|
||||
* @param[out] index Index of y in yp:s list of children
|
||||
|
|
@ -1609,6 +1637,7 @@ yang_order1(yang_stmt *yp,
|
|||
}
|
||||
|
||||
/*! Return order of yang statement y in parents child vector
|
||||
*
|
||||
* @param[in] y Find position of this data-node
|
||||
* @param[out] index Index of y in yp:s list of children
|
||||
* @retval >=0 Order of child with specified argument
|
||||
|
|
@ -1664,6 +1693,7 @@ yang_order(yang_stmt *y)
|
|||
}
|
||||
|
||||
/*! Map from YANG keywords ints to strings
|
||||
*
|
||||
* @param[in] int Integer representation of YANG keywords
|
||||
* @retval str String representation of YANG keywords
|
||||
*/
|
||||
|
|
@ -1674,6 +1704,7 @@ yang_key2str(int keyword)
|
|||
}
|
||||
|
||||
/*! Map from yang keyword strings to ints
|
||||
*
|
||||
* @param[in] str String representation of YANG keywords
|
||||
* @retval int Integer representation of YANG keywords
|
||||
*/
|
||||
|
|
@ -1684,6 +1715,7 @@ yang_str2key(char *str)
|
|||
}
|
||||
|
||||
/*! Find top data node among all modules by namespace in xml tree
|
||||
*
|
||||
* @param[in] yspec Yang specification
|
||||
* @param[in] xt XML node
|
||||
* @param[out] ymod Yang module (NULL if not found)
|
||||
|
|
@ -1722,6 +1754,7 @@ ys_module_by_xml(yang_stmt *yspec,
|
|||
}
|
||||
|
||||
/*! Find the top module or sub-module given a statement from within a yang tree
|
||||
*
|
||||
* Ultimate top is yang spec, dont return that
|
||||
* The routine recursively finds ancestors.
|
||||
* @param[in] ys Any yang statement in a yang tree
|
||||
|
|
@ -1757,6 +1790,7 @@ ys_module(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Find real top module given a statement in a yang tree
|
||||
*
|
||||
* With "real" top module means that if sub-module is the top-node,
|
||||
* the module that the sub-module belongs-to is found recursively
|
||||
* @param[in] ys Any yang statement in a yang tree
|
||||
|
|
@ -1807,6 +1841,7 @@ ys_real_module(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Find top of tree, the yang specification from within the tree
|
||||
*
|
||||
* @param[in] ys Any yang statement in a yang tree
|
||||
* @retval yspec The top yang specification
|
||||
* @see ys_module
|
||||
|
|
@ -1826,7 +1861,8 @@ ys_spec(yang_stmt *ys)
|
|||
return (yang_stmt*)ys;
|
||||
}
|
||||
|
||||
/*! string is quoted if it contains space or tab, needs double '' */
|
||||
/*! String is quoted if it contains space or tab, needs double ''
|
||||
*/
|
||||
static int inline
|
||||
quotedstring(char *s)
|
||||
{
|
||||
|
|
@ -1840,6 +1876,7 @@ quotedstring(char *s)
|
|||
}
|
||||
|
||||
/*! Print yang specification to file
|
||||
*
|
||||
* @param[in] f File to print to.
|
||||
* @param[in] yn Yang node to print
|
||||
* @param[in] fn Callback to make print function
|
||||
|
|
@ -1870,6 +1907,7 @@ yang_print_cb(FILE *f,
|
|||
}
|
||||
|
||||
/*! Print yang specification to file
|
||||
*
|
||||
* @param[in] f File to print to.
|
||||
* @param[in] yn Yang node to print
|
||||
* @see yang_print_cbuf
|
||||
|
|
@ -1882,6 +1920,7 @@ yang_print(FILE *f,
|
|||
}
|
||||
|
||||
/*! Print yang top-level modules only
|
||||
*
|
||||
* @param[in] f File to print to.
|
||||
* @param[in] yn Yang node to print
|
||||
* @see yang_print_cbuf
|
||||
|
|
@ -1944,6 +1983,7 @@ yang_spec_dump(yang_stmt *yspec,
|
|||
}
|
||||
|
||||
/*! Print yang specification to cligen buf
|
||||
*
|
||||
* @param[in] cb Cligen buffer. This is where the pretty print is.
|
||||
* @param[in] yn Yang node to print
|
||||
* @param[in] marginal Tab indentation, mainly for recursion.
|
||||
|
|
@ -2266,6 +2306,7 @@ ys_populate_leaf(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Populate list yang statement
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ys The yang statement (type) to populate.
|
||||
*/
|
||||
|
|
@ -2286,6 +2327,7 @@ ys_populate_list(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Set range or length boundary for built-in yang types
|
||||
*
|
||||
* Help functions to range and length statements
|
||||
*/
|
||||
static int
|
||||
|
|
@ -2459,6 +2501,7 @@ ys_populate_length(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Sanity check yang type statement
|
||||
*
|
||||
* XXX: Replace with generic parent/child type-check
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ys The yang statement (type) to populate.
|
||||
|
|
@ -2582,8 +2625,8 @@ ys_populate_identity(clicon_handle h,
|
|||
* @param[in] yspec yang specification
|
||||
* @param[in] module Name of module
|
||||
* @param[in] feature Name of feature
|
||||
* @retval 0 Not found or not set
|
||||
* @retval 1 Found and set
|
||||
* @retval 0 Not found or not set
|
||||
* XXX: should the in-param be h, ymod, or yspec?
|
||||
*/
|
||||
int
|
||||
|
|
@ -2671,6 +2714,7 @@ ys_populate_feature(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Populate the unique statement with a cvec
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ys The yang statement (unique) to populate.
|
||||
*/
|
||||
|
|
@ -2774,11 +2818,11 @@ ys_populate_unknown(clicon_handle h,
|
|||
}
|
||||
|
||||
/*! Populate modules / submodules
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ys The yang statement (module/submodule) to populate.
|
||||
*
|
||||
* Check RFC 7950: 7.1.4: All prefixes, including the prefix for the module itself,
|
||||
* MUST be unique within the module or submodule.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] ys The yang statement (module/submodule) to populate.
|
||||
*/
|
||||
static int
|
||||
ys_populate_module_submodule(clicon_handle h,
|
||||
|
|
@ -2888,6 +2932,7 @@ ys_populate(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Run after grouping expand and augment
|
||||
*
|
||||
* @see ys_populate run before grouping expand and augment
|
||||
*/
|
||||
int
|
||||
|
|
@ -2918,11 +2963,12 @@ ys_populate2(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Find feature and if-feature nodes, check features and remove disabled nodes
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] yt Yang statement
|
||||
* @retval -1 Error
|
||||
* @retval 0 Feature not enabled: remove yt
|
||||
* @retval 1 OK
|
||||
* @retval 0 Feature not enabled: remove yt
|
||||
* @retval -1 Error
|
||||
* @note On return 0 the over-lying function need to remove yt from its parent
|
||||
* @note cannot use yang_apply here since child-list is modified (destructive)
|
||||
* @note if-features is parsed in full context here, previous restricted pass in ys_parse_sub
|
||||
|
|
@ -3004,9 +3050,9 @@ yang_features(clicon_handle h,
|
|||
* @param[in] fn Callback
|
||||
* @param[in] depth Depth argument: where to start. If <=0 call the calling node yn, if 1 start with its children, etc
|
||||
* @param[in] arg Argument
|
||||
* @retval -1 Error, aborted at first error encounter
|
||||
* @retval 0 OK, all nodes traversed
|
||||
* @retval n OK, aborted at first encounter of first match
|
||||
* @retval 0 OK, all nodes traversed
|
||||
* @retval -1 Error, aborted at first error encounter
|
||||
* @code
|
||||
* int ys_fn(yang_stmt *ys, void *arg)
|
||||
* {
|
||||
|
|
@ -3053,6 +3099,7 @@ yang_apply(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Check if a node is a yang "data node"
|
||||
*
|
||||
* @param[in] ys Yang statement node
|
||||
* @retval 0 Yang node is NOT a data node
|
||||
* @retval !=0 Yang node IS a data noed
|
||||
|
|
@ -3082,8 +3129,8 @@ yang_datanode(yang_stmt *ys)
|
|||
* @param[in] cvv Schema-node path encoded as a name/value pair list.
|
||||
* @param[in] nsc Namespace context from yang for the prefixes (names) of cvv
|
||||
* @param[out] yres Result yang statement node, or NULL if not found
|
||||
* @retval -1 Error, with clicon_err called
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error, with clicon_err called
|
||||
* A schema node identifier consists of a path of identifiers, separated by slashes ("/").
|
||||
* References to identifiers defined in external modules MUST be
|
||||
* qualified with appropriate prefixes, and references to identifiers
|
||||
|
|
@ -3162,11 +3209,12 @@ schema_nodeid_iterate(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Given an absolute schema-nodeid (eg /a/b/c) find matching yang spec
|
||||
*
|
||||
* @param[in] yn Original yang stmt (where call is made)
|
||||
* @param[in] schema_nodeid Absolute schema-node-id, ie /a/b
|
||||
* @param[out] yres Result yang statement node, or NULL if not found
|
||||
* @retval -1 Error, with clicon_err called
|
||||
* @retval 0 OK , with result in yres
|
||||
* @retval -1 Error, with clicon_err called
|
||||
* Assume schema nodeid:s have prefixes, (actually the first).
|
||||
* @see RFC7950 6.5
|
||||
* o schema node: A node in the schema tree. One of action, container,
|
||||
|
|
@ -3255,6 +3303,7 @@ yang_abs_schema_nodeid(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Given a descendant schema-nodeid (eg a/b/c) find matching yang spec
|
||||
*
|
||||
* @param[in] yn Yang node (must be part of yspec tree, cannot be "dangling")
|
||||
* @param[in] schema_nodeid Descendant schema-node-id, ie a/b
|
||||
* @param[in] keyword A schemode of this type, or -1 if any
|
||||
|
|
@ -3329,9 +3378,10 @@ yang_desc_schema_nodeid(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Return config state of this node
|
||||
*
|
||||
* @param[in] ys Yang statement
|
||||
* @retval 0 If node has a config sub-statement and it is false
|
||||
* @retval 1 If node has not config sub-statement or it is true
|
||||
* @retval 0 If node has a config sub-statement and it is false
|
||||
* @see yang_config_ancestor which also takes ancestors into account, which you should normally do.
|
||||
*/
|
||||
int
|
||||
|
|
@ -3351,8 +3401,8 @@ yang_config(yang_stmt *ys)
|
|||
*
|
||||
* config statement is default true.
|
||||
* @param[in] ys Yang statement
|
||||
* @retval 0 Node or one of its ancestor has config false or is RPC or notification
|
||||
* @retval 1 Neither node nor any of its ancestors has config false
|
||||
* @retval 0 Node or one of its ancestor has config false or is RPC or notification
|
||||
*/
|
||||
int
|
||||
yang_config_ancestor(yang_stmt *ys)
|
||||
|
|
@ -3391,8 +3441,8 @@ yang_config_ancestor(yang_stmt *ys)
|
|||
*
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] delimiter Delimiter character (eg ' ' or ',')
|
||||
* @retval NULL Error
|
||||
* @retval cvec Vector of strings. Free with cvec_free()
|
||||
* @retval NULL Error
|
||||
* @code
|
||||
* cvec *cvv;
|
||||
* cg_var *cv = NULL;
|
||||
|
|
@ -3442,10 +3492,9 @@ yang_arg2cvec(yang_stmt *ys,
|
|||
* @param[in] yn Yang list node with sub-statements (look for a key child)
|
||||
* @param[in] name Check if this name (eg "b") is a key in the yang key statement
|
||||
* @param[out] lastkey If 1 this is the last key in a multi-key list
|
||||
*
|
||||
* @retval -1 Error
|
||||
* @retval 0 No match
|
||||
* @retval 1 Yes match
|
||||
* @retval 0 No match
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
yang_key_match(yang_stmt *yn,
|
||||
|
|
@ -3487,6 +3536,7 @@ yang_key_match(yang_stmt *yn,
|
|||
}
|
||||
|
||||
/*! Set type cache for yang type
|
||||
*
|
||||
* @param[in] rxmode Kludge to know which regexp engine is used
|
||||
* @see yang_type_cache_regexp_set where cache is extended w compiled regexps
|
||||
*/
|
||||
|
|
@ -3530,6 +3580,7 @@ yang_type_cache_set(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Extend yang type cache with compiled regexps
|
||||
*
|
||||
* Compiled Regexps are computed in validate code - after initial cache set
|
||||
* @param[in] regexps
|
||||
*/
|
||||
|
|
@ -3556,10 +3607,11 @@ yang_type_cache_regexp_set(yang_stmt *ytype,
|
|||
}
|
||||
|
||||
/*! Get individual fields (direct/destructively) from yang type cache.
|
||||
*
|
||||
* @param[out] patterns Initialized cvec of regexp patterns strings
|
||||
* @retval -1 Error
|
||||
* @retval 0 No cache
|
||||
* @retval 1 OK
|
||||
* @retval 0 No cache
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
yang_type_cache_get(yang_stmt *ytype,
|
||||
|
|
@ -3844,6 +3896,7 @@ yang_init(clicon_handle h)
|
|||
|
||||
#ifdef XML_EXPLICIT_INDEX
|
||||
/*! Mark element as search_index in list
|
||||
*
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
|
|
@ -3910,8 +3963,8 @@ yang_search_index_extension(clicon_handle h,
|
|||
* 3) no other data node children
|
||||
* @param[in] ys Yang node
|
||||
* @param[in] subkeyw Expected keyword of single child (typically Y_LIST)
|
||||
* @retval 0 No, node does not have single child of specified type
|
||||
* @retval 1 Yes, node has single child of specified type
|
||||
* @retval 0 No, node does not have single child of specified type
|
||||
* @see https://github.com/openconfig/ygot/blob/master/docs/design.md#openconfig-path-compression 2nd clause
|
||||
*/
|
||||
int
|
||||
|
|
@ -3951,6 +4004,7 @@ yang_single_child_type(yang_stmt *ys,
|
|||
}
|
||||
|
||||
/*! Get action callback list
|
||||
*
|
||||
* XXX rc shouldnt really be void* but the type definitions in .h file got complicated
|
||||
*/
|
||||
void *
|
||||
|
|
@ -3960,6 +4014,7 @@ yang_action_cb_get(yang_stmt *ys)
|
|||
}
|
||||
|
||||
/*! Add an action callback to YANG node
|
||||
*
|
||||
* XXX rc shouldnt really be void* but the type definitions in .h file got complicated
|
||||
*/
|
||||
int
|
||||
|
|
|
|||
|
|
@ -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,8 +510,10 @@ 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
|
||||
*/
|
||||
|
|
@ -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.
|
||||
|
|
@ -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_flag_get(ys, YANG_FLAG_GROUPING) == 0){
|
||||
if (yang_expand_uses_node(yn, ys, i) < 0)
|
||||
goto done;
|
||||
break; /* Note same child is re-iterated since it may be changed */
|
||||
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
|
||||
|
|
@ -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