* New clixon-config@2020-02-22.yang revision
* C-code changes: - Replaced stream uri:s w constants - Replaced large debug print code with single clicon_log_xml - Restconf put and post handling refactored using new parse API
This commit is contained in:
parent
de3853a126
commit
a71c256898
27 changed files with 308 additions and 250 deletions
|
|
@ -1066,7 +1066,6 @@ json_xmlns_translate(yang_stmt *yspec,
|
|||
yang_stmt *ymod;
|
||||
char *namespace;
|
||||
char *modname = NULL;
|
||||
char *prefix;
|
||||
cxobj *xc;
|
||||
int ret;
|
||||
|
||||
|
|
@ -1080,8 +1079,13 @@ json_xmlns_translate(yang_stmt *yspec,
|
|||
goto fail;
|
||||
}
|
||||
namespace = yang_find_mynamespace(ymod);
|
||||
prefix = yang_find_myprefix(ymod);
|
||||
if (xml_namespace_change(x, namespace, prefix) < 0)
|
||||
/* It would be possible to use canonical prefixes here, but probably not
|
||||
* necessary or even right. Therefore, the namespace given by the JSON prefix / module
|
||||
* is always the default namespace with prefix NULL.
|
||||
* If not, this would be the prefix to pass instead of NULL
|
||||
* prefix = yang_find_myprefix(ymod);
|
||||
*/
|
||||
if (xml_namespace_change(x, namespace, NULL) < 0)
|
||||
goto done;
|
||||
}
|
||||
xc = NULL;
|
||||
|
|
@ -1172,6 +1176,8 @@ _json_parse(char *str,
|
|||
* XXX should be xml_spec_populate0_parent() sometimes.
|
||||
*/
|
||||
switch (yb){
|
||||
case YB_RPC:
|
||||
case YB_UNKNOWN:
|
||||
case YB_NONE:
|
||||
break;
|
||||
case YB_PARENT:
|
||||
|
|
@ -1231,6 +1237,25 @@ _json_parse(char *str,
|
|||
* @retval -1 Error with clicon_err called
|
||||
* @see json_parse_file with a file descriptor (and more description)
|
||||
*/
|
||||
int
|
||||
json_parse_str2(char *str,
|
||||
enum yang_bind yb,
|
||||
yang_stmt *yspec,
|
||||
cxobj **xt,
|
||||
cxobj **xerr)
|
||||
{
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
if (xt==NULL){
|
||||
clicon_err(OE_XML, EINVAL, "xt is NULL");
|
||||
return -1;
|
||||
}
|
||||
if (*xt == NULL){
|
||||
if ((*xt = xml_new("top", NULL, NULL)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
return _json_parse(str, yb, yspec, *xt, xerr);
|
||||
}
|
||||
|
||||
int
|
||||
json_parse_str(char *str,
|
||||
yang_stmt *yspec,
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#include "clixon_xpath.h"
|
||||
#include "clixon_proto.h"
|
||||
#include "clixon_err.h"
|
||||
#include "clixon_stream.h"
|
||||
#include "clixon_err_string.h"
|
||||
#include "clixon_xml_nsctx.h"
|
||||
#include "clixon_xml_map.h"
|
||||
|
|
@ -750,7 +751,6 @@ clicon_rpc_get(clicon_handle h,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Close a (user) session
|
||||
* @param[in] h CLICON handle
|
||||
* @retval 0 OK
|
||||
|
|
@ -964,11 +964,12 @@ clicon_rpc_create_subscription(clicon_handle h,
|
|||
goto done;
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode(session_id,
|
||||
"<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
|
||||
"<rpc username=\"%s\"><create-subscription xmlns=\"%s\">"
|
||||
"<stream>%s</stream>"
|
||||
"<filter type=\"xpath\" select=\"%s\" />"
|
||||
"</create-subscription></rpc>",
|
||||
username?username:"",
|
||||
EVENT_RFC5277_NAMESPACE,
|
||||
stream?stream:"", filter?filter:"")) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, s0) < 0)
|
||||
|
|
|
|||
|
|
@ -581,7 +581,8 @@ stream_notify(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
/* From RFC5277 */
|
||||
cprintf(cb, "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>%s</eventTime>%s</notification>", timestr, str);
|
||||
cprintf(cb, "<notification xmlns=\"%s\"><eventTime>%s</eventTime>%s</notification>",
|
||||
NOTIFICATION_RFC5277_NAMESPACE, timestr, str);
|
||||
if (xml_parse_string(cbuf_get(cb), yspec, &xev) < 0)
|
||||
goto done;
|
||||
if (xml_rootchild(xev, 0, &xev) < 0)
|
||||
|
|
@ -644,7 +645,9 @@ stream_notify_xml(clicon_handle h,
|
|||
clicon_err(OE_UNIX, errno, "time2str");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb, "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>%s</eventTime>NULL</notification>", timestr); /* XXX str is always NULL */
|
||||
cprintf(cb, "<notification xmlns=\"%s\"><eventTime>%s</eventTime>NULL</notification>",
|
||||
NOTIFICATION_RFC5277_NAMESPACE,
|
||||
timestr); /* XXX str is always NULL */
|
||||
if (xml_parse_string(cbuf_get(cb), yspec, &xev) < 0)
|
||||
goto done;
|
||||
if (xml_rootchild(xev, 0, &xev) < 0)
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ uint64_t _stats_nr = 0;
|
|||
/*! Get global statistics about XML objects
|
||||
*/
|
||||
int
|
||||
xml_stats_get(uint64_t *nr)
|
||||
xml_stats_global(uint64_t *nr)
|
||||
{
|
||||
if (nr)
|
||||
*nr = _stats_nr;
|
||||
|
|
@ -187,8 +187,8 @@ xml_stats_get(uint64_t *nr)
|
|||
* (baseline: 96 bytes per object on x86-64)
|
||||
*/
|
||||
static int
|
||||
xml_size_one(cxobj *x,
|
||||
size_t *szp)
|
||||
xml_stats_one(cxobj *x,
|
||||
size_t *szp)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
|
|
@ -209,24 +209,26 @@ xml_size_one(cxobj *x,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Return the alloced memory of a XML obj tree recursively
|
||||
/*! Return statistics of an XML tree recursively
|
||||
* @param[in] x XML object
|
||||
* @param[out] szp Size of this XML obj recursively
|
||||
* @retval 0 OK
|
||||
*/
|
||||
size_t
|
||||
xml_size(cxobj *xt,
|
||||
size_t *szp)
|
||||
xml_stats(cxobj *xt,
|
||||
uint64_t *nrp,
|
||||
size_t *szp)
|
||||
{
|
||||
size_t sz = 0;
|
||||
cxobj *xc;
|
||||
|
||||
xml_size_one(xt, &sz);
|
||||
*nrp += 1;
|
||||
xml_stats_one(xt, &sz);
|
||||
if (szp)
|
||||
*szp += sz;
|
||||
xc = NULL;
|
||||
while ((xc = xml_child_each(xt, xc, -1)) != NULL) {
|
||||
xml_size(xc, &sz);
|
||||
xml_stats(xc, nrp, &sz);
|
||||
if (szp)
|
||||
*szp += sz;
|
||||
}
|
||||
|
|
@ -1737,8 +1739,6 @@ xml_free(cxobj *x)
|
|||
*------------------------------------------------------------------------*/
|
||||
|
||||
/*! Print an XML tree structure to an output stream and encode chars "<>&"
|
||||
*
|
||||
* Uses clicon_xml2cbuf internally
|
||||
*
|
||||
* @param[in] f UNIX output stream
|
||||
* @param[in] xn clicon xml tree
|
||||
|
|
@ -2070,6 +2070,8 @@ _xml_parse(const char *str,
|
|||
/* Populate, ie associate xml nodes with yang specs
|
||||
*/
|
||||
switch (yb){
|
||||
case YB_RPC:
|
||||
case YB_UNKNOWN:
|
||||
case YB_NONE:
|
||||
break;
|
||||
case YB_PARENT:
|
||||
|
|
@ -2325,7 +2327,8 @@ xml_parse_string2(const char *str,
|
|||
* @see xml_parse_file
|
||||
* @see xml_parse_va
|
||||
* @note You need to free the xml parse tree after use, using xml_free()
|
||||
* @note If empty on entry, a new TOP xml will be created named "top"
|
||||
* @note If xt is empty on entry, a new TOP xml will be created named "top" and yang binding
|
||||
* assumed to be TOP
|
||||
*/
|
||||
int
|
||||
xml_parse_string(const char *str,
|
||||
|
|
|
|||
|
|
@ -801,10 +801,16 @@ xml_tree_prune_flagged(cxobj *xt,
|
|||
}
|
||||
|
||||
/*! Add prefix:namespace pair to xml node, set cache, prefix, etc
|
||||
* @param[in] x XML node whose namespace should change
|
||||
* @param[in] xp XML node where namespace attribute should be declared (can be same)
|
||||
* @param[in] prefix1 Use this prefix
|
||||
* @param[in] namespace Use this namespace
|
||||
* @note x and xp must be different if x is an attribute and may be different otherwise
|
||||
*/
|
||||
static int
|
||||
add_namespace(cxobj *x1, /* target */
|
||||
char *prefix1,
|
||||
add_namespace(cxobj *x,
|
||||
cxobj *xp,
|
||||
char *prefix,
|
||||
char *namespace)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -813,26 +819,26 @@ add_namespace(cxobj *x1, /* target */
|
|||
/* Add binding to x1p. We add to parent due to heurestics, so we dont
|
||||
* end up in adding it to large number of siblings
|
||||
*/
|
||||
if (nscache_set(x1, prefix1, namespace) < 0)
|
||||
if (nscache_set(x, prefix, namespace) < 0)
|
||||
goto done;
|
||||
/* Create xmlns attribute to x1p/x1 XXX same code v */
|
||||
if (prefix1){
|
||||
if ((xa = xml_new(prefix1, x1, NULL)) == NULL)
|
||||
if (prefix){
|
||||
if ((xa = xml_new(prefix, xp, NULL)) == NULL)
|
||||
goto done;
|
||||
if (xml_prefix_set(xa, "xmlns") < 0)
|
||||
goto done;
|
||||
}
|
||||
else{
|
||||
if ((xa = xml_new("xmlns", x1, NULL)) == NULL)
|
||||
if ((xa = xml_new("xmlns", xp, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
xml_type_set(xa, CX_ATTR);
|
||||
if (xml_value_set(xa, namespace) < 0)
|
||||
goto done;
|
||||
xml_sort(x1, NULL); /* Ensure attr is first / XXX xml_insert? */
|
||||
xml_sort(xp, NULL); /* Ensure attr is first / XXX xml_insert? */
|
||||
|
||||
/* 5. Add prefix to x1, if any */
|
||||
if (prefix1 && xml_prefix_set(x1, prefix1) < 0)
|
||||
/* 5. Add prefix to x, if any */
|
||||
if (prefix && xml_prefix_set(x, prefix) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -855,15 +861,16 @@ xml_namespace_change(cxobj *x,
|
|||
int retval = -1;
|
||||
char *ns0 = NULL; /* existing namespace */
|
||||
char *prefix0 = NULL; /* existing prefix */
|
||||
|
||||
cxobj *xp;
|
||||
|
||||
ns0 = NULL;
|
||||
if (xml2ns(x, xml_prefix(x), &ns0) < 0)
|
||||
goto done;
|
||||
if (ns0 && strcmp(ns0, namespace) == 0)
|
||||
goto ok; /* Already has right namespace */
|
||||
goto ok; /* Already has right namespace */
|
||||
/* Is namespace already declared? */
|
||||
if (xml2prefix(x, namespace, &prefix0) == 1){
|
||||
/* Yes it is declared and the prefix is pexists */
|
||||
/* Yes it is declared and the prefix is prefix0 */
|
||||
if (xml_prefix_set(x, prefix0) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -871,7 +878,11 @@ xml_namespace_change(cxobj *x,
|
|||
/* Clear old prefix if any */
|
||||
if (xml_prefix_set(x, NULL) < 0)
|
||||
goto done;
|
||||
if (add_namespace(x, prefix0, namespace) < 0)
|
||||
if (xml_type(x) == CX_ELMNT) /* If not element, do the namespace addition to the element */
|
||||
xp = x;
|
||||
else
|
||||
xp = xml_parent(x);
|
||||
if (add_namespace(x, xp, prefix, namespace) < 0)
|
||||
goto done;
|
||||
}
|
||||
ok:
|
||||
|
|
@ -933,7 +944,7 @@ xml_default(cxobj *xt,
|
|||
clicon_err(OE_UNIX, errno, "strdup");
|
||||
goto done;
|
||||
}
|
||||
if (add_namespace(xc, prefix, namespace) < 0)
|
||||
if (add_namespace(xc, xc, prefix, namespace) < 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
@ -1634,7 +1645,7 @@ assign_namespaces(cxobj *x0, /* source */
|
|||
}
|
||||
}
|
||||
}
|
||||
if (add_namespace(x1, prefix1, namespace) < 0)
|
||||
if (add_namespace(x1, x1, prefix1, namespace) < 0)
|
||||
goto done;
|
||||
}
|
||||
ok:
|
||||
|
|
|
|||
|
|
@ -161,8 +161,8 @@ yang_augment_node(yang_stmt *ys,
|
|||
int retval = -1;
|
||||
char *schema_nodeid;
|
||||
yang_stmt *ytarget = NULL;
|
||||
yang_stmt *yc0;
|
||||
yang_stmt *yc;
|
||||
int i;
|
||||
yang_stmt *ymod;
|
||||
|
||||
if ((ymod = ys_module(ys)) == NULL){
|
||||
|
|
@ -179,8 +179,9 @@ yang_augment_node(yang_stmt *ys,
|
|||
/* Extend ytarget with ys' children
|
||||
* First enlarge ytarget vector
|
||||
*/
|
||||
for (i=0; i<ys->ys_len; i++){
|
||||
if ((yc = ys_dup(ys->ys_stmt[i])) == NULL)
|
||||
yc0 = NULL;
|
||||
while ((yc0 = yn_each(ys, yc0)) != NULL) {
|
||||
if ((yc = ys_dup(yc0)) == NULL)
|
||||
goto done;
|
||||
yc->ys_mymodule = ymod;
|
||||
if (yn_insert(ytarget, yc) < 0)
|
||||
|
|
@ -201,13 +202,13 @@ yang_augment_spec(yang_stmt *ysp,
|
|||
yang_stmt *ym;
|
||||
yang_stmt *ys;
|
||||
int i;
|
||||
int j;
|
||||
int j;
|
||||
|
||||
i = modnr;
|
||||
while (i<ysp->ys_len){ /* Loop through modules and sub-modules */
|
||||
i = modnr; /* cant use yang_each here since you dont start at 0 */
|
||||
while (i < yang_len_get(ysp)){ /* Loop through modules and sub-modules */
|
||||
ym = ysp->ys_stmt[i++];
|
||||
j = 0;
|
||||
while (j<ym->ys_len){ /* Top-level symbols in modules */
|
||||
while (j < yang_len_get(ym)){ /* Top-level symbols in modules */
|
||||
ys = ym->ys_stmt[j++];
|
||||
switch (yang_keyword_get(ys)){
|
||||
case Y_AUGMENT: /* top-level */
|
||||
|
|
@ -260,7 +261,7 @@ ys_do_refine(yang_stmt *yr,
|
|||
case Y_MAX_ELEMENTS:
|
||||
case Y_EXTENSION:
|
||||
/* Remove old matching, dont increment due to prune in loop */
|
||||
for (i=0; i<yt->ys_len; ){
|
||||
for (i=0; i<yang_len_get(yt); ){
|
||||
ytc = yt->ys_stmt[i];
|
||||
if (keyw != yang_keyword_get(ytc)){
|
||||
i++;
|
||||
|
|
@ -321,7 +322,7 @@ yang_expand_grouping(yang_stmt *yn)
|
|||
|
||||
/* Cannot use yang_apply here since child-list is modified (is destructive) */
|
||||
i = 0;
|
||||
while (i<yn->ys_len){
|
||||
while (i < yang_len_get(yn)){
|
||||
ys = yn->ys_stmt[i];
|
||||
switch(yang_keyword_get(ys)){
|
||||
case Y_USES:
|
||||
|
|
@ -359,15 +360,15 @@ yang_expand_grouping(yang_stmt *yn)
|
|||
/* Replace ys with ygrouping,...
|
||||
* First enlarge parent vector
|
||||
*/
|
||||
glen = ygrouping2->ys_len;
|
||||
glen = yang_len_get(ygrouping2);
|
||||
/*
|
||||
* yn is parent: the children of ygrouping replaces ys.
|
||||
* Is there a case when glen == 0? YES AND THIS BREAKS
|
||||
*/
|
||||
if (glen != 1){
|
||||
size = (yn->ys_len - i - 1)*sizeof(struct yang_stmt *);
|
||||
size = (yang_len_get(yn) - i - 1)*sizeof(struct yang_stmt *);
|
||||
yn->ys_len += glen - 1;
|
||||
if (glen && (yn->ys_stmt = realloc(yn->ys_stmt, (yn->ys_len)*sizeof(yang_stmt *))) == 0){
|
||||
if (glen && (yn->ys_stmt = realloc(yn->ys_stmt, (yang_len_get(yn))*sizeof(yang_stmt *))) == 0){
|
||||
clicon_err(OE_YANG, errno, "realloc");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -411,7 +412,7 @@ yang_expand_grouping(yang_stmt *yn)
|
|||
/* Remove 'uses' node */
|
||||
ys_free(ys);
|
||||
/* Remove the grouping copy */
|
||||
ygrouping2->ys_len = 0;
|
||||
ygrouping2->ys_len = 0; /* Cant do with get access function */
|
||||
ys_free(ygrouping2);
|
||||
break; /* Note same child is re-iterated since it may be changed */
|
||||
default:
|
||||
|
|
@ -420,7 +421,7 @@ yang_expand_grouping(yang_stmt *yn)
|
|||
}
|
||||
}
|
||||
/* Second pass since length may have changed */
|
||||
for (i=0; i<yn->ys_len; i++){
|
||||
for (i=0; i<yang_len_get(yn); i++){
|
||||
ys = yn->ys_stmt[i];
|
||||
if (yang_expand_grouping(ys) < 0)
|
||||
goto done;
|
||||
|
|
@ -903,22 +904,22 @@ yang_parse_post(clicon_handle h,
|
|||
/* 1: Parse from text to yang parse-tree.
|
||||
* Iterate through modules and detect module/submodules to parse
|
||||
* - note the list may grow on each iteration */
|
||||
for (i=modnr; i<yspec->ys_len; i++)
|
||||
for (i=modnr; i<yang_len_get(yspec); i++)
|
||||
if (yang_parse_recurse(h, yspec->ys_stmt[i], yspec) < 0)
|
||||
goto done;
|
||||
|
||||
/* 2. Check cardinality maybe this should be done after grouping/augment */
|
||||
for (i=modnr; i<yspec->ys_len; i++)
|
||||
for (i=modnr; i<yang_len_get(yspec); i++)
|
||||
if (yang_cardinality(h, yspec->ys_stmt[i], yang_argument_get(yspec->ys_stmt[i])) < 0)
|
||||
goto done;
|
||||
|
||||
/* 3: Check features: check if enabled and remove disabled features */
|
||||
for (i=modnr; i<yspec->ys_len; i++) /* XXX */
|
||||
for (i=modnr; i<yang_len_get(yspec); i++) /* XXX */
|
||||
if (yang_features(h, yspec->ys_stmt[i]) < 0)
|
||||
goto done;
|
||||
|
||||
/* 4: Go through parse tree and populate it with cv types */
|
||||
for (i=modnr; i<yspec->ys_len; i++)
|
||||
for (i=modnr; i<yang_len_get(yspec); i++)
|
||||
if (yang_apply(yspec->ys_stmt[i], -1, ys_populate, (void*)h) < 0)
|
||||
goto done;
|
||||
|
||||
|
|
@ -926,7 +927,7 @@ yang_parse_post(clicon_handle h,
|
|||
* from ys_populate step.
|
||||
* Must be done using static binding.
|
||||
*/
|
||||
for (i=modnr; i<yspec->ys_len; i++)
|
||||
for (i=modnr; i<yang_len_get(yspec); i++)
|
||||
if (yang_apply(yspec->ys_stmt[i], Y_TYPE, ys_resolve_type, h) < 0)
|
||||
goto done;
|
||||
|
||||
|
|
@ -938,7 +939,7 @@ yang_parse_post(clicon_handle h,
|
|||
*/
|
||||
|
||||
/* 6: Macro expansion of all grouping/uses pairs. Expansion needs marking */
|
||||
for (i=modnr; i<yspec->ys_len; i++){
|
||||
for (i=modnr; i<yang_len_get(yspec); i++){
|
||||
if (yang_expand_grouping(yspec->ys_stmt[i]) < 0)
|
||||
goto done;
|
||||
yang_apply(yspec->ys_stmt[i], -1, (yang_applyfn_t*)yang_flag_reset, (void*)YANG_FLAG_MARK);
|
||||
|
|
@ -949,12 +950,12 @@ yang_parse_post(clicon_handle h,
|
|||
goto done;
|
||||
|
||||
/* 4: Go through parse tree and do 2nd step populate (eg default) */
|
||||
for (i=modnr; i<yspec->ys_len; i++)
|
||||
for (i=modnr; i<yang_len_get(yspec); i++)
|
||||
if (yang_apply(yspec->ys_stmt[i], -1, ys_populate2, (void*)h) < 0)
|
||||
goto done;
|
||||
|
||||
/* 8: sanity check of schemanode references, need more here */
|
||||
for (i=modnr; i<yspec->ys_len; i++)
|
||||
for (i=modnr; i<yang_len_get(yspec); i++)
|
||||
if (yang_apply(yspec->ys_stmt[i], -1, ys_schemanode_check, NULL) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
|
|
@ -990,7 +991,7 @@ yang_spec_parse_module(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
/* Apply steps 2.. on new modules, ie ones after modnr. */
|
||||
modnr = yspec->ys_len;
|
||||
modnr = yang_len_get(yspec);
|
||||
/* Do not load module if it already exists */
|
||||
if (yang_find(yspec, Y_MODULE, module) != NULL)
|
||||
goto ok;
|
||||
|
|
@ -1026,7 +1027,7 @@ yang_spec_parse_file(clicon_handle h,
|
|||
char *base = NULL;;
|
||||
|
||||
/* Apply steps 2.. on new modules, ie ones after modnr. */
|
||||
modnr = yspec->ys_len;
|
||||
modnr = yang_len_get(yspec);
|
||||
/* Find module, and do not load file if module already exists */
|
||||
if (basename(filename) == NULL){
|
||||
clicon_err(OE_YANG, errno, "No basename");
|
||||
|
|
@ -1101,7 +1102,7 @@ yang_spec_load_dir(clicon_handle h,
|
|||
clicon_log(LOG_WARNING, "%s: No yang files found in %s",
|
||||
__FUNCTION__, dir);
|
||||
/* Apply post steps on new modules, ie ones after modnr. */
|
||||
modnr = yspec->ys_len;
|
||||
modnr = yang_len_get(yspec);
|
||||
/* Load all yang files in dir */
|
||||
for (i = 0; i < ndp; i++) {
|
||||
/* base = module name [+ @rev ] + .yang */
|
||||
|
|
@ -1151,7 +1152,7 @@ yang_spec_load_dir(clicon_handle h,
|
|||
if (revm && rev0){
|
||||
if (revm > rev0) /* Loaded module is older or eq -> remove ym */
|
||||
ym = ym0;
|
||||
for (j=0; j<yspec->ys_len; j++)
|
||||
for (j=0; j<yang_len_get(yspec); j++)
|
||||
if (yspec->ys_stmt[j] == ym)
|
||||
break;
|
||||
ys_prune(yspec, j);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue