diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ebbe998..11ffa9b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -96,18 +96,18 @@ Developers may need to change their code
* `clixon_cli2file()` - Print internal tree as CLI format to file
* `clixon_txt2file()` - Print internal tree as text format to file
* As developer, you need to replace the old functions to the new API as follows:
- * `clicon_xml2file(f, x, l, p)` -> `clixon_xml2file(f, x, l, p, NULL, 0)`
- * `clicon_xml2file_cb(f, x, l, p, fn)` -> `clixon_xml2file(f, x, l, p, fn, 0)`
- * `cli_xml2file(x, l, p, fn)` -> `clixon_xml2file(stdout, x, l, p, fn, 0)`
+ * `clicon_xml2file(f, x, l, p)` -> `clixon_xml2file(f, x, l, p, NULL, 0, 0)`
+ * `clicon_xml2file_cb(f, x, l, p, fn)` -> `clixon_xml2file(f, x, l, p, fn, 0, 0)`
+ * `cli_xml2file(x, l, p, fn)` -> `clixon_xml2file(stdout, x, l, p, fn, 0, 0)`
* `clicon_xml2cbuf(c, x, l, p, d)` -> `clixon_xml2cbuf(c, x, l, p, d, 0)`
* `clicon_xml2str(x)` -> Rewrite using cbufs and `clixon_xml2cbuf()`
- * `xml2json(f, x, p)` -> `clixon_json2file(f, x, p, NULL, 0)`
- * `xml2json_cb(f, x, p, fn)` -> `clixon_json2file(f, x, p, fn, 0)`
- * `xml2json_cbuf(c, x, p)` -> `clixon_json2cbuf(c, x, p, 0)`
+ * `xml2json(f, x, p)` -> `clixon_json2file(f, x, p, NULL, 0, 0)`
+ * `xml2json_cb(f, x, p, fn)` -> `clixon_json2file(f, x, p, fn, 0, 0)`
+ * `xml2json_cbuf(c, x, p)` -> `clixon_json2cbuf(c, x, p, 0, 0)`
* `xml2cli(h, f, x, p, fn)` -> `clixon_cli2file(h, f, x, p, fn, 0)`
- * `cli_xml2txt(x, fn, l)` -> `clixon_txt2file(stdout, x, l, NULL, 0)`
- * `xml2txt(f, x, l)` -> `clixon_txt2file(f, x, l, NULL, 0)`
- * `xml2txt_cb(f, x, fn)` -> `clixon_txt2file(f, x, 0, NULL, 0)`
+ * `cli_xml2txt(x, fn, l)` -> `clixon_txt2file(stdout, x, l, NULL, 0, 0)`
+ * `xml2txt(f, x, l)` -> `clixon_txt2file(f, x, l, NULL, 0, 0)`
+ * `xml2txt_cb(f, x, fn)` -> `clixon_txt2file(f, x, 0, NULL, 0, 0)`
### Minor features
@@ -122,6 +122,7 @@ Developers may need to change their code
### Corrected Bugs
+* Fixed: ["autocli:hide-show" extension cause bug in xmldb_put method #343](https://github.com/clicon/clixon/issues/343)
* Fixed: [Schema Ambiguity Error with openconfig-system re: NTP](https://github.com/clicon/clixon/issues/334)
* Fixed: [YANG mandatory statements within case nodes do not work](https://github.com/clicon/clixon/issues/344)
* Fixed: [Nested YANG choice does not work](https://github.com/clicon/clixon/issues/342)
diff --git a/apps/cli/cli_auto.c b/apps/cli/cli_auto.c
index c0d14d68..8f771bd8 100644
--- a/apps/cli/cli_auto.c
+++ b/apps/cli/cli_auto.c
@@ -452,17 +452,17 @@ cli_auto_show(clicon_handle h,
/* Print configuration according to format */
switch (format){
case FORMAT_XML:
- if (clixon_xml2file(stdout, xp, 0, pretty, cligen_output, skiproot) < 0)
+ if (clixon_xml2file(stdout, xp, 0, pretty, cligen_output, skiproot, 1) < 0)
goto done;
fprintf(stdout, "\n");
break;
case FORMAT_JSON:
- if (clixon_json2file(stdout, xp, pretty, cligen_output, skiproot) < 0)
+ if (clixon_json2file(stdout, xp, pretty, cligen_output, skiproot, 1) < 0)
goto done;
fprintf(stdout, "\n");
break;
case FORMAT_TEXT:
- if (clixon_txt2file(stdout, xp, 0, cligen_output, skiproot) < 0)
+ if (clixon_txt2file(stdout, xp, 0, cligen_output, skiproot, 1) < 0)
goto done;
break;
case FORMAT_CLI:
@@ -474,7 +474,7 @@ cli_auto_show(clicon_handle h,
NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR);
if (pretty)
fprintf(stdout, "\n");
- if (clixon_xml2file(stdout, xp, 2, pretty, cligen_output, skiproot) < 0)
+ if (clixon_xml2file(stdout, xp, 2, pretty, cligen_output, skiproot, 1) < 0)
goto done;
fprintf(stdout, "]]>]]>\n");
break;
diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c
index 430868cc..cb34e4f8 100644
--- a/apps/cli/cli_common.c
+++ b/apps/cli/cli_common.c
@@ -696,12 +696,12 @@ compare_xmls(cxobj *xc1,
goto done;
switch(format){
case FORMAT_TEXT:
- if (clixon_txt2file(f, xc1, 0, cligen_output, 1) < 0)
+ if (clixon_txt2file(f, xc1, 0, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_XML:
default:
- if (clixon_xml2file(f, xc1, 0, 1, cligen_output, 1) < 0)
+ if (clixon_xml2file(f, xc1, 0, 1, cligen_output, 1, 1) < 0)
goto done;
break;
}
@@ -717,12 +717,12 @@ compare_xmls(cxobj *xc1,
switch(format){
case FORMAT_TEXT:
- if (clixon_txt2file(f, xc2, 0, cligen_output, 1) < 0)
+ if (clixon_txt2file(f, xc2, 0, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_XML:
default:
- if (clixon_xml2file(f, xc2, 0, 1, cligen_output, 1) < 0)
+ if (clixon_xml2file(f, xc2, 0, 1, cligen_output, 1, 1) < 0)
goto done;
break;
}
@@ -1048,15 +1048,15 @@ save_config_file(clicon_handle h,
}
switch (format){
case FORMAT_XML:
- if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0) < 0)
+ if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0, 1) < 0)
goto done;
break;
case FORMAT_JSON:
- if (clixon_json2file(f, xt, pretty, fprintf, 0) < 0)
+ if (clixon_json2file(f, xt, pretty, fprintf, 0, 1) < 0)
goto done;
break;
case FORMAT_TEXT:
- if (clixon_txt2file(f, xt, 0, fprintf, 0) < 0)
+ if (clixon_txt2file(f, xt, 0, fprintf, 0, 1) < 0)
goto done;
break;
case FORMAT_CLI:
@@ -1067,7 +1067,7 @@ save_config_file(clicon_handle h,
fprintf(f, "",
NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR);
fprintf(f, "\n");
- if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0) < 0)
+ if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0, 1) < 0)
goto done;
fprintf(f, "]]>]]>\n");
break;
@@ -1171,14 +1171,14 @@ cli_notification_cb(int s,
}
switch (format){
case FORMAT_JSON:
- if (clixon_json2file(stdout, xt, 1, cligen_output, 1) < 0)
+ if (clixon_json2file(stdout, xt, 1, cligen_output, 1, 1) < 0)
goto done;
case FORMAT_TEXT:
- if (clixon_txt2file(stdout, xt, 0, cligen_output, 1) < 0)
+ if (clixon_txt2file(stdout, xt, 0, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_XML:
- if (clixon_xml2file(stdout, xt, 0, 1, cligen_output, 1) < 0)
+ if (clixon_xml2file(stdout, xt, 0, 1, cligen_output, 1, 1) < 0)
goto done;
break;
default:
diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c
index d9e4b503..8b71ea6d 100644
--- a/apps/cli/cli_show.c
+++ b/apps/cli/cli_show.c
@@ -494,15 +494,15 @@ cli_show_config1(clicon_handle h,
/* Print configuration according to format */
switch (format){
case FORMAT_XML:
- if (clixon_xml2file(stdout, xt, 0, 1, cligen_output, 1) < 0)
+ if (clixon_xml2file(stdout, xt, 0, 1, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_JSON:
- if (clixon_json2file(stdout, xt, 1, cligen_output, 0) < 0)
+ if (clixon_json2file(stdout, xt, 1, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_TEXT:
- if (clixon_txt2file(stdout, xt, 0, cligen_output, 1) < 0)
+ if (clixon_txt2file(stdout, xt, 0, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_CLI:
@@ -512,7 +512,7 @@ cli_show_config1(clicon_handle h,
case FORMAT_NETCONF:
cligen_output(stdout, "\n",
NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR);
- if (clixon_xml2file(stdout, xt, 2, 1, cligen_output, 1) < 0)
+ if (clixon_xml2file(stdout, xt, 2, 1, cligen_output, 1, 1) < 0)
goto done;
cligen_output(stdout, "]]>]]>\n");
break;
@@ -647,7 +647,7 @@ show_conf_xpath(clicon_handle h,
if (xpath_vec(xt, nsc, "%s", &xv, &xlen, xpath) < 0)
goto done;
for (i=0; i\n");
- if (clixon_xml2file(stdout, xp, 2, 1, fprintf, 0) < 0)
+ if (clixon_xml2file(stdout, xp, 2, 1, fprintf, 0, 1) < 0)
goto done;
fprintf(stdout, "]]>]]>\n");
break;
case FORMAT_JSON:
- if (clixon_json2file(stdout, xp, 1, cligen_output, 1) < 0) // XXX helper?
+ if (clixon_json2file(stdout, xp, 1, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_TEXT:
- if (clixon_txt2file(stdout, xp, 0, cligen_output, 1) < 0) // XXX helper?
+ if (clixon_txt2file(stdout, xp, 0, cligen_output, 1, 1) < 0)
goto done;
break;
case FORMAT_XML:
- if (clixon_xml2file(stdout, xp, 0, 1, fprintf, 0) < 0) // XXX helper?
+ if (clixon_xml2file(stdout, xp, 0, 1, fprintf, 0, 1) < 0)
goto done;
break;
}
@@ -970,15 +970,15 @@ cli_pagination(clicon_handle h,
xc = xvec[j];
switch (format){
case FORMAT_XML:
- if (clixon_xml2file(stdout, xc, 0, 1, cligen_output, 0) < 0)
+ if (clixon_xml2file(stdout, xc, 0, 1, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_JSON:
- if (clixon_json2file(stdout, xc, 1, cligen_output, 0) < 0)
+ if (clixon_json2file(stdout, xc, 1, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_TEXT:
- if (clixon_txt2file(stdout, xc, 0, cligen_output, 0) < 0)
+ if (clixon_txt2file(stdout, xc, 0, cligen_output, 0, 1) < 0)
goto done;
break;
case FORMAT_CLI:
diff --git a/apps/restconf/restconf_err.c b/apps/restconf/restconf_err.c
index c786db89..35c7277b 100644
--- a/apps/restconf/restconf_err.c
+++ b/apps/restconf/restconf_err.c
@@ -295,14 +295,14 @@ api_return_err(clicon_handle h,
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
if (pretty){
cprintf(cb, "{\n\"ietf-restconf:errors\" : ");
- if (clixon_json2cbuf(cb, xerr, pretty, 0) < 0)
+ if (clixon_json2cbuf(cb, xerr, pretty, 0, 0) < 0)
goto done;
cprintf(cb, "\n}\r\n");
}
else{
cprintf(cb, "{");
cprintf(cb, "\"ietf-restconf:errors\":");
- if (clixon_json2cbuf(cb, xerr, pretty, 0) < 0)
+ if (clixon_json2cbuf(cb, xerr, pretty, 0, 0) < 0)
goto done;
cprintf(cb, "}\r\n");
}
diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c
index 464fde4d..9161c9e8 100644
--- a/apps/restconf/restconf_methods_get.c
+++ b/apps/restconf/restconf_methods_get.c
@@ -229,7 +229,7 @@ api_data_get2(clicon_handle h,
goto done;
break;
case YANG_DATA_JSON:
- if (clixon_json2cbuf(cbx, xret, pretty, 0) < 0)
+ if (clixon_json2cbuf(cbx, xret, pretty, 0, 0) < 0)
goto done;
break;
default:
diff --git a/apps/restconf/restconf_methods_patch.c b/apps/restconf/restconf_methods_patch.c
index 33c39d82..56e9531b 100644
--- a/apps/restconf/restconf_methods_patch.c
+++ b/apps/restconf/restconf_methods_patch.c
@@ -119,7 +119,7 @@ yang_patch_xml2json_modified_cbuf(cxobj *x_simple_patch)
if (json_simple_patch == NULL)
return NULL;
cb = cbuf_new();
- if (clixon_json2cbuf(cb, x_simple_patch, 0) < 0)
+ if (clixon_json2cbuf(cb, x_simple_patch, 0, 0) < 0)
goto done;
// Insert a '[' after the first '{' to get the JSON to match what api_data_post/write() expect
@@ -267,7 +267,7 @@ yang_patch_do_replace(clicon_handle h,
}
}
// Convert the data to json
- if (clixon_json2cbuf(json_simple_patch, x_simple_patch, 0) < 0)
+ if (clixon_json2cbuf(json_simple_patch, x_simple_patch, 0, 0) < 0)
goto done;
// Send the POST request
@@ -329,7 +329,7 @@ yang_patch_do_create(clicon_handle h,
xml_addsub(x_simple_patch, value_vec_tmp);
}
}
- if (clixon_json2cbuf(cb, x_simple_patch, 0) < 0)
+ if (clixon_json2cbuf(cb, x_simple_patch, 0, 0) < 0)
goto done;
if (api_data_post(h, req, cbuf_get(simple_patch_request_uri),
pi, qvec,
@@ -479,7 +479,7 @@ yang_patch_do_merge(clicon_handle h,
xml_addsub(x_simple_patch, value_vec_tmp);
}
cbuf_reset(cb); /* reuse cb */
- if (clixon_json2cbuf(cb, x_simple_patch, 0) < 0)
+ if (clixon_json2cbuf(cb, x_simple_patch, 0, 0) < 0)
goto done;
if ((json_simple_patch = yang_patch_xml2json_modified_cbuf(x_simple_patch)) == NULL)
diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c
index ee4b78f9..69cf7ad9 100644
--- a/apps/restconf/restconf_methods_post.c
+++ b/apps/restconf/restconf_methods_post.c
@@ -879,7 +879,7 @@ api_operations_post(clicon_handle h,
/* xoutput should now look: */
break;
case YANG_DATA_JSON:
- if (clixon_json2cbuf(cbret, xoutput, pretty, 0) < 0)
+ if (clixon_json2cbuf(cbret, xoutput, pretty, 0, 0) < 0)
goto done;
/* xoutput should now look: {"example:output": {"x":0,"y":42}} */
break;
diff --git a/apps/restconf/restconf_root.c b/apps/restconf/restconf_root.c
index 686981b8..1cb8730f 100644
--- a/apps/restconf/restconf_root.c
+++ b/apps/restconf/restconf_root.c
@@ -209,7 +209,7 @@ api_root_restconf_exact(clicon_handle h,
break;
case YANG_DATA_JSON:
case YANG_PATCH_JSON:
- if (clixon_json2cbuf(cb, xt, pretty, 0) < 0)
+ if (clixon_json2cbuf(cb, xt, pretty, 0, 0) < 0)
goto done;
break;
default:
@@ -293,7 +293,7 @@ api_yang_library_version(clicon_handle h,
break;
case YANG_DATA_JSON:
case YANG_PATCH_JSON:
- if (clixon_json2cbuf(cb, xt, pretty, 0) < 0)
+ if (clixon_json2cbuf(cb, xt, pretty, 0, 0) < 0)
goto done;
break;
default:
diff --git a/example/main/example_cli.c b/example/main/example_cli.c
index 688a8153..d7dec97d 100644
--- a/example/main/example_cli.c
+++ b/example/main/example_cli.c
@@ -74,7 +74,7 @@ mycallback(clicon_handle h, cvec *cvv, cvec *argv)
nsc,
&xret) < 0)
goto done;
- if (clixon_xml2file(stdout, xret, 0, 1, cligen_output, 0) < 0)
+ if (clixon_xml2file(stdout, xret, 0, 1, cligen_output, 0, 1) < 0)
goto done;
retval = 0;
done:
@@ -119,7 +119,7 @@ example_client_rpc(clicon_handle h,
goto done;
}
/* Print result */
- if (clixon_xml2file(stdout, xml_child_i(xret, 0), 0, 0, cligen_output, 0) < 0)
+ if (clixon_xml2file(stdout, xml_child_i(xret, 0), 0, 0, cligen_output, 0, 1) < 0)
goto done;
fprintf(stdout,"\n");
diff --git a/lib/clixon/clixon_json.h b/lib/clixon/clixon_json.h
index 31562317..bd8cdfec 100644
--- a/lib/clixon/clixon_json.h
+++ b/lib/clixon/clixon_json.h
@@ -44,9 +44,9 @@
* Prototypes
*/
int json2xml_decode(cxobj *x, cxobj **xerr);
-int clixon_json2cbuf(cbuf *cb, cxobj *x, int pretty, int skiptop);
+int clixon_json2cbuf(cbuf *cb, cxobj *x, int pretty, int skiptop, int autocliext);
int xml2json_cbuf_vec(cbuf *cb, cxobj **vec, size_t veclen, int pretty);
-int clixon_json2file(FILE *f, cxobj *x, int pretty, clicon_output_cb *fn, int skiptop);
+int clixon_json2file(FILE *f, cxobj *x, int pretty, clicon_output_cb *fn, int skiptop, int autocliext);
int json_print(FILE *f, cxobj *x);
int xml2json_vec(FILE *f, cxobj **vec, size_t veclen, int pretty);
int clixon_json_parse_string(char *str, int rfc7951, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xret);
diff --git a/lib/clixon/clixon_text_syntax.h b/lib/clixon/clixon_text_syntax.h
index 79778e9c..e19d0509 100644
--- a/lib/clixon/clixon_text_syntax.h
+++ b/lib/clixon/clixon_text_syntax.h
@@ -39,7 +39,7 @@
/*
* Prototypes
*/
-int clixon_txt2file(FILE *f, cxobj *xn, int level, clicon_output_cb *fn, int skiptop);
+int clixon_txt2file(FILE *f, cxobj *xn, int level, clicon_output_cb *fn, int skiptop, int autocliext);
int clixon_text_syntax_parse_string(char *str, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr);
int clixon_text_syntax_parse_file(FILE *fp, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr);
diff --git a/lib/clixon/clixon_xml_io.h b/lib/clixon/clixon_xml_io.h
index f2e3323f..ce465895 100644
--- a/lib/clixon/clixon_xml_io.h
+++ b/lib/clixon/clixon_xml_io.h
@@ -43,7 +43,7 @@
/*
* Prototypes
*/
-int clixon_xml2file(FILE *f, cxobj *xn, int level, int pretty, clicon_output_cb *fn, int skiptop);
+int clixon_xml2file(FILE *f, cxobj *xn, int level, int pretty, clicon_output_cb *fn, int skiptop, int autocliext);
int xml_print(FILE *f, cxobj *xn);
int xml_dump(FILE *f, cxobj *x);
int clixon_xml2cbuf(cbuf *cb, cxobj *x, int level, int prettyprint, int32_t depth, int skiptop);
diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c
index 5061ed84..5e0c0ae8 100644
--- a/lib/src/clixon_datastore_read.c
+++ b/lib/src/clixon_datastore_read.c
@@ -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;
diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c
index f522b9db..c1d4df18 100644
--- a/lib/src/clixon_datastore_write.c
+++ b/lib/src/clixon_datastore_write.c
@@ -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:
diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c
index 60ba1f62..21afce16 100644
--- a/lib/src/clixon_json.c
+++ b/lib/src/clixon_json.c
@@ -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 0 -> {"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.
diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c
index 9caadd4d..2a7eb9ce 100644
--- a/lib/src/clixon_netconf_lib.c
+++ b/lib/src/clixon_netconf_lib.c
@@ -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);
diff --git a/lib/src/clixon_text_syntax.c b/lib/src/clixon_text_syntax.c
index 4398e90e..cba69917 100644
--- a/lib/src/clixon_text_syntax.c
+++ b/lib/src/clixon_text_syntax.c
@@ -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;
diff --git a/lib/src/clixon_xml_io.c b/lib/src/clixon_xml_io.c
index 23e95569..5f9d49ea 100644
--- a/lib/src/clixon_xml_io.c
+++ b/lib/src/clixon_xml_io.c
@@ -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
diff --git a/lib/src/clixon_xml_vec.c b/lib/src/clixon_xml_vec.c
index d5be0034..ab4b5003 100644
--- a/lib/src/clixon_xml_vec.c
+++ b/lib/src/clixon_xml_vec.c
@@ -377,7 +377,7 @@ clixon_xvec_print(FILE *f,
int i;
for (i=0; ixv_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;
}
diff --git a/test/test_autocli_extension.sh b/test/test_autocli_extension.sh
index 3dee8756..d6e58e57 100755
--- a/test/test_autocli_extension.sh
+++ b/test/test_autocli_extension.sh
@@ -8,6 +8,8 @@ s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
APPNAME=example
+: ${clixon_util_datastore:=clixon_util_datastore}
+
fin=$dir/in
cfg=$dir/conf_yang.xml
fyang=$dir/example.yang
@@ -113,20 +115,6 @@ module example-augment {
}
EOF
-new "test params: -f $cfg"
-if [ $BE -ne 0 ]; then
- new "kill old backend"
- sudo clixon_backend -z -f $cfg
- if [ $? -ne 0 ]; then
- err
- fi
- new "start backend -s init -f $cfg"
- start_backend -s init -f $cfg
-fi
-
-new "wait backend"
-wait_backend
-
function testparam()
{
# Try hidden parameter list
@@ -138,7 +126,16 @@ set table parameter x
show config xml
EOF
new "set table parameter hidden"
- expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "set table parameter x" ""
+ expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 "set table parameter x" ""
+
+ XML=""
+
+ new "check datastore using netconf"
+ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "$XML"
+
+ new "check datastore direct access"
+ expectpart "$($clixon_util_datastore -d candidate -b $dir -y $fyang -Y ${YANG_INSTALLDIR} -Y $dir get /)" 0 "$XML"
+
}
function testvalue()
@@ -157,8 +154,33 @@ show config xml
EOF
new "set table parameter hidden leaf2"
expectpart "$(cat $fin | $clixon_cli -f $cfg 2>&1)" 0 ""
+
+ XML=""
+
+ new "check datastore using netconf"
+ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "$XML"
+
+ new "check datastore direct access"
+ expectpart "$($clixon_util_datastore -d candidate -b $dir -y $fyang -Y ${YANG_INSTALLDIR} -Y $dir get /)" 0 "$XML"
+
}
+new "test params: -f $cfg"
+if [ $BE -ne 0 ]; then
+ new "kill old backend"
+ sudo clixon_backend -z -f $cfg
+ if [ $? -ne 0 ]; then
+ err
+ fi
+ new "start backend -s init -f $cfg"
+ start_backend -s init -f $cfg
+fi
+
+new "wait backend"
+wait_backend
+
+sudo chmod a+r $dir/candidate_db
+
# INLINE MODE
new "Test hidden parameter in table/param inline"
diff --git a/util/clixon_util_datastore.c b/util/clixon_util_datastore.c
index b74b96e3..cd1b6e0a 100644
--- a/util/clixon_util_datastore.c
+++ b/util/clixon_util_datastore.c
@@ -66,7 +66,7 @@
#include
/* Command line options to be passed to getopt(3) */
-#define DATASTORE_OPTS "hDd:b:f:x:y:"
+#define DATASTORE_OPTS "hDd:b:f:x:y:Y:"
/*! usage
*/
@@ -74,29 +74,30 @@ static void
usage(char *argv0)
{
fprintf(stderr, "usage:%s * []\n"
- "where options are\n"
- "\t-h\t\tHelp\n"
- "\t-D\t\tDebug\n"
- "\t-d \t\tDatabase name. Default: running. Alt: candidate,startup\n"
- "\t-b \tDatabase directory. Mandatory\n"
- "\t-f \tDatabase format: xml or json\n"
- "\t-x \tXML file. Alternative to put argument\n"
- "\t-y \tYang file. Mandatory\n"
- "and command is either:\n"
- "\tget []\n"
- "\tmget []\n"
- "\tput (merge|replace|create|delete|remove) []\n"
- "\tcopy \n"
- "\tlock \n"
- "\tunlock\n"
- "\tunlock_all \n"
- "\tislocked\n"
- "\texists\n"
- "\tdelete\n"
- "\tinit\n"
- ,
- argv0
- );
+ "where options are\n"
+ "\t-h\t\tHelp\n"
+ "\t-D\t\tDebug\n"
+ "\t-d \t\tDatabase name. Default: running. Alt: candidate,startup\n"
+ "\t-b \tDatabase directory. Mandatory\n"
+ "\t-f \tDatabase format: xml or json\n"
+ "\t-x \tXML file. Alternative to put argument\n"
+ "\t-y \tYang file. Mandatory\n"
+ "\t-Y \tYang dirs (can be several)\n"
+ "and command is either:\n"
+ "\tget []\n"
+ "\tmget []\n"
+ "\tput (merge|replace|create|delete|remove) []\n"
+ "\tcopy \n"
+ "\tlock \n"
+ "\tunlock\n"
+ "\tunlock_all \n"
+ "\tislocked\n"
+ "\texists\n"
+ "\tdelete\n"
+ "\tinit\n"
+ ,
+ argv0
+ );
exit(0);
}
@@ -122,6 +123,7 @@ main(int argc, char **argv)
cbuf *cbret = NULL;
int dbg = 0;
cxobj *xerr = NULL;
+ cxobj *xcfg = NULL;
/* In the startup, logs to stderr & debug flag set later */
clicon_log_init(__FILE__, LOG_INFO, CLICON_LOG_STDERR);
@@ -130,6 +132,10 @@ main(int argc, char **argv)
/* Defaults */
if ((h = clicon_handle_init()) == NULL)
goto done;
+ if ((xcfg = xml_new("clixon-config", NULL, CX_ELMNT)) == NULL)
+ goto done;
+ if (clicon_conf_xml_set(h, xcfg) < 0)
+ goto done;
/* getopt in two steps, first find config-file before over-riding options. */
clicon_option_str_set(h, "CLICON_XMLDB_FORMAT", "xml"); /* default */
while ((c = getopt(argc, argv, DATASTORE_OPTS)) != -1)
@@ -166,6 +172,10 @@ main(int argc, char **argv)
usage(argv0);
yangfilename = optarg;
break;
+ case 'Y':
+ if (clicon_option_add(h, "CLICON_YANG_DIR", optarg) < 0)
+ goto done;
+ break;
}
/*
* Logs, error and debug to stderr, set debug level
@@ -206,7 +216,7 @@ main(int argc, char **argv)
xpath = "/";
if (xmldb_get(h, db, NULL, xpath, &xt) < 0)
goto done;
- if (clixon_xml2file(stdout, xt, 0, 0, fprintf, 0) < 0)
+ if (clixon_xml2file(stdout, xt, 0, 0, fprintf, 0, 0) < 0)
goto done;
fprintf(stdout, "\n");
if (xt){
@@ -230,7 +240,7 @@ main(int argc, char **argv)
clicon_err(OE_DB, 0, "xt is NULL");
goto done;
}
- if (clixon_xml2file(stdout, xt, 0, 0, fprintf, 0) < 0)
+ if (clixon_xml2file(stdout, xt, 0, 0, fprintf, 0, 0) < 0)
goto done;
if (xt){
xml_free(xt);
@@ -341,6 +351,8 @@ main(int argc, char **argv)
goto done;
retval = 0;
done:
+ if (xcfg)
+ xml_free(xcfg);
if (cbret)
cbuf_free(cbret);
if (xt)
diff --git a/util/clixon_util_json.c b/util/clixon_util_json.c
index 8797d4a1..6882d129 100644
--- a/util/clixon_util_json.c
+++ b/util/clixon_util_json.c
@@ -144,7 +144,7 @@ main(int argc,
goto done;
}
if (json){
- if (clixon_json2cbuf(cb, xt, pretty, 1) < 0)
+ if (clixon_json2cbuf(cb, xt, pretty, 1, 0) < 0)
goto done;
}
else if (clixon_xml2cbuf(cb, xt, 0, pretty, -1, 1) < 0)
diff --git a/util/clixon_util_path.c b/util/clixon_util_path.c
index 9a8c382f..a1d2dfdf 100644
--- a/util/clixon_util_path.c
+++ b/util/clixon_util_path.c
@@ -281,7 +281,7 @@ main(int argc,
for (i = 0; i < xlen; i++){
xc = xvec[i];
fprintf(stdout, "%d: ", i);
- clixon_xml2file(stdout, xc, 0, 0, fprintf, 0);
+ clixon_xml2file(stdout, xc, 0, 0, fprintf, 0, 0);
fprintf(stdout, "\n");
fflush(stdout);
}
diff --git a/util/clixon_util_xml.c b/util/clixon_util_xml.c
index 65e68855..5733c651 100644
--- a/util/clixon_util_xml.c
+++ b/util/clixon_util_xml.c
@@ -334,11 +334,11 @@ main(int argc,
/* 4. Output data (xml/json/text) */
if (output){
if (textout){
- if (clixon_txt2file(stdout, xt, 0, fprintf, 1) < 0)
+ if (clixon_txt2file(stdout, xt, 0, fprintf, 1, 0) < 0)
goto done;
}
else if (jsonout){
- if (clixon_json2cbuf(cb, xt, pretty, 1) < 0)
+ if (clixon_json2cbuf(cb, xt, pretty, 1, 0) < 0)
goto done;
}
else if (clixon_xml2cbuf(cb, xt, 0, pretty, -1, 1) < 0)
diff --git a/util/clixon_util_xml_mod.c b/util/clixon_util_xml_mod.c
index a009c99f..94b60a92 100644
--- a/util/clixon_util_xml_mod.c
+++ b/util/clixon_util_xml_mod.c
@@ -282,11 +282,11 @@ main(int argc, char **argv)
if (sort)
xml_sort_recurse(xb);
if (strcmp(xml_name(xb),"top")==0){
- if (clixon_xml2file(stdout, xb, 0, 0, fprintf, 1) < 0)
+ if (clixon_xml2file(stdout, xb, 0, 0, fprintf, 1, 0) < 0)
goto done;
}
else{
- if (clixon_xml2file(stdout, xb, 0, 0, fprintf, 0) < 0)
+ if (clixon_xml2file(stdout, xb, 0, 0, fprintf, 0, 0) < 0)
goto done;
}
fprintf(stdout, "\n");