Fixed: ["autocli:hide-show" extension cause bug in xmldb_put method #343](https://github.com/clicon/clixon/issues/343)
As a side-effect, added extra "autocliext" parameter to: - clixon_xml2file() - clixon_json2file() - clixon_json2cbuf() - clixon_txt2file()
This commit is contained in:
parent
e724dd7f40
commit
4514f2a538
26 changed files with 213 additions and 144 deletions
|
|
@ -745,7 +745,7 @@ xmldb_get_nocache(clicon_handle h,
|
|||
clicon_log(LOG_NOTICE, "%s: sort verify failed #2", __FUNCTION__);
|
||||
#endif
|
||||
if (clicon_debug_get()>1)
|
||||
if (clixon_xml2file(stderr, xt, 0, 1, fprintf, 0) < 0)
|
||||
if (clixon_xml2file(stderr, xt, 0, 1, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
*xtop = xt;
|
||||
xt = NULL;
|
||||
|
|
@ -917,7 +917,7 @@ xmldb_get_cache(clicon_handle h,
|
|||
* If cache was empty, also update to datastore cache
|
||||
*/
|
||||
if (clicon_debug_get()>1)
|
||||
if (clixon_xml2file(stderr, x1t, 0, 1, fprintf, 0) < 0)
|
||||
if (clixon_xml2file(stderr, x1t, 0, 1, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
*xtop = x1t;
|
||||
retval = 1;
|
||||
|
|
@ -1019,7 +1019,7 @@ xmldb_get_zerocopy(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
if (clicon_debug_get() > 1)
|
||||
if (clixon_xml2file(stderr, x0t, 0, 1, fprintf, 0) < 0)
|
||||
if (clixon_xml2file(stderr, x0t, 0, 1, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
*xtop = x0t;
|
||||
retval = 1;
|
||||
|
|
|
|||
|
|
@ -1244,10 +1244,10 @@ xmldb_put(clicon_handle h,
|
|||
}
|
||||
pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY");
|
||||
if (strcmp(format,"json")==0){
|
||||
if (clixon_json2file(f, x0, pretty, fprintf, 0) < 0)
|
||||
if (clixon_json2file(f, x0, pretty, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (clixon_xml2file(f, x0, 0, pretty, fprintf, 0) < 0)
|
||||
else if (clixon_xml2file(f, x0, 0, pretty, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
/* Remove modules state after writing to file
|
||||
*/
|
||||
|
|
@ -1302,10 +1302,10 @@ xmldb_dump(clicon_handle h,
|
|||
}
|
||||
pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY");
|
||||
if (strcmp(format,"json")==0){
|
||||
if (clixon_json2file(f, xt, pretty, fprintf, 0) < 0)
|
||||
if (clixon_json2file(f, xt, pretty, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0) < 0)
|
||||
else if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -1043,6 +1043,7 @@ xml2json1_cbuf(cbuf *cb,
|
|||
* @param[in,out] cb Cligen buffer to write to
|
||||
* @param[in] x XML tree to translate from
|
||||
* @param[in] pretty Set if output is pretty-printed
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*
|
||||
|
|
@ -1052,18 +1053,27 @@ xml2json1_cbuf(cbuf *cb,
|
|||
static int
|
||||
xml2json_cbuf1(cbuf *cb,
|
||||
cxobj *x,
|
||||
int pretty)
|
||||
int pretty,
|
||||
int autocliext)
|
||||
{
|
||||
int retval = 1;
|
||||
int level = 0;
|
||||
yang_stmt *y;
|
||||
enum array_element_type arraytype = NO_ARRAY;
|
||||
int exist = 0;
|
||||
|
||||
y = xml_spec(x);
|
||||
if (autocliext && y != NULL) {
|
||||
if (yang_extension_value(y, "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0)
|
||||
goto done;
|
||||
if (exist)
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cb, "%*s{%s",
|
||||
pretty?level*JSON_INDENT:0,"",
|
||||
pretty?"\n":"");
|
||||
|
||||
if ((y = xml_spec(x)) != NULL){
|
||||
if (y != NULL){
|
||||
switch (yang_keyword_get(y)){
|
||||
case Y_LEAF_LIST:
|
||||
case Y_LIST:
|
||||
|
|
@ -1087,6 +1097,7 @@ xml2json_cbuf1(cbuf *cb,
|
|||
pretty?"\n":"",
|
||||
pretty?level*JSON_INDENT:0,"",
|
||||
pretty?"\n":"");
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
|
|
@ -1101,6 +1112,7 @@ xml2json_cbuf1(cbuf *cb,
|
|||
* @param[in] xt Top-level xml object
|
||||
* @param[in] pretty Set if output is pretty-printed
|
||||
* @param[in] skiptop 0: Include top object 1: Skip top-object, only children,
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @code
|
||||
|
|
@ -1115,7 +1127,8 @@ int
|
|||
clixon_json2cbuf(cbuf *cb,
|
||||
cxobj *xt,
|
||||
int pretty,
|
||||
int skiptop)
|
||||
int skiptop,
|
||||
int autocliext)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xc;
|
||||
|
|
@ -1123,11 +1136,11 @@ clixon_json2cbuf(cbuf *cb,
|
|||
if (skiptop){
|
||||
xc = NULL;
|
||||
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL)
|
||||
if (xml2json_cbuf1(cb, xc, pretty) < 0)
|
||||
if (xml2json_cbuf1(cb, xc, pretty, autocliext) < 0)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
if (xml2json_cbuf1(cb, xt, pretty) < 0)
|
||||
if (xml2json_cbuf1(cb, xt, pretty, autocliext) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
|
|
@ -1206,13 +1219,14 @@ xml2json_cbuf_vec(cbuf *cb,
|
|||
* @param[in] pretty Set if output is pretty-printed
|
||||
* @param[in] fn File print function (if NULL, use fprintf)
|
||||
* @param[in] skiptop 0: Include top object 1: Skip top-object, only children,
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*
|
||||
* @note yang is necessary to translate to one-member lists,
|
||||
* eg if a is a yang LIST <a>0</a> -> {"a":["0"]} and not {"a":"0"}
|
||||
* @code
|
||||
* if (clixon_json2file(stderr, xn, 0, fprintf, 0) < 0)
|
||||
* if (clixon_json2file(stderr, xn, 0, fprintf, 0, 0) < 0)
|
||||
* goto err;
|
||||
* @endcode
|
||||
*/
|
||||
|
|
@ -1221,7 +1235,8 @@ clixon_json2file(FILE *f,
|
|||
cxobj *xn,
|
||||
int pretty,
|
||||
clicon_output_cb *fn,
|
||||
int skiptop)
|
||||
int skiptop,
|
||||
int autocliext)
|
||||
{
|
||||
int retval = 1;
|
||||
cbuf *cb = NULL;
|
||||
|
|
@ -1232,7 +1247,7 @@ clixon_json2file(FILE *f,
|
|||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (clixon_json2cbuf(cb, xn, pretty, skiptop) < 0)
|
||||
if (clixon_json2cbuf(cb, xn, pretty, skiptop, autocliext) < 0)
|
||||
goto done;
|
||||
(*fn)(f, "%s", cbuf_get(cb));
|
||||
retval = 0;
|
||||
|
|
@ -1251,7 +1266,7 @@ int
|
|||
json_print(FILE *f,
|
||||
cxobj *x)
|
||||
{
|
||||
return clixon_json2file(f, x, 1, fprintf, 0);
|
||||
return clixon_json2file(f, x, 1, fprintf, 0, 0);
|
||||
}
|
||||
|
||||
/*! Translate a vector of xml objects to JSON File.
|
||||
|
|
|
|||
|
|
@ -1998,7 +1998,7 @@ netconf_output(int s,
|
|||
if (clicon_debug_get() > 1){ /* XXX: below only works to stderr, clicon_debug may log to syslog */
|
||||
cxobj *xt = NULL;
|
||||
if (clixon_xml_parse_string(buf, YB_NONE, NULL, &xt, NULL) == 0){
|
||||
if (clixon_xml2file(stderr, xml_child_i(xt, 0), 0, 0, fprintf, 0) < 0)
|
||||
if (clixon_xml2file(stderr, xml_child_i(xt, 0), 0, 0, fprintf, 0, 0) < 0)
|
||||
goto done;
|
||||
fprintf(stderr, "\n");
|
||||
xml_free(xt);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ tleaf(cxobj *x)
|
|||
* @param[in] fn Callback to make print function
|
||||
* @param[in] f File to print to
|
||||
* @param[in] level Print 4 spaces per level in front of each line
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @param[in,out] leafl Leaflist state for keeping track of when [] ends
|
||||
* @param[in,out] leaflname Leaflist state for []
|
||||
* leaflist state:
|
||||
|
|
@ -112,8 +113,10 @@ xml2txt1(cxobj *xn,
|
|||
clicon_output_cb *fn,
|
||||
FILE *f,
|
||||
int level,
|
||||
int autocliext,
|
||||
int *leafl,
|
||||
char **leaflname)
|
||||
|
||||
{
|
||||
cxobj *xc = NULL;
|
||||
int children=0;
|
||||
|
|
@ -134,10 +137,12 @@ xml2txt1(cxobj *xn,
|
|||
goto done;
|
||||
}
|
||||
if ((yn = xml_spec(xn)) != NULL){
|
||||
if (yang_extension_value(yn, "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0)
|
||||
goto done;
|
||||
if (exist)
|
||||
goto ok;
|
||||
if (autocliext){
|
||||
if (yang_extension_value(yn, "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0)
|
||||
goto done;
|
||||
if (exist)
|
||||
goto ok;
|
||||
}
|
||||
/* Find out prefix if needed: topmost or new module a la API-PATH */
|
||||
if (ys_real_module(yn, &ymod) < 0)
|
||||
goto done;
|
||||
|
|
@ -230,7 +235,7 @@ xml2txt1(cxobj *xn,
|
|||
if (xml_type(xc) == CX_ELMNT || xml_type(xc) == CX_BODY){
|
||||
if (yn && yang_key_match(yn, xml_name(xc), NULL))
|
||||
continue; /* Skip keys, already printed */
|
||||
if (xml2txt1(xc, fn, f, level+1, leafl, leaflname) < 0)
|
||||
if (xml2txt1(xc, fn, f, level+1, autocliext, leafl, leaflname) < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -256,6 +261,7 @@ xml2txt1(cxobj *xn,
|
|||
* @param[in] level Print 4 spaces per level in front of each line
|
||||
* @param[in] fn File print function (if NULL, use fprintf)
|
||||
* @param[in] skiptop 0: Include top object 1: Skip top-object, only children,
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
|
|
@ -264,7 +270,8 @@ clixon_txt2file(FILE *f,
|
|||
cxobj *xn,
|
||||
int level,
|
||||
clicon_output_cb *fn,
|
||||
int skiptop)
|
||||
int skiptop,
|
||||
int autocliext)
|
||||
{
|
||||
int retval = 1;
|
||||
cxobj *xc;
|
||||
|
|
@ -276,11 +283,11 @@ clixon_txt2file(FILE *f,
|
|||
if (skiptop){
|
||||
xc = NULL;
|
||||
while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL)
|
||||
if (xml2txt1(xc, fn, f, level, &leafl, &leaflname) < 0)
|
||||
if (xml2txt1(xc, fn, f, level, autocliext, &leafl, &leaflname) < 0)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
if (xml2txt1(xn, fn, f, level, &leafl, &leaflname) < 0)
|
||||
if (xml2txt1(xn, fn, f, level, autocliext, &leafl, &leaflname) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -89,21 +89,26 @@
|
|||
|
||||
/*! Print an XML tree structure to an output stream and encode chars "<>&"
|
||||
*
|
||||
* @param[in] f UNIX output stream
|
||||
* @param[in] xn Clicon xml tree
|
||||
* @param[in] level How many spaces to insert before each line
|
||||
* @param[in] pretty Insert \n and spaces to make the xml more readable.
|
||||
* @param[in] fn Callback to make print function
|
||||
* @param[in] f UNIX output stream
|
||||
* @param[in] xn Clicon xml tree
|
||||
* @param[in] level How many spaces to insert before each line
|
||||
* @param[in] pretty Insert \n and spaces to make the xml more readable.
|
||||
* @param[in] fn Callback to make print function
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see clixon_xml2cbuf
|
||||
* One can use clixon_xml2cbuf to get common code, but using fprintf is
|
||||
* much faster than using cbuf and then printing that,...
|
||||
*
|
||||
*/
|
||||
int
|
||||
static int
|
||||
xml2file_recurse(FILE *f,
|
||||
cxobj *x,
|
||||
int level,
|
||||
int pretty,
|
||||
clicon_output_cb *fn)
|
||||
clicon_output_cb *fn,
|
||||
int autocliext)
|
||||
{
|
||||
int retval = -1;
|
||||
char *name;
|
||||
|
|
@ -114,13 +119,17 @@ xml2file_recurse(FILE *f,
|
|||
char *val;
|
||||
char *encstr = NULL; /* xml encoded string */
|
||||
int exist = 0;
|
||||
yang_stmt *y;
|
||||
|
||||
if (x == NULL)
|
||||
goto ok;
|
||||
if (yang_extension_value(xml_spec(x), "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0)
|
||||
goto done;
|
||||
if (exist)
|
||||
goto ok;
|
||||
if (autocliext &&
|
||||
(y = xml_spec(x)) != NULL){
|
||||
if (yang_extension_value(y, "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0)
|
||||
goto done;
|
||||
if (exist)
|
||||
goto ok;
|
||||
}
|
||||
name = xml_name(x);
|
||||
namespace = xml_prefix(x);
|
||||
switch(xml_type(x)){
|
||||
|
|
@ -149,7 +158,7 @@ xml2file_recurse(FILE *f,
|
|||
while ((xc = xml_child_each(x, xc, -1)) != NULL) {
|
||||
switch (xml_type(xc)){
|
||||
case CX_ATTR:
|
||||
if (xml2file_recurse(f, xc, level+1, pretty, fn) <0)
|
||||
if (xml2file_recurse(f, xc, level+1, pretty, fn, autocliext) <0)
|
||||
goto done;
|
||||
break;
|
||||
case CX_BODY:
|
||||
|
|
@ -174,7 +183,7 @@ xml2file_recurse(FILE *f,
|
|||
xc = NULL;
|
||||
while ((xc = xml_child_each(x, xc, -1)) != NULL) {
|
||||
if (xml_type(xc) != CX_ATTR)
|
||||
if (xml2file_recurse(f, xc, level+1, pretty, fn) <0)
|
||||
if (xml2file_recurse(f, xc, level+1, pretty, fn, autocliext) <0)
|
||||
goto done;
|
||||
}
|
||||
if (pretty && hasbody==0)
|
||||
|
|
@ -206,9 +215,12 @@ xml2file_recurse(FILE *f,
|
|||
* @param[in] pretty Insert \n and spaces to make the xml more readable.
|
||||
* @param[in] fn File print function (if NULL, use fprintf)
|
||||
* @param[in] skiptop 0: Include top object 1: Skip top-object, only children,
|
||||
* @param[in] autocliext How to handle autocli extensions: 0: ignore 1: follow
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see clixon_xml2cbuf print to a cbuf string
|
||||
* @note There is a slight "layer violation" with the autocli parameter: it should normally be set
|
||||
* for CLI calls, but not for others.
|
||||
*/
|
||||
int
|
||||
clixon_xml2file(FILE *f,
|
||||
|
|
@ -216,7 +228,8 @@ clixon_xml2file(FILE *f,
|
|||
int level,
|
||||
int pretty,
|
||||
clicon_output_cb *fn,
|
||||
int skiptop)
|
||||
int skiptop,
|
||||
int autocliext)
|
||||
{
|
||||
int retval = 1;
|
||||
cxobj *xc;
|
||||
|
|
@ -226,11 +239,11 @@ clixon_xml2file(FILE *f,
|
|||
if (skiptop){
|
||||
xc = NULL;
|
||||
while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL)
|
||||
if (xml2file_recurse(f, xc, level, pretty, fn) < 0)
|
||||
if (xml2file_recurse(f, xc, level, pretty, fn, autocliext) < 0)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
if (xml2file_recurse(f, xn, level, pretty, fn) < 0)
|
||||
if (xml2file_recurse(f, xn, level, pretty, fn, autocliext) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
|
|
@ -241,8 +254,7 @@ clixon_xml2file(FILE *f,
|
|||
|
||||
/*! Print an XML tree structure to an output stream
|
||||
*
|
||||
* Uses clixon_xml2file internally
|
||||
*
|
||||
* Utility function eg in gdb. For code, use clixon_xml2file
|
||||
* @param[in] f UNIX output stream
|
||||
* @param[in] xn clicon xml tree
|
||||
* @see clixon_xml2cbuf
|
||||
|
|
@ -252,7 +264,7 @@ int
|
|||
xml_print(FILE *f,
|
||||
cxobj *x)
|
||||
{
|
||||
return xml2file_recurse(f, x, 0, 1, fprintf);
|
||||
return xml2file_recurse(f, x, 0, 1, fprintf, 0);
|
||||
}
|
||||
|
||||
/*! Dump cxobj structure with pointers and flags for debugging, internal function
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ clixon_xvec_print(FILE *f,
|
|||
int i;
|
||||
|
||||
for (i=0; i<xv->xv_len; i++)
|
||||
if (clixon_xml2file(f, xv->xv_vec[i], 0, 1, fprintf, 0) < 0)
|
||||
if (clixon_xml2file(f, xv->xv_vec[i], 0, 1, fprintf, 0, 0) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue