diff --git a/CHANGELOG.md b/CHANGELOG.md index bb5898b7c..4c4f28b35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 01cfb6b4b..f53ed9a5c 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -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, "%" PRIu64 "%zu", 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, "%s", 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, "%s", yang_argument_get(ym)); if (clixon_stats_module_get(h, ym, cbret) < 0) goto done; diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index 473513824..9d84e0975 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -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. */ @@ -1128,11 +1133,12 @@ yang2cli_choice(clixon_handle h, int level, cbuf *cb) { - int retval = -1; - yang_stmt *yc; + 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 */ diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index 3ea6a3c04..cb732001d 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -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: []"); @@ -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; diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c index a066b51f5..1027bb4cf 100644 --- a/apps/restconf/restconf_methods_get.c +++ b/apps/restconf/restconf_methods_get.c @@ -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){ diff --git a/apps/snmp/snmp_handler.c b/apps/snmp/snmp_handler.c index d30b6f428..34fce207b 100644 --- a/apps/snmp/snmp_handler.c +++ b/apps/snmp/snmp_handler.c @@ -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 */ diff --git a/apps/snmp/snmp_lib.c b/apps/snmp/snmp_lib.c index 924c896cf..ea395a658 100644 --- a/apps/snmp/snmp_lib.c +++ b/apps/snmp/snmp_lib.c @@ -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) diff --git a/apps/snmp/snmp_register.c b/apps/snmp/snmp_register.c index 5b7813a30..98fb91418 100644 --- a/apps/snmp/snmp_register.c +++ b/apps/snmp/snmp_register.c @@ -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; diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index 9ef63a675..914d884b6 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -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); diff --git a/lib/src/clixon_netconf_monitoring.c b/lib/src/clixon_netconf_monitoring.c index 17589ecd2..d0475df8f 100644 --- a/lib/src/clixon_netconf_monitoring.c +++ b/lib/src/clixon_netconf_monitoring.c @@ -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, ""); - while ((ym = yn_each(yspec, ym)) != NULL) { + inext = 0; + while ((ym = yn_iter(yspec, &inext)) != NULL) { cprintf(cb, ""); identifier = yang_argument_get(ym); cprintf(cb, "%s", identifier); diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index 129d7bd87..bc62b38d8 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -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) diff --git a/lib/src/clixon_validate_minmax.c b/lib/src/clixon_validate_minmax.c index f41675473..3904a9986 100644 --- a/lib/src/clixon_validate_minmax.c +++ b/lib/src/clixon_validate_minmax.c @@ -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 */ diff --git a/lib/src/clixon_xml_default.c b/lib/src/clixon_xml_default.c index 028cae59a..7c7747f0b 100644 --- a/lib/src/clixon_xml_default.c +++ b/lib/src/clixon_xml_default.c @@ -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; diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index d28de3b56..b78819724 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -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) diff --git a/lib/src/clixon_xml_nsctx.c b/lib/src/clixon_xml_nsctx.c index c860faf3e..275ef3172 100644 --- a/lib/src/clixon_xml_nsctx.c +++ b/lib/src/clixon_xml_nsctx.c @@ -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) diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index de6aa77cc..0f8e839a5 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -625,32 +625,37 @@ 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 * @retval -1 Error */ int -yang_stats(yang_stmt *yt, - uint64_t *nrp, - size_t *szp) +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; } - *nrp += 1; - yang_stats_one(yt, &sz); - if (szp) - *szp += sz; - ys = NULL; - while ((ys = yn_each(yt, ys)) != NULL) { + if (keyw == 0 || yang_keyword_get(yt) == keyw){ + *nrp += 1; + yang_stats_one(yt, &sz); + if (szp) + *szp += sz; + } + 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] yparent yang statement whose children are iterated + * @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; iys_len; i++){ - if ((yc = yparent->ys_stmt[i]) == NULL){ + for (; (*inext)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; iys_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": : @@ -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) diff --git a/lib/src/clixon_yang_cardinality.c b/lib/src/clixon_yang_cardinality.c index e4a42bee8..96d7f8def 100644 --- a/lib/src/clixon_yang_cardinality.c +++ b/lib/src/clixon_yang_cardinality.c @@ -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; diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h index d9a4ca421..69a376f82 100644 --- a/lib/src/clixon_yang_internal.h +++ b/lib/src/clixon_yang_internal.h @@ -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_ */ diff --git a/lib/src/clixon_yang_module.c b/lib/src/clixon_yang_module.c index 516831609..0108dae2b 100644 --- a/lib/src/clixon_yang_module.c +++ b/lib/src/clixon_yang_module.c @@ -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_argument_get(yns)); cprintf(cb,"%s", msid); cprintf(cb,"default"); - 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,""); @@ -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,""); @@ -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; diff --git a/lib/src/clixon_yang_parse.y b/lib/src/clixon_yang_parse.y index 028388a8f..931fec07f 100644 --- a/lib/src/clixon_yang_parse.y +++ b/lib/src/clixon_yang_parse.y @@ -235,7 +235,6 @@ yang_parse_init(clixon_yang_yacc *yy) return 0; } - int yang_parse_exit(clixon_yang_yacc *yy) { diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index 93e5693a2..8eae46d64 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -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%" PRIu64 "%zu", nr, sz); if (modules){ - ym = NULL; - while ((ym = yn_each(yspec, ym)) != NULL) { + inext = 0; + while ((ym = yn_iter(yspec, &inext)) != NULL) { cprintf(cb, "%s", 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, "%" PRIu64 "%zu", nr, sz); cprintf(cb, ""); diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index a4406e9f8..bd3f84ce3 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -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){