* Added yang access functions

* Change all y->ys_parent to yang_parent_get(y)
    * Change all y->ys_keyword to yang_keyword_get(y)
    * Change all y->ys_argument to yang_argument_get(y)
    * Change all y->ys_cv to yang_cv_get(y)
    * Change all y->ys_cvec to yang_cvec_get(y)
This commit is contained in:
Olof hagsand 2019-04-11 15:53:25 +02:00
parent 0a951899c8
commit cef0dc5a22
11 changed files with 269 additions and 124 deletions

View file

@ -42,9 +42,17 @@
* All references to plugin "text.so" should be removed. * All references to plugin "text.so" should be removed.
* The datastore directory is removed, code is moved to lib/src/clixon_datastore*.c * The datastore directory is removed, code is moved to lib/src/clixon_datastore*.c
* Removed clixon_backend -x <plugin> command-line options * Removed clixon_backend -x <plugin> command-line options
* Structural C-code change: Merged yang_spec and yang_node types into yang_stmt * Structural C-code change of yang statements:
* Change all yn_* and yp_ to ys_* * Merged yang_spec and yang_node types into yang_stmt
* Change all references to yang_node/yang_spec to yang_stmt * Change all references to types yang_node/yang_spec to yang_stmt
* Change all yang struct field accesses yn_* and yp_* to ys_* (but see next item for access functions).
* Added yang access functions
* Change all y->ys_parent to yang_parent_get(y)
* Change all y->ys_keyword to yang_keyword_get(y)
* Change all y->ys_argument to yang_argument_get(y)
* Change all y->ys_cv to yang_cv_get(y)
* Change all y->ys_cvec to yang_cvec_get(y)
* xmldb_get() removed unnecessary config option: * xmldb_get() removed unnecessary config option:
* Change all calls to dbget from: `xmldb_get(h, db, xpath, 0|1, &xret, msd)` to `xmldb_get(h, db, xpath, &xret, msd)` * Change all calls to dbget from: `xmldb_get(h, db, xpath, 0|1, &xret, msd)` to `xmldb_get(h, db, xpath, &xret, msd)`

View file

@ -187,7 +187,7 @@ client_get_streams(clicon_handle h,
clicon_err(OE_UNIX, 0, "clicon buffer"); clicon_err(OE_UNIX, 0, "clicon buffer");
goto done; goto done;
} }
cprintf(cb,"<%s xmlns=\"%s\">", top, yns->ys_argument); cprintf(cb,"<%s xmlns=\"%s\">", top, yang_argument_get(yns));
if (stream_get_xml(h, strcmp(top,"restconf-state")==0, cb) < 0) if (stream_get_xml(h, strcmp(top,"restconf-state")==0, cb) < 0)
goto done; goto done;
cprintf(cb,"</%s>", top); cprintf(cb,"</%s>", top);
@ -1110,7 +1110,7 @@ from_client_msg(clicon_handle h,
clicon_err(OE_XML, ENOENT, "rpc yang does not have module"); clicon_err(OE_XML, ENOENT, "rpc yang does not have module");
goto done; goto done;
} }
module = ymod->ys_argument; module = yang_argument_get(ymod);
clicon_debug(1, "%s module:%s rpc:%s", __FUNCTION__, module, rpc); clicon_debug(1, "%s module:%s rpc:%s", __FUNCTION__, module, rpc);
/* Pre-NACM access step */ /* Pre-NACM access step */
xnacm = NULL; xnacm = NULL;

View file

@ -243,7 +243,7 @@ cli_dbxml(clicon_handle h,
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
if (xml_value_set(xa, xml_operation2str(op)) < 0) if (xml_value_set(xa, xml_operation2str(op)) < 0)
goto done; goto done;
if (y->ys_keyword != Y_LIST && y->ys_keyword != Y_LEAF_LIST){ if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){
len = cvec_len(cvv); len = cvec_len(cvv);
if (len > 1){ if (len > 1){
cval = cvec_i(cvv, len-1); cval = cvec_i(cvv, len-1);

View file

@ -123,7 +123,7 @@ cli_expand_var_generate(clicon_handle h,
if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0) if (yang2api_path_fmt(ys, 1, &api_path_fmt) < 0)
goto done; goto done;
cprintf(cb, "|<%s:%s", ys->ys_argument, cprintf(cb, "|<%s:%s", yang_argument_get(ys),
cv_type2str(cvtype)); cv_type2str(cvtype));
if (options & YANG_OPTIONS_FRACTION_DIGITS) if (options & YANG_OPTIONS_FRACTION_DIGITS)
cprintf(cb, " fraction-digits:%u", fraction_digits); cprintf(cb, " fraction-digits:%u", fraction_digits);
@ -191,11 +191,11 @@ yang2cli_var_identityref(yang_stmt *ys,
if (helptext) if (helptext)
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL && if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL &&
(ybaseid = yang_find_identity(ys, ybaseref->ys_argument)) != NULL){ (ybaseid = yang_find_identity(ys, yang_argument_get(ybaseref))) != NULL){
if (cvec_len(ybaseid->ys_cvec) > 0){ if (cvec_len(yang_cvec_get(ybaseid)) > 0){
cprintf(cb, "|<%s:%s choice:", ys->ys_argument, cvtypestr); cprintf(cb, "|<%s:%s choice:", yang_argument_get(ys), cvtypestr);
i = 0; i = 0;
while ((cv = cvec_each(ybaseid->ys_cvec, cv)) != NULL){ while ((cv = cvec_each(yang_cvec_get(ybaseid), cv)) != NULL){
if (i++) if (i++)
cprintf(cb, "|"); cprintf(cb, "|");
name = strdup(cv_name_get(cv)); name = strdup(cv_name_get(cv));
@ -317,12 +317,12 @@ yang2cli_var_sub(clicon_handle h,
retval = 0; retval = 0;
goto done; goto done;
} }
type = ytype?ytype->ys_argument:NULL; type = ytype?yang_argument_get(ytype):NULL;
cvtypestr = cv_type2str(cvtype); cvtypestr = cv_type2str(cvtype);
if (type && strcmp(type, "identityref") == 0) if (type && strcmp(type, "identityref") == 0)
cprintf(cb, "("); cprintf(cb, "(");
cprintf(cb, "<%s:%s", ys->ys_argument, cvtypestr); cprintf(cb, "<%s:%s", yang_argument_get(ys), cvtypestr);
/* enumeration special case completion */ /* enumeration special case completion */
if (type){ if (type){
if (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0){ if (strcmp(type, "enumeration") == 0 || strcmp(type, "bits") == 0){
@ -330,11 +330,11 @@ yang2cli_var_sub(clicon_handle h,
i = 0; i = 0;
yi = NULL; yi = NULL;
while ((yi = yn_each(ytype, yi)) != NULL){ while ((yi = yn_each(ytype, yi)) != NULL){
if (yi->ys_keyword != Y_ENUM && yi->ys_keyword != Y_BIT) if (yang_keyword_get(yi) != Y_ENUM && yang_keyword_get(yi) != Y_BIT)
continue; continue;
if (i) if (i)
cprintf(cb, "|"); cprintf(cb, "|");
cprintf(cb, "%s", yi->ys_argument); cprintf(cb, "%s", yang_argument_get(yi));
i++; i++;
} }
} }
@ -399,7 +399,7 @@ yang2cli_var_union_one(clicon_handle h,
&ytype, &options, /* resolved type */ &ytype, &options, /* resolved type */
&cvv, &pattern, &fraction_digits) < 0) &cvv, &pattern, &fraction_digits) < 0)
goto done; goto done;
restype = ytype?ytype->ys_argument:NULL; restype = ytype?yang_argument_get(ytype):NULL;
if (restype && strcmp(restype, "union") == 0){ /* recursive union */ if (restype && strcmp(restype, "union") == 0){ /* recursive union */
if (yang2cli_var_union(h, ys, origtype, ytype, helptext, cb) < 0) if (yang2cli_var_union(h, ys, origtype, ytype, helptext, cb) < 0)
@ -444,7 +444,7 @@ yang2cli_var_union(clicon_handle h,
* made in the union_one call. * made in the union_one call.
*/ */
while ((ytsub = yn_each(ytype, ytsub)) != NULL){ while ((ytsub = yn_each(ytype, ytsub)) != NULL){
if (ytsub->ys_keyword != Y_TYPE) if (yang_keyword_get(ytsub) != Y_TYPE)
continue; continue;
if (i++) if (i++)
cprintf(cb, "|"); cprintf(cb, "|");
@ -490,7 +490,7 @@ yang2cli_var(clicon_handle h,
if (yang_type_get(ys, &origtype, &yrestype, if (yang_type_get(ys, &origtype, &yrestype,
&options, &cvv, &pattern, &fraction_digits) < 0) &options, &cvv, &pattern, &fraction_digits) < 0)
goto done; goto done;
restype = yrestype?yrestype->ys_argument:NULL; restype = yrestype?yang_argument_get(yrestype):NULL;
if (restype && strcmp(restype, "empty") == 0){ if (restype && strcmp(restype, "empty") == 0){
retval = 0; retval = 0;
@ -514,7 +514,7 @@ yang2cli_var(clicon_handle h,
cprintf(cb, ")"); cprintf(cb, ")");
} }
else{ else{
type = yrestype?yrestype->ys_argument:NULL; type = yrestype?yang_argument_get(yrestype):NULL;
if (type) if (type)
completionp = clicon_cli_genmodel_completion(h) && completionp = clicon_cli_genmodel_completion(h) &&
strcmp(type, "enumeration") != 0 && strcmp(type, "enumeration") != 0 &&
@ -564,7 +564,7 @@ yang2cli_leaf(clicon_handle h,
/* description */ /* description */
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
if ((helptext = strdup(yd->ys_argument)) == NULL){ if ((helptext = strdup(yang_argument_get(yd))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
@ -573,7 +573,7 @@ yang2cli_leaf(clicon_handle h,
} }
cprintf(cb, "%*s", level*3, ""); cprintf(cb, "%*s", level*3, "");
if (gt == GT_VARS|| gt == GT_ALL){ if (gt == GT_VARS|| gt == GT_ALL){
cprintf(cb, "%s", ys->ys_argument); cprintf(cb, "%s", yang_argument_get(ys));
if (helptext) if (helptext)
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
cprintf(cb, " "); cprintf(cb, " ");
@ -612,14 +612,13 @@ yang2cli_container(clicon_handle h,
{ {
yang_stmt *yc; yang_stmt *yc;
yang_stmt *yd; yang_stmt *yd;
int i;
int retval = -1; int retval = -1;
char *helptext = NULL; char *helptext = NULL;
char *s; char *s;
cprintf(cb, "%*s%s", level*3, "", ys->ys_argument); cprintf(cb, "%*s%s", level*3, "", yang_argument_get(ys));
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
if ((helptext = strdup(yd->ys_argument)) == NULL){ if ((helptext = strdup(yang_argument_get(yd))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
@ -630,10 +629,11 @@ yang2cli_container(clicon_handle h,
if (cli_callback_generate(h, ys, cb) < 0) if (cli_callback_generate(h, ys, cb) < 0)
goto done; goto done;
cprintf(cb, ";{\n"); cprintf(cb, ";{\n");
for (i=0; i<ys->ys_len; i++)
if ((yc = ys->ys_stmt[i]) != NULL) yc = NULL;
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0) while ((yc = yn_each(ys, yc)) != NULL)
goto done; if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done;
cprintf(cb, "%*s}\n", level*3, ""); cprintf(cb, "%*s}\n", level*3, "");
retval = 0; retval = 0;
done: done:
@ -659,7 +659,6 @@ yang2cli_list(clicon_handle h,
yang_stmt *yc; yang_stmt *yc;
yang_stmt *yd; yang_stmt *yd;
yang_stmt *yleaf; yang_stmt *yleaf;
int i;
cg_var *cvi; cg_var *cvi;
char *keyname; char *keyname;
cvec *cvk = NULL; /* vector of index keys */ cvec *cvk = NULL; /* vector of index keys */
@ -667,9 +666,9 @@ yang2cli_list(clicon_handle h,
char *helptext = NULL; char *helptext = NULL;
char *s; char *s;
cprintf(cb, "%*s%s", level*3, "", ys->ys_argument); cprintf(cb, "%*s%s", level*3, "", yang_argument_get(ys));
if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){ if ((yd = yang_find(ys, Y_DESCRIPTION, NULL)) != NULL){
if ((helptext = strdup(yd->ys_argument)) == NULL){ if ((helptext = strdup(yang_argument_get(yd))) == NULL){
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
@ -678,14 +677,14 @@ yang2cli_list(clicon_handle h,
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
} }
/* Loop over all key variables */ /* Loop over all key variables */
cvk = ys->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */ cvk = yang_cvec_get(ys); /* Use Y_LIST cache, see ys_populate_list() */
cvi = NULL; cvi = NULL;
/* Iterate over individual keys */ /* Iterate over individual keys */
while ((cvi = cvec_each(cvk, cvi)) != NULL) { while ((cvi = cvec_each(cvk, cvi)) != NULL) {
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
if ((yleaf = yang_find(ys, Y_LEAF, keyname)) == NULL){ if ((yleaf = yang_find(ys, Y_LEAF, keyname)) == NULL){
clicon_err(OE_XML, 0, "List statement \"%s\" has no key leaf \"%s\"", clicon_err(OE_XML, 0, "List statement \"%s\" has no key leaf \"%s\"",
ys->ys_argument, keyname); yang_argument_get(ys), keyname);
goto done; goto done;
} }
/* Print key variable now, and skip it in loop below /* Print key variable now, and skip it in loop below
@ -697,22 +696,22 @@ yang2cli_list(clicon_handle h,
} }
cprintf(cb, "{\n"); cprintf(cb, "{\n");
for (i=0; i<ys->ys_len; i++) yc = NULL;
if ((yc = ys->ys_stmt[i]) != NULL){ while ((yc = yn_each(ys, yc)) != NULL) {
/* cvk is a cvec of strings containing variable names /* cvk is a cvec of strings containing variable names
yc is a leaf that may match one of the values of cvk. yc is a leaf that may match one of the values of cvk.
*/ */
cvi = NULL; cvi = NULL;
while ((cvi = cvec_each(cvk, cvi)) != NULL) { while ((cvi = cvec_each(cvk, cvi)) != NULL) {
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
if (strcmp(keyname, yc->ys_argument) == 0) if (strcmp(keyname, yang_argument_get(yc)) == 0)
break; break;
}
if (cvi != NULL)
continue;
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done;
} }
if (cvi != NULL)
continue;
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done;
}
cprintf(cb, "%*s}\n", level*3, ""); cprintf(cb, "%*s}\n", level*3, "");
retval = 0; retval = 0;
done: done:
@ -746,25 +745,24 @@ yang2cli_choice(clicon_handle h,
{ {
int retval = -1; int retval = -1;
yang_stmt *yc; yang_stmt *yc;
int i;
for (i=0; i<ys->ys_len; i++) yc = NULL;
if ((yc = ys->ys_stmt[i]) != NULL){ while ((yc = yn_each(ys, yc)) != NULL) {
switch (yc->ys_keyword){ switch (yang_keyword_get(yc)){
case Y_CASE: case Y_CASE:
if (yang2cli_stmt(h, yc, gt, level+2, cb) < 0) if (yang2cli_stmt(h, yc, gt, level+2, cb) < 0)
goto done; goto done;
break; break;
case Y_CONTAINER: case Y_CONTAINER:
case Y_LEAF: case Y_LEAF:
case Y_LEAF_LIST: case Y_LEAF_LIST:
case Y_LIST: case Y_LIST:
default: default:
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0) if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done; goto done;
break; break;
}
} }
}
retval = 0; retval = 0;
done: done:
return retval; return retval;
@ -786,10 +784,9 @@ yang2cli_stmt(clicon_handle h,
{ {
yang_stmt *yc; yang_stmt *yc;
int retval = -1; int retval = -1;
int i;
if (yang_config(ys)){ if (yang_config(ys)){
switch (ys->ys_keyword){ switch (yang_keyword_get(ys)){
case Y_CONTAINER: case Y_CONTAINER:
if (yang2cli_container(h, ys, gt, level, cb) < 0) if (yang2cli_container(h, ys, gt, level, cb) < 0)
goto done; goto done;
@ -810,10 +807,10 @@ yang2cli_stmt(clicon_handle h,
case Y_CASE: case Y_CASE:
case Y_SUBMODULE: case Y_SUBMODULE:
case Y_MODULE: case Y_MODULE:
for (i=0; i<ys->ys_len; i++) yc = NULL;
if ((yc = ys->ys_stmt[i]) != NULL) while ((yc = yn_each(ys, yc)) != NULL)
if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0) if (yang2cli_stmt(h, yc, gt, level+1, cb) < 0)
goto done; goto done;
break; break;
default: /* skip */ default: /* skip */
break; break;
@ -841,7 +838,6 @@ yang2cli(clicon_handle h,
enum genmodel_type gt) enum genmodel_type gt)
{ {
cbuf *cb = NULL; cbuf *cb = NULL;
int i;
int retval = -1; int retval = -1;
yang_stmt *ymod = NULL; yang_stmt *ymod = NULL;
cvec *globals; /* global variables from syntax */ cvec *globals; /* global variables from syntax */
@ -851,11 +847,10 @@ yang2cli(clicon_handle h,
goto done; goto done;
} }
/* Traverse YANG, loop through all modules and generate CLI */ /* Traverse YANG, loop through all modules and generate CLI */
for (i=0; i<yspec->ys_len; i++) ymod = NULL;
if ((ymod = yspec->ys_stmt[i]) != NULL){ while ((ymod = yn_each(yspec, ymod)) != NULL)
if (yang2cli_stmt(h, ymod, gt, 0, cb) < 0) if (yang2cli_stmt(h, ymod, gt, 0, cb) < 0)
goto done; goto done;
}
clicon_debug(2, "%s: buf\n%s\n", __FUNCTION__, cbuf_get(cb)); clicon_debug(2, "%s: buf\n%s\n", __FUNCTION__, cbuf_get(cb));
/* Parse the buffer using cligen parser. XXX why this?*/ /* Parse the buffer using cligen parser. XXX why this?*/
if ((globals = cvec_new(0)) == NULL) if ((globals = cvec_new(0)) == NULL)

View file

@ -183,12 +183,12 @@ expand_dbvar(void *h,
* such operations to the datastore by a generic xpath function. * such operations to the datastore by a generic xpath function.
*/ */
if ((ytype = yang_find(y, Y_TYPE, NULL)) != NULL) if ((ytype = yang_find(y, Y_TYPE, NULL)) != NULL)
if (strcmp(ytype->ys_argument, "leafref")==0){ if (strcmp(yang_argument_get(ytype), "leafref")==0){
if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){ if ((ypath = yang_find(ytype, Y_PATH, NULL)) == NULL){
clicon_err(OE_DB, 0, "Leafref %s requires path statement", ytype->ys_argument); clicon_err(OE_DB, 0, "Leafref %s requires path statement", yang_argument_get(ytype));
goto done; goto done;
} }
xpathcur = ypath->ys_argument; xpathcur = yang_argument_get(ypath);
if (xml_merge(xt, xtop, yspec, &reason) < 0) /* Merge xtop into xt */ if (xml_merge(xt, xtop, yspec, &reason) < 0) /* Merge xtop into xt */
goto done; goto done;
if (reason){ if (reason){

View file

@ -642,9 +642,9 @@ match_list_keys(yang_stmt *y,
char *keya; char *keya;
char *keyd; char *keyd;
if (y->ys_keyword != Y_LIST &&y->ys_keyword != Y_LEAF_LIST) if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST)
goto done; goto done;
cvk = y->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */ cvk = yang_cvec_get(y); /* Use Y_LIST cache, see ys_populate_list() */
cvi = NULL; cvi = NULL;
while ((cvi = cvec_each(cvk, cvi)) != NULL) { while ((cvi = cvec_each(cvk, cvi)) != NULL) {
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
@ -847,7 +847,7 @@ api_data_put(clicon_handle h,
goto ok; goto ok;
} }
/* If list or leaf-list, api-path keys must match data keys */ /* If list or leaf-list, api-path keys must match data keys */
if (y && (y->ys_keyword == Y_LIST ||y->ys_keyword == Y_LEAF_LIST)){ if (y && (yang_keyword_get(y) == Y_LIST || yang_keyword_get(y) == Y_LEAF_LIST)){
if (match_list_keys((yang_stmt*)y, x, xbot) < 0){ if (match_list_keys((yang_stmt*)y, x, xbot) < 0){
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0) if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
goto done; goto done;
@ -1150,14 +1150,14 @@ api_operations_get(clicon_handle h,
namespace = yang_find_mynamespace(ymod); namespace = yang_find_mynamespace(ymod);
yc = NULL; yc = NULL;
while ((yc = yn_each(ymod, yc)) != NULL) { while ((yc = yn_each(ymod, yc)) != NULL) {
if (yc->ys_keyword != Y_RPC) if (yang_keyword_get(yc) != Y_RPC)
continue; continue;
if (use_xml) if (use_xml)
cprintf(cbx, "<%s xmlns=\"%s\"/>", yc->ys_argument, namespace); cprintf(cbx, "<%s xmlns=\"%s\"/>", yang_argument_get(yc), namespace);
else{ else{
if (i++) if (i++)
cprintf(cbx, ","); cprintf(cbx, ",");
cprintf(cbx, "\"%s:%s\": null", ymod->ys_argument, yc->ys_argument); cprintf(cbx, "\"%s:%s\": null", yang_argument_get(ymod), yang_argument_get(yc));
} }
} }
} }

View file

@ -300,7 +300,7 @@ upgrade_2016(clicon_handle h,
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL) if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL)
goto ok; /* shouldnt happen */ goto ok; /* shouldnt happen */
clicon_debug(1, "%s module %s", __FUNCTION__, ym?ym->ys_argument:"none"); clicon_debug(1, "%s module %s", __FUNCTION__, ym?yang_argument_get(ym):"none");
/* Get all XML nodes with that namespace */ /* Get all XML nodes with that namespace */
if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0) if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0)
goto done; goto done;
@ -398,7 +398,7 @@ upgrade_2018(clicon_handle h,
yspec = clicon_dbspec_yang(h); yspec = clicon_dbspec_yang(h);
if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL) if ((ym = yang_find_module_by_namespace(yspec, ns)) == NULL)
goto ok; /* shouldnt happen */ goto ok; /* shouldnt happen */
clicon_debug(1, "%s module %s", __FUNCTION__, ym?ym->ys_argument:"none"); clicon_debug(1, "%s module %s", __FUNCTION__, ym?yang_argument_get(ym):"none");
/* Get all XML nodes with that namespace */ /* Get all XML nodes with that namespace */
if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0) if (xml_namespace_vec(h, xt, ns, &vec, &vlen) < 0)
goto done; goto done;

View file

@ -169,7 +169,7 @@ typedef enum yang_class yang_class;
#define yang_schemanode(y) (yang_datanode(y) || (y)->ys_keyword == Y_RPC || (y)->ys_keyword == Y_CHOICE || (y)->ys_keyword == Y_CASE || (y)->ys_keyword == Y_INPUT || (y)->ys_keyword == Y_OUTPUT || (y)->ys_keyword == Y_NOTIFICATION) #define yang_schemanode(y) (yang_datanode(y) || (y)->ys_keyword == Y_RPC || (y)->ys_keyword == Y_CHOICE || (y)->ys_keyword == Y_CASE || (y)->ys_keyword == Y_INPUT || (y)->ys_keyword == Y_OUTPUT || (y)->ys_keyword == Y_NOTIFICATION)
typedef struct yang_stmt yang_stmt; /* forward */ typedef struct yang_stmt yang_stmt; /* Defined in clixon_yang_internal */
/*! Yang type cache. Yang type statements can cache all typedef info here /*! Yang type cache. Yang type statements can cache all typedef info here
* @note unions not cached * @note unions not cached
@ -189,6 +189,7 @@ typedef struct yang_type_cache yang_type_cache;
/*! yang statement /*! yang statement
*/ */
struct yang_stmt{ struct yang_stmt{
int ys_len; /* Number of children */ int ys_len; /* Number of children */
struct yang_stmt **ys_stmt; /* Vector of children statement pointers */ struct yang_stmt **ys_stmt; /* Vector of children statement pointers */
@ -197,7 +198,6 @@ struct yang_stmt{
char *ys_argument; /* String / argument depending on keyword */ char *ys_argument; /* String / argument depending on keyword */
int ys_flags; /* Flags according to YANG_FLAG_* above */ int ys_flags; /* Flags according to YANG_FLAG_* above */
/*--------------here common for all -------*/
yang_stmt *ys_module; /* Shortcut to "my" module. Augmented yang_stmt *ys_module; /* Shortcut to "my" module. Augmented
nodes can belong to other nodes can belong to other
modules than the ancestor module */ modules than the ancestor module */
@ -218,31 +218,22 @@ struct yang_stmt{
Y_TYPE & identity: store all derived types Y_TYPE & identity: store all derived types
*/ */
yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */ yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */
int _ys_vector_i; /* internal use: yn_each */
}; };
#if 0 /* Backward compatible */
typedef struct yang_stmt yang_node;
typedef struct yang_stmt yang_spec;
#define yn_len ys_len
#define yn_stmt ys_stmt
#define yn_parent ys_parent
#define yn_keyword ys_keyword
#define yn_argument ys_argument
#define yn_flags ys_flags
#define yp_len ys_len
#define yp_stmt ys_stmt
#define yp_parent ys_parent
#define yp_keyword ys_keyword
#define yp_argument ys_argument
#define yp_flags ys_flags
#endif
typedef int (yang_applyfn_t)(yang_stmt *ys, void *arg); typedef int (yang_applyfn_t)(yang_stmt *ys, void *arg);
/* /*
* Prototypes * Prototypes
*/ */
/* Access functions */
yang_stmt *yang_parent_get(yang_stmt *ys);
enum rfc_6020 yang_keyword_get(yang_stmt *ys);
char *yang_argument_get(yang_stmt *ys);
cg_var *yang_cv_get(yang_stmt *ys);
cvec *yang_cvec_get(yang_stmt *ys);
/* Other functions */
yang_stmt *yspec_new(void); yang_stmt *yspec_new(void);
yang_stmt *ys_new(enum rfc_6020 keyw); yang_stmt *ys_new(enum rfc_6020 keyw);
int ys_free(yang_stmt *ys); int ys_free(yang_stmt *ys);

View file

@ -625,6 +625,7 @@ xml_child_i_set(cxobj *xt,
* ... * ...
* } * }
* @endcode * @endcode
* @note makes uses _x_vector_i:can be changed if list changed between calls
*/ */
cxobj * cxobj *
xml_child_each(cxobj *xparent, xml_child_each(cxobj *xparent,
@ -791,7 +792,7 @@ xml_cv_set(cxobj *x,
* *
* @retval xmlobj if found. * @retval xmlobj if found.
* @retval NULL if no such node found. * @retval NULL if no such node found.
* @see xml_find_type which is a more generic function * @see xml_find_type A more generic function
*/ */
cxobj * cxobj *
xml_find(cxobj *x_up, xml_find(cxobj *x_up,

View file

@ -87,9 +87,9 @@
#include "clixon_plugin.h" #include "clixon_plugin.h"
#include "clixon_data.h" #include "clixon_data.h"
#include "clixon_options.h" #include "clixon_options.h"
#include "clixon_yang_type.h"
#include "clixon_yang_parse.h" #include "clixon_yang_parse.h"
#include "clixon_yang_cardinality.h" #include "clixon_yang_cardinality.h"
#include "clixon_yang_type.h"
/* Size of json read buffer when reading from file*/ /* Size of json read buffer when reading from file*/
#define BUFLEN 1024 #define BUFLEN 1024
@ -174,6 +174,56 @@ static const map_str2int ykmap[] = {
{NULL, -1} {NULL, -1}
}; };
/* Access functions
*/
/*! Get yang statement parent
* @param[in] ys Yang statement node
*/
yang_stmt *
yang_parent_get(yang_stmt *ys)
{
return ys->ys_parent;
}
/*! Get yang statement keyword
* @param[in] ys Yang statement node
*/
enum rfc_6020
yang_keyword_get(yang_stmt *ys)
{
return ys->ys_keyword;
}
/*! Get yang statement context-dependent argument
* @param[in] ys Yang statement node
*/
char*
yang_argument_get(yang_stmt *ys)
{
return ys->ys_argument;
}
/*! Get yang statement CLIgen variable
* @param[in] ys Yang statement node
*/
cg_var*
yang_cv_get(yang_stmt *ys)
{
return ys->ys_cv;
}
/*! Get yang statement CLIgen variable vector
* @param[in] ys Yang statement node
*/
cvec*
yang_cvec_get(yang_stmt *ys)
{
return ys->ys_cvec;
}
/* End access functions */
/*! Create new yang specification /*! Create new yang specification
* @retval yspec Free with yspec_free() * @retval yspec Free with yspec_free()
* @retval NULL Error * @retval NULL Error
@ -392,29 +442,38 @@ yn_insert(yang_stmt *ys_parent,
/*! Iterate through all yang statements from a yang node /*! Iterate through all yang statements from a yang node
* *
* Note that this is not optimized, one could use 'i' as index? * @param[in] yparent yang statement whose children should be iterated
* @param[in] yprev previous child, or NULL on init
* @code * @code
* yang_stmt *ys = NULL; * yang_stmt *yprev = NULL;
* while ((ys = yn_each(yn, ys)) != NULL) { * while ((yprev = yn_each(yparent, yprev)) != NULL) {
* ...ys... * ...yprev...
* } * }
* @endcode * @endcode
* @note makes uses _ys_vector_i:can be changed if list changed between calls
*/ */
yang_stmt * yang_stmt *
yn_each(yang_stmt *yn, yn_each(yang_stmt *yparent,
yang_stmt *ys) yang_stmt *yprev)
{ {
int i;
yang_stmt *yc = NULL; yang_stmt *yc = NULL;
int i;
for (i=0; i<yn->ys_len; i++){ if (yparent == NULL)
yc = yn->ys_stmt[i]; return NULL;
if (ys==NULL) for (i=yprev?yprev->_ys_vector_i+1:0; i<yparent->ys_len; i++){
return yc; if ((yc = yparent->ys_stmt[i]) == NULL){
if (ys==yc) assert(yc); /* XXX Check if happens */
ys = NULL; continue;
}
/* make room for other conditionals */
break; /* this is next object after previous */
} }
return NULL; if (i < yparent->ys_len) /* found */
yc->_ys_vector_i = i;
else
yc = NULL;
return yc;
} }
/*! Find first child yang_stmt with matching keyword and argument /*! Find first child yang_stmt with matching keyword and argument

View file

@ -0,0 +1,91 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
This file is part of CLIXON.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 3 or later (the "GPL"),
in which case the provisions of the GPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of the GPL, and not to allow others to
use your version of this file under the terms of Apache License version 2,
indicate your decision by deleting the provisions above and replace them with
the notice and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the Apache License version 2 or the GPL.
***** END LICENSE BLOCK *****
* Yang functions
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
*/
#ifndef _CLIXON_YANG_INTERNAL_H_
#define _CLIXON_YANG_INTERNAL_H_
/*! Yang type cache. Yang type statements can cache all typedef info here
* @note unions not cached
*/
struct yang_type_cache{
int yc_options; /* See YANG_OPTIONS_* that determines pattern/
fraction fields. */
cvec *yc_cvv; /* Range and length restriction. (if YANG_OPTION_
LENGTH|RANGE. Can be a vector if multiple
ranges*/
char *yc_pattern; /* regex (posix) (if YANG_OPTIONS_PATTERN) */
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;
/*! yang statement
*/
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; /* See clicon_yang_parse.tab.h */
char *ys_argument; /* String / argument depending on keyword */
int ys_flags; /* Flags according to YANG_FLAG_* above */
yang_stmt *ys_module; /* Shortcut to "my" module. Augmented
nodes can belong to other
modules than the ancestor module */
char *ys_extra; /* For unknown */
cg_var *ys_cv; /* cligen variable. See ys_populate()
Following stmts have cv:s:
leaf: for default value
leaf-list,
config: boolean true or false
mandatory: boolean true or false
fraction-digits for fraction-digits
unknown-stmt (argument)
*/
cvec *ys_cvec; /* List of stmt-specific variables
Y_RANGE: range_min, range_max
Y_LIST: vector of keys
Y_TYPE & identity: store all derived types
*/
yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */
int _ys_vector_i; /* internal use: yn_each */
};
#endif /* _CLIXON_YANG_INTERNAL_H_ */