Reverted some of the nsc xpath API changes. In the revert, xpath_first() and xpath_vec() retain their old syntax with nsc==NULL.
The reason is to be conservative with the API. However, less used functions, such as xpath_vec_bool(), xpath_vec_ctx() and xpath_vec_flag() are changed with a new `nsc`parameter, which should be set to NULL in most cases.
This commit is contained in:
parent
89f751357d
commit
40d5b99d3b
32 changed files with 391 additions and 266 deletions
|
|
@ -116,20 +116,39 @@ char* xpath_tree_int2str(int nodetype);
|
|||
int xpath_tree_print(cbuf *cb, xpath_tree *xs);
|
||||
int xpath_tree_free(xpath_tree *xs);
|
||||
int xpath_parse(cvec *nsc, char *xpath, xpath_tree **xptree);
|
||||
int xpath_vec_ctx(cxobj *xcur, cvec *nsc, char *xpath, xp_ctx **xrp);
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int xpath_vec(cxobj *xcur, cvec *nsc, char *format, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 6)));
|
||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *format, uint16_t flags,
|
||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *xpformat, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *xpformat, uint16_t flags,
|
||||
cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 7)));
|
||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
#else
|
||||
cxobj *xpath_first(cxobj *xcur, cvec *nsc, char *format, ...);
|
||||
int xpath_vec(cxobj *xcur, cvec *nsc, char *format, cxobj ***vec, size_t *veclen, ...);
|
||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *format, uint16_t flags,
|
||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *xpformat, ...);
|
||||
int xpath_vec_flag(cxobj *xcur, cvec *nsc, char *xpformat, uint16_t flags,
|
||||
cxobj ***vec, size_t *veclen, ...);
|
||||
int xpath_vec_bool(cxobj *xcur, cvec *nsc, char *format, ...);
|
||||
#endif
|
||||
int xpath_vec_ctx(cxobj *xcur, cvec *nsc, char *xpath, xp_ctx **xrp);
|
||||
|
||||
/* Functions with explicit namespace context (nsc) set. If you do not need
|
||||
* explicit namespace contexts (most do not) consider using the API functions
|
||||
* below without nsc set.
|
||||
* If you do not know what a namespace context is, see README.md#xml-and-xpath
|
||||
*/
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
cxobj *xpath_first_nsc(cxobj *xcur, cvec *nsc, char *xpformat, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int xpath_vec_nsc(cxobj *xcur, cvec *nsc, char *xpformat, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 3, 6)));
|
||||
#else
|
||||
cxobj *xpath_first_nsc(cxobj *xcur, cvec *nsc, char *xpformat, ...);
|
||||
int xpath_vec_nsc(cxobj *xcur, cvec *nsc, char *xpformat, cxobj ***vec, size_t *veclen, ...);
|
||||
#endif
|
||||
|
||||
/* Functions with nsc == NULL (implicit xpath context). */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
cxobj *xpath_first(cxobj *xcur, char *xpformat, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
int xpath_vec(cxobj *xcur, char *xpformat, cxobj ***vec, size_t *veclen, ...) __attribute__ ((format (printf, 2, 5)));
|
||||
#else
|
||||
cxobj *xpath_first(cxobj *xcur, char *xpformat, ...);
|
||||
int xpath_vec(cxobj *xcur, char *xpformat, cxobj ***vec, size_t *veclen, ...);
|
||||
#endif
|
||||
|
||||
#endif /* _CLIXON_XPATH_H */
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ text_read_modstate(clicon_handle h,
|
|||
if ((name = xml_find_body(xm, "name")) == NULL)
|
||||
continue;
|
||||
/* 3a) There is no such module in the system */
|
||||
if ((xs = xpath_first(xmcache, NULL, "module[name=\"%s\"]", name)) == NULL){
|
||||
if ((xs = xpath_first(xmcache, "module[name=\"%s\"]", name)) == NULL){
|
||||
// fprintf(stderr, "%s: Module %s: not in system\n", __FUNCTION__, name);
|
||||
if ((xm2 = xml_dup(xm)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -420,7 +420,7 @@ xmldb_get_nocache(clicon_handle h,
|
|||
goto done;
|
||||
/* Here xt looks like: <config>...</config> */
|
||||
/* Given the xpath, return a vector of matches in xvec */
|
||||
if (xpath_vec(xt, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
if (xpath_vec_nsc(xt, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
|
||||
/* If vectors are specified then mark the nodes found with all ancestors
|
||||
|
|
@ -526,7 +526,7 @@ xmldb_get_cache(clicon_handle h,
|
|||
*/
|
||||
|
||||
/* Here xt looks like: <config>...</config> */
|
||||
if (xpath_vec(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
if (xpath_vec_nsc(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
|
||||
/* Make new tree by copying top-of-tree from x0t to x1t */
|
||||
|
|
@ -615,7 +615,7 @@ xmldb_get_zerocopy(clicon_handle h,
|
|||
else
|
||||
x0t = de->de_xml;
|
||||
/* Here xt looks like: <config>...</config> */
|
||||
if (xpath_vec(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
if (xpath_vec_nsc(x0t, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
/* Iterate through the match vector
|
||||
* For every node found in x0, mark the tree up to t1
|
||||
|
|
|
|||
|
|
@ -662,7 +662,7 @@ xmldb_put(clicon_handle h,
|
|||
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:yang:ietf-netconf-acm")) == NULL)
|
||||
goto done;
|
||||
if (xnacm0 != NULL &&
|
||||
(xnacm = xpath_first(xnacm0, nsc, "nacm")) != NULL){
|
||||
(xnacm = xpath_first_nsc(xnacm0, nsc, "nacm")) != NULL){
|
||||
/* Pre-NACM access step, if permit, then dont do any nacm checks in
|
||||
* text_modify_* below */
|
||||
if ((permit = nacm_access(mode, xnacm, username)) < 0)
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ nacm_rpc(char *rpc,
|
|||
goto step10;
|
||||
|
||||
/* User's group */
|
||||
if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||
if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||
goto done;
|
||||
/* 5. If no groups are found, continue with step 10. */
|
||||
if (glen == 0)
|
||||
|
|
@ -223,14 +223,14 @@ nacm_rpc(char *rpc,
|
|||
configuration. If a rule-list's "group" leaf-list does not
|
||||
match any of the user's groups, proceed to the next rule-list
|
||||
entry. */
|
||||
if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||
if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||
goto done;
|
||||
for (i=0; i<rlistlen; i++){
|
||||
rlist = rlistvec[i];
|
||||
/* Loop through user's group to find match in this rule-list */
|
||||
for (j=0; j<glen; j++){
|
||||
gname = xml_find_body(gvec[j], "name");
|
||||
if (xpath_first(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||
if (xpath_first_nsc(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||
break; /* found */
|
||||
}
|
||||
if (j==glen) /* not found */
|
||||
|
|
@ -239,7 +239,7 @@ nacm_rpc(char *rpc,
|
|||
until a rule that matches the requested access operation is
|
||||
found.
|
||||
*/
|
||||
if (xpath_vec(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||
if (xpath_vec_nsc(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||
goto done;
|
||||
for (j=0; j<rlen; j++){
|
||||
xrule = rvec[j];
|
||||
|
|
@ -390,7 +390,7 @@ nacm_rule_datanode(cxobj *xt,
|
|||
}
|
||||
/* Here module is matched, now check for path if any NYI */
|
||||
if (path){
|
||||
if ((xpath = xpath_first(xt, nsc, "%s", path)) == NULL)
|
||||
if ((xpath = xpath_first_nsc(xt, nsc, "%s", path)) == NULL)
|
||||
goto nomatch;
|
||||
/* The requested node xr is the node specified by the path or is a
|
||||
* descendant node of the path:
|
||||
|
|
@ -447,7 +447,7 @@ nacm_data_read_xr(cxobj *xt,
|
|||
/* Loop through user's group to find match in this rule-list */
|
||||
for (j=0; j<glen; j++){
|
||||
gname = xml_find_body(gvec[j], "name");
|
||||
if (xpath_first(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||
if (xpath_first_nsc(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||
break; /* found */
|
||||
}
|
||||
if (j==glen) /* not found */
|
||||
|
|
@ -456,7 +456,7 @@ nacm_data_read_xr(cxobj *xt,
|
|||
until a rule that matches the requested access operation is
|
||||
found. (see 6 sub rules in nacm_rule_datanode
|
||||
*/
|
||||
if (xpath_vec(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||
if (xpath_vec_nsc(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||
goto done;
|
||||
for (j=0; j<rlen; j++){ /* Loop through rules */
|
||||
xrule = rvec[j];
|
||||
|
|
@ -588,7 +588,7 @@ nacm_datanode_read(cxobj *xt,
|
|||
if (username == NULL)
|
||||
goto step9;
|
||||
/* User's group */
|
||||
if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||
if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||
goto done;
|
||||
/* 4. If no groups are found (glen=0), continue and check read-default
|
||||
in step 11. */
|
||||
|
|
@ -596,7 +596,7 @@ nacm_datanode_read(cxobj *xt,
|
|||
configuration. If a rule-list's "group" leaf-list does not
|
||||
match any of the user's groups, proceed to the next rule-list
|
||||
entry. */
|
||||
if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||
if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||
goto done;
|
||||
/* read-default has default permit so should never be NULL */
|
||||
if ((read_default = xml_find_body(xnacm, "read-default")) == NULL){
|
||||
|
|
@ -713,7 +713,7 @@ nacm_datanode_write(cxobj *xt,
|
|||
if (username == NULL)
|
||||
goto step9;
|
||||
/* User's group */
|
||||
if (xpath_vec(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||
if (xpath_vec_nsc(xnacm, nsc, "groups/group[user-name='%s']", &gvec, &glen, username) < 0)
|
||||
goto done;
|
||||
/* 4. If no groups are found, continue with step 9. */
|
||||
if (glen == 0)
|
||||
|
|
@ -722,19 +722,19 @@ nacm_datanode_write(cxobj *xt,
|
|||
configuration. If a rule-list's "group" leaf-list does not
|
||||
match any of the user's groups, proceed to the next rule-list
|
||||
entry. */
|
||||
if (xpath_vec(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||
if (xpath_vec_nsc(xnacm, nsc, "rule-list", &rlistvec, &rlistlen) < 0)
|
||||
goto done;
|
||||
for (i=0; i<rlistlen; i++){
|
||||
rlist = rlistvec[i];
|
||||
/* Loop through user's group to find match in this rule-list */
|
||||
for (j=0; j<glen; j++){
|
||||
gname = xml_find_body(gvec[j], "name");
|
||||
if (xpath_first(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||
if (xpath_first_nsc(rlist, nsc, ".[group='%s']", gname)!=NULL)
|
||||
break; /* found */
|
||||
}
|
||||
if (j==glen) /* not found */
|
||||
continue;
|
||||
if (xpath_vec(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||
if (xpath_vec_nsc(rlist, nsc, "rule", &rvec, &rlen) < 0)
|
||||
goto done;
|
||||
/* 6. For each rule-list entry found, process all rules, in order,
|
||||
until a rule that matches the requested access operation is
|
||||
|
|
@ -862,7 +862,7 @@ nacm_access(char *mode,
|
|||
* RFC8341 3.4 */
|
||||
/* 1. If the "enable-nacm" leaf is set to "false", then the protocol
|
||||
operation is permitted. */
|
||||
if ((x = xpath_first(xnacm, nsc, "enable-nacm")) == NULL)
|
||||
if ((x = xpath_first_nsc(xnacm, nsc, "enable-nacm")) == NULL)
|
||||
goto permit;
|
||||
enabled = xml_body(x);
|
||||
if (strcmp(enabled, "true") != 0)
|
||||
|
|
@ -937,7 +937,7 @@ nacm_access_pre(clicon_handle h,
|
|||
if (xnacm0 == NULL)
|
||||
goto permit;
|
||||
/* If config does not exist then the operation is permitted(?) */
|
||||
if ((xnacm = xpath_first(xnacm0, nsc, "nacm")) == NULL)
|
||||
if ((xnacm = xpath_first_nsc(xnacm0, nsc, "nacm")) == NULL)
|
||||
goto permit;
|
||||
if (xml_rootchild_node(xnacm0, xnacm) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -1303,13 +1303,13 @@ netconf_err2cb(cxobj *xerr,
|
|||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if ((x=xpath_first(xerr, NULL, "error-type"))!=NULL)
|
||||
if ((x=xpath_first(xerr, "error-type"))!=NULL)
|
||||
cprintf(cb, "%s ", xml_body(x));
|
||||
if ((x=xpath_first(xerr, NULL, "error-tag"))!=NULL)
|
||||
if ((x=xpath_first(xerr, "error-tag"))!=NULL)
|
||||
cprintf(cb, "%s ", xml_body(x));
|
||||
if ((x=xpath_first(xerr, NULL, "error-message"))!=NULL)
|
||||
if ((x=xpath_first(xerr, "error-message"))!=NULL)
|
||||
cprintf(cb, "%s ", xml_body(x));
|
||||
if ((x=xpath_first(xerr, NULL, "error-info"))!=NULL)
|
||||
if ((x=xpath_first(xerr, "error-info"))!=NULL)
|
||||
clicon_xml2cbuf(cb, xml_child_i(x,0), 0, 0);
|
||||
*cberr = cb;
|
||||
retval = 0;
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ parse_configfile(clicon_handle h,
|
|||
/* Hard-coded config for < 3.10 and clixon-config for >= 3.10 */
|
||||
if ((nsc = xml_nsctx_init(NULL, CLIXON_CONF_NS)) == NULL)
|
||||
goto done;
|
||||
if ((xc = xpath_first(xt, nsc, "clixon-config")) == NULL){
|
||||
clicon_err(OE_CFG, 0, "Config file %s: Lacks top-level \"clixon-config\" element\nClixon config files should begin with: <clixon-config xmlns=\"%s\" (See Changelog in Clixon 3.10)>", filename, CLIXON_CONF_NS);
|
||||
if ((xc = xpath_first_nsc(xt, nsc, "clixon-config")) == NULL){
|
||||
clicon_err(OE_CFG, 0, "Config file %s: Lacks top-level \"clixon-config\" element\nClixon config files should begin with: <clixon-config xmlns=\"%s\">", filename, CLIXON_CONF_NS);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -362,7 +362,6 @@ clicon_options_main(clicon_handle h,
|
|||
goto done;
|
||||
if (xml_spec(xconfig) == NULL){
|
||||
clicon_err(OE_CFG, 0, "Config file %s: did not find corresponding Yang specification\nHint: File does not begin with: <clixon-config xmlns=\"%s\"> or clixon-config.yang not found?", configfile, CLIXON_CONF_NS);
|
||||
|
||||
goto done;
|
||||
}
|
||||
/* Set clixon_conf pointer to handle */
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ clicon_rpc_generate_error(char *prefix,
|
|||
* cxobj *xt = NULL;
|
||||
* if (clicon_rpc_get_config(h, "running", "/hello/world", "urn:example:hello", &xt) < 0)
|
||||
* err;
|
||||
* if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
||||
* if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||
* clicon_rpc_generate_error("", xerr);
|
||||
* err;
|
||||
* }
|
||||
|
|
@ -306,9 +306,9 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
/* Send xml error back: first check error, then ok */
|
||||
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
|
||||
if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
|
||||
xd = xml_parent(xd); /* point to rpc-reply */
|
||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL)
|
||||
else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
|
||||
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
if (xt){
|
||||
|
|
@ -369,7 +369,7 @@ clicon_rpc_edit_config(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Editing configuration", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -415,7 +415,7 @@ clicon_rpc_copy_config(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Copying configuration", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -454,7 +454,7 @@ clicon_rpc_delete_config(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Deleting configuration", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -489,7 +489,7 @@ clicon_rpc_lock(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Locking configuration", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -523,7 +523,7 @@ clicon_rpc_unlock(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Configuration unlock", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -550,7 +550,7 @@ clicon_rpc_unlock(clicon_handle h,
|
|||
* cxobj *xt = NULL;
|
||||
* if (clicon_rpc_get(h, "/hello/world", "urn:example:hello", &xt) < 0)
|
||||
* err;
|
||||
* if ((xerr = xpath_first(xt, NULL, "/rpc-error")) != NULL){
|
||||
* if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||
* clicon_rpc_generate_error(xerr);
|
||||
* err;
|
||||
* }
|
||||
|
|
@ -593,9 +593,9 @@ clicon_rpc_get(clicon_handle h,
|
|||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
/* Send xml error back: first check error, then ok */
|
||||
if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL)
|
||||
if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
|
||||
xd = xml_parent(xd); /* point to rpc-reply */
|
||||
else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL)
|
||||
else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
|
||||
if ((xd = xml_new("data", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
if (xt){
|
||||
|
|
@ -634,7 +634,7 @@ clicon_rpc_close_session(clicon_handle h)
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Close session", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -669,7 +669,7 @@ clicon_rpc_kill_session(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Kill session", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -703,7 +703,7 @@ clicon_rpc_validate(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error(CLIXON_ERRSTR_VALIDATE_FAILED, xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -735,7 +735,7 @@ clicon_rpc_commit(clicon_handle h)
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error(CLIXON_ERRSTR_COMMIT_FAILED, xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -767,7 +767,7 @@ clicon_rpc_discard_changes(clicon_handle h)
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Discard changes", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -812,7 +812,7 @@ clicon_rpc_create_subscription(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, s0) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Create subscription", xerr);
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -847,11 +847,11 @@ clicon_rpc_debug(clicon_handle h,
|
|||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){
|
||||
if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Debug",xerr);
|
||||
goto done;
|
||||
}
|
||||
if (xpath_first(xret, NULL, "//rpc-reply/ok") == NULL){
|
||||
if (xpath_first(xret, "//rpc-reply/ok") == NULL){
|
||||
clicon_err(OE_XML, 0, "rpc error"); /* XXX extract info from rpc-error */
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ stream_notify1(clicon_handle h,
|
|||
else{ /* xpath match */
|
||||
if (ss->ss_xpath == NULL ||
|
||||
strlen(ss->ss_xpath)==0 ||
|
||||
xpath_first(xevent, NULL, "%s", ss->ss_xpath) != NULL)
|
||||
xpath_first(xevent, "%s", ss->ss_xpath) != NULL)
|
||||
if ((*ss->ss_fn)(h, 0, xevent, ss->ss_arg) < 0)
|
||||
goto done;
|
||||
ss = NEXTQ(struct stream_subscription *, ss);
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ changelog_move(clicon_handle h,
|
|||
int retval = -1;
|
||||
cxobj *xp; /* destination parent node */
|
||||
|
||||
if ((xp = xpath_first(xt, nsc, "%s", dst)) == NULL){
|
||||
if ((xp = xpath_first_nsc(xt, nsc, "%s", dst)) == NULL){
|
||||
clicon_err(OE_XML, 0, "path required");
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -253,7 +253,7 @@ changelog_op(clicon_handle h,
|
|||
if ((wxpath = xml_find_body(xi, "where")) == NULL)
|
||||
goto ok;
|
||||
/* Get vector of target nodes meeting the where requirement */
|
||||
if (xpath_vec(xt, nsc, "%s", &wvec, &wlen, wxpath) < 0)
|
||||
if (xpath_vec_nsc(xt, nsc, "%s", &wvec, &wlen, wxpath) < 0)
|
||||
goto done;
|
||||
for (i=0; i<wlen; i++){
|
||||
xw = wvec[i];
|
||||
|
|
@ -328,7 +328,7 @@ changelog_iterate(clicon_handle h,
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
if (xpath_vec(xch, NULL, "step", &vec, &veclen) < 0)
|
||||
if (xpath_vec(xch, "step", &vec, &veclen) < 0)
|
||||
goto done;
|
||||
/* Iterate through changelog items */
|
||||
for (i=0; i<veclen; i++){
|
||||
|
|
@ -392,7 +392,7 @@ xml_changelog_upgrade(clicon_handle h,
|
|||
* - find all changelogs in the interval: [from, to]
|
||||
* - note it t=0 then no changelog is applied
|
||||
*/
|
||||
if (xpath_vec(xchlog, NULL, "changelog[namespace=\"%s\"]",
|
||||
if (xpath_vec(xchlog, "changelog[namespace=\"%s\"]",
|
||||
&vec, &veclen, namespace) < 0)
|
||||
goto done;
|
||||
/* Get all changelogs in the interval [from,to]*/
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ validate_leafref(cxobj *xt,
|
|||
/* XXX see comment above regarding typeref or not */
|
||||
if (xml_nsctx_yang(ytype, &nsc) < 0)
|
||||
goto done;
|
||||
if (xpath_vec(xt, nsc, "%s", &xvec, &xlen, yang_argument_get(ypath)) < 0)
|
||||
if (xpath_vec_nsc(xt, nsc, "%s", &xvec, &xlen, yang_argument_get(ypath)) < 0)
|
||||
goto done;
|
||||
for (i = 0; i < xlen; i++) {
|
||||
x = xvec[i];
|
||||
|
|
@ -2781,7 +2781,7 @@ xml2xpath(cxobj *x,
|
|||
xt = xml_parent(xt);
|
||||
xcp = xml_parent(xt);
|
||||
xml_parent_set(xt, NULL);
|
||||
x2 = xpath_first(xt, NULL, "%s", xpath); /* +1: skip first / */
|
||||
x2 = xpath_first(xt, "%s", xpath); /* +1: skip first / */
|
||||
xml_parent_set(xt, xcp);
|
||||
assert(x2 && x==x2);
|
||||
if (x==x2)
|
||||
|
|
|
|||
|
|
@ -183,17 +183,17 @@ xpath_tree_free(xpath_tree *xs)
|
|||
/*! Given XML tree and xpath, parse xpath, eval it and return xpath context,
|
||||
* This is a raw form of xpath where you can do type conversion, etc,
|
||||
* not just a nodeset.
|
||||
* @param[in] nsc XML Namespace context
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpath String with XPATH 1.0 syntax
|
||||
* @param[out] xptree Xpath-tree, parsed, structured XPATH, free:xpath_tree_free
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @code
|
||||
* xp_ctx *xc = NULL;
|
||||
* if (xpath_vec_ctx(x, NULL, xpath, &xc) < 0)
|
||||
* xpath_tree *xpt = NULL;
|
||||
* if (xpath_parse(NULL, xpath, &xpt) < 0)
|
||||
* err;
|
||||
* if (xc)
|
||||
* ctx_free(xc);
|
||||
* if (xpt)
|
||||
* xptree_free(xpt);
|
||||
* @endcode
|
||||
* @see xpath_tree_free
|
||||
*/
|
||||
|
|
@ -238,7 +238,7 @@ xpath_parse(cvec *nsc,
|
|||
* This is a raw form of xpath where you can do type conversion of the return
|
||||
* value, etc, not just a nodeset.
|
||||
* @param[in] xcur XML-tree where to search
|
||||
* @param[in] nsc XML Namespace context
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpath String with XPATH 1.0 syntax
|
||||
* @param[out] xrp Return XPATH context
|
||||
* @retval 0 OK
|
||||
|
|
@ -278,35 +278,33 @@ xpath_vec_ctx(cxobj *xcur,
|
|||
done:
|
||||
if (xptree)
|
||||
xpath_tree_free(xptree);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Xpath nodeset function where only the first matching entry is returned
|
||||
* args:
|
||||
*
|
||||
* @param[in] xcur XML tree where to search
|
||||
* @param[in] nsc XML Namespace context
|
||||
* @param[in] format string with XPATH syntax
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @retval xml-tree XML tree of first match
|
||||
* @retval NULL Error or not found
|
||||
*
|
||||
* @code
|
||||
* cxobj *x;
|
||||
* cvec *nsc; // namespace context
|
||||
* if ((x = xpath_first(xtop, nsc, "//symbol/foo")) != NULL) {
|
||||
* if ((x = xpath_first_nsc(xtop, nsc, "//symbol/foo")) != NULL) {
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
* @note the returned pointer points into the original tree so should not be freed fter use.
|
||||
* @note the returned pointer points into the original tree so should not be freed after use.
|
||||
* @note return value does not see difference between error and not found
|
||||
* @see also xpath_vec.
|
||||
* @experimental
|
||||
*/
|
||||
cxobj *
|
||||
xpath_first(cxobj *xcur,
|
||||
cvec *nsc,
|
||||
char *format,
|
||||
...)
|
||||
xpath_first_nsc(cxobj *xcur,
|
||||
cvec *nsc,
|
||||
char *xpformat,
|
||||
...)
|
||||
{
|
||||
cxobj *cx = NULL;
|
||||
va_list ap;
|
||||
|
|
@ -314,8 +312,8 @@ xpath_first(cxobj *xcur,
|
|||
char *xpath = NULL;
|
||||
xp_ctx *xr = NULL;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vsnprintf(NULL, 0, format, ap);
|
||||
va_start(ap, xpformat);
|
||||
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||
va_end(ap);
|
||||
/* allocate a message string exactly fitting the message length */
|
||||
if ((xpath = malloc(len+1)) == NULL){
|
||||
|
|
@ -323,8 +321,8 @@ xpath_first(cxobj *xcur,
|
|||
goto done;
|
||||
}
|
||||
/* second round: compute write message from reason and args */
|
||||
va_start(ap, format);
|
||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
||||
va_start(ap, xpformat);
|
||||
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||
va_end(ap);
|
||||
goto done;
|
||||
|
|
@ -342,20 +340,77 @@ xpath_first(cxobj *xcur,
|
|||
return cx;
|
||||
}
|
||||
|
||||
/*! Xpath nodeset function where only the first matching entry is returned
|
||||
*
|
||||
* @param[in] xcur XML tree where to search
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @retval xml-tree XML tree of first match
|
||||
* @retval NULL Error or not found
|
||||
*
|
||||
* @code
|
||||
* cxobj *x;
|
||||
* if ((x = xpath_first(xtop, "//symbol/foo")) != NULL) {
|
||||
* ...
|
||||
* }
|
||||
* @endcode
|
||||
* @note the returned pointer points into the original tree so should not be freed after use.
|
||||
* @note return value does not see difference between error and not found
|
||||
* @see also xpath_vec.
|
||||
* @see xpath_first_nsc which is more generic with namespace context
|
||||
*/
|
||||
cxobj *
|
||||
xpath_first(cxobj *xcur,
|
||||
char *xpformat,
|
||||
...)
|
||||
{
|
||||
cxobj *cx = NULL;
|
||||
va_list ap;
|
||||
size_t len;
|
||||
char *xpath = NULL;
|
||||
xp_ctx *xr = NULL;
|
||||
|
||||
va_start(ap, xpformat);
|
||||
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||
va_end(ap);
|
||||
/* allocate a message string exactly fitting the message length */
|
||||
if ((xpath = malloc(len+1)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
/* second round: compute write message from reason and args */
|
||||
va_start(ap, xpformat);
|
||||
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||
va_end(ap);
|
||||
goto done;
|
||||
}
|
||||
va_end(ap);
|
||||
if (xpath_vec_ctx(xcur, NULL, xpath, &xr) < 0)
|
||||
goto done;
|
||||
if (xr && xr->xc_type == XT_NODESET && xr->xc_size)
|
||||
cx = xr->xc_nodeset[0];
|
||||
done:
|
||||
if (xr)
|
||||
ctx_free(xr);
|
||||
if (xpath)
|
||||
free(xpath);
|
||||
return cx;
|
||||
}
|
||||
|
||||
/*! Given XML tree and xpath, returns nodeset as xml node vector
|
||||
* If result is not nodeset, return empty nodeset
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] format stdarg string with XPATH 1.0 syntax
|
||||
* @param[in] nsc XML Namespace context for XPATH
|
||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||
* @param[out] veclen returns length of vector in return value
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||
* @param[out] veclen returns length of vector in return value
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @code
|
||||
* cvec *nsc; // namespace context
|
||||
* cxobj **vec;
|
||||
* size_t veclen;
|
||||
* if (xpath_vec(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0)
|
||||
* if (xpath_vec_nsc(xcur, nsc, "//symbol/foo", &vec, &veclen) < 0)
|
||||
* goto err;
|
||||
* for (i=0; i<veclen; i++){
|
||||
* xn = vec[i];
|
||||
|
|
@ -363,15 +418,14 @@ xpath_first(cxobj *xcur,
|
|||
* }
|
||||
* free(vec);
|
||||
* @endcode
|
||||
* @note Namespace prefix checking is not properly implemented
|
||||
*/
|
||||
int
|
||||
xpath_vec(cxobj *xcur,
|
||||
cvec *nsc,
|
||||
char *format,
|
||||
cxobj ***vec,
|
||||
size_t *veclen,
|
||||
...)
|
||||
xpath_vec_nsc(cxobj *xcur,
|
||||
cvec *nsc,
|
||||
char *xpformat,
|
||||
cxobj ***vec,
|
||||
size_t *veclen,
|
||||
...)
|
||||
{
|
||||
int retval = -1;
|
||||
va_list ap;
|
||||
|
|
@ -380,7 +434,7 @@ xpath_vec(cxobj *xcur,
|
|||
xp_ctx *xr = NULL;
|
||||
|
||||
va_start(ap, veclen);
|
||||
len = vsnprintf(NULL, 0, format, ap);
|
||||
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||
va_end(ap);
|
||||
/* allocate a message string exactly fitting the message length */
|
||||
if ((xpath = malloc(len+1)) == NULL){
|
||||
|
|
@ -389,7 +443,7 @@ xpath_vec(cxobj *xcur,
|
|||
}
|
||||
/* second round: compute write message from reason and args */
|
||||
va_start(ap, veclen);
|
||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
||||
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||
va_end(ap);
|
||||
goto done;
|
||||
|
|
@ -413,15 +467,83 @@ xpath_vec(cxobj *xcur,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Given XML tree and xpath, returns nodeset as xml node vector
|
||||
* If result is not nodeset, return empty nodeset
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||
* @param[out] veclen returns length of vector in return value
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @code
|
||||
* cxobj **vec;
|
||||
* size_t veclen;
|
||||
* if (xpath_vec(xcur, "//symbol/foo", &vec, &veclen) < 0)
|
||||
* goto err;
|
||||
* for (i=0; i<veclen; i++){
|
||||
* xn = vec[i];
|
||||
* ...
|
||||
* }
|
||||
* free(vec);
|
||||
* @endcode
|
||||
* @see xpath_vec_nsc which is more generic with namespace context
|
||||
*/
|
||||
int
|
||||
xpath_vec(cxobj *xcur,
|
||||
char *xpformat,
|
||||
cxobj ***vec,
|
||||
size_t *veclen,
|
||||
...)
|
||||
{
|
||||
int retval = -1;
|
||||
va_list ap;
|
||||
size_t len;
|
||||
char *xpath = NULL;
|
||||
xp_ctx *xr = NULL;
|
||||
|
||||
va_start(ap, veclen);
|
||||
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||
va_end(ap);
|
||||
/* allocate a message string exactly fitting the message length */
|
||||
if ((xpath = malloc(len+1)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
/* second round: compute write message from reason and args */
|
||||
va_start(ap, veclen);
|
||||
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||
va_end(ap);
|
||||
goto done;
|
||||
}
|
||||
va_end(ap);
|
||||
*vec=NULL;
|
||||
*veclen = 0;
|
||||
if (xpath_vec_ctx(xcur, NULL, xpath, &xr) < 0)
|
||||
goto done;
|
||||
if (xr && xr->xc_type == XT_NODESET){
|
||||
*vec = xr->xc_nodeset;
|
||||
xr->xc_nodeset = NULL;
|
||||
*veclen = xr->xc_size;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (xr)
|
||||
ctx_free(xr);
|
||||
if (xpath)
|
||||
free(xpath);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Xpath that returns a vector of matches (only nodes marked with flags)
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] xpath string with XPATH syntax
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] flags Set of flags that return nodes must match (0 if all)
|
||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||
* @param[out] veclen returns length of vector in return value
|
||||
* @retval 0 OK
|
||||
* @retval -1 error.
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] flags Set of flags that return nodes must match (0 if all)
|
||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||
* @param[out] veclen returns length of vector in return value
|
||||
* @retval 0 OK
|
||||
* @retval -1 error.
|
||||
* @code
|
||||
* cxobj **vec;
|
||||
* size_t veclen;
|
||||
|
|
@ -434,14 +556,13 @@ xpath_vec(cxobj *xcur,
|
|||
* }
|
||||
* free(vec);
|
||||
* @endcode
|
||||
* @Note that although the returned vector must be freed after use, the returned xml
|
||||
* trees need not be.
|
||||
* @see also xpath_vec This is a specialized version.
|
||||
* @Note that although the returned vector must be freed after use, the returned xml trees need not be.
|
||||
* @see also xpath_vec This is a specialized version.
|
||||
*/
|
||||
int
|
||||
xpath_vec_flag(cxobj *xcur,
|
||||
cvec *nsc,
|
||||
char *format,
|
||||
char *xpformat,
|
||||
uint16_t flags,
|
||||
cxobj ***vec,
|
||||
size_t *veclen,
|
||||
|
|
@ -456,7 +577,7 @@ xpath_vec_flag(cxobj *xcur,
|
|||
cxobj *x;
|
||||
|
||||
va_start(ap, veclen);
|
||||
len = vsnprintf(NULL, 0, format, ap);
|
||||
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||
va_end(ap);
|
||||
/* allocate a message string exactly fitting the message length */
|
||||
if ((xpath = malloc(len+1)) == NULL){
|
||||
|
|
@ -465,7 +586,7 @@ xpath_vec_flag(cxobj *xcur,
|
|||
}
|
||||
/* second round: compute write message from reason and args */
|
||||
va_start(ap, veclen);
|
||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
||||
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||
va_end(ap);
|
||||
goto done;
|
||||
|
|
@ -494,17 +615,17 @@ xpath_vec_flag(cxobj *xcur,
|
|||
|
||||
/*! Given XML tree and xpath, returns boolean
|
||||
* Returns true if the nodeset is non-empty
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpath stdarg string with XPATH 1.0 syntax
|
||||
* @retval 1 True
|
||||
* @retval 0 False
|
||||
* @retval -1 Error
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @retval 1 True
|
||||
* @retval 0 False
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
xpath_vec_bool(cxobj *xcur,
|
||||
cvec *nsc,
|
||||
char *format,
|
||||
char *xpformat,
|
||||
...)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -513,8 +634,8 @@ xpath_vec_bool(cxobj *xcur,
|
|||
char *xpath = NULL;
|
||||
xp_ctx *xr = NULL;
|
||||
|
||||
va_start(ap, format);
|
||||
len = vsnprintf(NULL, 0, format, ap);
|
||||
va_start(ap, xpformat);
|
||||
len = vsnprintf(NULL, 0, xpformat, ap);
|
||||
va_end(ap);
|
||||
/* allocate a message string exactly fitting the message length */
|
||||
if ((xpath = malloc(len+1)) == NULL){
|
||||
|
|
@ -522,8 +643,8 @@ xpath_vec_bool(cxobj *xcur,
|
|||
goto done;
|
||||
}
|
||||
/* second round: compute write message from reason and args */
|
||||
va_start(ap, format);
|
||||
if (vsnprintf(xpath, len+1, format, ap) < 0){
|
||||
va_start(ap, xpformat);
|
||||
if (vsnprintf(xpath, len+1, xpformat, ap) < 0){
|
||||
clicon_err(OE_UNIX, errno, "vsnprintf");
|
||||
va_end(ap);
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ yang_modules_state_get(clicon_handle h,
|
|||
/* xc is also original tree, need to copy it */
|
||||
if ((xw = xml_wrap(xc, "top")) == NULL)
|
||||
goto done;
|
||||
if (xpath_first(xw, NULL, "%s", xpath)){
|
||||
if (xpath_first(xw, "%s", xpath)){
|
||||
if ((x = xml_dup(xc)) == NULL) /* Make copy and use below */
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -337,7 +337,7 @@ yang_modules_state_get(clicon_handle h,
|
|||
if ((x = xml_wrap(x, "top")) < 0)
|
||||
goto done;
|
||||
/* extract xpath part of module-state tree */
|
||||
if (xpath_vec(x, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
if (xpath_vec_nsc(x, nsc, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||
goto done;
|
||||
if (xvec != NULL){
|
||||
for (i=0; i<xlen; i++)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue