From 0c79298e762c7d1cc28e4bea3a67e6c0524dc04e Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 1 Jun 2022 20:02:27 +0200 Subject: [PATCH] Changed C-API for xml translation/print the internal `cxobj` tree data structure to other formats New API is as follows: * `clixon_xml2file()` - Print internal tree as XML to file * `clixon_xml2cbuf()` - Print internal tree as XML to buffer * `clixon_json2file()` - Print internal tree as JSON to file * `clixon_json2cbuf()` - Print internal tree as JSON to buffer * `clixon_cli2file()` - Print internal tree as CLI format to file * `clixon_txt2file()` - Print internal tree as text format to file --- CHANGELOG.md | 33 +++-- apps/backend/backend_client.c | 10 +- apps/backend/backend_commit.c | 16 +-- apps/backend/backend_get.c | 10 +- apps/backend/backend_plugin_restconf.c | 2 +- apps/backend/clixon_backend_transaction.c | 12 +- apps/cli/cli_auto.c | 140 ++-------------------- apps/cli/cli_common.c | 104 ++++++++-------- apps/cli/cli_generate.c | 2 +- apps/cli/cli_show.c | 108 ++++++++--------- apps/cli/clixon_cli_api.h | 3 +- apps/netconf/netconf_main.c | 18 ++- apps/netconf/netconf_rpc.c | 4 +- apps/restconf/restconf_err.c | 8 +- apps/restconf/restconf_methods.c | 4 +- apps/restconf/restconf_methods_get.c | 8 +- apps/restconf/restconf_methods_patch.c | 15 ++- apps/restconf/restconf_methods_post.c | 6 +- apps/restconf/restconf_root.c | 8 +- apps/restconf/restconf_stream_fcgi.c | 2 +- example/main/example_backend.c | 2 +- example/main/example_cli.c | 8 +- example/main/example_netconf.c | 2 +- example/main/example_restconf.c | 2 +- lib/clixon/clixon_json.h | 4 +- lib/clixon/clixon_text_syntax.h | 2 +- lib/clixon/clixon_xml_io.h | 21 ++-- lib/src/clixon_datastore_read.c | 11 +- lib/src/clixon_datastore_write.c | 8 +- lib/src/clixon_json.c | 47 ++++---- lib/src/clixon_netconf_lib.c | 31 ++--- lib/src/clixon_proto.c | 2 +- lib/src/clixon_proto_client.c | 2 +- lib/src/clixon_stream.c | 2 +- lib/src/clixon_text_syntax.c | 41 +++++-- lib/src/clixon_validate.c | 4 +- lib/src/clixon_xml.c | 3 +- lib/src/clixon_xml_io.c | 135 ++++++++++----------- lib/src/clixon_xml_vec.c | 4 +- test/test_c++.sh | 2 +- test/test_pagination_expect.exp | 2 + util/clixon_util_datastore.c | 6 +- util/clixon_util_json.c | 10 +- util/clixon_util_path.c | 2 +- util/clixon_util_socket.c | 2 +- util/clixon_util_text_syntax.c | 17 ++- util/clixon_util_xml.c | 17 ++- util/clixon_util_xml_mod.c | 12 +- util/clixon_util_xpath.c | 10 +- 49 files changed, 421 insertions(+), 503 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 714dadcb..b7533e79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,17 +50,30 @@ Planned: July 2022 Developers may need to change their code -* Changed C-API for xml translation/print to other formats. - * Added `skiptop` parameter, if set only apply to children of a node, skip top node - * default is 0 +* Changed C-API for xml translation/print the internal `cxobj` tree data structure to other formats. * Functions are merged, ie removed and replaced with more generic functions - * `xml2json_cbuf()`: Added `skiptop` parameter: `xml2json_cbuf(..., int skiptop)` - * `xml2json()` and `xml2json_cb()` merged into `xml2json_file()` with `skiptop` - * Replace `xml2json(...)` with `xml2json_file(..., stdout, 0)` - * Replace `xml2json_cb(...)` with `xml2json_file(..., 0)` - * `clicon_xml2cbuf()`: Added `skiptop` parameter: `clicon_xml2cbuf(..., int skiptop)` - * `xml2cli()`: Added `skiptop` parameter: `xml2cli(..., int skiptop)` - * Merged `cli_xml2txt()` and `xml2txt_cb()` with `xml2txt()` + * Added `skiptop` parameter, if set only apply to children of a node, skip top node + * default is 0 + * The new API is as follows, with how to change old functions to new: + * `clixon_xml2file()` - Print internal tree as XML to file + * `clixon_xml2cbuf()` - Print internal tree as XML to buffer + * `clixon_json2file()` - Print internal tree as JSON to file + * `clixon_json2cbuf()` - Print internal tree as JSON to buffer + * `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_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)` + * `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)` ## 5.7.0 17 May 2022 diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 3daede97..45dda83a 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -366,7 +366,7 @@ from_client_edit_config(clicon_handle h, if ((ret = xml_bind_yang(xc, YB_MODULE, yspec, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto ok; } @@ -374,7 +374,7 @@ from_client_edit_config(clicon_handle h, if ((ret = xml_non_config_data(xc, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto ok; } @@ -387,7 +387,7 @@ from_client_edit_config(clicon_handle h, if ((ret = xml_yang_validate_list_key_only(xc, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto ok; } @@ -1241,7 +1241,7 @@ from_client_msg(clicon_handle h, goto reply; } if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto reply; } @@ -1303,7 +1303,7 @@ from_client_msg(clicon_handle h, if ((ret = xml_yang_validate_rpc(h, x, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto reply; } diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index b7491f5f..5fcab8e5 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -216,7 +216,7 @@ startup_common(clicon_handle h, * See similar clause below */ } - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; goto fail; } @@ -276,7 +276,7 @@ startup_common(clicon_handle h, if ((ret = xml_bind_yang(xt, YB_MODULE, yspec, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto fail; } @@ -284,7 +284,7 @@ startup_common(clicon_handle h, if ((ret = xml_non_config_data(xt, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto fail; } @@ -319,7 +319,7 @@ startup_common(clicon_handle h, if ((ret = generic_validate(h, yspec, td, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto fail; /* STARTUP_INVALID */ } @@ -625,7 +625,7 @@ candidate_validate(clicon_handle h, clicon_err(OE_CFG, EINVAL, "xret is NULL"); goto done; } - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; if (!cbuf_len(cbret) && netconf_operation_failed(cbret, "application", clicon_err_reason)< 0) @@ -685,7 +685,7 @@ candidate_commit(clicon_handle h, if ((ret = validate_common(h, db, td, &xret)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto fail; } @@ -957,7 +957,7 @@ from_client_restart_one(clicon_handle h, if ((ret = xml_yang_validate_all_top(h, td->td_target, &xerr)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; goto fail; } @@ -1007,7 +1007,7 @@ from_client_restart_one(clicon_handle h, if ((ret = generic_validate(h, yspec, td, &xerr)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; goto fail; } diff --git a/apps/backend/backend_get.c b/apps/backend/backend_get.c index 5e1a9a46..b4874798 100644 --- a/apps/backend/backend_get.c +++ b/apps/backend/backend_get.c @@ -365,7 +365,7 @@ get_nacm_and_reply(clicon_handle h, if (xml_name_set(xret, NETCONF_OUTPUT_DATA) < 0) goto done; /* Top level is data, so add 1 to depth if significant */ - if (clicon_xml2cbuf(cbret, xret, 0, 0, depth>0?depth+1:depth, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, depth>0?depth+1:depth, 0) < 0) goto done; } cprintf(cbret, ""); @@ -605,7 +605,7 @@ get_list_pagination(clicon_handle h, clicon_err_reason); if (netconf_operation_failed_xml(&xerr, "application", cbuf_get(cberr)) < 0) goto done; - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; goto ok; } @@ -620,7 +620,7 @@ get_list_pagination(clicon_handle h, ". Internal error, state callback returned invalid XML", NULL) < 0) goto done; - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; goto ok; } @@ -832,7 +832,7 @@ get_common(clicon_handle h, if ((ret = get_client_statedata(h, xpath?xpath:"/", nsc, &xret)) < 0) goto done; if (ret == 0){ /* Error from callback (error in xret) */ - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto ok; } @@ -857,7 +857,7 @@ get_common(clicon_handle h, ". Internal error, state callback returned invalid XML", NULL) < 0) goto done; - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; goto ok; } diff --git a/apps/backend/backend_plugin_restconf.c b/apps/backend/backend_plugin_restconf.c index 4e0bfdcc..dbe4f8e5 100644 --- a/apps/backend/backend_plugin_restconf.c +++ b/apps/backend/backend_plugin_restconf.c @@ -163,7 +163,7 @@ restconf_pseudo_set_inline(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(cb, xrestconf, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xrestconf, 0, 0, -1, 0) < 0) goto done; if ((str = strdup(cbuf_get(cb))) == NULL){ clicon_err(OE_XML, errno, "stdup"); diff --git a/apps/backend/clixon_backend_transaction.c b/apps/backend/clixon_backend_transaction.c index 62eb57a6..3fccf089 100644 --- a/apps/backend/clixon_backend_transaction.c +++ b/apps/backend/clixon_backend_transaction.c @@ -256,7 +256,8 @@ transaction_log(clicon_handle h, } for (i=0; itd_dlen; i++){ xn = td->td_dvec[i]; - clicon_xml2cbuf(cb, xn, 0, 0, -1, 0); + if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0) + goto done; } if (i) clicon_log(level, "%s %" PRIu64 " %s del: %s", @@ -264,7 +265,8 @@ transaction_log(clicon_handle h, cbuf_reset(cb); for (i=0; itd_alen; i++){ xn = td->td_avec[i]; - clicon_xml2cbuf(cb, xn, 0, 0, -1, 0); + if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0) + goto done; } if (i) clicon_log(level, "%s %" PRIu64 " %s add: %s", __FUNCTION__, td->td_id, op, cbuf_get(cb)); @@ -272,10 +274,12 @@ transaction_log(clicon_handle h, for (i=0; itd_clen; i++){ if (td->td_scvec){ xn = td->td_scvec[i]; - clicon_xml2cbuf(cb, xn, 0, 0, -1, 0); + if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0) + goto done; } xn = td->td_tcvec[i]; - clicon_xml2cbuf(cb, xn, 0, 0, -1, 0); + if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0) + goto done; } if (i) clicon_log(level, "%s %" PRIu64 " %s change: %s", __FUNCTION__, td->td_id, op, cbuf_get(cb)); diff --git a/apps/cli/cli_auto.c b/apps/cli/cli_auto.c index 9ffc2692..30932192 100644 --- a/apps/cli/cli_auto.c +++ b/apps/cli/cli_auto.c @@ -125,115 +125,6 @@ cvec_append(cvec *cvv0, return cvv2; } -/*! Print an XML tree structure from an auto-cli env to stdout and encode chars "<>&" - * - * @param[in] xn clicon xml tree - * @param[in] level how many spaces to insert before each line - * @param[in] prettyprint insert \n and spaces tomake the xml more readable. - * @param[in] fn Callback to make print function - * @see clicon_xml2cbuf - * One can use clicon_xml2cbuf to get common code, but using fprintf is - * much faster than using cbuf and then printing that,... - */ -int -cli_xml2file(cxobj *xn, - int level, - int prettyprint, - clicon_output_cb *fn) -{ - int retval = -1; - char *name; - char *namespace; - cxobj *xc; - int hasbody; - int haselement; - char *val; - char *encstr = NULL; /* xml encoded string */ - int exist = 0; - - if (xn == NULL) - goto ok; - if (yang_extension_value(xml_spec(xn), "hide-show", CLIXON_AUTOCLI_NS, &exist, NULL) < 0) - goto done; - if (exist) - goto ok; - name = xml_name(xn); - namespace = xml_prefix(xn); - switch(xml_type(xn)){ - case CX_BODY: - if ((val = xml_value(xn)) == NULL) /* incomplete tree */ - break; - if (xml_chardata_encode(&encstr, "%s", val) < 0) - goto done; - (*fn)(stdout, "%s", encstr); - break; - case CX_ATTR: - (*fn)(stdout, " "); - if (namespace) - (*fn)(stdout, "%s:", namespace); - (*fn)(stdout, "%s=\"%s\"", name, xml_value(xn)); - break; - case CX_ELMNT: - (*fn)(stdout, "%*s<", prettyprint?(level*3):0, ""); - if (namespace) - (*fn)(stdout, "%s:", namespace); - (*fn)(stdout, "%s", name); - hasbody = 0; - haselement = 0; - xc = NULL; - /* print attributes only */ - while ((xc = xml_child_each(xn, xc, -1)) != NULL) { - switch (xml_type(xc)){ - case CX_ATTR: - if (cli_xml2file(xc, level+1, prettyprint, fn) <0) - goto done; - break; - case CX_BODY: - hasbody=1; - break; - case CX_ELMNT: - haselement=1; - break; - default: - break; - } - } - /* Check for special case instead of : - * Ie, no CX_BODY or CX_ELMNT child. - */ - if (hasbody==0 && haselement==0) - (*fn)(stdout, "/>"); - else{ - (*fn)(stdout, ">"); - if (prettyprint && hasbody == 0) - (*fn)(stdout, "\n"); - xc = NULL; - while ((xc = xml_child_each(xn, xc, -1)) != NULL) { - if (xml_type(xc) != CX_ATTR) - if (cli_xml2file(xc, level+1, prettyprint, fn) <0) - goto done; - } - if (prettyprint && hasbody==0) - (*fn)(stdout, "%*s", level*3, ""); - (*fn)(stdout, "", name); - } - if (prettyprint) - (*fn)(stdout, "\n"); - break; - default: - break; - }/* switch */ - ok: - retval = 0; - done: - if (encstr) - free(encstr); - return retval; -} - /*! Enter a CLI edit mode * @param[in] h CLICON handle * @param[in] cvv Vector of variables from CLIgen command-line @@ -473,7 +364,6 @@ cli_auto_show(clicon_handle h, pt_head *ph; char *xpath = NULL; cxobj *xp; - cxobj *xc = NULL; cvec *nsc = NULL; yang_stmt *yspec; cxobj *xerr; @@ -481,7 +371,7 @@ cli_auto_show(clicon_handle h, cxobj **vec = NULL; size_t veclen; int i; - int isroot; + int skiproot; int pretty; char *prefix = NULL; int state; @@ -537,7 +427,7 @@ cli_auto_show(clicon_handle h, api_path = "/"; if (api_path2xpath(api_path, yspec, &xpath, &nsc, NULL) < 0) goto done; - isroot = (xpath == NULL) || strcmp(xpath,"/")==0; + skiproot = (xpath != NULL) && (strcmp(xpath,"/") != 0); if (state == 0){ /* Get configuration-only from database */ if (clicon_rpc_get_config(h, NULL, db, xpath, nsc, &xt) < 0) goto done; @@ -562,28 +452,21 @@ cli_auto_show(clicon_handle h, /* Print configuration according to format */ switch (format){ case FORMAT_XML: - if (isroot) - cli_xml2file(xp, 0, pretty, fprintf); - else{ - while ((xc = xml_child_each(xp, xc, CX_ELMNT)) != NULL) - cli_xml2file(xc, 0, pretty, fprintf); - } + if (clixon_xml2file(stdout, xp, 0, pretty, fprintf, skiproot) < 0) + goto done; fprintf(stdout, "\n"); break; case FORMAT_JSON: - if (xml2json_file(stdout, xp, pretty, cligen_output, !isroot) < 0) + if (clixon_json2file(stdout, xp, pretty, cligen_output, skiproot) < 0) goto done; fprintf(stdout, "\n"); break; case FORMAT_TEXT: - if (isroot) - xml2txt(xp, cligen_output, stdout, 0); /* tree-formed text */ - else - while ((xc = xml_child_each(xp, xc, CX_ELMNT)) != NULL) - xml2txt(xc, cligen_output, stdout, 0); /* tree-formed text */ + if (clixon_txt2file(stdout, xp, 0, cligen_output, skiproot) < 0) + goto done; break; case FORMAT_CLI: - if (xml2cli(h, stdout, xp, prefix, cligen_output, !isroot) < 0) + if (clixon_cli2file(h, stdout, xp, prefix, cligen_output, skiproot) < 0) goto done; break; case FORMAT_NETCONF: @@ -591,11 +474,8 @@ cli_auto_show(clicon_handle h, NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR); if (pretty) fprintf(stdout, "\n"); - if (isroot) - cli_xml2file(xp, 2, pretty, fprintf); - else - while ((xc = xml_child_each(xp, xc, CX_ELMNT)) != NULL) - cli_xml2file(xc, 2, pretty, fprintf); + if (clixon_xml2file(stdout, xp, 2, pretty, fprintf, skiproot) < 0) + goto done; fprintf(stdout, "]]>]]>\n"); break; } /* switch */ diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index 1bc1b3b7..495a5b18 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -325,7 +325,7 @@ cli_dbxml(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(cb, xtop, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xtop, 0, 0, -1, 0) < 0) goto done; if (clicon_rpc_edit_config(h, "candidate", OP_NONE, cbuf_get(cb)) < 0) goto done; @@ -675,16 +675,15 @@ cli_validate(clicon_handle h, /*! Compare two dbs using XML. Write to file and run diff */ static int -compare_xmls(cxobj *xc1, - cxobj *xc2, - int astext) +compare_xmls(cxobj *xc1, + cxobj *xc2, + enum format_enum format) { int fd; FILE *f; char filename1[MAXPATHLEN]; char filename2[MAXPATHLEN]; int retval = -1; - cxobj *xc; cbuf *cb = NULL; snprintf(filename1, sizeof(filename1), "/tmp/cliconXXXXXX"); @@ -695,14 +694,17 @@ compare_xmls(cxobj *xc1, } if ((f = fdopen(fd, "w")) == NULL) goto done; - xc = NULL; - if (astext) - while ((xc = xml_child_each(xc1, xc, -1)) != NULL) - xml2txt(xc, cligen_output, f, 0); - else - while ((xc = xml_child_each(xc1, xc, -1)) != NULL) - clicon_xml2file_cb(f, xc, 0, 1, cligen_output); - + switch(format){ + case FORMAT_TEXT: + if (clixon_txt2file(f, xc1, 0, cligen_output, 1) < 0) + goto done; + break; + case FORMAT_XML: + default: + if (clixon_xml2file(f, xc1, 0, 1, cligen_output, 1) < 0) + goto done; + break; + } fclose(f); close(fd); @@ -712,13 +714,19 @@ compare_xmls(cxobj *xc1, } if ((f = fdopen(fd, "w")) == NULL) goto done; - xc = NULL; - if (astext) - while ((xc = xml_child_each(xc2, xc, -1)) != NULL) - xml2txt(xc, cligen_output, f, 0); - else - while ((xc = xml_child_each(xc2, xc, -1)) != NULL) - clicon_xml2file_cb(f, xc, 0, 1, cligen_output); + + switch(format){ + case FORMAT_TEXT: + if (clixon_txt2file(f, xc2, 0, cligen_output, 1) < 0) + goto done; + break; + case FORMAT_XML: + default: + if (clixon_xml2file(f, xc2, 0, 1, cligen_output, 1) < 0) + goto done; + break; + } + fclose(f); close(fd); @@ -754,16 +762,16 @@ compare_dbs(clicon_handle h, cxobj *xc2 = NULL; /* candidate xml */ cxobj *xerr = NULL; int retval = -1; - int astext; + enum format_enum format; if (cvec_len(argv) > 1){ clicon_err(OE_PLUGIN, EINVAL, "Requires 0 or 1 element. If given: astext flag 0|1"); goto done; } - if (cvec_len(argv)) - astext = cv_int32_get(cvec_i(argv, 0)); + if (cvec_len(argv) && cv_int32_get(cvec_i(argv, 0)) == 1) + format = FORMAT_TEXT; else - astext = 0; + format = FORMAT_XML; if (clicon_rpc_get_config(h, NULL, "running", "/", NULL, &xc1) < 0) goto done; if ((xerr = xpath_first(xc1, NULL, "/rpc-error")) != NULL){ @@ -776,7 +784,7 @@ compare_dbs(clicon_handle h, clixon_netconf_error(xerr, "Get configuration", NULL); goto done; } - if (compare_xmls(xc1, xc2, astext) < 0) /* astext? */ + if (compare_xmls(xc1, xc2, format) < 0) /* astext? */ goto done; retval = 0; done: @@ -934,7 +942,7 @@ load_config_file(clicon_handle h, /* Read as datastore-top but transformed into an edit-config "config" */ xml_name_set(x, NETCONF_INPUT_CONFIG); } - if (clicon_xml2cbuf(cbxml, xt, 0, 0, -1, 1) < 0) + if (clixon_xml2cbuf(cbxml, xt, 0, 0, -1, 1) < 0) goto done; if (clicon_rpc_edit_config(h, "candidate", replace?OP_REPLACE:OP_MERGE, @@ -1034,26 +1042,26 @@ save_config_file(clicon_handle h, } switch (format){ case FORMAT_XML: - if (clicon_xml2file(f, xt, 0, pretty) < 0) + if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0) < 0) goto done; break; case FORMAT_JSON: - if (xml2json_file(f, xt, pretty, fprintf, 0) < 0) + if (clixon_json2file(f, xt, pretty, fprintf, 0) < 0) goto done; break; case FORMAT_TEXT: - if (xml2txt(xt, fprintf, f, 0) < 0) + if (clixon_txt2file(f, xt, 0, fprintf, 0) < 0) goto done; break; case FORMAT_CLI: - if (xml2cli(h, f, xt, prefix, fprintf, 1) < 0) + if (clixon_cli2file(h, f, xt, prefix, fprintf, 1) < 0) goto done; break; case FORMAT_NETCONF: fprintf(f, "", NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR); fprintf(f, "\n"); - if (clicon_xml2file(f, xt, 0, pretty) < 0) + if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0) < 0) goto done; fprintf(f, "]]>]]>\n"); break; @@ -1135,8 +1143,6 @@ cli_notification_cb(int s, int eof; int retval = -1; cxobj *xt = NULL; - cxobj *xe; - cxobj *x; enum format_enum format = (enum format_enum)arg; int ret; @@ -1159,30 +1165,19 @@ cli_notification_cb(int s, } switch (format){ case FORMAT_JSON: - if (xml2json_file(stdout, xt, 1, cligen_output, 1) < 0) + if (clixon_json2file(stdout, xt, 1, cligen_output, 1) < 0) goto done; + case FORMAT_TEXT: + if (clixon_txt2file(stdout, xt, 0, cligen_output, 1) < 0) + goto done; + break; + case FORMAT_XML: + if (clixon_xml2file(stdout, xt, 0, 1, cligen_output, 1) < 0) + goto done; + break; default: break; } - if ((xe = xpath_first(xt, NULL, "//event")) != NULL){ - x = NULL; - while ((x = xml_child_each(xe, x, -1)) != NULL) { - switch (format){ - case FORMAT_XML: - if (clicon_xml2file_cb(stdout, x, 0, 1, cligen_output) < 0) - goto done; - break; - case FORMAT_TEXT: - if (xml2txt(x, cligen_output, stdout, 0) < 0) - goto done; - break; - default: - break; - } - if (cli_output_status() < 0) - break; - } - } retval = 0; done: if (xt) @@ -1424,7 +1419,8 @@ cli_copy_config(clicon_handle h, /* resuse cb */ cbuf_reset(cb); /* create xml copy tree and merge it with database configuration */ - clicon_xml2cbuf(cb, x2, 0, 0, -1, 0); + if (clixon_xml2cbuf(cb, x2, 0, 0, -1, 0) < 0) + goto done; if (clicon_rpc_edit_config(h, db, OP_MERGE, cbuf_get(cb)) < 0) goto done; retval = 0; diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index ee3ff3d6..436a9902 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -882,7 +882,7 @@ yang2cli_container(clicon_handle h, goto done; /* If non-presence container && HIDE mode && only child is * a list, then skip container keyword - * See also xml2cli + * See also clixon_cli2file */ if (autocli_compress(h, ys, &compress) < 0) goto done; diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index ca42233e..a950882e 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -434,7 +434,6 @@ cli_show_config1(clicon_handle h, cbuf *cbxpath = NULL; char *val = NULL; cxobj *xt = NULL; - cxobj *xc; cxobj *xerr; yang_stmt *yspec; char *namespace = NULL; @@ -495,28 +494,26 @@ cli_show_config1(clicon_handle h, /* Print configuration according to format */ switch (format){ case FORMAT_XML: - xc = NULL; /* Dont print xt itself */ - while ((xc = xml_child_each(xt, xc, -1)) != NULL) - cli_xml2file(xc, 0, 1, cligen_output); + if (clixon_xml2file(stdout, xt, 0, 1, cligen_output, 1) < 0) + goto done; break; case FORMAT_JSON: - xml2json_file(stdout, xt, 1, cligen_output, 0); + if (clixon_json2file(stdout, xt, 1, cligen_output, 0) < 0) + goto done; break; case FORMAT_TEXT: - xc = NULL; /* Dont print xt itself */ - while ((xc = xml_child_each(xt, xc, -1)) != NULL) - xml2txt(xc, cligen_output, stdout, 0); /* tree-formed text */ + if (clixon_txt2file(stdout, xt, 0, cligen_output, 1) < 0) + goto done; break; case FORMAT_CLI: - if (xml2cli(h, stdout, xt, prefix, cligen_output, 1) < 0) + if (clixon_cli2file(h, stdout, xt, prefix, cligen_output, 1) < 0) goto done; break; case FORMAT_NETCONF: cligen_output(stdout, "\n", NETCONF_BASE_NAMESPACE, NETCONF_MESSAGE_ID_ATTR); - xc = NULL; /* Dont print xt itself */ - while ((xc = xml_child_each(xt, xc, -1)) != NULL) - cli_xml2file(xc, 2, 1, cligen_output); + if (clixon_xml2file(stdout, xt, 2, 1, cligen_output, 1) < 0) + goto done; cligen_output(stdout, "]]>]]>\n"); break; } @@ -650,7 +647,8 @@ show_conf_xpath(clicon_handle h, if (xpath_vec(xt, nsc, "%s", &xv, &xlen, xpath) < 0) goto done; for (i=0; i 4){ @@ -763,40 +758,28 @@ cli_show_generated(clicon_handle h, } if ((xp = xpath_first(xt, nsc, "%s", xpath)) != NULL){ /* Print configuration according to format */ - ys_keyword = yang_keyword_get(xml_spec(xp)); - if (ys_keyword == Y_LIST) - xp_helper = xml_child_i(xml_parent(xp), i); - else - xp_helper = xp; - switch (format){ case FORMAT_CLI: - if (xml2cli(h, stdout, xp, prefix, cligen_output, 0) < 0) /* cli syntax */ + if (clixon_cli2file(h, stdout, xp, prefix, cligen_output, 0) < 0) /* cli syntax */ goto done; break; case FORMAT_NETCONF: fprintf(stdout, "\n"); - cli_xml2file(xp, 2, 1, fprintf); + if (clixon_xml2file(stdout, xp, 2, 1, fprintf, 0) < 0) + goto done; fprintf(stdout, "]]>]]>\n"); break; case FORMAT_JSON: - xml2json_file(stdout, xp_helper, 1, cligen_output, 1); + if (clixon_json2file(stdout, xp, 1, cligen_output, 1) < 0) // XXX helper? + goto done; break; - default: - for (; i < xml_child_nr(xml_parent(xp)) ; ++i, xp_helper = xml_child_i(xml_parent(xp), i)) { - switch (format){ - case FORMAT_XML: - cli_xml2file(xp_helper, 0, 1, fprintf); - break; - case FORMAT_TEXT: - xml2txt(xp_helper, cligen_output, stdout, 0); /* tree-formed text */ - break; - default: /* see cli_show_config() */ - break; - } - if (ys_keyword != Y_LIST) - break; - } + case FORMAT_TEXT: + if (clixon_txt2file(stdout, xp, 0, cligen_output, 1) < 0) // XXX helper? + goto done; + break; + case FORMAT_XML: + if (clixon_xml2file(stdout, xp, 0, 1, fprintf, 0) < 0) // XXX helper? + goto done; break; } } @@ -828,7 +811,7 @@ cli_show_auto(clicon_handle h, cvec *cvv, cvec *argv) { - return cli_show_generated(h, 0, cvv, argv); + return cli_show_auto1(h, 0, cvv, argv); } /*! Generic show config and state CLIgen callback using generated CLI syntax @@ -845,7 +828,7 @@ cli_show_auto_state(clicon_handle h, cvec *cvv, cvec *argv) { - return cli_show_generated(h, 1, cvv, argv); + return cli_show_auto1(h, 1, cvv, argv); } /*! Show clixon configuration options as loaded @@ -980,17 +963,21 @@ cli_pagination(clicon_handle h, xc = xvec[j]; switch (format){ case FORMAT_XML: - clicon_xml2file_cb(stdout, xc, 0, 1, cligen_output); + if (clixon_xml2file(stdout, xc, 0, 1, cligen_output, 0) < 0) + goto done; break; case FORMAT_JSON: - xml2json_file(stdout, xc, 1, cligen_output, 0); + if (clixon_json2file(stdout, xc, 1, cligen_output, 0) < 0) + goto done; break; case FORMAT_TEXT: - xml2txt(xc, cligen_output, stdout, 0); /* tree-formed text */ + if (clixon_txt2file(stdout, xc, 0, cligen_output, 0) < 0) + goto done; break; case FORMAT_CLI: /* hardcoded to compress and list-keyword = nokey */ - xml2cli(h, stdout, xc, NULL, cligen_output, 0); + if (clixon_cli2file(h, stdout, xc, NULL, cligen_output, 0) < 0) + goto done; break; default: break; @@ -1155,21 +1142,24 @@ xml2cli1(clicon_handle h, * @param[in] f Output FILE (eg stdout) * @param[in] xn XML Parse-tree (to translate) * @param[in] prepend Print this text in front of all commands. - * @param[in] fn Callback to make print function + * @param[in] fn File print function (if NULL, use fprintf) * @param[in] skiptop 0: Include top object 1: Skip top-object, only children, - + * @retval 0 OK + * @retval -1 Error */ int -xml2cli(clicon_handle h, - FILE *f, - cxobj *xn, - char *prepend, - clicon_output_cb *fn, - int skiptop) +clixon_cli2file(clicon_handle h, + FILE *f, + cxobj *xn, + char *prepend, + clicon_output_cb *fn, + int skiptop) { int retval = 1; cxobj *xc; + if (fn == NULL) + fn = fprintf; if (skiptop){ xc = NULL; while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL) diff --git a/apps/cli/clixon_cli_api.h b/apps/cli/clixon_cli_api.h index a270b69b..553dbb04 100644 --- a/apps/cli/clixon_cli_api.h +++ b/apps/cli/clixon_cli_api.h @@ -135,8 +135,7 @@ int cli_help(clicon_handle h, cvec *vars, cvec *argv); /* In cli_show.c */ int expand_dbvar(void *h, char *name, cvec *cvv, cvec *argv, cvec *commands, cvec *helptexts); -int cli_xml2file (cxobj *xn, int level, int prettyprint, clicon_output_cb *fn); -int xml2cli(clicon_handle h, FILE *f, cxobj *xn, char *prepend, clicon_output_cb *fn, int skiptop); +int clixon_cli2file(clicon_handle h, FILE *f, cxobj *xn, char *prepend, clicon_output_cb *fn, int skiptop); /* cli_show.c: CLIgen new vector arg callbacks */ int show_yang(clicon_handle h, cvec *vars, cvec *argv); diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index 435a8f82..afd34278 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -211,7 +211,8 @@ netconf_rpc_message(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0); + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + goto done; if (netconf_output_encap(framing, cbret) < 0) goto done; if (netconf_output(1, cbret, "rpc-error") < 0) @@ -231,7 +232,8 @@ netconf_rpc_message(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0); + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + goto done; if (netconf_output_encap(framing, cbret) < 0) goto done; if (netconf_output(1, cbret, "rpc-error") < 0) @@ -251,7 +253,8 @@ netconf_rpc_message(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0); + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + goto done; if (netconf_output_encap(framing, cbret) < 0) goto done; if (netconf_output(1, cbret, "rpc-error") < 0) @@ -266,7 +269,8 @@ netconf_rpc_message(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - clicon_xml2cbuf(cbret, xml_child_i(xret,0), 0, 0, -1, 0); + if (clixon_xml2cbuf(cbret, xml_child_i(xret,0), 0, 0, -1, 0) < 0) + goto done; if (netconf_output_encap(framing, cbret) < 0) goto done; if (netconf_output(1, cbret, "rpc-reply") < 0) @@ -322,7 +326,8 @@ netconf_input_packet(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0); + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + goto done; if (netconf_output_encap(framing, cbret) < 0) goto done; if (netconf_output(1, cbret, "rpc-error") < 0) @@ -435,7 +440,8 @@ netconf_input_frame(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0); + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + goto done; if (netconf_output_encap(framing, cbret) < 0) goto done; if (netconf_output(1, cbret, "rpc-error") < 0) diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index 95e6dcd7..ff8c0c32 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -481,7 +481,7 @@ netconf_notification_cb(int s, clicon_err(OE_PLUGIN, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xn, 0, 0, -1, 0) < 0) goto done; /* Send it to listening client on stdout */ if (netconf_output_encap(clicon_option_int(h, "netconf-framing"), cb) < 0){ @@ -659,7 +659,7 @@ netconf_application_rpc(clicon_handle h, if (ret > 0 && (ret = xml_yang_validate_add(h, xoutput, &xerr)) < 0) goto done; if (ret == 0){ - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xerr, 0, 0, -1, 0) < 0) goto done; clicon_log(LOG_WARNING, "Errors in output netconf %s", cbuf_get(cbret)); goto ok; diff --git a/apps/restconf/restconf_err.c b/apps/restconf/restconf_err.c index 7cfe18c7..c786db89 100644 --- a/apps/restconf/restconf_err.c +++ b/apps/restconf/restconf_err.c @@ -279,13 +279,13 @@ api_return_err(clicon_handle h, clicon_debug(1, "%s code:%d", __FUNCTION__, code); if (pretty){ cprintf(cb, " \n"); - if (clicon_xml2cbuf(cb, xerr, 2, pretty, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xerr, 2, pretty, -1, 0) < 0) goto done; cprintf(cb, " \r\n"); } else { cprintf(cb, ""); - if (clicon_xml2cbuf(cb, xerr, 2, pretty, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xerr, 2, pretty, -1, 0) < 0) goto done; cprintf(cb, "\r\n"); } @@ -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 (xml2json_cbuf(cb, xerr, pretty, 0) < 0) + if (clixon_json2cbuf(cb, xerr, pretty, 0) < 0) goto done; cprintf(cb, "\n}\r\n"); } else{ cprintf(cb, "{"); cprintf(cb, "\"ietf-restconf:errors\":"); - if (xml2json_cbuf(cb, xerr, pretty, 0) < 0) + if (clixon_json2cbuf(cb, xerr, pretty, 0) < 0) goto done; cprintf(cb, "}\r\n"); } diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 26d99d5d..2b370313 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -537,7 +537,7 @@ api_data_write(clicon_handle h, cprintf(cbx, " autocommit=\"true\""); cprintf(cbx, ">"); cprintf(cbx, "none"); - if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbx, xtop, 0, 0, -1, 0) < 0) goto done; cprintf(cbx, ""); clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path); @@ -782,7 +782,7 @@ api_data_delete(clicon_handle h, cprintf(cbx, " autocommit=\"true\""); cprintf(cbx, ">"); cprintf(cbx, "none"); - if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbx, xtop, 0, 0, -1, 0) < 0) goto done; cprintf(cbx, ""); if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0) diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c index e2c72112..464fde4d 100644 --- a/apps/restconf/restconf_methods_get.c +++ b/apps/restconf/restconf_methods_get.c @@ -225,11 +225,11 @@ api_data_get2(clicon_handle h, if (xpath==NULL || strcmp(xpath,"/")==0){ /* Special case: data root */ switch (media_out){ case YANG_DATA_XML: - if (clicon_xml2cbuf(cbx, xret, 0, pretty, -1, 0) < 0) /* Dont print top object? */ + if (clixon_xml2cbuf(cbx, xret, 0, pretty, -1, 0) < 0) /* Dont print top object? */ goto done; break; case YANG_DATA_JSON: - if (xml2json_cbuf(cbx, xret, pretty, 0) < 0) + if (clixon_json2cbuf(cbx, xret, pretty, 0) < 0) goto done; break; default: @@ -270,7 +270,7 @@ api_data_get2(clicon_handle h, if (namespace && xmlns_set(x, prefix, namespace) < 0) goto done; } - if (clicon_xml2cbuf(cbx, x, 0, pretty, -1, 0) < 0) /* Dont print top object? */ + if (clixon_xml2cbuf(cbx, x, 0, pretty, -1, 0) < 0) /* Dont print top object? */ goto done; } break; @@ -535,7 +535,7 @@ api_data_pagination(clicon_handle h, if (xml_insert(xpr, xp, INS_LAST, NULL, NULL) < 0) goto done; } - if (clicon_xml2cbuf(cbx, xpr, 0, pretty, -1, 0) < 0) /* Dont print top object? */ + if (clixon_xml2cbuf(cbx, xpr, 0, pretty, -1, 0) < 0) /* Dont print top object? */ goto done; break; case YANG_DATA_JSON: diff --git a/apps/restconf/restconf_methods_patch.c b/apps/restconf/restconf_methods_patch.c index f9519e34..33c39d82 100644 --- a/apps/restconf/restconf_methods_patch.c +++ b/apps/restconf/restconf_methods_patch.c @@ -100,9 +100,9 @@ yang_patch_op2int(char *op) } /*! Add square brackets after the surrounding curly brackets in JSON - * Needed, in order to modify the result of xml2json_cbuf() to be valid input + * Needed, in order to modify the result of clixon_json2cbuf() to be valid input * to api_data_post() and api_data_write() - * @param[in] x_simple_patch a cxobj to pass to xml2json_cbuf() + * @param[in] x_simple_patch a cxobj to pass to clixon_json2cbuf() * @retva cbuf With the modified json * @retva NULL Error */ @@ -119,7 +119,8 @@ yang_patch_xml2json_modified_cbuf(cxobj *x_simple_patch) if (json_simple_patch == NULL) return NULL; cb = cbuf_new(); - xml2json_cbuf(cb, x_simple_patch, 0); + if (clixon_json2cbuf(cb, x_simple_patch, 0) < 0) + goto done; // Insert a '[' after the first '{' to get the JSON to match what api_data_post/write() expect json_simple_patch_tmp = cbuf_get(cb); @@ -266,7 +267,8 @@ yang_patch_do_replace(clicon_handle h, } } // Convert the data to json - xml2json_cbuf(json_simple_patch, x_simple_patch, 0); + if (clixon_json2cbuf(json_simple_patch, x_simple_patch, 0) < 0) + goto done; // Send the POST request if (api_data_post(h, req, cbuf_get(simple_patch_request_uri), pi, qvec, cbuf_get(json_simple_patch), pretty, YANG_DATA_JSON, media_out, ds ) < 0) @@ -327,7 +329,7 @@ yang_patch_do_create(clicon_handle h, xml_addsub(x_simple_patch, value_vec_tmp); } } - if (xml2json_cbuf(cb, x_simple_patch, 0) < 0) + if (clixon_json2cbuf(cb, x_simple_patch, 0) < 0) goto done; if (api_data_post(h, req, cbuf_get(simple_patch_request_uri), pi, qvec, @@ -477,7 +479,8 @@ yang_patch_do_merge(clicon_handle h, xml_addsub(x_simple_patch, value_vec_tmp); } cbuf_reset(cb); /* reuse cb */ - xml2json_cbuf(cb, x_simple_patch, 0); + if (clixon_json2cbuf(cb, x_simple_patch, 0) < 0) + goto done; if ((json_simple_patch = yang_patch_xml2json_modified_cbuf(x_simple_patch)) == NULL) goto done; diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c index 3992f5c5..ee4b78f9 100644 --- a/apps/restconf/restconf_methods_post.c +++ b/apps/restconf/restconf_methods_post.c @@ -360,7 +360,7 @@ api_data_post(clicon_handle h, cprintf(cbx, " autocommit=\"true\""); cprintf(cbx, ">"); cprintf(cbx, "none"); - if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbx, xtop, 0, 0, -1, 0) < 0) goto done; cprintf(cbx, ""); clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path); @@ -874,12 +874,12 @@ api_operations_post(clicon_handle h, cbuf_reset(cbret); switch (media_out){ case YANG_DATA_XML: - if (clicon_xml2cbuf(cbret, xoutput, 0, pretty, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xoutput, 0, pretty, -1, 0) < 0) goto done; /* xoutput should now look: 0 */ break; case YANG_DATA_JSON: - if (xml2json_cbuf(cbret, xoutput, pretty, 0) < 0) + if (clixon_json2cbuf(cbret, xoutput, pretty, 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 27221f68..686981b8 100644 --- a/apps/restconf/restconf_root.c +++ b/apps/restconf/restconf_root.c @@ -204,12 +204,12 @@ api_root_restconf_exact(clicon_handle h, switch (media_out){ case YANG_DATA_XML: case YANG_PATCH_XML: - if (clicon_xml2cbuf(cb, xt, 0, pretty, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xt, 0, pretty, -1, 0) < 0) goto done; break; case YANG_DATA_JSON: case YANG_PATCH_JSON: - if (xml2json_cbuf(cb, xt, pretty, 0) < 0) + if (clixon_json2cbuf(cb, xt, pretty, 0) < 0) goto done; break; default: @@ -288,12 +288,12 @@ api_yang_library_version(clicon_handle h, switch (media_out){ case YANG_DATA_XML: case YANG_PATCH_XML: - if (clicon_xml2cbuf(cb, xt, 0, pretty, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xt, 0, pretty, -1, 0) < 0) goto done; break; case YANG_DATA_JSON: case YANG_PATCH_JSON: - if (xml2json_cbuf(cb, xt, pretty, 0) < 0) + if (clixon_json2cbuf(cb, xt, pretty, 0) < 0) goto done; break; default: diff --git a/apps/restconf/restconf_stream_fcgi.c b/apps/restconf/restconf_stream_fcgi.c index 218edb71..45014309 100644 --- a/apps/restconf/restconf_stream_fcgi.c +++ b/apps/restconf/restconf_stream_fcgi.c @@ -254,7 +254,7 @@ restconf_stream_cb(int s, FCGX_FPrintF(r->out, "M#id: %02d:0\r\n", tv.tv_sec); } #endif - if (clicon_xml2cbuf(cb, xn, 0, pretty, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xn, 0, pretty, -1, 0) < 0) goto done; FCGX_FPrintF(r->out, "data: %s\r\n", cbuf_get(cb)); FCGX_FPrintF(r->out, "\r\n"); diff --git a/example/main/example_backend.c b/example/main/example_backend.c index 12f11e2f..289db5a6 100644 --- a/example/main/example_backend.c +++ b/example/main/example_backend.c @@ -331,7 +331,7 @@ example_rpc(clicon_handle h, /* Clicon handle */ if (xmlns_set(x, NULL, namespace) < 0) goto done; } - if (clicon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) + if (clixon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) goto done; } cprintf(cbret, ""); diff --git a/example/main/example_cli.c b/example/main/example_cli.c index 3d086aec..688a8153 100644 --- a/example/main/example_cli.c +++ b/example/main/example_cli.c @@ -74,7 +74,8 @@ mycallback(clicon_handle h, cvec *cvv, cvec *argv) nsc, &xret) < 0) goto done; - clicon_xml2file_cb(stdout, xret, 0, 1, cligen_output); + if (clixon_xml2file(stdout, xret, 0, 1, cligen_output, 0) < 0) + goto done; retval = 0; done: if (nsc) @@ -118,11 +119,12 @@ example_client_rpc(clicon_handle h, goto done; } /* Print result */ - clicon_xml2file_cb(stdout, xml_child_i(xret, 0), 0, 0, cligen_output); + if (clixon_xml2file(stdout, xml_child_i(xret, 0), 0, 0, cligen_output, 0) < 0) + goto done; fprintf(stdout,"\n"); /* pretty-print: - xml2txt(xml_child_i(xret, 0), cligen_output, stdout, 0); + clixon_txt2file(stdout, xml_child_i(xret, 0), 0, cligen_output, 0); */ retval = 0; done: diff --git a/example/main/example_netconf.c b/example/main/example_netconf.c index 1daf10c5..31b5f83b 100644 --- a/example/main/example_netconf.c +++ b/example/main/example_netconf.c @@ -90,7 +90,7 @@ netconf_client_rpc(clicon_handle h, if (xmlns_set(x, NULL, namespace) < 0) goto done; } - if (clicon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) + if (clixon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) goto done; } cprintf(cbret, ""); diff --git a/example/main/example_restconf.c b/example/main/example_restconf.c index 83039c6c..90b1aaa1 100644 --- a/example/main/example_restconf.c +++ b/example/main/example_restconf.c @@ -330,7 +330,7 @@ restconf_client_rpc(clicon_handle h, if (xmlns_set(x, NULL, namespace) < 0) goto done; } - if (clicon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) + if (clixon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) goto done; } cprintf(cbret, ""); diff --git a/lib/clixon/clixon_json.h b/lib/clixon/clixon_json.h index 2f84fa15..31562317 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 xml2json_cbuf(cbuf *cb, cxobj *x, int pretty, int skiptop); +int clixon_json2cbuf(cbuf *cb, cxobj *x, int pretty, int skiptop); int xml2json_cbuf_vec(cbuf *cb, cxobj **vec, size_t veclen, int pretty); -int xml2json_file(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 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 fb2c3599..79778e9c 100644 --- a/lib/clixon/clixon_text_syntax.h +++ b/lib/clixon/clixon_text_syntax.h @@ -39,7 +39,7 @@ /* * Prototypes */ -int xml2txt(cxobj *xn, clicon_output_cb *fn, FILE *f, int level); +int clixon_txt2file(FILE *f, cxobj *xn, int level, clicon_output_cb *fn, int skiptop); 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 af863bab..f2e3323f 100644 --- a/lib/clixon/clixon_xml_io.h +++ b/lib/clixon/clixon_xml_io.h @@ -43,18 +43,15 @@ /* * Prototypes */ -int clicon_xml2file_cb(FILE *f, cxobj *x, int level, int prettyprint, clicon_output_cb *fn); -int clicon_xml2file(FILE *f, cxobj *x, int level, int prettyprint); -int xml_print(FILE *f, cxobj *xn); -int xml_dump(FILE *f, cxobj *x); -int clicon_xml2cbuf(cbuf *cb, cxobj *x, int level, int prettyprint, int32_t depth, int skiptop); -char *clicon_xml2str(cxobj *x); -int xmltree2cbuf(cbuf *cb, cxobj *x, int level); - -int clixon_xml_parse_file(FILE *f, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr); -int clixon_xml_parse_string(const char *str, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr); -int clixon_xml_parse_va(yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr, +int clixon_xml2file(FILE *f, cxobj *xn, int level, int pretty, clicon_output_cb *fn, int skiptop); +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); +int xmltree2cbuf(cbuf *cb, cxobj *x, int level); +int clixon_xml_parse_file(FILE *f, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr); +int clixon_xml_parse_string(const char *str, yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr); +int clixon_xml_parse_va(yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr, const char *format, ...) __attribute__ ((format (printf, 5, 6))); -int clixon_xml_attr_copy(cxobj *xin, cxobj *xout, char *name); +int clixon_xml_attr_copy(cxobj *xin, cxobj *xout, char *name); #endif /* _CLIXON_XML_IO_H_ */ diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 506b6dfa..5061ed84 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -745,7 +745,8 @@ xmldb_get_nocache(clicon_handle h, clicon_log(LOG_NOTICE, "%s: sort verify failed #2", __FUNCTION__); #endif if (clicon_debug_get()>1) - clicon_xml2file(stderr, xt, 0, 1); + if (clixon_xml2file(stderr, xt, 0, 1, fprintf, 0) < 0) + goto done; *xtop = xt; xt = NULL; retval = 1; @@ -916,7 +917,8 @@ xmldb_get_cache(clicon_handle h, * If cache was empty, also update to datastore cache */ if (clicon_debug_get()>1) - clicon_xml2file(stderr, x1t, 0, 1); + if (clixon_xml2file(stderr, x1t, 0, 1, fprintf, 0) < 0) + goto done; *xtop = x1t; retval = 1; done: @@ -1016,8 +1018,9 @@ xmldb_get_zerocopy(clicon_handle h, if (disable_nacm_on_empty(x0t, yspec) < 0) goto done; } - if (clicon_debug_get()>1) - clicon_xml2file(stderr, x0t, 0, 1); + if (clicon_debug_get() > 1) + if (clixon_xml2file(stderr, x0t, 0, 1, fprintf, 0) < 0) + goto done; *xtop = x0t; retval = 1; done: diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 03e08c59..b9ca299f 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -1206,10 +1206,10 @@ xmldb_put(clicon_handle h, } pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY"); if (strcmp(format,"json")==0){ - if (xml2json_file(f, x0, pretty, fprintf, 0) < 0) + if (clixon_json2file(f, x0, pretty, fprintf, 0) < 0) goto done; } - else if (clicon_xml2file(f, x0, 0, pretty) < 0) + else if (clixon_xml2file(f, x0, 0, pretty, fprintf, 0) < 0) goto done; /* Remove modules state after writing to file */ @@ -1264,10 +1264,10 @@ xmldb_dump(clicon_handle h, } pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY"); if (strcmp(format,"json")==0){ - if (xml2json_file(f, xt, pretty, fprintf, 0) < 0) + if (clixon_json2file(f, xt, pretty, fprintf, 0) < 0) goto done; } - else if (clicon_xml2file(f, xt, 0, pretty) < 0) + else if (clixon_xml2file(f, xt, 0, pretty, fprintf, 0) < 0) goto done; retval = 0; done: diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 30b6fc8d..60ba1f62 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -1046,14 +1046,7 @@ xml2json1_cbuf(cbuf *cb, * @retval 0 OK * @retval -1 Error * - * @code - * cbuf *cb; - * cb = cbuf_new(); - * if (xml2json_cbuf(cb, xn, 0, 0) < 0) - * goto err; - * cbuf_free(cb); - * @endcode - * @see clicon_xml2cbuf XML corresponding function + * @see clixon_xml2cbuf XML corresponding function * @see xml2json_cbuf_vec Top symbol is list */ static int @@ -1110,13 +1103,19 @@ xml2json_cbuf1(cbuf *cb, * @param[in] skiptop 0: Include top object 1: Skip top-object, only children, * @retval 0 OK * @retval -1 Error + * @code + * cbuf *cb = cbuf_new(); + * if (xml2json_cbuf(cb, xn, 0, 0, 0) < 0) + * goto err; + * cbuf_free(cb); + * @endcode * @see xml2json_cbuf where the top level object is included */ int -xml2json_cbuf(cbuf *cb, - cxobj *xt, - int pretty, - int skiptop) +clixon_json2cbuf(cbuf *cb, + cxobj *xt, + int pretty, + int skiptop) { int retval = -1; cxobj *xc; @@ -1126,7 +1125,6 @@ xml2json_cbuf(cbuf *cb, while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) if (xml2json_cbuf1(cb, xc, pretty) < 0) goto done; - } else { if (xml2json_cbuf1(cb, xt, pretty) < 0) @@ -1148,7 +1146,7 @@ xml2json_cbuf(cbuf *cb, * @retval -1 Error * @note This only works if the vector is uniform, ie same object name. * Example: --> --> {"b" : null,"c" : null} - * @see xml2json_cbuf + * @see clixon_json2cbuf */ int xml2json_cbuf_vec(cbuf *cb, @@ -1204,8 +1202,9 @@ xml2json_cbuf_vec(cbuf *cb, /*! Translate from xml tree to JSON and print to file using a callback * @param[in] f File to print to - * @param[in] x XML tree to translate from + * @param[in] xn XML tree to translate from * @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, * @retval 0 OK * @retval -1 Error @@ -1213,25 +1212,27 @@ xml2json_cbuf_vec(cbuf *cb, * @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 (xml2json_file(stderr, xn, 0, fprintf, 0) < 0) + * if (clixon_json2file(stderr, xn, 0, fprintf, 0) < 0) * goto err; * @endcode */ int -xml2json_file(FILE *f, - cxobj *x, - int pretty, - clicon_output_cb *fn, - int skiptop) +clixon_json2file(FILE *f, + cxobj *xn, + int pretty, + clicon_output_cb *fn, + int skiptop) { int retval = 1; cbuf *cb = NULL; + if (fn == NULL) + fn = fprintf; if ((cb = cbuf_new()) ==NULL){ clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (xml2json_cbuf(cb, x, pretty, skiptop) < 0) + if (clixon_json2cbuf(cb, xn, pretty, skiptop) < 0) goto done; (*fn)(f, "%s", cbuf_get(cb)); retval = 0; @@ -1250,7 +1251,7 @@ int json_print(FILE *f, cxobj *x) { - return xml2json_file(f, x, 1, fprintf, 0); + return clixon_json2file(f, x, 1, fprintf, 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 4924cacb..9caadd4d 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -186,7 +186,7 @@ netconf_invalid_value(cbuf *cb, if (netconf_invalid_value_xml(&xret, type, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -309,7 +309,7 @@ netconf_missing_attribute(cbuf *cb, if (netconf_missing_attribute_xml(&xret, type, attr, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -338,7 +338,7 @@ netconf_bad_attribute(cbuf *cb, if (netconf_bad_attribute_xml(&xret, type, info, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -521,7 +521,7 @@ netconf_missing_element(cbuf *cb, if (netconf_common_xml(&xret, type, "missing-element", "bad-element", element, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -567,7 +567,7 @@ netconf_bad_element(cbuf *cb, if (netconf_common_xml(&xret, type, "bad-element", "bad-element",element, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -605,7 +605,7 @@ netconf_unknown_element(cbuf *cb, if (netconf_common_xml(&xret, type, "unknown-element", "bad-element", element, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -652,7 +652,7 @@ netconf_unknown_namespace(cbuf *cb, if (netconf_common_xml(&xret, type, "unknown-namespace", "bad-namespace", ns, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -690,7 +690,7 @@ netconf_access_denied(cbuf *cb, if (netconf_access_denied_xml(&xret, type, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -936,7 +936,7 @@ netconf_data_missing(cbuf *cb, if (netconf_data_missing_xml(&xret, missing_choice, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -1085,7 +1085,7 @@ netconf_operation_not_supported(cbuf *cb, if (netconf_operation_not_supported_xml(&xret, type, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -1113,7 +1113,7 @@ netconf_operation_failed(cbuf *cb, if (netconf_operation_failed_xml(&xret, type, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -1201,7 +1201,7 @@ netconf_malformed_message(cbuf *cb, if (netconf_malformed_message_xml(&xret, message) < 0) goto done; - if (clicon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0) goto done; retval = 0; done: @@ -1606,13 +1606,15 @@ netconf_err2cb(cxobj *xerr, cprintf(cberr, "%s ", xml_body(x)); if ((x=xpath_first(xerr, NULL, "//error-info")) != NULL && xml_child_nr(x) > 0){ - clicon_xml2cbuf(cberr, xml_child_i(x, 0), 0, 0, -1, 0); + if (clixon_xml2cbuf(cberr, xml_child_i(x, 0), 0, 0, -1, 0) < 0) + goto done; } if ((x=xpath_first(xerr, NULL, "//error-app-tag"))!=NULL) cprintf(cberr, ": %s ", xml_body(x)); if ((x=xpath_first(xerr, NULL, "//error-path"))!=NULL) cprintf(cberr, ": %s ", xml_body(x)); retval = 0; + done: return retval; } @@ -1996,7 +1998,8 @@ 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){ - clicon_xml2file(stderr, xml_child_i(xt, 0), 0, 0); + if (clixon_xml2file(stderr, xml_child_i(xt, 0), 0, 0, fprintf, 0) < 0) + goto done; fprintf(stderr, "\n"); xml_free(xt); } diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 4408b360..d4222bf3 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -763,7 +763,7 @@ send_msg_notify_xml(clicon_handle h, clicon_err(OE_PLUGIN, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(cb, xev, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xev, 0, 0, -1, 0) < 0) goto done; if (send_msg_notify(s, cbuf_get(cb)) < 0) goto done; diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index f04eff6d..261562f9 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -420,7 +420,7 @@ clicon_rpc_netconf_xml(clicon_handle h, goto done; } rpcname = xml_name(xname); /* Store rpc name and use in yang binding after reply */ - if (clicon_xml2cbuf(cb, xml, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xml, 0, 0, -1, 0) < 0) goto done; if (clicon_rpc_netconf(h, cbuf_get(cb), xret, sp) < 0) goto done; diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index 70826e00..331257a2 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -990,7 +990,7 @@ stream_publish_cb(clicon_handle h, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(d, event, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(d, event, 0, 0, -1, 0) < 0) goto done; if (url_post(cbuf_get(u), /* url+stream */ cbuf_get(d), /* postfields */ diff --git a/lib/src/clixon_text_syntax.c b/lib/src/clixon_text_syntax.c index 68b150ea..93cbac4e 100644 --- a/lib/src/clixon_text_syntax.c +++ b/lib/src/clixon_text_syntax.c @@ -237,20 +237,41 @@ xml2txt1(cxobj *xn, } /*! Translate XML to a "pseudo-code" textual format using a callback - * @param[in] xn XML object to print - * @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] f File to print to + * @param[in] xn XML object to print + * @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, + * @retval 0 OK + * @retval -1 Error */ int -xml2txt(cxobj *xn, - clicon_output_cb *fn, - FILE *f, - int level) +clixon_txt2file(FILE *f, + cxobj *xn, + int level, + clicon_output_cb *fn, + int skiptop) { - int leaflist = 0; + int retval = 1; + cxobj *xc; + int leaflist = 0; - return xml2txt1(xn, fn, f, level, &leaflist); + if (fn == NULL) + fn = fprintf; + if (skiptop){ + xc = NULL; + while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL) + if (xml2txt1(xc, fn, f, level, &leaflist) < 0) + goto done; + } + else { + if (xml2txt1(xn, fn, f, level, &leaflist) < 0) + goto done; + } + retval = 0; + done: + return retval; } /*! Parse a string containing text syntax and return an XML tree diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index 43dddd57..01b92ba8 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -1680,7 +1680,7 @@ rpc_reply_check(clicon_handle h, if (ret == 0){ clicon_debug(1, "%s failure when validating:%s", __FUNCTION__, cbuf_get(cbret)); cbuf_reset(cbret); - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto fail; } @@ -1689,7 +1689,7 @@ rpc_reply_check(clicon_handle h, if (ret == 0){ clicon_debug(1, "%s failure when validating:%s", __FUNCTION__, cbuf_get(cbret)); cbuf_reset(cbret); - if (clicon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cbret, xret, 0, 0, -1, 0) < 0) goto done; goto fail; } diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index 1f06811f..f885a467 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -2353,9 +2353,8 @@ clicon_log_xml(int level, clicon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (clicon_xml2cbuf(cb, x, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, x, 0, 0, -1, 0) < 0) goto done; - /* first round: compute length of debug message */ va_start(args, format); len = vsnprintf(NULL, 0, format, args); diff --git a/lib/src/clixon_xml_io.c b/lib/src/clixon_xml_io.c index 7944a099..6d6e5db3 100644 --- a/lib/src/clixon_xml_io.c +++ b/lib/src/clixon_xml_io.c @@ -94,8 +94,8 @@ * @param[in] level how many spaces to insert before each line * @param[in] prettyprint insert \n and spaces tomake the xml more readable. * @param[in] fn Callback to make print function - * @see clicon_xml2cbuf - * One can use clicon_xml2cbuf to get common code, but using fprintf is + * @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 @@ -113,9 +113,14 @@ xml2file_recurse(FILE *f, int haselement; char *val; char *encstr = NULL; /* xml encoded string */ + int exist = 0; 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; name = xml_name(x); namespace = xml_prefix(x); switch(xml_type(x)){ @@ -195,48 +200,53 @@ xml2file_recurse(FILE *f, /*! 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] prettyprint insert \n and spaces tomake the xml more readable. - * @see clicon_xml2cbuf print to a cbuf string - * @see clicon_xml2cbuf_cb print using a callback + * @param[in] f Output file + * @param[in] xn XML tree + * @param[in] level How many spaces to insert before each line + * @param[in] pretty Insert \n and spaces tomake 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, + * @retval 0 OK + * @retval -1 Error + * @see clixon_xml2cbuf print to a cbuf string */ int -clicon_xml2file(FILE *f, - cxobj *x, - int level, - int prettyprint) +clixon_xml2file(FILE *f, + cxobj *xn, + int level, + int pretty, + clicon_output_cb *fn, + int skiptop) { - return xml2file_recurse(f, x, level, prettyprint, fprintf); -} + int retval = 1; + cxobj *xc; + + if (fn == NULL) + fn = fprintf; + if (skiptop){ + xc = NULL; + while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL) + if (xml2file_recurse(f, xc, level, pretty, fn) < 0) + goto done; + } + else { + if (xml2file_recurse(f, xn, level, pretty, fn) < 0) + goto done; + } + retval = 0; + done: + return retval; -/*! 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] prettyprint insert \n and spaces tomake the xml more readable. - * @see clicon_xml2cbuf - */ -int -clicon_xml2file_cb(FILE *f, - cxobj *x, - int level, - int prettyprint, - clicon_output_cb *fn) -{ - return xml2file_recurse(f, x, level, prettyprint, fn); } /*! Print an XML tree structure to an output stream * - * Uses clicon_xml2file internally + * Uses clixon_xml2file internally * * @param[in] f UNIX output stream * @param[in] xn clicon xml tree - * @see clicon_xml2cbuf - * @see clicon_xml2cbuf_cb print using a callback + * @see clixon_xml2cbuf + * @see clixon_xml2cbuf_cb print using a callback */ int xml_print(FILE *f, @@ -245,6 +255,8 @@ xml_print(FILE *f, return xml2file_recurse(f, x, 0, 1, fprintf); } +/*! Dump cxobj structure with pointers and flags for debugging, internal function + */ static int xml_dump1(FILE *f, cxobj *x, @@ -297,7 +309,7 @@ xml_dump(FILE *f, * @param[in] depth Limit levels of child resources: -1 is all, 0 is none, 1 is node itself */ static int -clicon_xml2cbuf1(cbuf *cb, +clixon_xml2cbuf1(cbuf *cb, cxobj *x, int level, int prettyprint, @@ -347,7 +359,7 @@ clicon_xml2cbuf1(cbuf *cb, while ((xc = xml_child_each(x, xc, -1)) != NULL) switch (xml_type(xc)){ case CX_ATTR: - if (clicon_xml2cbuf1(cb, xc, level+1, prettyprint, -1) < 0) + if (clixon_xml2cbuf1(cb, xc, level+1, prettyprint, -1) < 0) goto done; break; case CX_BODY: @@ -369,7 +381,7 @@ clicon_xml2cbuf1(cbuf *cb, xc = NULL; while ((xc = xml_child_each(x, xc, -1)) != NULL) if (xml_type(xc) != CX_ATTR) - if (clicon_xml2cbuf1(cb, xc, level+1, prettyprint, depth-1) < 0) + if (clixon_xml2cbuf1(cb, xc, level+1, prettyprint, depth-1) < 0) goto done; if (prettyprint && hasbody == 0) cprintf(cb, "%*s", level*XML_INDENT, ""); @@ -396,27 +408,26 @@ clicon_xml2cbuf1(cbuf *cb, /*! Print an XML tree structure to a cligen buffer and encode chars "<>&" * * @param[in,out] cb Cligen buffer to write to - * @param[in] xt Top-level xml object + * @param[in] xn Top-level xml object * @param[in] level Indentation level for prettyprint * @param[in] prettyprint insert \n and spaces tomake the xml more readable. * @param[in] depth Limit levels of child resources: -1: all, 0: none, 1: node itself * @param[in] skiptop 0: Include top object 1: Skip top-object, only children, * @retval 0 OK * @retval -1 Error - * + * Depth is used in NACM * @code - * cbuf *cb; - * cb = cbuf_new(); - * if (clicon_xml2cbuf(cb, xn, 0, 1, -1, 0) < 0) - * goto err; - * fprintf(stderr, "%s", cbuf_get(cb)); - * cbuf_free(cb); + * cbuf *cb = cbuf_new(); + * if (clixon_xml2cbuf(cb, xn, 0, 1, -1, 0) < 0) + * goto err; + * fprintf(stderr, "%s", cbuf_get(cb)); + * cbuf_free(cb); * @endcode - * @see clicon_xml2file + * @see clixon_xml2file */ int -clicon_xml2cbuf(cbuf *cb, - cxobj *xt, +clixon_xml2cbuf(cbuf *cb, + cxobj *xn, int level, int pretty, int32_t depth, @@ -427,12 +438,12 @@ clicon_xml2cbuf(cbuf *cb, if (skiptop){ xc = NULL; - while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) - if (clicon_xml2cbuf1(cb, xc, level, pretty, depth) < 0) + while ((xc = xml_child_each(xn, xc, CX_ELMNT)) != NULL) + if (clixon_xml2cbuf1(cb, xc, level, pretty, depth) < 0) goto done; } else { - if (clicon_xml2cbuf1(cb, xt, level, pretty, depth) < 0) + if (clixon_xml2cbuf1(cb, xn, level, pretty, depth) < 0) goto done; } retval = 0; @@ -440,30 +451,6 @@ clicon_xml2cbuf(cbuf *cb, return retval; } -/*! Return an xml tree as a pretty-printed malloced string. - * @param[in] x XML tree - * @retval str Malloced pretty-printed string (should be free:d after use) - * @retval NULL Error - */ -char * -clicon_xml2str(cxobj *x) -{ - cbuf *cb; - char *str; - - if ((cb = cbuf_new()) == NULL){ - clicon_err(OE_XML, errno, "cbuf_new"); - return NULL; - } - if (clicon_xml2cbuf(cb, x, 0, 1, -1, 0) < 0) - return NULL; - if ((str = strdup(cbuf_get(cb))) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - return NULL; - } - return str; -} - /*! Print actual xml tree datastructures (not xml), mainly for debugging * @param[in,out] cb Cligen buffer to write to * @param[in] xn Clicon xml tree diff --git a/lib/src/clixon_xml_vec.c b/lib/src/clixon_xml_vec.c index f3a09032..d5be0034 100644 --- a/lib/src/clixon_xml_vec.c +++ b/lib/src/clixon_xml_vec.c @@ -368,6 +368,7 @@ clixon_xvec_rm_pos(clixon_xvec *xv, * @param[in] f UNIX output stream * @param[in] xv XML tree vector * @retval 0 OK + * @retval -1 Error */ int clixon_xvec_print(FILE *f, @@ -376,7 +377,8 @@ clixon_xvec_print(FILE *f, int i; for (i=0; ixv_len; i++) - clicon_xml2file(f, xv->xv_vec[i], 0, 1); + if (clixon_xml2file(f, xv->xv_vec[i], 0, 1, fprintf, 0) < 0) + return -1; return 0; } diff --git a/test/test_c++.sh b/test/test_c++.sh index fd84e3d1..d00521b5 100755 --- a/test/test_c++.sh +++ b/test/test_c++.sh @@ -145,7 +145,7 @@ int example_rpc(clicon_handle h, if (xmlns_set(x, NULL, ns) < 0) goto done; } - if (clicon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) + if (clixon_xml2cbuf(cbret, xe, 0, 0, -1, 1) < 0) goto done; } cprintf(cbret, ""); diff --git a/test/test_pagination_expect.exp b/test/test_pagination_expect.exp index 2fca51e7..23c8de9d 100755 --- a/test/test_pagination_expect.exp +++ b/test/test_pagination_expect.exp @@ -19,6 +19,8 @@ set xpath [lindex $argv 1] set line1 [lindex $argv 2] set line2 [lindex $argv 3] +set timeout 15 + spawn clixon_cli -f $cfg send "show pagination xpath $xpath cli\n" diff --git a/util/clixon_util_datastore.c b/util/clixon_util_datastore.c index 81dae81d..b74b96e3 100644 --- a/util/clixon_util_datastore.c +++ b/util/clixon_util_datastore.c @@ -206,7 +206,8 @@ main(int argc, char **argv) xpath = "/"; if (xmldb_get(h, db, NULL, xpath, &xt) < 0) goto done; - clicon_xml2file(stdout, xt, 0, 0); + if (clixon_xml2file(stdout, xt, 0, 0, fprintf, 0) < 0) + goto done; fprintf(stdout, "\n"); if (xt){ xml_free(xt); @@ -229,7 +230,8 @@ main(int argc, char **argv) clicon_err(OE_DB, 0, "xt is NULL"); goto done; } - clicon_xml2file(stdout, xt, 0, 0); + if (clixon_xml2file(stdout, xt, 0, 0, fprintf, 0) < 0) + goto done; if (xt){ xml_free(xt); xt = NULL; diff --git a/util/clixon_util_json.c b/util/clixon_util_json.c index 532147bd..8797d4a1 100644 --- a/util/clixon_util_json.c +++ b/util/clixon_util_json.c @@ -143,10 +143,12 @@ main(int argc, xml_print(stderr, xerr); goto done; } - if (json) - xml2json_cbuf(cb, xt, pretty, 1); /* print json */ - else - clicon_xml2cbuf(cb, xt, 0, pretty, -1, 1); /* print xml */ + if (json){ + if (clixon_json2cbuf(cb, xt, pretty, 1) < 0) + goto done; + } + else if (clixon_xml2cbuf(cb, xt, 0, pretty, -1, 1) < 0) + goto done; fprintf(stdout, "%s", cbuf_get(cb)); fflush(stdout); retval = 0; diff --git a/util/clixon_util_path.c b/util/clixon_util_path.c index 43b89e65..9a8c382f 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); - clicon_xml2file(stdout, xc, 0, 0); + clixon_xml2file(stdout, xc, 0, 0, fprintf, 0); fprintf(stdout, "\n"); fflush(stdout); } diff --git a/util/clixon_util_socket.c b/util/clixon_util_socket.c index 27ec2e01..3c29e834 100644 --- a/util/clixon_util_socket.c +++ b/util/clixon_util_socket.c @@ -167,7 +167,7 @@ main(int argc, fprintf(stderr, "No xml\n"); goto done; } - if (clicon_xml2cbuf(cb, xc, 0, 0, -1, 0) < 0) + if (clixon_xml2cbuf(cb, xc, 0, 0, -1, 0) < 0) goto done; if ((msg = clicon_msg_encode(getpid(), "%s", cbuf_get(cb))) < 0) goto done; diff --git a/util/clixon_util_text_syntax.c b/util/clixon_util_text_syntax.c index 249ec730..c67ef72d 100644 --- a/util/clixon_util_text_syntax.c +++ b/util/clixon_util_text_syntax.c @@ -83,7 +83,6 @@ main(int argc, { int retval = -1; cxobj *xt = NULL; - cxobj *xc; cbuf *cb = cbuf_new(); int c; int logdst = CLICON_LOG_STDERR; @@ -147,14 +146,14 @@ main(int argc, xml_print(stderr, xerr); goto done; } - xc = NULL; - while ((xc = xml_child_each(xt, xc, -1)) != NULL){ - if (text_syntax_output) - xml2txt(xc, fprintf, stdout, 0); - else{ - clicon_xml2cbuf(cb, xc, 0, 1, -1); /* print xml */ - fprintf(stdout, "%s", cbuf_get(cb)); - } + if (text_syntax_output){ + if (clixon_txt2file(stdout, xt, 0, fprintf, 1) < 0) + goto done; + } + else{ + if (clixon_xml2cbuf(cb, xt, 0, 1, -1, 1) < 0) + goto done; + fprintf(stdout, "%s", cbuf_get(cb)); } fflush(stdout); retval = 0; diff --git a/util/clixon_util_xml.c b/util/clixon_util_xml.c index 6ecf27c4..65e68855 100644 --- a/util/clixon_util_xml.c +++ b/util/clixon_util_xml.c @@ -334,16 +334,15 @@ main(int argc, /* 4. Output data (xml/json/text) */ if (output){ if (textout){ - xc = NULL; - while ((xc = xml_child_each(xt, xc, -1)) != NULL){ - if (xml2txt(xc, fprintf, stdout, 0) < 0) - goto done; - } + if (clixon_txt2file(stdout, xt, 0, fprintf, 1) < 0) + goto done; } - else if (jsonout) - xml2json_cbuf(cb, xt, pretty, 1); /* print json */ - else - clicon_xml2cbuf(cb, xt, 0, pretty, -1, 1); /* print xml */ + else if (jsonout){ + if (clixon_json2cbuf(cb, xt, pretty, 1) < 0) + goto done; + } + else if (clixon_xml2cbuf(cb, xt, 0, pretty, -1, 1) < 0) + goto done; fprintf(stdout, "%s", cbuf_get(cb)); fflush(stdout); } diff --git a/util/clixon_util_xml_mod.c b/util/clixon_util_xml_mod.c index 5656f6e2..a009c99f 100644 --- a/util/clixon_util_xml_mod.c +++ b/util/clixon_util_xml_mod.c @@ -281,10 +281,14 @@ main(int argc, char **argv) } if (sort) xml_sort_recurse(xb); - if (strcmp(xml_name(xb),"top")==0) - clicon_xml2file(stdout, xml_child_i_type(xb, 0, CX_ELMNT), 0, 0); - else - clicon_xml2file(stdout, xb, 0, 0); + if (strcmp(xml_name(xb),"top")==0){ + if (clixon_xml2file(stdout, xb, 0, 0, fprintf, 1) < 0) + goto done; + } + else{ + if (clixon_xml2file(stdout, xb, 0, 0, fprintf, 0) < 0) + goto done; + } fprintf(stdout, "\n"); retval = 0; done: diff --git a/util/clixon_util_xpath.c b/util/clixon_util_xpath.c index 2580d431..6d001114 100644 --- a/util/clixon_util_xpath.c +++ b/util/clixon_util_xpath.c @@ -91,14 +91,16 @@ static int ctx_print2(cbuf *cb, xp_ctx *xc) { - int i; + int retval = -1; + int i; cprintf(cb, "%s:", (char*)clicon_int2str(ctxmap, xc->xc_type)); switch (xc->xc_type){ case XT_NODESET: for (i=0; ixc_size; i++){ cprintf(cb, "%d:", i); - clicon_xml2cbuf(cb, xc->xc_nodeset[i], 0, 0, -1, 0); + if (clixon_xml2cbuf(cb, xc->xc_nodeset[i], 0, 0, -1, 0) < 0) + goto done; } break; case XT_BOOL: @@ -111,7 +113,9 @@ ctx_print2(cbuf *cb, cprintf(cb, "%s", xc->xc_string); break; } - return 0; + retval = 0; + done: + return retval; } int