C-API changes: Replace yn_each with yn_iter, add keyw argument to yang_stats()

This commit is contained in:
Olof hagsand 2024-06-17 12:51:39 +02:00
parent 3e07a1d279
commit 4b9ee6740b
23 changed files with 358 additions and 248 deletions

View file

@ -14,6 +14,15 @@
## 7.2.0
Expected: October 2024
### C/CLI-API changes on existing features
Developers may need to change their code
* New `yn_iter()` yang iterator replaces `yn_each()`
* Use an integer iteratorinstead of yang object
* Replace `y1 = NULL; y1 = yn_each(y0, y1)` with `int inext = 0; yn_iter(y0, &inext)`
* Add `keyw`argument to `yang_stats()`
## 7.1.0
3 July 2024

View file

@ -436,7 +436,7 @@ clixon_stats_module_get(clixon_handle h,
if (ys == NULL)
return 0;
if (yang_stats(ys, &nr, &sz) < 0)
if (yang_stats(ys, 0, &nr, &sz) < 0)
goto done;
cprintf(cb, "<nr>%" PRIu64 "</nr><size>%zu</size>", nr, sz);
retval = 0;
@ -1248,6 +1248,7 @@ from_client_get_schema(clixon_handle h,
cbuf *cbyang = NULL;
cbuf *cbmsg = NULL;
const char *filename;
int inext;
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clixon_err(OE_YANG, ENOENT, "No yang spec");
@ -1266,8 +1267,8 @@ from_client_get_schema(clixon_handle h,
if ((x = xpath_first(xe, nsc, "format")) != NULL)
format = xml_body(x);
ymatch = NULL;
ymod = NULL;
while ((ymod = yn_each(yspec, ymod)) != NULL) {
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL) {
if (yang_keyword_get(ymod) != Y_MODULE &&
yang_keyword_get(ymod) != Y_SUBMODULE)
continue;
@ -1425,6 +1426,7 @@ from_client_stats(clixon_handle h,
yang_stmt *ymodext;
cxobj *xt = NULL;
int ret;
int inext;
if ((str = xml_find_body(xe, "modules")) != NULL)
modules = strcmp(str, "true") == 0;
@ -1454,8 +1456,8 @@ from_client_stats(clixon_handle h,
if (clixon_stats_module_get(h, yspec, cbret) < 0)
goto done;
if (modules){
ym = NULL;
while ((ym = yn_each(yspec, ym)) != NULL) {
inext = 0;
while ((ym = yn_iter(yspec, &inext)) != NULL) {
cprintf(cbret, "<module><name>%s</name>", yang_argument_get(ym));
if (clixon_stats_module_get(h, ym, cbret) < 0)
goto done;
@ -1468,8 +1470,8 @@ from_client_stats(clixon_handle h,
if (clixon_stats_module_get(h, yspec, cbret) < 0)
goto done;
if (modules){
ym = NULL;
while ((ym = yn_each(yspec, ym)) != NULL) {
inext = 0;
while ((ym = yn_iter(yspec, &inext)) != NULL) {
cprintf(cbret, "<module><name>%s</name>", yang_argument_get(ym));
if (clixon_stats_module_get(h, ym, cbret) < 0)
goto done;

View file

@ -483,7 +483,8 @@ yang2cli_var_sub(clixon_handle h,
int retval = -1;
char *type;
yang_stmt *yi = NULL;
int i = 0;
int i;
int inext;
int j;
const char *cvtypestr;
char *arg;
@ -503,8 +504,8 @@ yang2cli_var_sub(clixon_handle h,
if (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0){
cprintf(cb, " choice:");
i = 0;
yi = NULL;
while ((yi = yn_each(ytype, yi)) != NULL){
inext = 0;
while ((yi = yn_iter(ytype, &inext)) != NULL){
if (yang_keyword_get(yi) != Y_ENUM && yang_keyword_get(yi) != Y_BIT)
continue;
if (i)
@ -629,15 +630,17 @@ yang2cli_var_union(clixon_handle h,
cbuf *cb)
{
int retval = -1;
yang_stmt *ytsub = NULL;
yang_stmt *ytsub;
int i;
int inext;
i = 0;
inext = 0;
/* Loop over all sub-types in the resolved union type, note these are
* not resolved types (unless they are built-in, but the resolve call is
* made in the union_one call.
*/
while ((ytsub = yn_each(ytype, ytsub)) != NULL){
while ((ytsub = yn_iter(ytype, &inext)) != NULL){
if (yang_keyword_get(ytsub) != Y_TYPE)
continue;
if (i++)
@ -952,6 +955,7 @@ yang2cli_container(clixon_handle h,
int compress = 0;
yang_stmt *ymod = NULL;
int extvalue = 0;
int inext;
int ret;
if (ys_real_module(ys, &ymod) < 0)
@ -990,8 +994,8 @@ yang2cli_container(clixon_handle h,
cprintf(cb, "%*s%s", (level+1)*3, "", "@mountpoint;\n");
}
}
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL)
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL)
if (yang2cli_stmt(h, yc, level+1, cb) < 0)
goto done;
if (!compress)
@ -1030,6 +1034,7 @@ yang2cli_list(clixon_handle h,
int last_key = 0;
int exist = 0;
int keynr = 0;
int inext;
cprintf(cb, "%*s%s", level*3, "", yang_argument_get(ys));
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
@ -1078,8 +1083,8 @@ yang2cli_list(clixon_handle h,
keynr++;
}
cprintf(cb, "{\n");
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL) {
/* cvk is a cvec of strings containing variable names
yc is a leaf that may match one of the values of cvk.
*/
@ -1130,9 +1135,10 @@ yang2cli_choice(clixon_handle h,
{
int retval = -1;
yang_stmt *yc;
int inext;
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL) {
switch (yang_keyword_get(yc)){
case Y_CASE:
if (yang2cli_stmt(h, yc, level+2, cb) < 0)
@ -1257,6 +1263,7 @@ yang2cli_stmt(clixon_handle h,
int treeref_state = 0;
int grouping_treeref = 0;
int extvalue = 0;
int inext;
if (ys == NULL){
clixon_err(OE_YANG, EINVAL, "No yang spec");
@ -1319,8 +1326,8 @@ yang2cli_stmt(clixon_handle h,
case Y_CASE:
case Y_SUBMODULE:
case Y_MODULE:
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL)
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL)
if (yang2cli_stmt(h, yc, level+1, cb) < 0)
goto done;
break;
@ -1443,8 +1450,10 @@ yang2cli_post(clixon_handle h,
if ((yc = yang_find_datanode(yp, co->co_command)) == NULL){
#if 1
/* XXX In case of compress, look at next level */
yang_stmt *y = NULL;
while ((y = yn_each(yp, y)) != NULL){
yang_stmt *y;
int inext = 0;
while ((y = yn_iter(yp, &inext)) != NULL){
if (yang_datanode(y)){
if ((yc = yang_find_datanode(y, co->co_command)) != NULL)
break;
@ -1530,6 +1539,7 @@ yang2cli_grouping(clixon_handle h,
cg_obj *co;
int config;
int i;
int inext;
if ((pt0 = pt_new()) == NULL){
clixon_err(OE_UNIX, errno, "pt_new");
@ -1551,8 +1561,8 @@ yang2cli_grouping(clixon_handle h,
if (autocli_treeref_state(h, &treeref_state) < 0)
goto done;
if (treeref_state || yang_config(ys)){
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL)
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL)
if (yang2cli_stmt(h, yc, 1, cb) < 0)
goto done;
}
@ -1664,6 +1674,7 @@ yang2cli_yspec(clixon_handle h,
cg_obj *co;
int i;
int config;
int inext;
if ((pt0 = pt_new()) == NULL){
clixon_err(OE_UNIX, errno, "pt_new");
@ -1674,8 +1685,8 @@ yang2cli_yspec(clixon_handle h,
goto done;
}
/* Traverse YANG, loop through all modules and generate CLI */
ymod = NULL;
while ((ymod = yn_each(yspec, ymod)) != NULL){
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL){
/* Filter module name according to cli_autocli.yang setting
* Default is pass and ordering is significant
*/

View file

@ -494,6 +494,7 @@ expand_yang_list(void *h,
yang_stmt *ymod;
int modname = 0;
cbuf *cb = NULL;
int inext;
if (argv == NULL || cvec_len(argv) < 1 || cvec_len(argv) > 2){
clixon_err(OE_PLUGIN, EINVAL, "requires arguments: <schemanode> [<modname>]");
@ -518,8 +519,8 @@ expand_yang_list(void *h,
clixon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
yn = NULL;
while ((yn = yn_each(yres, yn)) != NULL) {
inext = 0;
while ((yn = yn_iter(yres, &inext)) != NULL) {
if (yang_keyword_get(yn) != Y_LIST)
continue;
cbuf_reset(cb);
@ -559,6 +560,7 @@ show_yang(clixon_handle h,
yang_stmt *yn;
char *str = NULL;
yang_stmt *yspec;
int inext;
yspec = clicon_dbspec_yang(h);
if (cvec_len(argv) > 0){
@ -568,8 +570,8 @@ show_yang(clixon_handle h,
goto done;
}
else{
yn = NULL;
while ((yn = yn_each(yspec, yn)) != NULL) {
inext = 0;
while ((yn = yn_iter(yspec, &inext)) != NULL) {
if (yang_print_cb(stdout, yn, cligen_output) < 0)
goto done;
}
@ -1900,7 +1902,6 @@ cli_show_statistics(clixon_handle h,
uint64_t u64;
char *unit;
if (argv == NULL || (cvec_len(argv) < 1 || cvec_len(argv) > 2)){
clixon_err(OE_PLUGIN, EINVAL, "Expected arguments: [(cli|backend|all) [detail]]");
goto done;
@ -1938,7 +1939,7 @@ cli_show_statistics(clixon_handle h,
cligen_output(stdout, "%-25s %-10s\n", "YANG", "Mem");
}
nr = 0; sz = 0;
if (yang_stats(yspec, &nr, &sz) < 0)
if (yang_stats(yspec, 0, &nr, &sz) < 0)
goto done;
tnr = nr;
tsz = sz;
@ -1961,7 +1962,7 @@ cli_show_statistics(clixon_handle h,
while ((cv2 = cvec_each(cvv2, cv2)) != NULL) {
yspec1 = cv_void_get(cv2);
nr = 0; sz = 0;
if (yang_stats(yspec1, &nr, &sz) < 0)
if (yang_stats(yspec1, 0, &nr, &sz) < 0)
goto done;
/* check if not duplicate */
cv3 = cv2;

View file

@ -716,6 +716,8 @@ api_operations_get(clixon_handle h,
char *namespace;
cbuf *cbx = NULL;
cxobj *xt = NULL;
int inext;
int inext2;
int i;
clixon_debug(CLIXON_DBG_RESTCONF, "");
@ -735,12 +737,12 @@ api_operations_get(clixon_handle h,
default:
break;
}
ymod = NULL;
i = 0;
while ((ymod = yn_each(yspec, ymod)) != NULL) {
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL) {
namespace = yang_find_mynamespace(ymod);
yc = NULL;
while ((yc = yn_each(ymod, yc)) != NULL) {
inext2 = 0;
while ((yc = yn_iter(ymod, &inext2)) != NULL) {
if (yang_keyword_get(yc) != Y_RPC)
continue;
switch (media_out){

View file

@ -852,11 +852,12 @@ snmp_table_get(clixon_handle h,
int i;
cg_var *cv;
char *defaultval = NULL;
int inext;
int ret;
/* Get yang of leaf from first part of OID */
ys = NULL;
while ((ys = yn_each(yt, ys)) != NULL) {
inext = 0;
while ((ys = yn_iter(yt, &inext)) != NULL) {
if (yang_keyword_get(ys) != Y_LEAF)
continue;
/* reset oid */
@ -973,6 +974,7 @@ snmp_table_set(clixon_handle h,
netsnmp_variable_list *requestvb;
int rowstatus = 0;
char *origtype;
int inext;
/* Get OID from table /list */
if ((ret = yangext_oid_get(yt, oidt, &oidtlen, NULL)) < 0)
@ -984,8 +986,8 @@ snmp_table_set(clixon_handle h,
*/
ys = NULL;
yrowst = NULL;
yi = NULL;
while ((yi = yn_each(yt, yi)) != NULL) {
inext = 0;
while ((yi = yn_iter(yt, &inext)) != NULL) {
if (yang_keyword_get(yi) != Y_LEAF)
continue;
/* reset oid */

View file

@ -170,7 +170,7 @@ is_same_subtypes_union(yang_stmt *ytype,
char **restype)
{
int retval = 0;
yang_stmt *y_sub_type = NULL;
yang_stmt *y_sub_type;
yang_stmt *y_resolved_type = NULL; /* resolved type */
char *resolved_type_str; /* resolved type */
char *type_str = NULL;
@ -178,12 +178,14 @@ is_same_subtypes_union(yang_stmt *ytype,
cvec *cvv = NULL;
cvec *patterns = NULL;
uint8_t fraction_digits = 0;
int inext;
/* Loop over all sub-types in the resolved union type, note these are
* not resolved types (unless they are built-in, but the resolve call is
* made in the union_one call.
*/
while ((y_sub_type = yn_each(ytype, y_sub_type)) != NULL){
inext = 0;
while ((y_sub_type = yn_iter(ytype, &inext)) != NULL){
if (yang_keyword_get(y_sub_type) != Y_TYPE)
continue;
@ -413,6 +415,7 @@ yang_extension_value_opt(yang_stmt *ys,
int retval = -1;
yang_stmt *yext;
cg_var *cv;
int inext;
if (ys == NULL){
clixon_err(OE_YANG, EINVAL, "ys is NULL");
@ -420,8 +423,9 @@ yang_extension_value_opt(yang_stmt *ys,
}
if (exist)
*exist = 0;
yext = NULL; /* This loop gets complicated in the case the extension is augmented */
while ((yext = yn_each(ys, yext)) != NULL) {
/* This loop gets complicated in the case the extension is augmented */
inext = 0;
while ((yext = yn_iter(ys, &inext)) != NULL) {
if (yang_keyword_get(yext) != Y_UNKNOWN)
continue;
if (strcmp(yang_argument_get(yext), id) != 0)

View file

@ -237,6 +237,7 @@ mibyang_table_register(clixon_handle h,
int asn1type;
yang_stmt *ys;
char *name;
int inext;
if ((ys = yang_parent_get(ylist)) == NULL ||
yang_keyword_get(ys) != Y_CONTAINER){
@ -315,9 +316,9 @@ mibyang_table_register(clixon_handle h,
table_info->min_column = 1;
/* Count columns */
yleaf = NULL;
table_info->max_column = 0;
while ((yleaf = yn_each(ylist, yleaf)) != NULL) {
inext = 0;
while ((yleaf = yn_iter(ylist, &inext)) != NULL) {
if ((yang_keyword_get(yleaf) != Y_LEAF) || (ret = yangext_is_oid_exist(yleaf)) != 1)
continue;
table_info->max_column++;
@ -557,6 +558,7 @@ mibyang_traverse(clixon_handle h,
yang_stmt *ys = NULL;
yang_stmt *yp;
int ret;
int inext;
static oid zero_oid = 0;
clixon_debug(CLIXON_DBG_SNMP, "%s", yang_argument_get(yn));
@ -586,8 +588,8 @@ mibyang_traverse(clixon_handle h,
break;
}
/* Traverse data nodes in tree (module is special case */
ys = NULL;
while ((ys = yn_each(yn, ys)) != NULL) {
inext = 0;
while ((ys = yn_iter(yn, &inext)) != NULL) {
/* augment special case of table */
if (!yang_schemanode(ys) && yang_keyword_get(ys) != Y_AUGMENT)
continue;

View file

@ -237,7 +237,6 @@ yang_stmt *yang_parent_get(yang_stmt *ys);
enum rfc_6020 yang_keyword_get(yang_stmt *ys);
char *yang_argument_get(yang_stmt *ys);
int yang_argument_set(yang_stmt *ys, char *arg);
cg_var *yang_cv_get(yang_stmt *ys);
int yang_cv_set(yang_stmt *ys, cg_var *cv);
cvec *yang_cvec_get(yang_stmt *ys);
@ -260,7 +259,7 @@ int yang_linenum_set(yang_stmt *ys, int linenum);
/* Stats */
int yang_stats_global(uint64_t *nr);
int yang_stats(yang_stmt *y, uint64_t *nrp, size_t *szp);
int yang_stats(yang_stmt *y, enum rfc_6020 keyw, uint64_t *nrp, size_t *szp);
/* Other functions */
yang_stmt *yspec_new(void);
@ -273,7 +272,7 @@ int ys_cp(yang_stmt *nw, yang_stmt *old);
yang_stmt *ys_dup(yang_stmt *old);
int yn_insert(yang_stmt *ys_parent, yang_stmt *ys_child);
int yn_insert1(yang_stmt *ys_parent, yang_stmt *ys_child);
yang_stmt *yn_each(yang_stmt *yn, yang_stmt *ys);
yang_stmt *yn_iter(yang_stmt *yparent, int *inext);
char *yang_key2str(int keyword);
int yang_str2key(char *str);
int ys_module_by_xml(yang_stmt *ysp, struct xml *xt, yang_stmt **ymodp);

View file

@ -144,14 +144,16 @@ netconf_monitoring_schemas(clixon_handle h,
cbuf *cb)
{
int retval = -1;
yang_stmt *ym = NULL;
yang_stmt *ym;
yang_stmt *y1;
char *identifier;
char *revision;
char *dir;
int inext;
cprintf(cb, "<schemas>");
while ((ym = yn_each(yspec, ym)) != NULL) {
inext = 0;
while ((ym = yn_iter(yspec, &inext)) != NULL) {
cprintf(cb, "<schema>");
identifier = yang_argument_get(ym);
cprintf(cb, "<identifier>%s</identifier>", identifier);

View file

@ -659,13 +659,14 @@ check_list_key(cxobj *xt,
cvec *cvk = NULL; /* vector of index keys */
cg_var *cvi;
char *keyname;
int inext;
if (yt == NULL || !yang_config(yt) || yang_keyword_get(yt) != Y_LIST){
clixon_err(OE_YANG, EINVAL, "yt is not a config true list node");
goto done;
}
yc = NULL;
while ((yc = yn_each(yt, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yt, &inext)) != NULL) {
if (yang_keyword_get(yc) != Y_KEY)
continue;
/* Check if a list does not have mandatory key leafs */
@ -716,12 +717,14 @@ choice_mandatory_check(cxobj *xt,
cxobj **xret)
{
int retval = -1;
yang_stmt *yc = NULL;
yang_stmt *yc;
cbuf *cb = NULL;
int fail = 0;
int inext;
int ret;
while ((yc = yn_each(ycase, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(ycase, &inext)) != NULL) {
if ((ret = yang_xml_mandatory(xt, yc)) < 0)
goto done;
if (ret == 1){
@ -898,6 +901,7 @@ check_mandatory(cxobj *xt,
yang_stmt *yc;
yang_stmt *yp;
cbuf *cb = NULL;
int inext;
int ret;
if (yt == NULL || !yang_config(yt)){
@ -910,8 +914,8 @@ check_mandatory(cxobj *xt,
if (ret == 0)
goto fail;
}
yc = NULL;
while ((yc = yn_each(yt, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yt, &inext)) != NULL) {
/* Choice is more complex because of choice/case structure and possibly hierarchical */
if (yang_keyword_get(yc) == Y_CHOICE){
if (yang_xml_mandatory(xt, yc)){
@ -1146,13 +1150,15 @@ xml_yang_validate_leaf_union(clixon_handle h,
{
int retval = -1;
int ret;
yang_stmt *ytsub = NULL;
yang_stmt *ytsub;
cxobj *xret1 = NULL;
yang_stmt *ytype; /* resolved type */
char *restype;
int inext;
/* Enough that one is valid, eg returns 1,otherwise fail */
while ((ytsub = yn_each(yrestype, ytsub)) != NULL){
inext = 0;
while ((ytsub = yn_iter(yrestype, &inext)) != NULL){
if (yang_keyword_get(ytsub) != Y_TYPE)
continue;
/* Resolve the sub-union type to a resolved type */
@ -1238,6 +1244,7 @@ xml_yang_validate_all(clixon_handle h,
int hit = 0;
validate_level vl = VL_NONE;
int saw_node = 0;
int inext;
if (clicon_option_bool(h, "CLICON_YANG_SCHEMA_MOUNT")){
if ((ret = xml_yang_mount_get(h, xt, &vl, NULL)) < 0)
@ -1333,8 +1340,8 @@ xml_yang_validate_all(clixon_handle h,
}
/* must sub-node RFC 7950 Sec 7.5.3. Can be several.
* XXX. use yang path instead? */
yc = NULL;
while ((yc = yn_each(yt, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yt, &inext)) != NULL) {
if (yang_keyword_get(yc) != Y_MUST)
continue;
if (!saw_node)

View file

@ -449,12 +449,13 @@ check_empty_list_minmax(cxobj *xt,
int retval = -1;
int ret;
yang_stmt *yprev = NULL;
int inext;
if (yang_config(ye) == 1){
if(yang_keyword_get(ye) == Y_CONTAINER &&
yang_find(ye, Y_PRESENCE, NULL) == NULL){
yprev = NULL;
while ((yprev = yn_each(ye, yprev)) != NULL) {
inext = 0;
while ((yprev = yn_iter(ye, &inext)) != NULL) {
if ((ret = check_empty_list_minmax(xt, yprev, xret)) < 0)
goto done;
if (ret == 0)
@ -496,6 +497,7 @@ xml_yang_minmax_new_list(cxobj *x,
{
int retval = -1;
yang_stmt *yu;
int inext;
int ret;
/* Here new (first element) of lists only
@ -507,8 +509,8 @@ xml_yang_minmax_new_list(cxobj *x,
goto fail;
/* Check if there is a unique constraint on the list
*/
yu = NULL;
while ((yu = yn_each(y, yu)) != NULL) {
inext = 0;
while ((yu = yn_iter(y, &inext)) != NULL) {
if (yang_keyword_get(yu) != Y_UNIQUE)
continue;
/* Here is a list w unique constraints identified by:
@ -608,6 +610,7 @@ static int
xml_yang_minmax_gap_analysis(cxobj *xt,
yang_stmt *y,
yang_stmt *yt,
int *inext,
yang_stmt **yep,
cxobj **xret)
{
@ -626,14 +629,14 @@ xml_yang_minmax_gap_analysis(cxobj *xt,
/* Skip analysis if Yang spec is unknown OR
* if we are still iterating the same Y_CASE w multiple lists
*/
ye = yn_each(yt, ye);
ye = yn_iter(yt, inext);
if (ye && ych != ye)
do {
if ((ret = check_empty_list_minmax(xt, ye, xret)) < 0)
goto done;
if (ret == 0)
goto fail;
ye = yn_each(yt, ye);
ye = yn_iter(yt, inext);
} while(ye != NULL && /* to avoid livelock (shouldnt happen) */
ye != ych);
}
@ -727,6 +730,7 @@ xml_yang_validate_minmax(cxobj *xt,
int nr = 0;
int ret;
yang_stmt *yt;
int inext = 0;
yt = xml_spec(xt); /* If yt == NULL, then no gap-analysis is done */
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL){
@ -740,7 +744,7 @@ xml_yang_validate_minmax(cxobj *xt,
continue;
}
/* gap analysis */
if ((ret = xml_yang_minmax_gap_analysis(xt, y, yt, &ye, xret)) < 0)
if ((ret = xml_yang_minmax_gap_analysis(xt, y, yt, &inext, &ye, xret)) < 0)
goto done;
/* check-minmax of previous list */
if (ret &&
@ -777,7 +781,7 @@ xml_yang_validate_minmax(cxobj *xt,
goto fail;
}
/* gap analysis */
if ((ret = xml_yang_minmax_gap_analysis(xt, y, yt, &ye, xret)) < 0)
if ((ret = xml_yang_minmax_gap_analysis(xt, y, yt, &inext, &ye, xret)) < 0)
goto done;
/* check-minmax of previous list */
if (ret &&
@ -792,8 +796,11 @@ xml_yang_validate_minmax(cxobj *xt,
goto fail;
if (presence && keyw == Y_CONTAINER &&
yang_find(y, Y_PRESENCE, NULL) == NULL){
yang_stmt *yc = NULL;
while ((yc = yn_each(y, yc)) != NULL) {
yang_stmt *yc;
int inext;
inext = 0;
while ((yc = yn_iter(y, &inext)) != NULL) {
if ((ret = xml_yang_validate_minmax(x, presence, xret)) < 0)
goto done;
if (ret == 0)
@ -809,17 +816,17 @@ xml_yang_validate_minmax(cxobj *xt,
/* Variant of gap analysis, does not use ych
* XXX: try to unify with xml_yang_minmax_gap_analysis()
*/
if ((ye = yn_each(yt, ye)) != NULL){
if ((ye = yn_iter(yt, &inext)) != NULL){
do {
if ((ret = check_empty_list_minmax(xt, ye, xret)) < 0)
goto done;
if (ret == 0)
goto fail;
} while((ye = yn_each(yt, ye)) != NULL);
} while ((ye = yn_iter(yt, &inext)) != NULL);
}
ret = 1;
#else
if ((ret = xml_yang_minmax_gap_analysis(xt, NULL, yt, &ye, xret)) < 0)
if ((ret = xml_yang_minmax_gap_analysis(xt, NULL, yt, &inext, &ye, xret)) < 0)
goto done;
#endif
/* check-minmax of previous list */

View file

@ -229,14 +229,15 @@ xml_nopresence_try(yang_stmt *yt,
int retval = -1;
yang_stmt *y;
yang_stmt *ydef;
int inext;
if (yt == NULL || yang_keyword_get(yt) != Y_CONTAINER){
clixon_err(OE_XML, EINVAL, "yt argument is not container");
goto done;
}
*createp = 0;
y = NULL;
while ((y = yn_each(yt, y)) != NULL) {
inext = 0;
while ((y = yn_iter(yt, &inext)) != NULL) {
switch (yang_keyword_get(y)){
case Y_LEAF:
/* Default value exists */
@ -302,6 +303,7 @@ xml_default(yang_stmt *yt,
int nr = 0;
int hit = 0;
cg_var *cv;
int inext;
if (xt == NULL){ /* No xml */
clixon_err(OE_XML, EINVAL, "No XML argument");
@ -316,8 +318,8 @@ xml_default(yang_stmt *yt,
case Y_INPUT:
case Y_OUTPUT:
case Y_CASE:
yc = NULL;
while ((yc = yn_each(yt, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yt, &inext)) != NULL) {
// XXX consider only data nodes for optimization?
/* If config parameter and local is config false */
if (!state && !yang_config(yc))
@ -459,13 +461,15 @@ xml_global_defaults_create(cxobj *xt,
int state)
{
int retval = -1;
yang_stmt *ymod = NULL;
yang_stmt *ymod;
int inext;
if (yspec == NULL || yang_keyword_get(yspec) != Y_SPEC){
clixon_err(OE_XML, EINVAL, "yspec argument is not yang spec");
goto done;
}
while ((ymod = yn_each(yspec, ymod)) != NULL)
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL)
if (xml_default(ymod, xt, state) < 0)
goto done;
retval = 0;

View file

@ -1510,14 +1510,16 @@ yang_valstr2enum(yang_stmt *ytype,
char **enumstr)
{
int retval = -1;
yang_stmt *yenum = NULL;
yang_stmt *yenum;
yang_stmt *yval;
int inext;
if (enumstr == NULL){
clixon_err(OE_UNIX, EINVAL, "str is NULL");
goto done;
}
while ((yenum = yn_each(ytype, yenum)) != NULL) {
inext = 0;
while ((yenum = yn_iter(ytype, &inext)) != NULL) {
if ((yval = yang_find(yenum, Y_VALUE, NULL)) == NULL)
goto done;
if (strcmp(yang_argument_get(yval), valstr) == 0)
@ -1635,10 +1637,12 @@ yang_bits_pos(yang_stmt *ytype,
int ret = 0;
int is_first = 1;
char *reason;
yang_stmt *yprev = NULL;
yang_stmt *yprev;
yang_stmt *ypos = NULL;
int inext;
while ((yprev = yn_each(ytype, yprev)) != NULL){
inext = 0;
while ((yprev = yn_iter(ytype, &inext)) != NULL){
/* Check for the given bit name (flag) */
if (yang_keyword_get(yprev) == Y_BIT){
/* Use position from Y_POSITION statement if defined */
@ -1826,16 +1830,18 @@ yang_val2bitsstr(clixon_handle h,
int ret = 0;
int byte = 0;
char *reason = NULL;
yang_stmt *yprev = NULL;
yang_stmt *yprev;
yang_stmt *ypos;
uint32_t bitpos = 0;
int inext;
if (cb == NULL){
clixon_err(OE_UNIX, EINVAL, "cb is NULL");
goto done;
}
/* Go over all defined bits and check if it is seet in intval */
while ((yprev = yn_each(ytype, yprev)) != NULL && byte < inlen){
inext = 0;
while ((yprev = yn_iter(ytype, &inext)) != NULL && byte < inlen){
if (yang_keyword_get(yprev) == Y_BIT) {
/* Use position from Y_POSITION statement if defined */
if ((ypos = yang_find(yprev, Y_POSITION, NULL)) != NULL){
@ -2156,6 +2162,7 @@ yang_xml_mandatory(cxobj *xt,
yang_stmt *yc;
int hit;
int nr;
int inext;
/* Create dummy xs if not exist */
if ((xs = xml_new(yang_argument_get(ys), xt, CX_ELMNT)) == NULL)
@ -2180,8 +2187,8 @@ yang_xml_mandatory(cxobj *xt,
* least one mandatory node as a child. */
else if (keyw == Y_CONTAINER &&
yang_find(ys, Y_PRESENCE, NULL) == NULL){
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL) {
if ((ret = yang_xml_mandatory(xs, yc)) < 0)
goto done;
if (ret == 1)

View file

@ -340,6 +340,7 @@ xml_nsctx_yang(yang_stmt *yn,
char *prefix;
char *mynamespace;
char *myprefix;
int inext;
if (yang_keyword_get(yn) == Y_SPEC){
clixon_err(OE_YANG, EINVAL, "yang spec node is invalid argument");
@ -371,8 +372,8 @@ xml_nsctx_yang(yang_stmt *yn,
/* Iterate over module and register all import prefixes
*/
y = NULL;
while ((y = yn_each(ymod, y)) != NULL) {
inext = 0;
while ((y = yn_iter(ymod, &inext)) != NULL) {
if (yang_keyword_get(y) == Y_IMPORT){
if ((name = yang_argument_get(y)) == NULL)
continue; /* Just skip - shouldnt happen) */
@ -424,6 +425,7 @@ xml_nsctx_yangspec(yang_stmt *yspec,
yang_stmt *ymod = NULL;
yang_stmt *yprefix;
yang_stmt *ynamespace;
int inext;
if (ncp && *ncp)
nc = *ncp;
@ -431,8 +433,8 @@ xml_nsctx_yangspec(yang_stmt *yspec,
clixon_err(OE_XML, errno, "cvec_new");
goto done;
}
ymod = NULL;
while ((ymod = yn_each(yspec, ymod)) != NULL){
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL){
if (yang_keyword_get(ymod) != Y_MODULE)
continue;
if ((yprefix = yang_find(ymod, Y_PREFIX, NULL)) == NULL)

View file

@ -625,6 +625,7 @@ yang_stats_one(yang_stmt *y,
/*! Return statistics of an YANG-stmt tree recursively
*
* @param[in] yt YANG object
* @param[in] keyw YANG keyword, or 0 for all
* @param[out] nrp Number of YANG objects recursively
* @param[out] szp Size of this YANG stmt recursively
* @retval 0 OK
@ -632,25 +633,29 @@ yang_stats_one(yang_stmt *y,
*/
int
yang_stats(yang_stmt *yt,
enum rfc_6020 keyw,
uint64_t *nrp,
size_t *szp)
{
int retval = -1;
size_t sz = 0;
yang_stmt *ys;
int inext;
if (yt == NULL){
clixon_err(OE_XML, EINVAL, "yang spec is NULL");
goto done;
}
if (keyw == 0 || yang_keyword_get(yt) == keyw){
*nrp += 1;
yang_stats_one(yt, &sz);
if (szp)
*szp += sz;
ys = NULL;
while ((ys = yn_each(yt, ys)) != NULL) {
}
inext = 0;
while ((ys = yn_iter(yt, &inext)) != NULL) {
sz = 0;
yang_stats(ys, nrp, &sz);
yang_stats(ys, keyw, nrp, &sz);
if (szp)
*szp += sz;
}
@ -808,12 +813,13 @@ ys_prune_self(yang_stmt *ys)
yang_stmt *yp;
yang_stmt *yc;
int i;
int inext;
if ((yp = yang_parent_get(ys)) != NULL){
yc = NULL;
i = 0;
inext = 0;
/* Find order of ys in child-list */
while ((yc = yn_each(yp, yc)) != NULL) {
while ((yc = yn_iter(yp, &inext)) != NULL) {
if (ys == yc)
break;
i++;
@ -1060,39 +1066,35 @@ yn_insert1(yang_stmt *ys_parent,
return 0;
}
/*! Iterate through all yang statements from a yang node
/*! Iterate through all yang statements from a yang node using an integer iterator
*
* @param[in] yparent yang statement whose children are iterated
* @param[in] yprev previous child, or NULL on init
* @param[in,out] inext Iterator, or 0 on init
* @code
* yang_stmt *yprev = NULL;
* while ((yprev = yn_each(yparent, yprev)) != NULL) {
* ...yprev...
* yang_stmt *yprev;
* int inext = 0;
* while ((ynext = yn_iter(yparent, &inext)) != NULL) {
* ...ynext...
* }
* @endcode
* @note makes uses _ys_vector_i:can be changed if list changed between calls
* @note also does not work in recursive calls (to same node)
* @see yn_each
*/
yang_stmt *
yn_each(yang_stmt *yparent,
yang_stmt *yprev)
yn_iter(yang_stmt *yparent,
int *inext)
{
int i;
yang_stmt *yc = NULL;
if (yparent == NULL)
if (yparent == NULL || *inext < 0 || (*inext)>=yparent->ys_len)
return NULL;
for (i=yprev?yprev->_ys_vector_i+1:0; i<yparent->ys_len; i++){
if ((yc = yparent->ys_stmt[i]) == NULL){
for (; (*inext)<yparent->ys_len;){
if ((yc = yparent->ys_stmt[*inext]) == NULL){
(*inext)++;
continue;
}
/* make room for other conditionals */
(*inext)++;
break; /* this is next object after previous */
}
if (i < yparent->ys_len) /* found */
yc->_ys_vector_i = i;
else
yc = NULL;
return yc;
}
@ -1169,12 +1171,14 @@ yang_find_datanode(yang_stmt *yn,
yang_stmt *yspec;
yang_stmt *ysmatch = NULL;
char *name;
int inext;
int inext2;
ys = NULL;
while ((ys = yn_each(yn, ys)) != NULL){
inext = 0;
while ((ys = yn_iter(yn, &inext)) != NULL){
if (yang_keyword_get(ys) == Y_CHOICE){ /* Look for its children */
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL){
inext2 = 0;
while ((yc = yn_iter(ys, &inext2)) != NULL){
if (yang_keyword_get(yc) == Y_CASE) /* Look for its children */
ysmatch = yang_find_datanode(yc, argument);
else
@ -1207,8 +1211,8 @@ yang_find_datanode(yang_stmt *yn,
(yang_keyword_get(yn) == Y_MODULE ||
yang_keyword_get(yn) == Y_SUBMODULE)){
yspec = ys_spec(yn);
ys = NULL;
while ((ys = yn_each(yn, ys)) != NULL){
inext = 0;
while ((ys = yn_iter(yn, &inext)) != NULL){
if (yang_keyword_get(ys) == Y_INCLUDE){
name = yang_argument_get(ys);
yc = yang_find_module_by_name(yspec, name);
@ -1395,6 +1399,7 @@ yang_find_prefix_by_namespace(yang_stmt *ys,
char *modname = NULL;
yang_stmt *yimport;
yang_stmt *yprefix;
int inext;
clixon_debug(CLIXON_DBG_YANG | CLIXON_DBG_DETAIL, "namespace %s", ns);
if (prefix == NULL){
@ -1414,8 +1419,8 @@ yang_find_prefix_by_namespace(yang_stmt *ys,
modname = yang_argument_get(ymod);
my_ymod = ys_module(ys);
/* Loop through import statements to find a match with ymod */
yimport = NULL;
while ((yimport = yn_each(my_ymod, yimport)) != NULL) {
inext = 0;
while ((yimport = yn_iter(my_ymod, &inext)) != NULL) {
if (yang_keyword_get(yimport) == Y_IMPORT &&
strcmp(modname, yang_argument_get(yimport)) == 0){ /* match */
yprefix = yang_find(yimport, Y_PREFIX, NULL);
@ -1935,16 +1940,18 @@ int
yang_spec_print(FILE *f,
yang_stmt *yspec)
{
yang_stmt *ym = NULL;
yang_stmt *ym;
yang_stmt *yrev;
int inext;
if (yspec == NULL || yang_keyword_get(yspec) != Y_SPEC){
clixon_err(OE_YANG, EINVAL, "yspec is not of type YSPEC");
return -1;
}
while ((ym = yn_each(yspec, ym)) != NULL) {
inext = 0;
while ((ym = yn_iter(yspec, &inext)) != NULL) {
fprintf(f, "%s", yang_key2str(ym->ys_keyword));
fprintf(f, " %s", ym->ys_argument);
fprintf(f, " %s", yang_argument_get(ym));
if ((yrev = yang_find(ym, Y_REVISION, NULL)) != NULL){
fprintf(f, "@%s", yang_argument_get(yrev));
}
@ -1963,17 +1970,19 @@ yang_spec_dump(yang_stmt *yspec,
int dbglevel)
{
int retval = -1;
yang_stmt *ym = NULL;
yang_stmt *ym;
yang_stmt *yrev;
cbuf *cb = NULL;
int inext;
if ((cb = cbuf_new()) ==NULL){
clixon_err(OE_YANG, errno, "cbuf_new");
goto done;
}
while ((ym = yn_each(yspec, ym)) != NULL) {
inext = 0;
while ((ym = yn_iter(yspec, &inext)) != NULL) {
cprintf(cb, "%s", yang_key2str(ym->ys_keyword));
cprintf(cb, " %s", ym->ys_argument);
cprintf(cb, " %s", yang_argument_get(ym));
if ((yrev = yang_find(ym, Y_REVISION, NULL)) != NULL){
cprintf(cb, "@%u", cv_uint32_get(yang_cv_get(yrev)));
}
@ -2013,6 +2022,7 @@ yang_print_cbuf(cbuf *cb,
yang_stmt *ys;
enum rfc_6020 keyw;
char *arg;
int inext;
if (yn == NULL || cb == NULL){
clixon_err(OE_YANG, EINVAL, "cb or yn is NULL");
@ -2040,8 +2050,8 @@ yang_print_cbuf(cbuf *cb,
cprintf(cb, " {");
if (pretty)
cprintf(cb, "\n");
ys = NULL;
while ((ys = yn_each(yn, ys)) != NULL) {
inext = 0;
while ((ys = yn_iter(yn, &inext)) != NULL) {
if (yang_print_cbuf(cb, ys, marginal + PRETTYPRINT_INDENT, pretty) < 0)
goto done;
}
@ -2087,6 +2097,7 @@ yang_deviation(yang_stmt *ys,
enum rfc_6020 kw;
int min;
int max;
int inext;
if (yang_keyword_get(ys) != Y_DEVIATION)
goto ok;
@ -2107,8 +2118,8 @@ yang_deviation(yang_stmt *ys,
*/
}
/* Go through deviates of deviation */
yd = NULL;
while ((yd = yn_each(ys, yd)) != NULL) {
inext = 0;
while ((yd = yn_iter(ys, &inext)) != NULL) {
/* description / if-feature / reference */
if (yang_keyword_get(yd) != Y_DEVIATE)
continue;
@ -2121,8 +2132,8 @@ yang_deviation(yang_stmt *ys,
goto ok; /* Target node removed, no other deviates possible */
}
else if (strcmp(devop, "add") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yd, &inext)) != NULL) {
/* If a property can only appear once, the property MUST NOT exist in the target node. */
kw = yang_keyword_get(yc);
if (yang_find(ytarget, kw, NULL) != NULL){
@ -2148,8 +2159,8 @@ yang_deviation(yang_stmt *ys,
}
}
else if (strcmp(devop, "replace") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yd, &inext)) != NULL) {
/* The properties to replace MUST exist in the target node.*/
kw = yang_keyword_get(yc);
ytc = yang_find(ytarget, kw, NULL);
@ -2181,8 +2192,8 @@ yang_deviation(yang_stmt *ys,
}
}
else if (strcmp(devop, "delete") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(yd, &inext)) != NULL) {
/* The substatement's keyword MUST match a corresponding keyword in the target node, and the
* argument's string MUST be equal to the corresponding keyword's argument string in the
* target node. */
@ -2248,7 +2259,7 @@ ys_populate_leaf(clixon_handle h,
/* 1. Find type specification and set cv type accordingly */
if (yang_type_get(ys, &origtype, &yrestype, &options, NULL, NULL, NULL, &fraction_digits) < 0)
goto done;
restype = yrestype?yrestype->ys_argument:NULL;
restype = yrestype?yang_argument_get(yrestype):NULL;
if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0) /* This handles non-resolved also */
goto done;
/* 2. Create the CV using cvtype and name it */
@ -2259,7 +2270,7 @@ ys_populate_leaf(clixon_handle h,
if (options & YANG_OPTIONS_FRACTION_DIGITS && cvtype == CGV_DEC64) /* XXX: Seems misplaced? / too specific */
cv_dec64_n_set(cv, fraction_digits);
if (cv_name_set(cv, ys->ys_argument) == NULL){
if (cv_name_set(cv, yang_argument_get(ys)) == NULL){
clixon_err(OE_YANG, errno, "cv_name_set");
goto done;
}
@ -2271,7 +2282,7 @@ ys_populate_leaf(clixon_handle h,
* 3a) First check local default
*/
if ((ydef = yang_find(ys, Y_DEFAULT, NULL)) != NULL){
if ((cvret = cv_parse1(ydef->ys_argument, cv, &reason)) < 0){ /* error */
if ((cvret = cv_parse1(yang_argument_get(ydef), cv, &reason)) < 0){ /* error */
clixon_err(OE_YANG, errno, "parsing cv");
goto done;
}
@ -2284,7 +2295,7 @@ ys_populate_leaf(clixon_handle h,
/* 2. then check typedef default */
else if (ytypedef != ys &&
(ydef = yang_find(ytypedef, Y_DEFAULT, NULL)) != NULL) {
if ((cvret = cv_parse1(ydef->ys_argument, cv, &reason)) < 0){ /* error */
if ((cvret = cv_parse1(yang_argument_get(ydef), cv, &reason)) < 0){ /* error */
clixon_err(OE_YANG, errno, "parsing cv");
goto done;
}
@ -2300,7 +2311,7 @@ ys_populate_leaf(clixon_handle h,
}
/* 4. Check if leaf is part of list, if key exists mark leaf as key/unique */
if (yparent && yparent->ys_keyword == Y_LIST){
if ((ret = yang_key_match(yparent, ys->ys_argument, NULL)) < 0)
if ((ret = yang_key_match(yparent, yang_argument_get(ys), NULL)) < 0)
goto done;
}
yang_cv_set(ys, cv);
@ -2397,7 +2408,7 @@ range_parse(yang_stmt *ys,
char *v;
char *v2;
if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL)
if ((vec = clicon_strsep(yang_argument_get(ys), "|", &nvec)) == NULL)
goto done;
for (i=0; i<nvec; i++){
v = vec[i];
@ -2461,7 +2472,7 @@ ys_populate_range(clixon_handle h,
clixon_err(OE_YANG, 0, "result-type should not be NULL");
goto done;
}
restype = yrestype?yrestype->ys_argument:NULL;
restype = yrestype?yang_argument_get(yrestype):NULL;
if (nodeid_split(yang_argument_get(yparent), NULL, &origtype) < 0)
goto done;
/* This handles non-resolved also */
@ -2538,9 +2549,10 @@ ys_populate_type_enum(clixon_handle h,
int v;
int i = 0;
cg_var *cv = NULL;
int inext;
yenum = NULL;
while ((yenum = yn_each(ys, yenum)) != NULL) {
inext = 0;
while ((yenum = yn_iter(ys, &inext)) != NULL) {
if ((cv = cv_new(CGV_INT32)) == NULL){
clixon_err(OE_YANG, errno, "cv_new");
goto done;
@ -2576,24 +2588,24 @@ ys_populate_type(clixon_handle h,
int retval = -1;
yang_stmt *ybase;
if (strcmp(ys->ys_argument, "decimal64") == 0){
if (strcmp(yang_argument_get(ys), "decimal64") == 0){
if (yang_find(ys, Y_FRACTION_DIGITS, NULL) == NULL){
clixon_err(OE_YANG, 0, "decimal64 type requires fraction-digits sub-statement");
goto done;
}
}
else if (strcmp(ys->ys_argument, "identityref") == 0){
else if (strcmp(yang_argument_get(ys), "identityref") == 0){
if ((ybase = yang_find(ys, Y_BASE, NULL)) == NULL){
clixon_err(OE_YANG, 0, "identityref type requires base sub-statement");
goto done;
}
if ((yang_find_identity(ys, ybase->ys_argument)) == NULL){
if ((yang_find_identity(ys, yang_argument_get(ybase))) == NULL){
clixon_err(OE_YANG, 0, "Identity %s not found (base type of %s)",
ybase->ys_argument, ys->ys_argument);
yang_argument_get(ybase), yang_argument_get(ys));
goto done;
}
}
else if (strcmp(ys->ys_argument, "enumeration") == 0){
else if (strcmp(yang_argument_get(ys), "enumeration") == 0){
if (ys_populate_type_enum(h, ys) < 0)
goto done;
}
@ -2629,6 +2641,7 @@ ys_populate_identity(clixon_handle h,
cbuf *cb = NULL;
yang_stmt *ymod;
cvec *idrefvec; /* Derived identityref list: (module:id)**/
int inext;
/* Top-call (no recursion) create idref
* The idref is (here) in "canonical form": <module>:<id>
@ -2651,8 +2664,8 @@ ys_populate_identity(clixon_handle h,
/* Iterate through all base statements and check the base identity exists
* AND populate the base identity recursively
*/
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL) {
if (yc->ys_keyword != Y_BASE)
continue;
baseid = yang_argument_get(yc); /* on the form: prefix:id */
@ -2746,8 +2759,8 @@ ys_populate_feature(clixon_handle h,
clixon_err(OE_YANG, 0, "module not found");
goto done;
}
module = ymod->ys_argument;
feature = ys->ys_argument;
module = yang_argument_get(ymod);
feature = yang_argument_get(ys);
xc = NULL;
while ((xc = xml_child_each(x, xc, CX_ELMNT)) != NULL && found == 0) {
m = NULL;
@ -2908,12 +2921,14 @@ ys_populate_module_submodule(clixon_handle h,
char *p0 = NULL;
char *pi;
char *pi2; /* remaining */
int inext;
int inext2;
/* Modules but not submodules have prefixes */
if ((yp = yang_find(ym, Y_PREFIX, NULL)) != NULL)
p0 = yang_argument_get(yp);
yi = NULL;
while ((yi = yn_each(ym, yi)) != NULL) {
inext = 0;
while ((yi = yn_iter(ym, &inext)) != NULL) {
if (yang_keyword_get(yi) != Y_IMPORT)
continue;
yp = yang_find(yi, Y_PREFIX, NULL);
@ -2924,8 +2939,8 @@ ys_populate_module_submodule(clixon_handle h,
goto done;
}
/* Check rest of imports */
yi2 = yi;
while ((yi2 = yn_each(ym, yi2)) != NULL) {
inext2 = inext;
while ((yi2 = yn_iter(ym, &inext2)) != NULL) {
if (yang_keyword_get(yi2) != Y_IMPORT)
continue;
yp = yang_find(yi2, Y_PREFIX, NULL);
@ -3132,7 +3147,7 @@ yang_features(clixon_handle h,
* The tree is traversed depth-first, which at least guarantees that a parent is
* traversed before a child.
* @param[in] yn yang node
* @param[in] key yang keyword to use as filer or -1 for all
* @param[in] key yang keyword to use as filter or -1 for all
* @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
@ -3537,7 +3552,7 @@ yang_arg2cvec(yang_stmt *ys,
cvec *cvv = NULL;
cg_var *cv;
if ((vec = clicon_strsep(ys->ys_argument, " ", &nvec)) == NULL)
if ((vec = clicon_strsep(yang_argument_get(ys), " ", &nvec)) == NULL)
goto done;
if ((cvv = cvec_new(nvec)) == NULL){
clixon_err(OE_YANG, errno, "cvec_new");
@ -3876,6 +3891,7 @@ yang_extension_value(yang_stmt *ys,
char *prefix = NULL;
cbuf *cb = NULL;
int ret;
int inext;
if (ys == NULL){
clixon_err(OE_YANG, EINVAL, "ys is NULL");
@ -3887,8 +3903,8 @@ yang_extension_value(yang_stmt *ys,
clixon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
yext = NULL; /* This loop gets complicated in the case the extension is augmented */
while ((yext = yn_each(ys, yext)) != NULL) {
inext = 0; /* This loop gets complicated in the case the extension is augmented */
while ((yext = yn_iter(ys, &inext)) != NULL) {
if (yang_keyword_get(yext) != Y_UNKNOWN)
continue;
if ((ymod = ys_module(yext)) == NULL)
@ -3917,6 +3933,7 @@ yang_extension_value(yang_stmt *ys,
return retval;
}
#if 0 /* NOTE this may need to reinserted with new implementation */
/* Sort substatements with when:s last */
static int
yang_sort_subelements_fn(const void* arg1,
@ -3937,7 +3954,7 @@ yang_sort_subelements_fn(const void* arg1,
return -1;
else return ys1->_ys_vector_i - ys2->_ys_vector_i;
}
#endif
/*! Experimental code for sorting YANG children
*
* RFC 7950 7.5.7 and 7.8.5 says that containers and list sub elements are encoded in any order.
@ -3949,18 +3966,23 @@ yang_sort_subelements_fn(const void* arg1,
int
yang_sort_subelements(yang_stmt *ys)
{
#if 1
return 0;
#else
int retval = -1;
yang_stmt *yc = NULL;
int inext;
if ((yang_keyword_get(ys) == Y_CONTAINER ||
yang_keyword_get(ys) == Y_LIST)){
/* This enumerates _ys_vector_i in ys->ys_stmt vector */
while ((yc = yn_each(ys, yc)) != NULL) ;
qsort(ys->ys_stmt, ys->ys_len, sizeof(ys), yang_sort_subelements_fn);
inext = 0;
while (yn_iter(ys, &inext) != NULL) ;
// qsort(ys->ys_stmt, ys->ys_len, sizeof(ys), yang_sort_subelements_fn);
}
retval = 0;
// done:
return retval;
#endif
}
int
@ -4047,8 +4069,9 @@ yang_single_child_type(yang_stmt *ys,
enum rfc_6020 subkeyw)
{
yang_stmt *yc = NULL;
yang_stmt *yc;
int i;
int inext;
enum rfc_6020 keyw;
/* Match parent */
@ -4059,7 +4082,8 @@ yang_single_child_type(yang_stmt *ys,
}
/* Ensure a single list child and no other data nodes */
i = 0; /* Number of list nodes */
while ((yc = yn_each(ys, yc)) != NULL) {
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL) {
keyw = yang_keyword_get(yc);
/* case/choice could hide anything so disqualify those */
if (keyw == Y_CASE || keyw == Y_CHOICE)

View file

@ -498,6 +498,7 @@ yang_cardinality(clixon_handle h,
yang_stmt *yprev = NULL;
int nr;
int yc_count[Y_SPEC] = {0,};
int inext;
pk = yang_keyword_get(yt);
if ((yc0 = _yc_exist[pk]) == NULL)
@ -506,8 +507,8 @@ yang_cardinality(clixon_handle h,
* Also: check monotonically increasing order
*/
order = 0;
ys = NULL;
while ((ys = yn_each(yt, ys)) != NULL) {
inext = 0;
while ((ys = yn_iter(yt, &inext)) != NULL) {
ck = yang_keyword_get(ys);
if (pk == Y_UNKNOWN || ck == Y_UNKNOWN) /* special case */
continue;

View file

@ -48,14 +48,15 @@
struct yang_type_cache{
int yc_options; /* See YANG_OPTIONS_* that determines pattern/
fraction fields. */
int yc_rxmode; /* need to store mode for freeing since handle may not be available
* see regexp_mode
*/
uint8_t yc_fraction; /* Fraction digits for decimal64 (if YANG_OPTIONS_FRACTION_DIGITS */
cvec *yc_cvv; /* Range and length restriction. (if YANG_OPTION_
LENGTH|RANGE. Can be a vector if multiple
ranges*/
cvec *yc_patterns; /* list of regexp, if cvec_len() > 0 */
int yc_rxmode; /* need to store mode for freeing since handle may not be available */
cvec *yc_regexps; /* list of _compiled_ regexp, if cvec_len() > 0 */
uint8_t yc_fraction; /* Fraction digits for decimal64 (if
YANG_OPTIONS_FRACTION_DIGITS */
yang_stmt *yc_resolved; /* Resolved type object, can be NULL - note direct ptr */
};
typedef struct yang_type_cache yang_type_cache;
@ -69,13 +70,13 @@ struct yang_stmt{
int ys_len; /* Number of children */
struct yang_stmt **ys_stmt; /* Vector of children statement pointers */
struct yang_stmt *ys_parent; /* Backpointer to parent: yang-stmt or yang-spec */
enum rfc_6020 ys_keyword; /* */
struct yang_stmt *ys_orig; /* Backpointer to grouping/augment original */
enum rfc_6020 ys_keyword; /* YANG keyword */
char *ys_argument; /* String / argument depending on keyword */
uint16_t ys_flags; /* Flags according to YANG_FLAG_MARK and others */
yang_stmt *ys_mymodule; /* Shortcut to "my" module. Used by:
1) Augmented nodes "belong" to the module where the
augment is declared, which may be differnt from
augment is declared, which may be different from
the direct ancestor module
2) Unknown nodes "belong" to where the extension is
declared
@ -111,8 +112,6 @@ struct yang_stmt{
char *ys_filename; /* For debug/errors: filename (only (sub)modules) */
int ys_linenum; /* For debug/errors: line number (in ys_filename) */
rpc_callback_t *ys_action_cb; /* Action callback list, only for Y_ACTION */
/* Internal use */
int _ys_vector_i; /* internal use: yn_each */
};
#endif /* _CLIXON_YANG_INTERNAL_H_ */

View file

@ -216,6 +216,8 @@ yang_modules_state_build(clixon_handle h,
yang_stmt *yinc;
yang_stmt *ysub;
char *name;
int inext;
int inext2;
/* In case of several mountpoints, this is always the top-level */
if ((ylib = yang_find(yspec, Y_MODULE, module)) == NULL
@ -232,8 +234,8 @@ yang_modules_state_build(clixon_handle h,
cprintf(cb,"<yang-library xmlns=\"%s\">", yang_argument_get(yns));
cprintf(cb,"<content-id>%s</content-id>", msid);
cprintf(cb,"<module-set><name>default</name>");
ymod = NULL;
while ((ymod = yn_each(yspec, ymod)) != NULL) {
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL) {
if (yang_keyword_get(ymod) != Y_MODULE)
continue;
cprintf(cb,"<module>");
@ -256,8 +258,8 @@ yang_modules_state_build(clixon_handle h,
/* This follows order in rfc 7895: feature, conformance-type,
submodules */
if (!brief){
yc = NULL;
while ((yc = yn_each(ymod, yc)) != NULL) {
inext2 = 0;
while ((yc = yn_iter(ymod, &inext2)) != NULL) {
switch(yang_keyword_get(yc)){
case Y_FEATURE:
if (yang_cv_get(yc) && cv_bool_get(yang_cv_get(yc)))
@ -268,8 +270,8 @@ yang_modules_state_build(clixon_handle h,
}
}
}
yinc = NULL;
while ((yinc = yn_each(ymod, yinc)) != NULL) {
inext2 = 0;
while ((yinc = yn_iter(ymod, &inext2)) != NULL) {
if (yang_keyword_get(yinc) != Y_INCLUDE)
continue;
cprintf(cb,"<submodule>");
@ -540,6 +542,7 @@ yang_find_module_by_prefix(yang_stmt *ys,
yang_stmt *ymod = NULL;
yang_stmt *yspec;
char *myprefix;
int inext;
if ((yspec = ys_spec(ys)) == NULL){
clixon_err(OE_YANG, 0, "My yang spec not found");
@ -556,8 +559,8 @@ yang_find_module_by_prefix(yang_stmt *ys,
goto done;
}
/* If no match, try imported modules */
yimport = NULL;
while ((yimport = yn_each(my_ymod, yimport)) != NULL) {
inext = 0;
while ((yimport = yn_iter(my_ymod, &inext)) != NULL) {
if (yang_keyword_get(yimport) != Y_IMPORT)
continue;
if ((yprefix = yang_find(yimport, Y_PREFIX, NULL)) != NULL &&
@ -584,10 +587,12 @@ yang_stmt *
yang_find_module_by_prefix_yspec(yang_stmt *yspec,
char *prefix)
{
yang_stmt *ymod = NULL;
yang_stmt *ymod;
yang_stmt *yprefix;
int inext;
while ((ymod = yn_each(yspec, ymod)) != NULL)
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL)
if (yang_keyword_get(ymod) == Y_MODULE &&
(yprefix = yang_find(ymod, Y_PREFIX, NULL)) != NULL &&
strcmp(yang_argument_get(yprefix), prefix) == 0)
@ -609,11 +614,13 @@ yang_stmt *
yang_find_module_by_namespace(yang_stmt *yspec,
char *ns)
{
yang_stmt *ymod = NULL;
yang_stmt *ymod;
int inext;
if (ns == NULL)
goto done;
while ((ymod = yn_each(yspec, ymod)) != NULL) {
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL) {
if (yang_find(ymod, Y_NAMESPACE, ns) != NULL)
break;
}
@ -636,15 +643,17 @@ yang_find_module_by_namespace_revision(yang_stmt *yspec,
const char *ns,
const char *rev)
{
yang_stmt *ymod = NULL;
yang_stmt *ymod;
yang_stmt *yrev;
char *rev1;
int inext;
if (ns == NULL || rev == NULL){
clixon_err(OE_CFG, EINVAL, "No ns or rev");
goto done;
}
while ((ymod = yn_each(yspec, ymod)) != NULL) {
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL) {
if (yang_find(ymod, Y_NAMESPACE, ns) != NULL)
/* Get FIRST revision */
if ((yrev = yang_find(ymod, Y_REVISION, NULL)) != NULL){
@ -672,15 +681,17 @@ yang_find_module_by_name_revision(yang_stmt *yspec,
const char *name,
const char *rev)
{
yang_stmt *ymod = NULL;
yang_stmt *ymod;
yang_stmt *yrev;
char *rev1;
int inext;
if (name == NULL){
clixon_err(OE_CFG, EINVAL, "No ns or rev");
goto done;
}
while ((ymod = yn_each(yspec, ymod)) != NULL) {
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL) {
if (yang_keyword_get(ymod) != Y_MODULE)
continue;
if (strcmp(yang_argument_get(ymod), name) != 0)
@ -711,9 +722,11 @@ yang_stmt *
yang_find_module_by_name(yang_stmt *yspec,
char *name)
{
yang_stmt *ymod = NULL;
yang_stmt *ymod;
int inext;
while ((ymod = yn_each(yspec, ymod)) != NULL)
inext = 0;
while ((ymod = yn_iter(yspec, &inext)) != NULL)
if ((yang_keyword_get(ymod) == Y_MODULE || yang_keyword_get(ymod) == Y_SUBMODULE) &&
strcmp(yang_argument_get(ymod), name)==0)
return ymod;
@ -779,12 +792,14 @@ yang_metadata_annotation_check(cxobj *xa,
int *ismeta)
{
int retval = -1;
yang_stmt *yma = NULL;
yang_stmt *yma;
char *name;
cg_var *cv;
int inext;
/* Loop through annotations */
while ((yma = yn_each(ymod, yma)) != NULL){
inext = 0;
while ((yma = yn_iter(ymod, &inext)) != NULL){
/* Assume here md:annotation is written using canonical prefix */
if (yang_keyword_get(yma) != Y_UNKNOWN)
continue;

View file

@ -235,7 +235,6 @@ yang_parse_init(clixon_yang_yacc *yy)
return 0;
}
int
yang_parse_exit(clixon_yang_yacc *yy)
{

View file

@ -119,6 +119,7 @@ ys_grouping_module_resolve(yang_stmt *ymod,
yang_stmt *yrealmod = NULL;
yang_stmt *ygrouping = NULL;
char *submname;
int inext;
/* Find grouping from own sub/module */
if ((ygrouping = yang_find(ymod, Y_GROUPING, name)) != NULL)
@ -132,8 +133,8 @@ ys_grouping_module_resolve(yang_stmt *ymod,
if ((ygrouping = yang_find(yrealmod, Y_GROUPING, name)) != NULL)
goto done;
/* Find grouping from sub-modules */
yinc = NULL;
while ((yinc = yn_each(yrealmod, yinc)) != NULL){
inext = 0;
while ((yinc = yn_iter(yrealmod, &inext)) != NULL){
if (yang_keyword_get(yinc) != Y_INCLUDE)
continue;
submname = yang_argument_get(yinc);
@ -237,6 +238,7 @@ yang_augment_node(clixon_handle h,
cvec *wnsc = NULL; /* namespace context of when statement */
enum rfc_6020 targetkey;
enum rfc_6020 childkey;
int inext;
if ((ymod = ys_module(ys)) == NULL){
clixon_err(OE_YANG, 0, "My yang module not found");
@ -281,8 +283,8 @@ yang_augment_node(clixon_handle h,
goto done;
}
/* Extend ytarget with ys' schemanode children */
yc0 = NULL;
while ((yc0 = yn_each(ys, yc0)) != NULL) {
inext = 0;
while ((yc0 = yn_iter(ys, &inext)) != NULL) {
childkey = yang_keyword_get(yc0);
/* Only shemanodes and extensions */
if (!yang_schemanode(yc0) && childkey != Y_UNKNOWN
@ -361,7 +363,6 @@ yang_augment_node(clixon_handle h,
yang_flag_reset(yc, YANG_FLAG_GROUPING);
#endif
yc->ys_mymodule = ymod;
if (yn_insert(ytarget, yc) < 0)
goto done;
/* If there is an associated when statement, add a special when struct to the yang
@ -405,9 +406,10 @@ yang_augment_module(clixon_handle h,
{
int retval = -1;
yang_stmt *ys;
int inext;
ys = NULL;
while ((ys = yn_each(ymod, ys)) != NULL){
inext = 0;
while ((ys = yn_iter(ymod, &inext)) != NULL){
switch (yang_keyword_get(ys)){
case Y_AUGMENT: /* top-level */
if (yang_augment_node(h, ys) < 0)
@ -443,12 +445,13 @@ ys_do_refine(yang_stmt *yr,
yang_stmt *ytc; /* target child */
enum rfc_6020 keyw;
int i;
int inext;
/* Loop through refine node children. First if remove do that first
* In some cases remove a set of nodes.
*/
yrc = NULL;
while ((yrc = yn_each(yr, yrc)) != NULL) {
inext = 0;
while ((yrc = yn_iter(yr, &inext)) != NULL) {
keyw = yang_keyword_get(yrc);
switch (keyw){
case Y_DEFAULT: /* remove old, add new */
@ -479,8 +482,8 @@ ys_do_refine(yang_stmt *yr,
}
}
/* Second, add the node(s) */
yrc = NULL;
while ((yrc = yn_each(yr, yrc)) != NULL) {
inext = 0;
while ((yrc = yn_iter(yr, &inext)) != NULL) {
keyw = yang_keyword_get(yrc);
/* Make copy */
if ((yrc1 = ys_dup(yrc)) == NULL)
@ -524,6 +527,7 @@ ys_iskey(yang_stmt *y,
return 0;
}
/*! Helper function to yang_expand_grouping
*
* @param[in] yn Yang parent node of uses ststement
@ -552,6 +556,7 @@ yang_expand_uses_node(yang_stmt *yn,
yang_stmt *ywhen;
char *wxpath = NULL; /* xpath of when statement */
cvec *wnsc = NULL; /* namespace context of when statement */
int inext;
/* Split argument into prefix and name */
if (nodeid_split(yang_argument_get(ys), &prefix, &id) < 0)
@ -595,8 +600,8 @@ yang_expand_uses_node(yang_stmt *yn,
* Compute the number of such nodes, and extend the child vector with that below
*/
glen = 0;
yg = NULL;
while ((yg = yn_each(ygrouping2, yg)) != NULL) {
inext = 0;
while ((yg = yn_iter(ygrouping2, &inext)) != NULL) {
if (yang_schemanode(yg) || yang_keyword_get(yg) == Y_UNKNOWN)
glen++;
}
@ -636,8 +641,8 @@ yang_expand_uses_node(yang_stmt *yn,
/* Iterate through refinements and modify grouping copy
* See RFC 7950 7.13.2 yrt is the refine target node
*/
yr = NULL;
while ((yr = yn_each(ys, yr)) != NULL) {
inext = 0;
while ((yr = yn_iter(ys, &inext)) != NULL) {
yang_stmt *yrt; /* refine target node */
if (yang_keyword_get(yr) != Y_REFINE)
continue;
@ -1191,7 +1196,7 @@ yang_parse_recurse(clixon_handle h,
yang_stmt *ysp)
{
int retval = -1;
yang_stmt *yi = NULL; /* import */
yang_stmt *yi; /* import */
yang_stmt *yrev;
yang_stmt *ybelongto;
yang_stmt *yrealmod;
@ -1199,11 +1204,13 @@ yang_parse_recurse(clixon_handle h,
char *subrevision;
yang_stmt *subymod;
enum rfc_6020 keyw;
int inext;
if (ys_real_module(ymod, &yrealmod) < 0)
goto done;
/* go through all import (modules) and include(submodules) of ysp */
while ((yi = yn_each(ymod, yi)) != NULL){
inext = 0;
while ((yi = yn_iter(ymod, &inext)) != NULL){
keyw = yang_keyword_get(yi);
if (keyw != Y_IMPORT && keyw != Y_INCLUDE)
continue;
@ -1268,6 +1275,7 @@ ys_list_check(clixon_handle h,
yang_stmt *yc = NULL;
enum rfc_6020 keyw;
yang_stmt *yroot;
int inext;
/* This node is state, not config */
if (yang_config_ancestor(ys) == 0)
@ -1293,8 +1301,8 @@ ys_list_check(clixon_handle h,
}
/* Traverse subs */
if (yang_schemanode(ys) || keyw == Y_MODULE || keyw == Y_SUBMODULE){
yc = NULL;
while ((yc = yn_each(ys, yc)) != NULL){
inext = 0;
while ((yc = yn_iter(ys, &inext)) != NULL){
if (ys_list_check(h, yc) < 0)
goto done;
}
@ -1488,7 +1496,6 @@ yang_parse_post(clixon_handle h,
for (i=modmin; i<modmax; i++)
if (yang_apply(yang_child_i(yspec, i), Y_TYPE, ys_resolve_type, 1, h) < 0)
goto done;
/* Up to here resolving is made in the context they are defined, rather
* than the context they are used (except for submodules being merged w
* modules). Like static scoping.
@ -1513,7 +1520,6 @@ yang_parse_post(clixon_handle h,
for (i=0; i<ylen; i++)
if (yang_augment_module(h, ylist[i]) < 0)
goto done;
/* 8: Check deviations: not-supported add/delete/replace statements
* done late since eg groups must be expanded
*/

View file

@ -751,6 +751,7 @@ yang_schema_mount_statistics(clixon_handle h,
size_t sz;
cg_var *cv1;
yang_stmt *yspec1;
int inext;
if (yang_mount_xtop2xmnt(xtop, &cvv) < 0)
goto done;
@ -789,15 +790,15 @@ yang_schema_mount_statistics(clixon_handle h,
}
continue;
}
if (yang_stats(yspec, &nr, &sz) < 0)
if (yang_stats(yspec, 0, &nr, &sz) < 0)
goto done;
cprintf(cb, "<nr>%" PRIu64 "</nr><size>%zu</size>", nr, sz);
if (modules){
ym = NULL;
while ((ym = yn_each(yspec, ym)) != NULL) {
inext = 0;
while ((ym = yn_iter(yspec, &inext)) != NULL) {
cprintf(cb, "<module><name>%s</name>", yang_argument_get(ym));
nr = 0; sz = 0;
if (yang_stats(ym, &nr, &sz) < 0)
if (yang_stats(ym, 0, &nr, &sz) < 0)
goto done;
cprintf(cb, "<nr>%" PRIu64 "</nr><size>%zu</size>", nr, sz);
cprintf(cb, "</module>");

View file

@ -577,6 +577,7 @@ cv_validate1(clixon_handle h,
int reti; /* must keep signed, unsigned and string retval */
int retu; /* separated due to different error handling */
int rets;
int inext;
if (reason && *reason){
free(*reason);
@ -676,10 +677,10 @@ cv_validate1(clixon_handle h,
if (restype){
if (strcmp(restype, "enumeration") == 0){
found = 0;
yi = NULL;
if (str != NULL) {
// str = clixon_trim2(str, " \t\n"); /* May be misplaced, strip earlier? */
while ((yi = yn_each(yrestype, yi)) != NULL){
inext = 0;
while ((yi = yn_iter(yrestype, &inext)) != NULL){
if (yang_keyword_get(yi) != Y_ENUM)
continue;
if (strcmp(yang_argument_get(yi), str) == 0){
@ -707,8 +708,8 @@ cv_validate1(clixon_handle h,
if ((v = vec[i]) == NULL || !strlen(v))
continue;
found = 0;
yi = NULL;
while ((yi = yn_each(yrestype, yi)) != NULL){
inext = 0;
while ((yi = yn_iter(yrestype, &inext)) != NULL){
if (yang_keyword_get(yi) != Y_BIT)
continue;
if (strcmp(yang_argument_get(yi), v) == 0){
@ -933,10 +934,12 @@ ys_cv_validate_union(clixon_handle h,
yang_stmt **ysubp)
{
int retval = 1; /* valid */
yang_stmt *yt = NULL;
yang_stmt *yt;
char *reason1 = NULL; /* saved reason */
int inext;
while ((yt = yn_each(yrestype, yt)) != NULL){
inext = 0;
while ((yt = yn_iter(yrestype, &inext)) != NULL){
if (yang_keyword_get(yt) != Y_TYPE)
continue;
if ((retval = ys_cv_validate_union_one(h, ys, reason, yt, type, val)) < 0)
@ -1251,6 +1254,7 @@ yang_type_resolve_restrictions(yang_stmt *ytype,
yang_stmt *ys;
cg_var *cv;
char *pattern;
int inext;
if (options && cvv &&
(ys = yang_find(ytype, Y_RANGE, NULL)) != NULL){
@ -1264,8 +1268,8 @@ yang_type_resolve_restrictions(yang_stmt *ytype,
}
/* Find all patterns */
if (options && regexps){
ys = NULL;
while ((ys = yn_each(ytype, ys)) != NULL) {
inext = 0;
while ((ys = yn_iter(ytype, &inext)) != NULL) {
if (yang_keyword_get(ys) != Y_PATTERN)
continue;
if ((cv = cvec_add(regexps, CGV_STRING)) == NULL){