diff --git a/CHANGELOG.md b/CHANGELOG.md index ee5e94b1..3dd37a24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,9 +72,10 @@ features include optimized search functions and a repair callback. * New (example): `Netconf error: application operation-failed Identityref validation failed, undefined not derived from acl-base . Validate failed. Edit and try again or discard changes" ### C-API changes on existing features (you may need to change your plugin C-code) -* `xml_new()` changed from `xml_new(name, xp, ys)` to `xml_new(name, prefix, xp, type)` +* `xml_new()` changed from `xml_new(name, xp, ys)` to `xml_new(name, xp, type)` * If you have used, `ys`, add `xml_spec_set(x, ys)` after the statement - * If you have `xml_type_set(x, TYPE)` or `xml_prefix_set(x, PREFIX)` immediately after the statement, you can remove those and set them directly as: `xml_new(name, PREFIX, xp, TYPE)` + * If you have `xml_type_set(x, TYPE)` after the statement, you can remove it and set it directly as: `xml_new(name, xp, TYPE)` +* `xml_type_set()`has been removed in the API. The type must be set at creation timw with `xml_new` * All uses of `api_path2xpath_cvv()` should be replaced by `api_path2xpath()` * `api_path2xpath()` added an `xerr` argument. * Parse and validation API more capable diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 807ae0bc..95303645 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -120,7 +120,7 @@ clixon_plugin_statedata(clicon_handle h, while ((cp = clixon_plugin_each(h, cp)) != NULL) { if ((fn = cp->cp_api.ca_statedata) == NULL) continue; - if ((x = xml_new("config", NULL, NULL, CX_ELMNT)) == NULL) + if ((x = xml_new("config", NULL, CX_ELMNT)) == NULL) goto done; if (fn(h, nsc, xpath, x) < 0) goto fail; /* Dont quit here on user callbacks */ diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index 6bf75bf7..631435d0 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -200,7 +200,7 @@ dbxml_body(cxobj *xbot, clicon_err(OE_UNIX, errno, "cv2str_dup"); goto done; } - if ((xb = xml_new("body", NULL, xbot, CX_BODY)) == NULL) + if ((xb = xml_new("body", xbot, CX_BODY)) == NULL) goto done; if (xml_value_set(xb, str) < 0) goto done; @@ -258,7 +258,7 @@ cli_dbxml(clicon_handle h, if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0) goto done; /* Create config top-of-tree */ - if ((xtop = xml_new("config", NULL, NULL, CX_ELMNT)) == NULL) + if ((xtop = xml_new("config", NULL, CX_ELMNT)) == NULL) goto done; xbot = xtop; if (api_path){ @@ -276,7 +276,9 @@ cli_dbxml(clicon_handle h, goto done; } } - if ((xa = xml_new("operation", NETCONF_BASE_PREFIX, xbot, CX_ATTR)) == NULL) + if ((xa = xml_new("operation", xbot, CX_ATTR)) == NULL) + goto done; + if (xml_prefix_set(xa, NETCONF_BASE_PREFIX) < 0) goto done; if (xml_value_set(xa, xml_operation2str(op)) < 0) goto done; @@ -1231,7 +1233,7 @@ cli_copy_config(clicon_handle h, } toname = cv_string_get(tocv); /* Create copy xml tree x2 */ - if ((x2 = xml_new("config", NULL, NULL, CX_ELMNT)) == NULL) + if ((x2 = xml_new("config", NULL, CX_ELMNT)) == NULL) goto done; if (xml_copy(x1, x2) < 0) goto done; diff --git a/apps/cli/cli_show.c b/apps/cli/cli_show.c index b97ad7b1..5c545614 100644 --- a/apps/cli/cli_show.c +++ b/apps/cli/cli_show.c @@ -165,7 +165,7 @@ expand_dbvar(void *h, xcur = xt; /* default top-of-tree */ xpathcur = xpath; /* Create config top-of-tree */ - if ((xtop = xml_new("config", NULL, NULL, CX_ELMNT)) == NULL) + if ((xtop = xml_new("config", NULL, CX_ELMNT)) == NULL) goto done; xbot = xtop; /* This is primarily to get "y", diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c index cc365cc3..e7b838bb 100644 --- a/apps/netconf/netconf_rpc.c +++ b/apps/netconf/netconf_rpc.c @@ -671,7 +671,7 @@ netconf_rpc_dispatch(clicon_handle h, * It may even be wrong if something else is done with the incoming message? */ if ((username = clicon_username_get(h)) != NULL){ - if ((xa = xml_new("username", NULL, xn, CX_ATTR)) == NULL) + if ((xa = xml_new("username", xn, CX_ATTR)) == NULL) goto done; if (xml_value_set(xa, username) < 0) goto done; diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c index 58f98823..bfda75c0 100644 --- a/apps/restconf/restconf_lib.c +++ b/apps/restconf/restconf_lib.c @@ -685,7 +685,9 @@ restconf_insert_attributes(cxobj *xdata, if (xmlns_set(xdata, "yang", YANG_XML_NAMESPACE) < 0) goto done; /* Then add insert attribute */ - if ((xa = xml_new("insert", "yang", xdata, CX_ATTR)) == NULL) + if ((xa = xml_new("insert", xdata, CX_ATTR)) == NULL) + goto done; + if (xml_prefix_set(xa, "yang") < 0) goto done; if (xml_value_set(xa, instr) < 0) goto done; @@ -700,7 +702,9 @@ restconf_insert_attributes(cxobj *xdata, else attrname="value"; /* Then add value/key attribute */ - if ((xa = xml_new(attrname, "yang", xdata, CX_ATTR)) == NULL) + if ((xa = xml_new(attrname, xdata, CX_ATTR)) == NULL) + goto done; + if (xml_prefix_set(xa, "yang") < 0) goto done; if ((ret = api_path2xpath(pstr, ys_spec(y), &xpath, &nsc, NULL)) < 0) goto done; diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 70919ba4..ffe07f18 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -327,7 +327,7 @@ api_data_write(clicon_handle h, xret = NULL; } /* Create config top-of-tree */ - if ((xtop = xml_new("config", NULL, NULL, CX_ELMNT)) == NULL) + if ((xtop = xml_new("config", NULL, CX_ELMNT)) == NULL) goto done; /* Translate api_path to xml in the form of xtop/xbot */ xbot = xtop; @@ -362,7 +362,7 @@ api_data_write(clicon_handle h, } /* Create a dummy data tree parent to hook in the parsed data. */ - if ((xdata0 = xml_new("data0", NULL, NULL, CX_ELMNT)) == NULL) + if ((xdata0 = xml_new("data0", NULL, CX_ELMNT)) == NULL) goto done; if (api_path){ /* XXX mv to copy? */ cxobj *xfrom; @@ -373,7 +373,7 @@ api_data_write(clicon_handle h, goto done; xa = NULL; while ((xa = xml_child_each(xfrom, xa, CX_ATTR)) != NULL) { - if ((xac = xml_new(xml_name(xa), NULL, xdata0, CX_ATTR)) == NULL) + if ((xac = xml_new(xml_name(xa), xdata0, CX_ATTR)) == NULL) goto done; if (xml_copy(xa, xac) < 0) /* recursion */ goto done; @@ -479,7 +479,9 @@ api_data_write(clicon_handle h, /* Add operation create as attribute. If that fails with Conflict, then * try "replace" (see comment in function header) */ - if ((xa = xml_new("operation", NETCONF_BASE_PREFIX, xdata, CX_ATTR)) == NULL) + if ((xa = xml_new("operation", xdata, CX_ATTR)) == NULL) + goto done; + if (xml_prefix_set(xa, NETCONF_BASE_PREFIX) < 0) goto done; if (xml_value_set(xa, xml_operation2str(op)) < 0) goto done; @@ -836,7 +838,7 @@ api_data_delete(clicon_handle h, for (i=0; i */ - if ((xtop = xml_new("rpc", NULL, NULL, CX_ELMNT)) == NULL) + if ((xtop = xml_new("rpc", NULL, CX_ELMNT)) == NULL) goto done; xbot = xtop; /* Here xtop is: */ if ((username = clicon_username_get(h)) != NULL){ - if ((xa = xml_new("username", NULL, xtop, CX_ATTR)) == NULL) + if ((xa = xml_new("username", xtop, CX_ATTR)) == NULL) goto done; if (xml_value_set(xa, username) < 0) goto done; diff --git a/lib/clixon/clixon_xml.h b/lib/clixon/clixon_xml.h index eb62e69b..29668c2d 100644 --- a/lib/clixon/clixon_xml.h +++ b/lib/clixon/clixon_xml.h @@ -146,7 +146,6 @@ char *xml_value(cxobj *xn); int xml_value_set(cxobj *xn, char *val); int xml_value_append(cxobj *xn, char *val); enum cxobj_type xml_type(cxobj *xn); -int xml_type_set(cxobj *xn, enum cxobj_type type); int xml_child_nr(cxobj *xn); int xml_child_nr_type(cxobj *xn, enum cxobj_type type); @@ -160,8 +159,8 @@ cxobj *xml_child_each(cxobj *xparent, cxobj *xprev, enum cxobj_type type); int xml_child_insert_pos(cxobj *x, cxobj *xc, int i); int xml_childvec_set(cxobj *x, int len); cxobj **xml_childvec_get(cxobj *x); -cxobj *xml_new(char *name, char *prefix, cxobj *xn_parent, enum cxobj_type type); - +cxobj *xml_new(char *name, cxobj *xn_parent, enum cxobj_type type); +cxobj *xml_new_body(char *name, cxobj *parent, char *val); yang_stmt *xml_spec(cxobj *x); int xml_spec_set(cxobj *x, yang_stmt *spec); cg_var *xml_cv(cxobj *x); diff --git a/lib/src/clixon_datastore.c b/lib/src/clixon_datastore.c index f0b8ab34..1c9debde 100644 --- a/lib/src/clixon_datastore.c +++ b/lib/src/clixon_datastore.c @@ -213,14 +213,14 @@ xmldb_copy(clicon_handle h, x2 = NULL; } else if (x2 == NULL){ /* create x2 and copy from x1 */ - if ((x2 = xml_new(xml_name(x1), NULL, NULL, CX_ELMNT)) == NULL) + if ((x2 = xml_new(xml_name(x1), NULL, CX_ELMNT)) == NULL) goto done; if (xml_copy(x1, x2) < 0) goto done; } else{ /* copy x1 to x2 */ xml_free(x2); - if ((x2 = xml_new(xml_name(x1), NULL, NULL, CX_ELMNT)) == NULL) + if ((x2 = xml_new(xml_name(x1), NULL, CX_ELMNT)) == NULL) goto done; if (xml_copy(x1, x2) < 0) goto done; diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 22dcfbb3..b1c4267e 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -155,7 +155,7 @@ xml_copy_marked(cxobj *x0, x = NULL; while ((x = xml_child_each(x0, x, CX_ATTR)) != NULL) { name = xml_name(x); - if ((xcopy = xml_new(name, NULL, x1, CX_ATTR)) == NULL) + if ((xcopy = xml_new(name, x1, CX_ATTR)) == NULL) goto done; if (xml_copy(x, xcopy) < 0) goto done; @@ -178,7 +178,7 @@ xml_copy_marked(cxobj *x0, name = xml_name(x); if (xml_flag(x, XML_FLAG_MARK)){ /* (2) the complete subtree of that node is copied. */ - if ((xcopy = xml_new(name, NULL, x1, CX_ELMNT)) == NULL) + if ((xcopy = xml_new(name, x1, CX_ELMNT)) == NULL) goto done; if (xml_copy(x, xcopy) < 0) goto done; @@ -186,7 +186,7 @@ xml_copy_marked(cxobj *x0, } if (xml_flag(x, XML_FLAG_CHANGE)){ /* Copy individual nodes marked with XML_FLAG_CHANGE */ - if ((xcopy = xml_new(name, NULL, x1, CX_ELMNT)) == NULL) + if ((xcopy = xml_new(name, x1, CX_ELMNT)) == NULL) goto done; if (xml_copy_marked(x, xcopy) < 0) /* */ goto done; @@ -198,7 +198,7 @@ xml_copy_marked(cxobj *x0, if ((iskey = yang_key_match(yt, name)) < 0) goto done; if (iskey){ - if ((xcopy = xml_new(name, NULL, x1, CX_ELMNT)) == NULL) + if ((xcopy = xml_new(name, x1, CX_ELMNT)) == NULL) goto done; if (xml_copy(x, xcopy) < 0) goto done; @@ -538,7 +538,7 @@ xmldb_get_cache(clicon_handle h, goto done; /* Make new tree by copying top-of-tree from x0t to x1t */ - if ((x1t = xml_new(xml_name(x0t), NULL, NULL, CX_ELMNT)) == NULL) + if ((x1t = xml_new(xml_name(x0t), NULL, CX_ELMNT)) == NULL) goto done; xml_spec_set(x1t, xml_spec(x0t)); diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 2dcb688d..9afabe94 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -180,11 +180,14 @@ check_identityref(cxobj *x0, goto done; /* Create xmlns attribute to x1 XXX same code ^*/ if (prefix){ - if ((xa = xml_new(prefix, "xmlns", x, CX_ATTR)) == NULL) + if ((xa = xml_new(prefix, x, CX_ATTR)) == NULL) goto done; + if (xml_prefix_set(xa, "xmlns") < 0) + goto done; + } else{ - if ((xa = xml_new("xmlns", NULL, x, CX_ATTR)) == NULL) + if ((xa = xml_new("xmlns", x, CX_ATTR)) == NULL) goto done; } if (xml_value_set(xa, ns0) < 0) @@ -340,7 +343,7 @@ text_modify(clicon_handle h, } /* Add new xml node but without parent - insert when node fully copied (see changed conditional below) */ - if ((x0 = xml_new(x1name, NULL, NULL, CX_ELMNT)) == NULL) + if ((x0 = xml_new(x1name, NULL, CX_ELMNT)) == NULL) goto done; xml_spec_set(x0, y0); @@ -354,7 +357,7 @@ text_modify(clicon_handle h, if (op==OP_NONE) xml_flag_set(x0, XML_FLAG_NONE); /* Mark for potential deletion */ if (x1bstr){ /* empty type does not have body */ - if ((x0b = xml_new("body", NULL, x0, CX_BODY)) == NULL) + if ((x0b = xml_new("body", x0, CX_BODY)) == NULL) goto done; } } @@ -488,7 +491,7 @@ text_modify(clicon_handle h, if (x0){ xml_purge(x0); } - if ((x0 = xml_new(x1name, NULL, x0p, CX_ELMNT)) == NULL) + if ((x0 = xml_new(x1name, x0p, CX_ELMNT)) == NULL) goto done; if (xml_copy(x1, x0) < 0) goto done; @@ -506,7 +509,7 @@ text_modify(clicon_handle h, * copied (see changed conditional below) * Note x0 may dangle cases if exit before changed conditional */ - if ((x0 = xml_new(x1name, NULL, NULL, CX_ELMNT)) == NULL) + if ((x0 = xml_new(x1name, NULL, CX_ELMNT)) == NULL) goto done; xml_spec_set(x0, y0); diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 944d5fe5..507d09a5 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -345,7 +345,9 @@ json2xml_decode_identityref(cxobj *x, if (prefix2 == NULL) prefix2 = yang_find_myprefix(ymod); /* Add "xmlns:prefix2=namespace" */ - if ((xa = xml_new(prefix2, "xmlns", x, CX_ATTR)) == NULL) + if ((xa = xml_new(prefix2, x, CX_ATTR)) == NULL) + goto done; + if (xml_prefix_set(xa, "xmlns") < 0) goto done; if (xml_value_set(xa, namespace) < 0) goto done; @@ -965,7 +967,7 @@ xml2json_cbuf_vec(cbuf *cb, cxobj *xc; cvec *nsc = NULL; - if ((xp = xml_new("xml2json", NULL, NULL, CX_ELMNT)) == NULL) + if ((xp = xml_new("xml2json", NULL, CX_ELMNT)) == NULL) goto done; /* Make a copy of old and graft it into new top-object * Also copy namespace context */ @@ -1295,7 +1297,7 @@ json_parse_str2(char *str, return -1; } if (*xt == NULL){ - if ((*xt = xml_new("top", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xt = xml_new("top", NULL, CX_ELMNT)) == NULL) return -1; } return _json_parse(str, yb, yspec, *xt, xerr); @@ -1316,7 +1318,7 @@ json_parse_str(char *str, } if (*xt == NULL){ yb = YB_TOP; /* ad-hoc #1 */ - if ((*xt = xml_new("top", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xt = xml_new("top", NULL, CX_ELMNT)) == NULL) return -1; } else{ @@ -1397,7 +1399,7 @@ json_parse_file(int fd, jsonbuf[len++] = ch; if (ret == 0){ if (*xt == NULL) - if ((*xt = xml_new(JSON_TOP_SYMBOL, NULL, NULL, CX_ELMNT)) == NULL) + if ((*xt = xml_new(JSON_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL) goto done; if (len){ if ((ret = _json_parse(ptr, yb, yspec, *xt, xerr)) < 0) diff --git a/lib/src/clixon_json_parse.y b/lib/src/clixon_json_parse.y index ce1a1432..44a4c020 100644 --- a/lib/src/clixon_json_parse.y +++ b/lib/src/clixon_json_parse.y @@ -179,8 +179,11 @@ json_current_new(clixon_json_yacc *jy, /* Find colon separator and if found split into prefix:name */ if (nodeid_split(name, &prefix, &id) < 0) goto done; - if ((x = xml_new(id, prefix, jy->jy_current, CX_ELMNT)) == NULL) - goto done; + if ((x = xml_new(id, jy->jy_current, CX_ELMNT)) == NULL) + goto done; + if (xml_prefix_set(x, prefix) < 0) + goto done; + /* If topmost, add to top-list created list */ if (jy->jy_current == jy->jy_xtop){ if (cxvec_append(x, &jy->jy_xvec, &jy->jy_xlen) < 0) @@ -227,7 +230,7 @@ json_current_body(clixon_json_yacc *jy, cxobj *xn; clicon_debug(2, "%s", __FUNCTION__); - if ((xn = xml_new("body", NULL, jy->jy_current, CX_BODY)) == NULL) + if ((xn = xml_new("body", jy->jy_current, CX_BODY)) == NULL) goto done; if (value && xml_value_append(xn, value) < 0) goto done; diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index 29c2d0a4..15e78be4 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -127,12 +127,12 @@ netconf_invalid_value_xml(cxobj **xret, char *encstr = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "%s" "invalid-value" @@ -307,12 +307,12 @@ netconf_bad_attribute_xml(cxobj **xret, char *encstr = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "%s" "bad-attribute" @@ -396,12 +396,12 @@ netconf_common_xml(cxobj **xret, char *encstr = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "%s" "%s" @@ -646,12 +646,12 @@ netconf_access_denied_xml(cxobj **xret, char *encstr = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "%s" "access-denied" @@ -876,12 +876,12 @@ netconf_data_missing_xml(cxobj **xret, cxobj *xerr; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "application" @@ -1004,12 +1004,12 @@ netconf_operation_failed_xml(cxobj **xret, char *encstr = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "%s" "operation-failed" @@ -1083,12 +1083,12 @@ netconf_malformed_message_xml(cxobj **xret, char *encstr = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "rpc" "malformed-message" @@ -1130,12 +1130,12 @@ netconf_data_not_unique_xml(cxobj **xret, cbuf *cb = NULL; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "protocol" "operation-failed" @@ -1143,7 +1143,7 @@ netconf_data_not_unique_xml(cxobj **xret, "error") < 0) goto done; if (cvec_len(cvk)){ - if ((xinfo = xml_new("error-info", NULL, xerr, CX_ELMNT)) == NULL) + if ((xinfo = xml_new("error-info", xerr, CX_ELMNT)) == NULL) goto done; if ((cb = cbuf_new()) == NULL){ clicon_err(OE_UNIX, errno, "cbuf_new"); @@ -1183,12 +1183,12 @@ netconf_minmax_elements_xml(cxobj **xret, cxobj *xerr; if (*xret == NULL){ - if ((*xret = xml_new("rpc-reply", NULL, NULL, CX_ELMNT)) == NULL) + if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL) goto done; } else if (xml_name_set(*xret, "rpc-reply") < 0) goto done; - if ((xerr = xml_new("rpc-error", NULL, *xret, CX_ELMNT)) == NULL) + if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL) goto done; if (xml_parse_va(&xerr, NULL, "protocol" "operation-failed" diff --git a/lib/src/clixon_path.c b/lib/src/clixon_path.c index baa67b73..138da6f2 100644 --- a/lib/src/clixon_path.c +++ b/lib/src/clixon_path.c @@ -953,11 +953,11 @@ api_path2xml_vec(char **vec, clicon_err(OE_XML, 0, "malformed key, expected '=restval'"); goto done; } - if ((x = xml_new(yang_argument_get(y), NULL, x0, CX_ELMNT)) == NULL) + if ((x = xml_new(yang_argument_get(y), x0, CX_ELMNT)) == NULL) goto done; xml_spec_set(x, y); - if ((xb = xml_new("body", NULL, x, CX_BODY)) == NULL) + if ((xb = xml_new("body", x, CX_BODY)) == NULL) goto done; if (restval && xml_value_set(xb, restval) < 0) goto done; @@ -991,7 +991,7 @@ api_path2xml_vec(char **vec, } cvi = NULL; /* create list object */ - if ((x = xml_new(name, NULL, x0, CX_ELMNT)) == NULL) + if ((x = xml_new(name, x0, CX_ELMNT)) == NULL) goto done; xml_spec_set(x, y); @@ -1006,11 +1006,11 @@ api_path2xml_vec(char **vec, goto done; goto fail; } - if ((xn = xml_new(keyname, NULL, x, CX_ELMNT)) == NULL) + if ((xn = xml_new(keyname, x, CX_ELMNT)) == NULL) goto done; xml_spec_set(xn, ykey); - if ((xb = xml_new("body", NULL, xn, CX_BODY)) == NULL) + if ((xb = xml_new("body", xn, CX_BODY)) == NULL) goto done; if (vi++ < nvalvec){ if (xml_value_set(xb, valvec[vi-1]) < 0) @@ -1020,7 +1020,7 @@ api_path2xml_vec(char **vec, break; default: /* eg Y_CONTAINER, Y_LEAF */ if ((x = xml_find_type(x0, NULL, name, CX_ELMNT)) == NULL){ /* eg key of list */ - if ((x = xml_new(name, NULL, x0, CX_ELMNT)) == NULL) + if ((x = xml_new(name, x0, CX_ELMNT)) == NULL) goto done; xml_spec_set(x, y); } diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 02ca779f..6b1c7f78 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -398,7 +398,7 @@ clicon_rpc_get_config(clicon_handle h, if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL) xd = xml_parent(xd); /* point to rpc-reply */ else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){ - if ((xd = xml_new("data", NULL, NULL, CX_ELMNT)) == NULL) + if ((xd = xml_new("data", NULL, CX_ELMNT)) == NULL) goto done; } else{ @@ -754,7 +754,7 @@ clicon_rpc_get(clicon_handle h, if ((xd = xpath_first(xret, NULL, "/rpc-reply/rpc-error")) != NULL) xd = xml_parent(xd); /* point to rpc-reply */ else if ((xd = xpath_first(xret, NULL, "/rpc-reply/data")) == NULL){ - if ((xd = xml_new("data", NULL, NULL, CX_ELMNT)) == NULL) + if ((xd = xml_new("data", NULL, CX_ELMNT)) == NULL) goto done; } else{ diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index 09b44240..aabb8387 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -658,7 +658,7 @@ xml_type(cxobj *xn) * @param[in] type new type * @retval type old type */ -enum cxobj_type +static enum cxobj_type xml_type_set(cxobj *xn, enum cxobj_type type) { @@ -950,25 +950,20 @@ xml_childvec_get(cxobj *x) * * @param[in] name Name of XML node * @param[in] xp The parent where the new xml node will be appended - * @param[in] spec Yang statement of this XML or NULL. + * @param[in] type XML type * @retval xml Created xml object if successful. Free with xml_free() * @retval NULL Error and clicon_err() called * @code * cxobj *x; - * if ((x = xml_new(name, prefix, xparent, CX_ELMNT)) == NULL) + * if ((x = xml_new(name, xparent, CX_ELMNT)) == NULL) * err; * ... * xml_free(x); * @endcode - * @note As a rule, yspec should be given in normal Clixon calls to enable - * proper sorting and insert functionality. Except as follows: - * - type is body or attribute - * - Yang is unknown * @see xml_sort_insert */ cxobj * xml_new(char *name, - char *prefix, cxobj *xp, enum cxobj_type type) { @@ -983,9 +978,6 @@ xml_new(char *name, if (name != NULL && xml_name_set(x, name) < 0) return NULL; - if (prefix != NULL && - xml_prefix_set(x, prefix) < 0) - return NULL; if (xp){ xml_parent_set(x, xp); if (xml_child_append(xp, x) < 0) @@ -996,6 +988,41 @@ xml_new(char *name, return x; } +/*! Create a new XML node and set it's body to a value + * + * @param[in] name The name of the new node + * @param[in] parent The parent to put the new node under + * @param[in] val The value to set in the body + * + * Creates a new node, sets it as a child of the parent, if one was passed in. + * Creates a child of the node, sets the child's type to CX_BODY, and sets + * the value of the body/child. + * Thanks mgsmith@netgate.com + */ +cxobj * +xml_new_body(char *name, + cxobj *parent, + char *val) +{ + cxobj *new_node = NULL; + cxobj *body_node; + + if (!name || !parent || !val) { + return NULL; + } + if ((new_node = xml_new(name, parent, CX_ELMNT)) == NULL) { + return NULL; + } + if ((body_node = xml_new("body", new_node, CX_BODY)) == NULL || + xml_value_set(body_node, val) < 0) { + xml_free(new_node); + new_node = NULL; + body_node = NULL; + } else { + xml_type_set(body_node, CX_BODY); + } + return new_node; +} #ifdef NOTYET /*! Create new xml node given a name and parent. Free with xml_free(). @@ -1202,7 +1229,7 @@ xml_wrap_all(cxobj *xp, if (!is_element(xp)) return NULL; - if ((xw = xml_new(tag, NULL, NULL, CX_ELMNT)) == NULL) + if ((xw = xml_new(tag, NULL, CX_ELMNT)) == NULL) goto done; while (xp->x_childvec_len) if (xml_addsub(xw, xml_child_i(xp, 0)) < 0) @@ -1231,7 +1258,7 @@ xml_wrap(cxobj *xc, cxobj *xp; /* parent */ xp = xml_parent(xc); - if ((xw = xml_new(tag, NULL, xp, CX_ELMNT)) == NULL) + if ((xw = xml_new(tag, xp, CX_ELMNT)) == NULL) goto done; if (xml_addsub(xw, xc) < 0) goto done; @@ -1812,7 +1839,7 @@ xml_copy_one(cxobj *x0, * @retval 0 OK * @retval -1 Error * @code - * x1 = xml_new("new", NULL, xparent, xml_type(x0)); + * x1 = xml_new("new", xparent, xml_type(x0)); * if (xml_copy(x0, x1) < 0) * err; * @endcode @@ -1830,7 +1857,7 @@ xml_copy(cxobj *x0, goto done; x = NULL; while ((x = xml_child_each(x0, x, -1)) != NULL) { - if ((xcopy = xml_new(xml_name(x), NULL, x1, xml_type(x))) == NULL) + if ((xcopy = xml_new(xml_name(x), x1, xml_type(x))) == NULL) goto done; if (xml_copy(x, xcopy) < 0) /* recursion */ goto done; @@ -1854,7 +1881,7 @@ xml_dup(cxobj *x0) { cxobj *x1; - if ((x1 = xml_new("new", NULL, NULL, xml_type(x0))) == NULL) + if ((x1 = xml_new("new", NULL, xml_type(x0))) == NULL) return NULL; if (xml_copy(x0, x1) < 0) return NULL; diff --git a/lib/src/clixon_xml_io.c b/lib/src/clixon_xml_io.c index f9352b16..c844d3b4 100644 --- a/lib/src/clixon_xml_io.c +++ b/lib/src/clixon_xml_io.c @@ -591,7 +591,7 @@ xml_parse_file2(int fd, (endtag && (state == endtaglen))){ state = 0; if (*xt == NULL) - if ((*xt = xml_new(XML_TOP_SYMBOL, NULL, NULL, CX_ELMNT)) == NULL) + if ((*xt = xml_new(XML_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL) goto done; if ((ret = _xml_parse(ptr, yb, yspec, *xt, xerr)) < 0) goto done; @@ -657,7 +657,7 @@ xml_parse_string2(const char *str, return -1; } if (*xt == NULL){ - if ((*xt = xml_new(XML_TOP_SYMBOL, NULL, NULL, CX_ELMNT)) == NULL) + if ((*xt = xml_new(XML_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL) return -1; } return _xml_parse(str, yb, yspec, *xt, xerr); @@ -698,7 +698,7 @@ xml_parse_string(const char *str, } if (*xt == NULL){ yb = YB_TOP; /* ad-hoc #1 */ - if ((*xt = xml_new(XML_TOP_SYMBOL, NULL, NULL, CX_ELMNT)) == NULL) + if ((*xt = xml_new(XML_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL) return -1; } else{ diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 85059046..47014a45 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -386,7 +386,7 @@ cvec2xml_1(cvec *cvv, cv = NULL; while ((cv = cvec_each(cvv, cv)) != NULL) len++; - if ((xt = xml_new(toptag, NULL, xp, CX_ELMNT)) == NULL) + if ((xt = xml_new(toptag, xp, CX_ELMNT)) == NULL) goto err; if (xml_childvec_set(xt, len) < 0) goto err; @@ -395,11 +395,11 @@ cvec2xml_1(cvec *cvv, while ((cv = cvec_each(cvv, cv)) != NULL) { if (cv_type_get(cv)==CGV_ERR || cv_name_get(cv) == NULL) continue; - if ((xn = xml_new(cv_name_get(cv), NULL, NULL, CX_ELMNT)) == NULL) /* this leaks */ + if ((xn = xml_new(cv_name_get(cv), NULL, CX_ELMNT)) == NULL) /* this leaks */ goto err; xml_parent_set(xn, xt); xml_child_i_set(xt, i++, xn); - if ((xb = xml_new("body", NULL, xn, CX_BODY)) == NULL) /* this leaks */ + if ((xb = xml_new("body", xn, CX_BODY)) == NULL) /* this leaks */ goto err; val = cv2str_dup(cv); xml_value_set(xb, val); /* this leaks */ @@ -822,11 +822,13 @@ add_namespace(cxobj *x, goto done; /* Create xmlns attribute to x1p/x1 XXX same code v */ if (prefix){ - if ((xa = xml_new(prefix, "xmlns", xp, CX_ATTR)) == NULL) + if ((xa = xml_new(prefix, xp, CX_ATTR)) == NULL) + goto done; + if (xml_prefix_set(xa, "xmlns") < 0) goto done; } else{ - if ((xa = xml_new("xmlns", NULL, xp, CX_ATTR)) == NULL) + if ((xa = xml_new("xmlns", xp, CX_ATTR)) == NULL) goto done; } if (xml_value_set(xa, namespace) < 0) @@ -924,7 +926,7 @@ xml_default(cxobj *xt, continue; if (!cv_flag(yang_cv_get(y), V_UNSET)){ /* Default value exists */ if (!xml_find(xt, yang_argument_get(y))){ - if ((xc = xml_new(yang_argument_get(y), NULL, NULL, CX_ELMNT)) == NULL) + if ((xc = xml_new(yang_argument_get(y), NULL, CX_ELMNT)) == NULL) goto done; xml_spec_set(xc, y); @@ -948,7 +950,7 @@ xml_default(cxobj *xt, } xml_flag_set(xc, XML_FLAG_DEFAULT); - if ((xb = xml_new("body", NULL, xc, CX_BODY)) == NULL) + if ((xb = xml_new("body", xc, CX_BODY)) == NULL) goto done; if ((str = cv2str_dup(yang_cv_get(y))) == NULL){ clicon_err(OE_UNIX, errno, "cv2str_dup"); @@ -1749,17 +1751,17 @@ xml_merge1(cxobj *x0, /* the target */ if (yang_keyword_get(y0) == Y_LEAF_LIST || yang_keyword_get(y0) == Y_LEAF){ x1bstr = xml_body(x1); if (x0==NULL){ - if ((x0 = xml_new(x1name, NULL, x0p, CX_ELMNT)) == NULL) + if ((x0 = xml_new(x1name, x0p, CX_ELMNT)) == NULL) goto done; xml_spec_set(x0, y0); if (x1bstr){ /* empty type does not have body */ - if ((x0b = xml_new("body", NULL, x0, CX_BODY)) == NULL) + if ((x0b = xml_new("body", x0, CX_BODY)) == NULL) goto done; } } if (x1bstr){ if ((x0b = xml_body_get(x0)) == NULL){ - if ((x0b = xml_new("body", NULL, x0, CX_BODY)) == NULL) + if ((x0b = xml_new("body", x0, CX_BODY)) == NULL) goto done; } if (xml_value_set(x0b, x1bstr) < 0) @@ -1770,7 +1772,7 @@ xml_merge1(cxobj *x0, /* the target */ } /* if LEAF|LEAF_LIST */ else { /* eg Y_CONTAINER, Y_LIST */ if (x0==NULL){ - if ((x0 = xml_new(x1name, NULL, NULL, CX_ELMNT)) == NULL) + if ((x0 = xml_new(x1name, NULL, CX_ELMNT)) == NULL) goto done; xml_spec_set(x0, y0); } diff --git a/lib/src/clixon_xml_nsctx.c b/lib/src/clixon_xml_nsctx.c index cb3cd929..17dd2c21 100644 --- a/lib/src/clixon_xml_nsctx.c +++ b/lib/src/clixon_xml_nsctx.c @@ -489,11 +489,14 @@ xmlns_set(cxobj *x, cxobj *xa; if (prefix != NULL){ /* xmlns:="" */ - if ((xa = xml_new(prefix, "xmlns", x, CX_ATTR)) == NULL) + if ((xa = xml_new(prefix, x, CX_ATTR)) == NULL) goto done; + if (xml_prefix_set(xa, "xmlns") < 0) + goto done; + } else{ /* xmlns="" */ - if ((xa = xml_new("xmlns", NULL, x, CX_ATTR)) == NULL) + if ((xa = xml_new("xmlns", x, CX_ATTR)) == NULL) goto done; } if (xml_value_set(xa, ns) < 0) diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y index 8a836d7d..01ff1f6f 100644 --- a/lib/src/clixon_xml_parse.y +++ b/lib/src/clixon_xml_parse.y @@ -108,7 +108,7 @@ xml_parse_content(clixon_xml_yacc *xy, xy->xy_xelement = NULL; /* init */ if (xn == NULL){ - if ((xn = xml_new("body", NULL, xp, CX_BODY)) == NULL) + if ((xn = xml_new("body", xp, CX_BODY)) == NULL) goto done; } if (xml_value_append(xn, str) < 0) @@ -144,7 +144,7 @@ xml_parse_whitespace(clixon_xml_yacc *xy, goto ok; /* Skip if already element */ } if (xn == NULL){ - if ((xn = xml_new("body", NULL, xp, CX_BODY)) == NULL) + if ((xn = xml_new("body", xp, CX_BODY)) == NULL) goto done; } if (xml_value_append(xn, str) < 0) @@ -187,8 +187,11 @@ xml_parse_prefixed_name(clixon_xml_yacc *xy, cxobj *xp; /* xml parent */ xp = xy->xy_xparent; - if ((x = xml_new(name, prefix, xp, CX_ELMNT)) == NULL) + if ((x = xml_new(name, xp, CX_ELMNT)) == NULL) goto done; + if (xml_prefix_set(x, prefix) < 0) + goto done; + xy->xy_xelement = x; /* If topmost, add to top-list created list */ if (xp == xy->xy_xtop){ @@ -300,8 +303,11 @@ xml_parse_attr(clixon_xml_yacc *xy, cxobj *xa = NULL; if ((xa = xml_find_type(xy->xy_xelement, prefix, name, CX_ATTR)) == NULL){ - if ((xa = xml_new(name, prefix, xy->xy_xelement, CX_ATTR)) == NULL) + if ((xa = xml_new(name, xy->xy_xelement, CX_ATTR)) == NULL) goto done; + if (xml_prefix_set(xa, prefix) < 0) + goto done; + } if (xml_value_set(xa, attval) < 0) goto done; diff --git a/util/clixon_util_path.c b/util/clixon_util_path.c index c0be5ed0..dfc65657 100644 --- a/util/clixon_util_path.c +++ b/util/clixon_util_path.c @@ -116,7 +116,7 @@ main(int argc, if ((h = clicon_handle_init()) == NULL) goto done; /* Initialize config tree (needed for -Y below) */ - if ((xcfg = xml_new("clixon-config", NULL, NULL, CX_ELMNT)) == NULL) + if ((xcfg = xml_new("clixon-config", NULL, CX_ELMNT)) == NULL) goto done; if (clicon_conf_xml_set(h, xcfg) < 0) goto done; diff --git a/util/clixon_util_xml.c b/util/clixon_util_xml.c index d27deb16..fcf42ad2 100644 --- a/util/clixon_util_xml.c +++ b/util/clixon_util_xml.c @@ -169,11 +169,11 @@ main(int argc, /* Initialize clixon handle */ if ((h = clicon_handle_init()) == NULL) goto done; - if ((xcfg = xml_new("clixon-config", NULL, NULL, CX_ELMNT)) == NULL) + if ((xcfg = xml_new("clixon-config", NULL, CX_ELMNT)) == NULL) goto done; if (clicon_conf_xml_set(h, xcfg) < 0) goto done; - xcfg = xml_new("clixon-config", NULL, NULL, CX_ELMNT); + xcfg = xml_new("clixon-config", NULL, CX_ELMNT); clicon_conf_xml_set(h, xcfg); optind = 1; opterr = 0; diff --git a/util/clixon_util_xpath.c b/util/clixon_util_xpath.c index b38a0875..106b91de 100644 --- a/util/clixon_util_xpath.c +++ b/util/clixon_util_xpath.c @@ -147,7 +147,7 @@ main(int argc, if ((h = clicon_handle_init()) == NULL) goto done; /* Initialize config tree (needed for -Y below) */ - if ((xcfg = xml_new("clixon-config", NULL, NULL, CX_ELMNT)) == NULL) + if ((xcfg = xml_new("clixon-config", NULL, CX_ELMNT)) == NULL) goto done; if (clicon_conf_xml_set(h, xcfg) < 0) goto done;