From b726c5008ef89d09cc8f9f6b104f54db1191264b Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 17 Mar 2020 15:55:47 +0100 Subject: [PATCH] renamed xml_spec_populate*() to xml_bind_yang*() --- CHANGELOG.md | 10 +- apps/backend/backend_client.c | 4 +- apps/backend/backend_commit.c | 2 +- apps/backend/backend_plugin.c | 2 +- apps/netconf/netconf_main.c | 2 +- apps/netconf/netconf_rpc.c | 8 +- apps/restconf/restconf_methods_post.c | 6 +- lib/clixon/clixon_xml_map.h | 12 +- lib/src/clixon_json.c | 6 +- lib/src/clixon_proto_client.c | 6 +- lib/src/clixon_xml.c | 4 +- lib/src/clixon_xml_io.c | 10 +- lib/src/clixon_xml_map.c | 294 +++++++++++++------------- lib/src/clixon_xml_parse.y | 2 +- util/clixon_util_insert.c | 4 +- util/clixon_util_path.c | 2 +- util/clixon_util_xpath.c | 2 +- 17 files changed, 191 insertions(+), 185 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dd37a24..73003756 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,8 +79,14 @@ features include optimized search functions and a repair callback. * All uses of `api_path2xpath_cvv()` should be replaced by `api_path2xpath()` * `api_path2xpath()` added an `xerr` argument. * Parse and validation API more capable - * `xml_spec_populate` family of functions extended with three-value return values - * -1: error, 0: parse OK, 1: parse and YANG binding OK. + * `xml_spec_populate` has been split into a family of functions + * `xml_bind_yang_rpc()` + * `xml_bind_yang_rpc_reply()` + * `xml_bind_yang0()` + * `xml_bind_yang0_parent()` + * `xml_bind_yang()` + * `xml_bind_yang_parent()` + * All have three-value return values: -1: error, 0: parse OK, 1: parse and YANG binding OK. * `xml_parse` and `json_parse` API changes * Three value returns: -1: error, 0: parse OK, 1: parse and YANG binding OK. * Extended `xml_parse_file2` and `xml_parse_string2` extended API functions with all options available. diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 28caf4e0..8f83d01d 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -670,7 +670,7 @@ from_client_edit_config(clicon_handle h, xml_spec_set(xc, NULL); /* Populate XML with Yang spec (why not do this in parser?) */ - if (xml_spec_populate(xc, yspec, NULL) < 0) + if (xml_bind_yang(xc, yspec, NULL) < 0) goto done; /* Maybe validate xml here as in text_modify_top? */ if (xml_apply(xc, CX_ELMNT, xml_non_config_data, &non_config) < 0) @@ -1593,7 +1593,7 @@ from_client_msg(clicon_handle h, * should really have been dealt with by decode above * but it still is needed - test_cli debug test fails */ - if (xml_spec_populate_rpc(x, yspec, NULL) < 0) + if (xml_bind_yang_rpc(x, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_rpc(h, x, &xret)) < 0) goto done; diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index 22b7d410..db48c410 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -214,7 +214,7 @@ startup_common(clicon_handle h, goto done; } /* After upgrading, XML tree needs to be sorted and yang spec populated */ - if (xml_spec_populate(xt, yspec, NULL) < 0) + if (xml_bind_yang(xt, yspec, NULL) < 0) goto done; if (xml_apply0(xt, CX_ELMNT, xml_sort, h) < 0) goto done; diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 95303645..0d754593 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -128,7 +128,7 @@ clixon_plugin_statedata(clicon_handle h, if (debug) clicon_log_xml(LOG_DEBUG, x, "%s STATE:", __FUNCTION__); #endif - if (xml_spec_populate(x, yspec, NULL) < 0) + if (xml_bind_yang(x, yspec, NULL) < 0) goto done; if ((ret = netconf_trymerge(x, yspec, xret)) < 0) goto done; diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index 52f842c3..cfced64f 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -148,7 +148,7 @@ netconf_input_packet(clicon_handle h, free(str0); if ((xrpc=xpath_first(xreq, NULL, "//rpc")) != NULL){ isrpc++; - if (xml_spec_populate_rpc(xrpc, yspec, NULL) < 0) + if (xml_bind_yang_rpc(xrpc, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_rpc(h, xrpc, &xret)) < 0) goto done; diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index e7b838bb..249f8c5b 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -586,8 +586,8 @@ netconf_application_rpc(clicon_handle h, if (yrpc != NULL){ /* 1. Check xn arguments with input statement. */ if ((yinput = yang_find(yrpc, Y_INPUT, NULL)) != NULL){ - xml_spec_set(xn, yinput); /* needed for xml_spec_populate */ - if (xml_spec_populate(xn, yspec, NULL) < 0) + xml_spec_set(xn, yinput); /* needed for xml_bind_yang */ + if (xml_bind_yang(xn, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_all_top(h, xn, &xerr)) < 0) goto done; @@ -618,8 +618,8 @@ netconf_application_rpc(clicon_handle h, if (0) if ((youtput = yang_find(yrpc, Y_OUTPUT, NULL)) != NULL){ xoutput=xpath_first(*xret, NULL, "/"); - xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */ - if (xml_spec_populate(xoutput, yspec, NULL) < 0) + xml_spec_set(xoutput, youtput); /* needed for xml_bind_yang */ + if (xml_bind_yang(xoutput, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_all_top(h, xoutput, &xerr)) < 0) goto done; diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c index 9efa862f..5308134b 100644 --- a/apps/restconf/restconf_methods_post.c +++ b/apps/restconf/restconf_methods_post.c @@ -609,9 +609,9 @@ api_operations_post_output(clicon_handle h, * (2) Uncertain how validation errors should be logged/handled */ if (youtput != NULL){ - xml_spec_set(xoutput, youtput); /* needed for xml_spec_populate */ + xml_spec_set(xoutput, youtput); /* needed for xml_bind_yang */ #if 0 - if (xml_spec_populate(xoutput, yspec, NULL) < 0) + if (xml_bind_yang(xoutput, yspec, NULL) < 0) goto done; if ((ret = xml_yang_validate_all(xoutput, &xerr)) < 0) goto done; @@ -832,7 +832,7 @@ api_operations_post(clicon_handle h, clicon_log_xml(LOG_DEBUG, xtop, "%s 5. Translate input args:", __FUNCTION__); #endif /* 6. Validate outgoing RPC and fill in defaults */ - if (xml_spec_populate_rpc(xtop, yspec, NULL) < 0) /* */ + if (xml_bind_yang_rpc(xtop, yspec, NULL) < 0) /* */ goto done; if ((ret = xml_yang_validate_rpc(h, xtop, &xret)) < 0) goto done; diff --git a/lib/clixon/clixon_xml_map.h b/lib/clixon/clixon_xml_map.h index 0be94e19..67a27bed 100644 --- a/lib/clixon/clixon_xml_map.h +++ b/lib/clixon/clixon_xml_map.h @@ -61,12 +61,12 @@ int xml_namespace_change(cxobj *x, char *namespace, char *prefix); int xml_default(cxobj *x, void *arg); int xml_sanity(cxobj *x, void *arg); int xml_non_config_data(cxobj *xt, void *arg); -int xml_spec_populate_rpc(cxobj *xrpc, yang_stmt *yspec, cxobj **xerr); -int xml_spec_populate_rpc_reply(cxobj *xrpc, char *name, yang_stmt *yspec, cxobj **xerr); -int xml_spec_populate0(cxobj *xt, yang_stmt *yspec, cxobj **xerr); -int xml_spec_populate0_parent(cxobj *xt, cxobj **xerr); -int xml_spec_populate(cxobj *xt, yang_stmt *yspec, cxobj **xerr); -int xml_spec_populate_parent(cxobj *xt, cxobj **xerr); +int xml_bind_yang_rpc(cxobj *xrpc, yang_stmt *yspec, cxobj **xerr); +int xml_bind_yang_rpc_reply(cxobj *xrpc, char *name, yang_stmt *yspec, cxobj **xerr); +int xml_bind_yang0(cxobj *xt, yang_stmt *yspec, cxobj **xerr); +int xml_bind_yang0_parent(cxobj *xt, cxobj **xerr); +int xml_bind_yang(cxobj *xt, yang_stmt *yspec, cxobj **xerr); +int xml_bind_yang_parent(cxobj *xt, cxobj **xerr); int xml2xpath(cxobj *x, char **xpath); int assign_namespaces(cxobj *x0, cxobj *x1, cxobj *x1p); diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 507d09a5..0b424457 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -1220,7 +1220,7 @@ _json_parse(char *str, if (ret == 0) goto fail; /* Now assign yang stmts to each XML node - * XXX should be xml_spec_populate0_parent() sometimes. + * XXX should be xml_bind_yang0_parent() sometimes. */ switch (yb){ case YB_RPC: @@ -1228,13 +1228,13 @@ _json_parse(char *str, case YB_NONE: break; case YB_PARENT: - if ((ret = xml_spec_populate0_parent(x, xerr)) < 0) + if ((ret = xml_bind_yang0_parent(x, xerr)) < 0) goto done; if (ret == 0) failed++; break; case YB_TOP: - if (xml_spec_populate0(x, yspec, xerr) < 0) + if (xml_bind_yang0(x, yspec, xerr) < 0) goto done; if (ret == 0) failed++; diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 6b1c7f78..6c9905af 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -270,7 +270,7 @@ clicon_rpc_netconf_xml(clicon_handle h, xml_find_type(xreply, NULL, "rpc-error", CX_ELMNT) == NULL){ yspec = clicon_dbspec_yang(h); /* Here use rpc name to bind to yang */ - if (xml_spec_populate_rpc_reply(xreply, rpcname, yspec, NULL) < 0) + if (xml_bind_yang_rpc_reply(xreply, rpcname, yspec, NULL) < 0) goto done; } retval = 0; @@ -403,7 +403,7 @@ clicon_rpc_get_config(clicon_handle h, } else{ yspec = clicon_dbspec_yang(h); - if ((ret = xml_spec_populate(xd, yspec, &xerr)) < 0) + if ((ret = xml_bind_yang(xd, yspec, &xerr)) < 0) goto done; if (ret == 0){ if ((xd = xpath_first(xerr, NULL, "rpc-error")) == NULL){ @@ -759,7 +759,7 @@ clicon_rpc_get(clicon_handle h, } else{ yspec = clicon_dbspec_yang(h); - if ((ret = xml_spec_populate(xd, yspec, &xerr)) < 0) + if ((ret = xml_bind_yang(xd, yspec, &xerr)) < 0) goto done; if (ret == 0){ if ((xd = xpath_first(xerr, NULL, "rpc-error")) == NULL){ diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index aabb8387..4892d13d 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -66,9 +66,9 @@ #include "clixon_log.h" #include "clixon_yang.h" #include "clixon_xml.h" -#include "clixon_options.h" /* xml_spec_populate */ +#include "clixon_options.h" /* xml_bind_yang */ #include "clixon_yang_module.h" -#include "clixon_xml_map.h" /* xml_spec_populate */ +#include "clixon_xml_map.h" /* xml_bind_yang */ #include "clixon_xml_vec.h" #include "clixon_xml_sort.h" #include "clixon_xml_io.h" diff --git a/lib/src/clixon_xml_io.c b/lib/src/clixon_xml_io.c index c844d3b4..e97a8a27 100644 --- a/lib/src/clixon_xml_io.c +++ b/lib/src/clixon_xml_io.c @@ -66,9 +66,9 @@ #include "clixon_log.h" #include "clixon_yang.h" #include "clixon_xml.h" -#include "clixon_options.h" /* xml_spec_populate */ +#include "clixon_options.h" /* xml_bind_yang */ #include "clixon_yang_module.h" -#include "clixon_xml_map.h" /* xml_spec_populate */ +#include "clixon_xml_map.h" /* xml_bind_yang */ #include "clixon_xml_vec.h" #include "clixon_xml_sort.h" #include "clixon_xml_nsctx.h" @@ -431,7 +431,7 @@ _xml_parse(const char *str, /* xt:n Has spec * x: <-- populate from parent */ - if ((ret = xml_spec_populate0_parent(x, xerr)) < 0) + if ((ret = xml_bind_yang0_parent(x, xerr)) < 0) goto done; if (ret == 0) failed++; @@ -448,12 +448,12 @@ _xml_parse(const char *str, * x: * <-- populate from modules */ - if ((ret = xml_spec_populate(x, yspec, xerr)) < 0) + if ((ret = xml_bind_yang(x, yspec, xerr)) < 0) goto done; } else #endif - if ((ret = xml_spec_populate0(x, yspec, xerr)) < 0) + if ((ret = xml_bind_yang0(x, yspec, xerr)) < 0) goto done; if (ret == 0) failed++; diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 47014a45..a3659a7c 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1022,134 +1022,6 @@ xml_non_config_data(cxobj *xt, return retval; } -/*! Find yang spec association of XML node for incoming RPC starting with - * - * Incoming RPC has an "input" structure that is not taken care of by xml_spec_populate - * @param[in] xrpc XML rpc node - * @param[in] yspec Yang spec - * @param[out] xerr Reason for failure, or NULL - * @retval 1 OK yang assignment made - * @retval 0 Partial or no yang assigment made (at least one failed) and xerr set - * @retval -1 Error - * The - * @code - * if (xml_spec_populate_rpc(h, x, NULL) < 0) - * err; - * @endcode - * @see xml_spec_populate For other generic cases - * @see xml_spec_populate_rpc_reply - */ -int -xml_spec_populate_rpc(cxobj *xrpc, - yang_stmt *yspec, - cxobj **xerr) -{ - int retval = -1; - yang_stmt *yrpc = NULL; /* yang node */ - yang_stmt *ymod=NULL; /* yang module */ - yang_stmt *yi = NULL; /* input */ - cxobj *x; - int ret; - - if ((strcmp(xml_name(xrpc), "rpc")) != 0){ - clicon_err(OE_UNIX, EINVAL, "RPC expected"); - goto done; - } - x = NULL; - while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) { - if (ys_module_by_xml(yspec, x, &ymod) < 0) - goto done; - if (ymod != NULL) - yrpc = yang_find(ymod, Y_RPC, xml_name(x)); - /* Non-strict semantics: loop through all modules to find the node - */ - if (yrpc){ - xml_spec_set(x, yrpc); - if ((yi = yang_find(yrpc, Y_INPUT, NULL)) != NULL){ - /* xml_spec_populate need to have parent with yang spec for - * recursive population to work. Therefore, assign input yang - * to rpc level although not 100% intuitive */ - xml_spec_set(x, yi); - if ((ret = xml_spec_populate_parent(x, xerr)) < 0) - goto done; - if (ret == 0) - goto fail; - } - } - } - retval = 1; - done: - return retval; - fail: - retval = 0; - goto done; -} - -/*! Find yang spec association of XML node for outgoing RPC starting with - * - * Incoming RPC has an "input" structure that is not taken care of by xml_spec_populate - * @param[in] xrpc XML rpc node - * @param[in] name Name of RPC (not seen in output/reply) - * @param[in] yspec Yang spec - * @param[out] xerr Reason for failure, or NULL - * @retval 1 OK yang assignment made - * @retval 0 Partial or no yang assigment made (at least one failed) and xerr set - * @retval -1 Error - * - * @code - * if (xml_spec_populate_rpc_reply(x, "get-config", yspec, name) < 0) - * err; - * @endcode - * @see xml_spec_populate For other generic cases - */ -int -xml_spec_populate_rpc_reply(cxobj *xrpc, - char *name, - yang_stmt *yspec, - cxobj **xerr) -{ - int retval = -1; - yang_stmt *yrpc = NULL; /* yang node */ - yang_stmt *ymod=NULL; /* yang module */ - yang_stmt *yo = NULL; /* output */ - cxobj *x; - int ret; - - if (strcmp(xml_name(xrpc), "rpc-reply")){ - clicon_err(OE_UNIX, EINVAL, "rpc-reply expected"); - goto done; - } - x = NULL; - while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) { - if (ys_module_by_xml(yspec, x, &ymod) < 0) - goto done; - if (ymod == NULL) - continue; - if ((yrpc = yang_find(ymod, Y_RPC, name)) == NULL) - continue; - // xml_spec_set(xrpc, yrpc); - if ((yo = yang_find(yrpc, Y_OUTPUT, NULL)) == NULL) - continue; - /* xml_spec_populate need to have parent with yang spec for - * recursive population to work. Therefore, assign input yang - * to rpc level although not 100% intuitive */ - break; - } - if (yo != NULL){ - xml_spec_set(xrpc, yo); - if ((ret = xml_spec_populate(xrpc, yspec, xerr)) < 0) - goto done; - if (ret == 0) - goto fail; - } - retval = 1; - done: - return retval; - fail: - retval = 0; - goto done; -} - /*! Associate XML node x with x:s parents yang:s matching child * * @param[in] xt XML tree node @@ -1329,20 +1201,20 @@ strip_whitespace(cxobj *xt) * @retval 0 Partial or no yang assigment made (at least one failed) and xerr set * @retval -1 Error * @code - * if (xml_spec_populate(x, yspec, NULL) < 0) + * if (xml_bind_yang(x, yspec, NULL) < 0) * err; * @endcode * @note For subs to anyxml nodes will not have spec set * There are several functions in the API family - * @see xml_spec_populate_rpc for incoming rpc - * @see xml_spec_populate_parent Not top-level and parent is properly yang populated - * @see xml_spec_populate0 If the calling xml object should also be populated - * @see xml_spec_populate0_parent + * @see xml_bind_yang_rpc for incoming rpc + * @see xml_bind_yang_parent Not top-level and parent is properly yang populated + * @see xml_bind_yang0 If the calling xml object should also be populated + * @see xml_bind_yang0_parent */ int -xml_spec_populate(cxobj *xt, - yang_stmt *yspec, - cxobj **xerr) +xml_bind_yang(cxobj *xt, + yang_stmt *yspec, + cxobj **xerr) { int retval = -1; cxobj *xc; /* xml child */ @@ -1352,7 +1224,7 @@ xml_spec_populate(cxobj *xt, strip_whitespace(xt); xc = NULL; /* Apply on children */ while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) { - if ((ret = xml_spec_populate0(xc, yspec, xerr)) < 0) + if ((ret = xml_bind_yang0(xc, yspec, xerr)) < 0) goto done; if (ret == 0) failed++; @@ -1367,8 +1239,8 @@ xml_spec_populate(cxobj *xt, * Populate xt:s children outgoing from that xt is populated */ int -xml_spec_populate_parent(cxobj *xt, - cxobj **xerr) +xml_bind_yang_parent(cxobj *xt, + cxobj **xerr) { int retval = -1; cxobj *xc; /* xml child */ @@ -1378,7 +1250,7 @@ xml_spec_populate_parent(cxobj *xt, strip_whitespace(xt); xc = NULL; /* Apply on children */ while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) { - if ((ret = xml_spec_populate0_parent(xc, xerr)) < 0) + if ((ret = xml_bind_yang0_parent(xc, xerr)) < 0) goto done; if (ret == 0) failed++; @@ -1399,9 +1271,9 @@ xml_spec_populate_parent(cxobj *xt, * Populate xt as top-level node */ int -xml_spec_populate0(cxobj *xt, - yang_stmt *yspec, - cxobj **xerr) +xml_bind_yang0(cxobj *xt, + yang_stmt *yspec, + cxobj **xerr) { int retval = -1; cxobj *xc; /* xml child */ @@ -1415,7 +1287,7 @@ xml_spec_populate0(cxobj *xt, strip_whitespace(xt); xc = NULL; /* Apply on children */ while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) { - if ((ret = xml_spec_populate0_parent(xc, xerr)) < 0) + if ((ret = xml_bind_yang0_parent(xc, xerr)) < 0) goto done; if (ret == 0) failed++; @@ -1435,8 +1307,8 @@ xml_spec_populate0(cxobj *xt, * Populate xt as if xt:s parent is populated */ int -xml_spec_populate0_parent(cxobj *xt, - cxobj **xerr) +xml_bind_yang0_parent(cxobj *xt, + cxobj **xerr) { int retval = -1; cxobj *xc; /* xml child */ @@ -1450,7 +1322,7 @@ xml_spec_populate0_parent(cxobj *xt, strip_whitespace(xt); xc = NULL; /* Apply on children */ while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) { - if ((ret = xml_spec_populate0_parent(xc, xerr)) < 0) + if ((ret = xml_bind_yang0_parent(xc, xerr)) < 0) goto done; if (ret == 0) failed++; @@ -1465,6 +1337,134 @@ xml_spec_populate0_parent(cxobj *xt, goto done; } +/*! Find yang spec association of XML node for incoming RPC starting with + * + * Incoming RPC has an "input" structure that is not taken care of by xml_bind_yang + * @param[in] xrpc XML rpc node + * @param[in] yspec Yang spec + * @param[out] xerr Reason for failure, or NULL + * @retval 1 OK yang assignment made + * @retval 0 Partial or no yang assigment made (at least one failed) and xerr set + * @retval -1 Error + * The + * @code + * if (xml_bind_yang_rpc(h, x, NULL) < 0) + * err; + * @endcode + * @see xml_bind_yang For other generic cases + * @see xml_bind_yang_rpc_reply + */ +int +xml_bind_yang_rpc(cxobj *xrpc, + yang_stmt *yspec, + cxobj **xerr) +{ + int retval = -1; + yang_stmt *yrpc = NULL; /* yang node */ + yang_stmt *ymod=NULL; /* yang module */ + yang_stmt *yi = NULL; /* input */ + cxobj *x; + int ret; + + if ((strcmp(xml_name(xrpc), "rpc")) != 0){ + clicon_err(OE_UNIX, EINVAL, "RPC expected"); + goto done; + } + x = NULL; + while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) { + if (ys_module_by_xml(yspec, x, &ymod) < 0) + goto done; + if (ymod != NULL) + yrpc = yang_find(ymod, Y_RPC, xml_name(x)); + /* Non-strict semantics: loop through all modules to find the node + */ + if (yrpc){ + xml_spec_set(x, yrpc); + if ((yi = yang_find(yrpc, Y_INPUT, NULL)) != NULL){ + /* xml_bind_yang need to have parent with yang spec for + * recursive population to work. Therefore, assign input yang + * to rpc level although not 100% intuitive */ + xml_spec_set(x, yi); + if ((ret = xml_bind_yang_parent(x, xerr)) < 0) + goto done; + if (ret == 0) + goto fail; + } + } + } + retval = 1; + done: + return retval; + fail: + retval = 0; + goto done; +} + +/*! Find yang spec association of XML node for outgoing RPC starting with + * + * Incoming RPC has an "input" structure that is not taken care of by xml_bind_yang + * @param[in] xrpc XML rpc node + * @param[in] name Name of RPC (not seen in output/reply) + * @param[in] yspec Yang spec + * @param[out] xerr Reason for failure, or NULL + * @retval 1 OK yang assignment made + * @retval 0 Partial or no yang assigment made (at least one failed) and xerr set + * @retval -1 Error + * + * @code + * if (xml_bind_yang_rpc_reply(x, "get-config", yspec, name) < 0) + * err; + * @endcode + * @see xml_bind_yang For other generic cases + */ +int +xml_bind_yang_rpc_reply(cxobj *xrpc, + char *name, + yang_stmt *yspec, + cxobj **xerr) +{ + int retval = -1; + yang_stmt *yrpc = NULL; /* yang node */ + yang_stmt *ymod=NULL; /* yang module */ + yang_stmt *yo = NULL; /* output */ + cxobj *x; + int ret; + + if (strcmp(xml_name(xrpc), "rpc-reply")){ + clicon_err(OE_UNIX, EINVAL, "rpc-reply expected"); + goto done; + } + x = NULL; + while ((x = xml_child_each(xrpc, x, CX_ELMNT)) != NULL) { + if (ys_module_by_xml(yspec, x, &ymod) < 0) + goto done; + if (ymod == NULL) + continue; + if ((yrpc = yang_find(ymod, Y_RPC, name)) == NULL) + continue; + // xml_spec_set(xrpc, yrpc); + if ((yo = yang_find(yrpc, Y_OUTPUT, NULL)) == NULL) + continue; + /* xml_bind_yang need to have parent with yang spec for + * recursive population to work. Therefore, assign input yang + * to rpc level although not 100% intuitive */ + break; + } + if (yo != NULL){ + xml_spec_set(xrpc, yo); + if ((ret = xml_bind_yang(xrpc, yspec, xerr)) < 0) + goto done; + if (ret == 0) + goto fail; + } + retval = 1; + done: + return retval; + fail: + retval = 0; + goto done; +} + /*! Given an XML node, build an xpath to root, internal function * @retval 0 OK * @retval -1 Error. eg XML malformed diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y index 01ff1f6f..391f20ef 100644 --- a/lib/src/clixon_xml_parse.y +++ b/lib/src/clixon_xml_parse.y @@ -270,7 +270,7 @@ xml_parse_bslash(clixon_xml_yacc *xy, * So the rule is: if there is at least on element, then remove all bodies. * See also code in xml_parse_whitespace * But there is more: when YANG is assigned, if not leaf/leaf-lists, then all contents should - * be stripped, see xml_spec_populate() + * be stripped, see xml_bind_yang() */ xc = NULL; while ((xc = xml_child_each(x, xc, CX_ELMNT)) != NULL) diff --git a/util/clixon_util_insert.c b/util/clixon_util_insert.c index fc528724..ee923fbc 100644 --- a/util/clixon_util_insert.c +++ b/util/clixon_util_insert.c @@ -152,7 +152,7 @@ main(int argc, char **argv) clicon_err(OE_XML, 0, "Parsing base xml: %s", x0str); goto done; } - if (xml_spec_populate(x0, yspec, NULL) < 0) + if (xml_bind_yang(x0, yspec, NULL) < 0) goto done; if ((xb = xpath_first(x0, NULL, "%s", xpath)) == NULL){ clicon_err(OE_XML, 0, "xpath: %s not found in x0", xpath); @@ -167,7 +167,7 @@ main(int argc, char **argv) clicon_err(OE_XML, 0, "Parsing insert xml: %s", xistr); goto done; } - if (xml_spec_populate(xi, yspec, NULL) < 0) + if (xml_bind_yang(xi, yspec, NULL) < 0) goto done; if ((xi = xpath_first(xi, NULL, "%s", xpath)) == NULL){ clicon_err(OE_XML, 0, "xpath: %s not found in xi", xpath); diff --git a/util/clixon_util_path.c b/util/clixon_util_path.c index dfc65657..48c7b558 100644 --- a/util/clixon_util_path.c +++ b/util/clixon_util_path.c @@ -220,7 +220,7 @@ main(int argc, /* Validate XML as well */ if (yang_file_dir){ /* Populate */ - if (xml_spec_populate(x, yspec, NULL) < 0) + if (xml_bind_yang(x, yspec, NULL) < 0) goto done; /* Add default values */ if (xml_apply(x, CX_ELMNT, xml_default, h) < 0) diff --git a/util/clixon_util_xpath.c b/util/clixon_util_xpath.c index 106b91de..9d374c77 100644 --- a/util/clixon_util_xpath.c +++ b/util/clixon_util_xpath.c @@ -288,7 +288,7 @@ main(int argc, /* Validate XML as well */ if (yang_file_dir){ /* Populate */ - if (xml_spec_populate(x0, yspec, NULL) < 0) + if (xml_bind_yang(x0, yspec, NULL) < 0) goto done; /* Sort */ if (xml_apply(x0, CX_ELMNT, xml_sort, h) < 0)