* Replaced separate autocli trees with a single @basemodel tree by using filter labels
* Added lastkey argument to yang_key_match() * Fixed segv in process-sigchld * Added ietf-yang-library to CLICON_CLI_AUTOCLI_EXCLUDE default value * Added yang_spec_print() function
This commit is contained in:
parent
87d243d7e5
commit
f8f34e3571
17 changed files with 666 additions and 192 deletions
|
|
@ -323,7 +323,7 @@ yang2api_path_fmt_1(yang_stmt *ys,
|
|||
*/
|
||||
if (yang_keyword_get(ys) == Y_LEAF && yp &&
|
||||
yang_keyword_get(yp) == Y_LIST &&
|
||||
yang_key_match(yp, ys->ys_argument) == 1)
|
||||
yang_key_match(yp, ys->ys_argument, NULL) == 1)
|
||||
;
|
||||
else
|
||||
#endif
|
||||
|
|
@ -347,7 +347,7 @@ yang2api_path_fmt_1(yang_stmt *ys,
|
|||
else{
|
||||
if (yang_keyword_get(ys) == Y_LEAF && yp &&
|
||||
yang_keyword_get(yp) == Y_LIST){
|
||||
if (yang_key_match(yp, yang_argument_get(ys)) == 0)
|
||||
if (yang_key_match(yp, yang_argument_get(ys), NULL) == 0)
|
||||
cprintf(cb, "%s", yang_argument_get(ys)); /* Not if leaf and key */
|
||||
}
|
||||
else
|
||||
|
|
@ -477,7 +477,10 @@ api_path_fmt2api_path(const char *api_path_fmt,
|
|||
if (j == cvec_len(cvv)) /* last element */
|
||||
;
|
||||
else{
|
||||
cv = cvec_i(cvv, j++);
|
||||
if ((cv = cvec_i(cvv, j++)) == NULL){
|
||||
clicon_err(OE_XML, 0, "Number of elements in cvv does not match api_path_fmt string");
|
||||
goto done;
|
||||
}
|
||||
if ((str = cv2str_dup(cv)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cv2str_dup");
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ clixon_process_argv_get(clicon_handle h,
|
|||
* @param[in] name Process name
|
||||
* @param[in] description Description of process
|
||||
* @param[in] netns Namespace netspace (or NULL)
|
||||
* @param[in] callback
|
||||
* @param[in] callback Wrapper function
|
||||
* @param[in] argv NULL-terminated vector of vectors
|
||||
* @param[in] argc Length of argv
|
||||
* @retval 0 OK
|
||||
|
|
@ -620,8 +620,8 @@ clixon_process_operation(clicon_handle h,
|
|||
clicon_debug(1, "%s name:%s op:%s", __FUNCTION__, name, clicon_int2str(proc_operation_map, op0));
|
||||
if (_proc_entry_list == NULL)
|
||||
goto ok;
|
||||
pe = _proc_entry_list;
|
||||
do {
|
||||
if ((pe = _proc_entry_list) != NULL)
|
||||
do {
|
||||
if (strcmp(pe->pe_name, name) == 0){
|
||||
/* Call wrapper function that eg changes op1 based on config */
|
||||
op = op0;
|
||||
|
|
@ -983,7 +983,7 @@ clixon_process_waitpid(clicon_handle h)
|
|||
clicon_debug(1, "%s waitpid(%d) nomatch:%d", __FUNCTION__, pe->pe_pid, wpid);
|
||||
}
|
||||
pe = NEXTQ(process_entry_t *, pe);
|
||||
} while (pe != _proc_entry_list);
|
||||
} while (pe && pe != _proc_entry_list);
|
||||
retval = 0;
|
||||
done:
|
||||
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ xml2cli_recurse(FILE *f,
|
|||
if (yang_keyword_get(ys) == Y_LIST){
|
||||
xe = NULL;
|
||||
while ((xe = xml_child_each(x, xe, -1)) != NULL){
|
||||
if ((match = yang_key_match(ys, xml_name(xe))) < 0)
|
||||
if ((match = yang_key_match(ys, xml_name(xe), NULL)) < 0)
|
||||
goto done;
|
||||
if (!match)
|
||||
continue;
|
||||
|
|
@ -301,7 +301,7 @@ xml2cli_recurse(FILE *f,
|
|||
xe = NULL;
|
||||
while ((xe = xml_child_each(x, xe, -1)) != NULL){
|
||||
if (yang_keyword_get(ys) == Y_LIST){
|
||||
if ((match = yang_key_match(ys, xml_name(xe))) < 0)
|
||||
if ((match = yang_key_match(ys, xml_name(xe), NULL)) < 0)
|
||||
goto done;
|
||||
if (match){
|
||||
(*fn)(f, "%s\n", cbuf_get(cbpre));
|
||||
|
|
@ -730,7 +730,7 @@ xml_tree_prune_flagged_sub(cxobj *xt,
|
|||
}
|
||||
/* If it is key dont remove it yet (see second round) */
|
||||
if (yt){
|
||||
if ((iskey = yang_key_match(yt, xml_name(x))) < 0)
|
||||
if ((iskey = yang_key_match(yt, xml_name(x), NULL)) < 0)
|
||||
goto done;
|
||||
if (iskey){
|
||||
anykey++;
|
||||
|
|
@ -758,7 +758,7 @@ xml_tree_prune_flagged_sub(cxobj *xt,
|
|||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||
/* If it is key remove it here */
|
||||
if (yt){
|
||||
if ((iskey = yang_key_match(yt, xml_name(x))) < 0)
|
||||
if ((iskey = yang_key_match(yt, xml_name(x), NULL)) < 0)
|
||||
goto done;
|
||||
if (iskey && xml_purge(x) < 0)
|
||||
goto done;
|
||||
|
|
@ -2166,7 +2166,7 @@ xml_copy_marked(cxobj *x0,
|
|||
* node in list is marked */
|
||||
if (mark && yt && yang_keyword_get(yt) == Y_LIST){
|
||||
/* XXX: I think yang_key_match is suboptimal here */
|
||||
if ((iskey = yang_key_match(yt, name)) < 0)
|
||||
if ((iskey = yang_key_match(yt, name, NULL)) < 0)
|
||||
goto done;
|
||||
if (iskey){
|
||||
if ((xcopy = xml_new(name, x1, CX_ELMNT)) == NULL)
|
||||
|
|
|
|||
|
|
@ -1701,6 +1701,34 @@ yang_print(FILE *f,
|
|||
return yang_print_cb(f, yn, fprintf);
|
||||
}
|
||||
|
||||
/*! Print yang top-level modules only
|
||||
* @param[in] f File to print to.
|
||||
* @param[in] yn Yang node to print
|
||||
* @see yang_print_cbuf
|
||||
*/
|
||||
int
|
||||
yang_spec_print(FILE *f,
|
||||
yang_stmt *yspec)
|
||||
{
|
||||
yang_stmt *ym = NULL;
|
||||
yang_stmt *yrev;
|
||||
|
||||
if (yspec == NULL || yang_keyword_get(yspec) != Y_SPEC){
|
||||
clicon_err(OE_YANG, EINVAL, "yspec is not of type YSPEC");
|
||||
return -1;
|
||||
}
|
||||
while ((ym = yn_each(yspec, ym)) != NULL) {
|
||||
fprintf(f, "%s", yang_key2str(ym->ys_keyword));
|
||||
fprintf(f, " %s", ym->ys_argument);
|
||||
if ((yrev = yang_find(ym, Y_REVISION, NULL)) != NULL){
|
||||
fprintf(f, "@%u", cv_uint32_get(yang_cv_get(yrev)));
|
||||
}
|
||||
fprintf(f, ".yang");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Log/debug info about top-level (sub)modules no recursion
|
||||
* @param[in] yspec Yang spec
|
||||
* @param[in] dbglevel Debug level
|
||||
|
|
@ -2005,7 +2033,7 @@ ys_populate_leaf(clicon_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)) < 0)
|
||||
if ((ret = yang_key_match(yparent, ys->ys_argument, NULL)) < 0)
|
||||
goto done;
|
||||
}
|
||||
yang_cv_set(ys, cv);
|
||||
|
|
@ -3417,6 +3445,7 @@ yang_container_cli_hide(yang_stmt *ys,
|
|||
* The function looks at the LIST argument string (not actual children)
|
||||
* @param[in] yn Yang list node with sub-statements (look for a key child)
|
||||
* @param[in] name Check if this name (eg "b") is a key in the yang key statement
|
||||
* @param[out] lastkey If 1 this is the last key in a multi-key list
|
||||
*
|
||||
* @retval -1 Error
|
||||
* @retval 0 No match
|
||||
|
|
@ -3424,11 +3453,13 @@ yang_container_cli_hide(yang_stmt *ys,
|
|||
*/
|
||||
int
|
||||
yang_key_match(yang_stmt *yn,
|
||||
char *name)
|
||||
char *name,
|
||||
int *lastkey)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *ys = NULL;
|
||||
int i;
|
||||
int j;
|
||||
cvec *cvv = NULL;
|
||||
cg_var *cv;
|
||||
|
||||
|
|
@ -3437,12 +3468,17 @@ yang_key_match(yang_stmt *yn,
|
|||
if (ys->ys_keyword == Y_KEY){
|
||||
if ((cvv = yang_arg2cvec(ys, " ")) == NULL)
|
||||
goto done;
|
||||
j = 0;
|
||||
cv = NULL;
|
||||
while ((cv = cvec_each(cvv, cv)) != NULL) {
|
||||
j++;
|
||||
if (strcmp(name, cv_string_get(cv)) == 0){
|
||||
if (j == cvec_len(cvv) && lastkey)
|
||||
*lastkey = 1;
|
||||
retval = 1; /* match */
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
cvec_free(cvv);
|
||||
cvv = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue