From 56e51f1a8d3fd9aa024a925038bdc8f6a59ce00f Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sun, 22 Jul 2018 21:29:21 +0200 Subject: [PATCH] 3.8.0.PRE preparations and * Obsoleted COMPAT_CLIV and COMPAT_XSL that were optional in 3.7 --- CHANGELOG.md | 18 + apps/backend/backend_client.c | 16 +- apps/cli/cli_common.c | 90 --- apps/cli/cli_show.c | 11 +- apps/cli/clixon_cli_api.h | 21 - configure | 4 +- configure.ac | 4 +- example/example_cli.c | 4 - include/clixon_custom.h | 15 - lib/clixon/clixon.h.in | 1 - lib/clixon/clixon_xsl.h | 50 -- lib/src/Makefile.in | 2 +- lib/src/clixon_options.c | 1 - lib/src/clixon_proto.c | 1 - lib/src/clixon_proto_client.c | 1 - lib/src/clixon_xml_map.c | 17 +- lib/src/clixon_xpath.c | 19 - lib/src/clixon_xsl.c | 1041 --------------------------------- test/lib.sh | 4 - test/test_netconf.sh | 19 +- test/test_order.sh | 18 - test/test_yang.sh | 5 - 22 files changed, 29 insertions(+), 1333 deletions(-) delete mode 100644 lib/clixon/clixon_xsl.h delete mode 100644 lib/src/clixon_xsl.c diff --git a/CHANGELOG.md b/CHANGELOG.md index ff9c8650..b9538186 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Clixon Changelog +## 3.8.0 (Upcoming) + +### Major New features + +### API changes on existing features (you may need to change your code) + +### Minor changes +* Obsoleted COMPAT_CLIV and COMPAT_XSL that were optional in 3.7 + +### Corrected Bugs + +### Known issues +* Namespace name relabeling is not supported. + * Eg: if "des" is defined as prefix for an imported module, then a relabeling using xmlfns is not supported, such as: +``` + x:des3 +``` + ## 3.7.0 (22 July 2018) ### Major New features diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 7ffdbf2b..224b371d 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -987,13 +987,7 @@ nacm_access(clicon_handle h, if (username == NULL) goto step10; /* User's group */ - if (xpath_vec(xacm, -#ifdef COMPAT_XSL - "groups/group[user-name=%s]", -#else - "groups/group[user-name='%s']", -#endif - &gvec, &glen, username) < 0) + if (xpath_vec(xacm, "groups/group[user-name='%s']", &gvec, &glen, username) < 0) goto done; /* 5. If no groups are found, continue with step 10. */ if (glen == 0) @@ -1010,13 +1004,7 @@ nacm_access(clicon_handle h, for (j=0; j #include #include -#include #include #include #include diff --git a/lib/clixon/clixon_xsl.h b/lib/clixon/clixon_xsl.h deleted file mode 100644 index 5d572528..00000000 --- a/lib/clixon/clixon_xsl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - ***** BEGIN LICENSE BLOCK ***** - - Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren - - This file is part of CLIXON. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - Alternatively, the contents of this file may be used under the terms of - the GNU General Public License Version 3 or later (the "GPL"), - in which case the provisions of the GPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of the GPL, and not to allow others to - use your version of this file under the terms of Apache License version 2, - indicate your decision by deleting the provisions above and replace them with - the notice and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the Apache License version 2 or the GPL. - - ***** END LICENSE BLOCK ***** - - * XML XPATH and XSLT functions. - */ -#ifndef _CLIXON_XSL_H -#define _CLIXON_XSL_H - -/* - * Prototypes - */ -int xpath_vec_xsl(cxobj *cxtop, char *xpath, cxobj ***vec, size_t *veclen); -int xpath_vec_flag_xsl(cxobj *cxtop, char *xpath, uint16_t flags, - cxobj ***vec, size_t *veclen); -cxobj *xpath_first_xsl(cxobj *cxtop, char *xpath); -#ifdef COMPAT_XSL -cxobj *xpath_each(cxobj *xn_top, char *xpath, cxobj *prev); -#endif - -#endif /* _CLIXON_XSL_H */ diff --git a/lib/src/Makefile.in b/lib/src/Makefile.in index a37680c9..23126689 100644 --- a/lib/src/Makefile.in +++ b/lib/src/Makefile.in @@ -72,7 +72,7 @@ SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \ clixon_json.c clixon_yang.c clixon_yang_type.c \ clixon_hash.c clixon_options.c clixon_plugin.c \ clixon_proto.c clixon_proto_client.c \ - clixon_xsl.c clixon_xpath.c clixon_xpath_ctx.c clixon_sha1.c \ + clixon_xpath.c clixon_xpath_ctx.c clixon_sha1.c \ clixon_xml_db.c clixon_netconf_lib.c YACCOBJS := lex.clixon_xml_parse.o clixon_xml_parse.tab.o \ diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index cfd0d76c..7b97439f 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -67,7 +67,6 @@ #include "clixon_options.h" #include "clixon_xml.h" #include "clixon_plugin.h" -#include "clixon_xsl.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" #include "clixon_xml_map.h" diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 2a71992e..6b41c6a5 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -71,7 +71,6 @@ #include "clixon_yang.h" #include "clixon_sig.h" #include "clixon_xml.h" -#include "clixon_xsl.h" #include "clixon_proto.h" static int _atomicio_sig = 0; diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index 35c4b28c..63c4e4cf 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -64,7 +64,6 @@ #include "clixon_options.h" #include "clixon_xml.h" #include "clixon_plugin.h" -#include "clixon_xsl.h" #include "clixon_string.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 301dfa0d..4576fc82 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -85,7 +85,6 @@ #include "clixon_plugin.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" -#include "clixon_xsl.h" #include "clixon_log.h" #include "clixon_err.h" #include "clixon_xml_sort.h" @@ -1088,13 +1087,7 @@ api_path_fmt2xpath(char *api_path_fmt, clicon_err(OE_UNIX, errno, "cv2str_dup"); goto done; } - cprintf(cb, -#ifdef COMPAT_XSL - "[%s=%s]", -#else - "[%s='%s']", -#endif - cv_name_get(cv), str); + cprintf(cb, "[%s='%s']", cv_name_get(cv), str); free(str); } } @@ -1511,13 +1504,7 @@ api_path2xpath_cvv(yang_spec *yspec, cprintf(xpath, "/%s", name); v = val; while ((cvi = cvec_each(cvk, cvi)) != NULL){ - cprintf(xpath, -#ifdef COMPAT_XSL - "[%s=%s]", -#else - "[%s='%s']", -#endif - cv_string_get(cvi), v); + cprintf(xpath, "[%s='%s']", cv_string_get(cvi), v); v += strlen(v)+1; } if (val) diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 173b30e5..e4c9513a 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -62,7 +62,6 @@ #include "clixon_handle.h" #include "clixon_yang.h" #include "clixon_xml.h" -#include "clixon_xsl.h" #include "clixon_xpath_parse.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" @@ -1142,16 +1141,11 @@ xpath_first(cxobj *xcur, goto done; } va_end(ap); -#ifdef COMPAT_XSL - if ((cx = xpath_first_xsl(xcur, xpath)) == NULL) - goto done; -#else if (xpath_vec_ctx(xcur, xpath, &xr) < 0) goto done; if (xr && xr->xc_type == XT_NODESET && xr->xc_size) cx = xr->xc_nodeset[0]; -#endif done: if (xr) ctx_free(xr); @@ -1211,10 +1205,6 @@ xpath_vec(cxobj *xcur, va_end(ap); *vec=NULL; *veclen = 0; -#ifdef COMPAT_XSL - if (xpath_vec_xsl(xcur, xpath, vec, veclen) < 0) - goto done; -#else if (xpath_vec_ctx(xcur, xpath, &xr) < 0) goto done; if (xr && xr->xc_type == XT_NODESET){ @@ -1222,7 +1212,6 @@ xpath_vec(cxobj *xcur, xr->xc_nodeset = NULL; *veclen = xr->xc_size; } -#endif retval = 0; done: if (xr) @@ -1268,10 +1257,8 @@ xpath_vec_flag(cxobj *xcur, size_t len; char *xpath = NULL; xp_ctx *xr = NULL; -#ifndef COMPAT_XSL int i; cxobj *x; -#endif va_start(ap, veclen); len = vsnprintf(NULL, 0, format, ap); @@ -1291,10 +1278,6 @@ xpath_vec_flag(cxobj *xcur, va_end(ap); *vec=NULL; *veclen = 0; -#ifdef COMPAT_XSL - if (xpath_vec_flag_xsl(xcur, xpath, flags, vec, veclen) < 0) - goto done; -#else if (xpath_vec_ctx(xcur, xpath, &xr) < 0) goto done; if (xr && xr->xc_type == XT_NODESET){ @@ -1305,8 +1288,6 @@ xpath_vec_flag(cxobj *xcur, goto done; } } -#endif - retval = 0; done: if (xr) diff --git a/lib/src/clixon_xsl.c b/lib/src/clixon_xsl.c deleted file mode 100644 index 86ab22e8..00000000 --- a/lib/src/clixon_xsl.c +++ /dev/null @@ -1,1041 +0,0 @@ -/* - * - ***** BEGIN LICENSE BLOCK ***** - - Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren - - This file is part of CLIXON. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - Alternatively, the contents of this file may be used under the terms of - the GNU General Public License Version 3 or later (the "GPL"), - in which case the provisions of the GPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of the GPL, and not to allow others to - use your version of this file under the terms of Apache License version 2, indicate - your decision by deleting the provisions above and replace them with the - notice and other provisions required by the GPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the Apache License version 2 or the GPL. - - ***** END LICENSE BLOCK ***** - - * Limited XML XPATH and XSLT functions. - * NOTE: there is a main function at the end of this file where you can test out - * different xpath expressions. - * Look at the end of the file for a test unit program - -The code is implemented according to XPATH 1.0: - https://www.w3.org/TR/xpath-10/ - -The primary syntactic construct in XPath is the expression. An expression matches -the production Expr (see https://www.w3.org/TR/xpath-10/#NT-Expr) - */ -#ifdef HAVE_CONFIG_H -#include "clixon_config.h" /* generated by config & autoconf */ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* cligen */ -#include - -/* clicon */ -#include "clixon_err.h" -#include "clixon_log.h" -#include "clixon_string.h" -#include "clixon_queue.h" -#include "clixon_hash.h" -#include "clixon_handle.h" -#include "clixon_yang.h" -#include "clixon_xml.h" -#include "clixon_xpath_ctx.h" -#include "clixon_xpath.h" -#include "clixon_xsl.h" - - -/* Constants */ -#define XPATH_VEC_START 128 - -/* - * Types - */ - -struct searchvec{ - cxobj **sv_v0; /* here is result */ - int sv_v0len; - cxobj **sv_v1; /* this is tmp storage */ - int sv_v1len; - int sv_max; -}; -typedef struct searchvec searchvec; - -/* Local types - */ - -struct xpath_predicate{ - struct xpath_predicate *xp_next; - char *xp_expr; -}; - -/* XPATH Axis according to https://www.w3.org/TR/xpath-10/#NT-Step - * Axis ::= AxisSpecifier NodeTest Predicate* - * Eg "child:: - */ -struct xpath_element{ - struct xpath_element *xe_next; - enum axis_type xe_type; - char *xe_prefix; /* eg for namespaces */ - char *xe_str; /* eg for child */ - struct xpath_predicate *xe_predicate; /* eg within [] */ -}; - -/* Mapping between axis type string <--> int */ -static const map_str2int axismap[] = { - {"self", A_SELF}, - {"child", A_CHILD}, - {"parent", A_PARENT}, - {"root", A_ROOT}, - {"ancestor", A_ANCESTOR}, - {"descendant-or-self", A_DESCENDANT_OR_SELF}, - {NULL, -1} -}; - -static int xpath_split(char *xpathstr, char **pathexpr); - -/*! Print xpath structure for debug */ -static int -xpath_print(FILE *f, - struct xpath_element *xplist) -{ - struct xpath_element *xe; - struct xpath_predicate *xp; - - for (xe=xplist; xe; xe=xe->xe_next){ - fprintf(f, "\t:%s %s ", clicon_int2str(axismap, xe->xe_type), - xe->xe_str?xe->xe_str:""); - for (xp=xe->xe_predicate; xp; xp=xp->xp_next) - fprintf(f, "[%s]", xp->xp_expr); - } - return 0; -} - -/*! Extract PredicateExpr (Expr) from a Predicate within [] - * @see xpath_expr For evaluation of predicate - */ -static int -xpath_parse_predicate(struct xpath_element *xe, - char *pred) -{ - int retval = -1; - struct xpath_predicate *xp; - char *s; - int i; - int len; - - len = strlen(pred); - for (i=len-1; i>=0; i--){ /* -1 since we search for ][ */ - s = &pred[i]; - if (i==0 || - (*(s)==']' && *(s+1)=='[')){ - if (i) { - *(s)= '\0'; - s += 2; - } - if ((xp = malloc(sizeof(*xp))) == NULL){ - clicon_err(OE_UNIX, errno, "malloc"); - goto done; - } - memset(xp, 0, sizeof(*xp)); - if ((xp->xp_expr = strdup(s)) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - xp->xp_next = xe->xe_predicate; - xe->xe_predicate = xp; - } - } - retval = 0; - done: - return retval; -} - -/*! XPATH parse, create new child element - * @param[in] atype Axis type, see https://www.w3.org/TR/xpath-10/#axes - * @param[in] str - * @param[out] xpnext - */ -static int -xpath_element_new(enum axis_type atype, - char *str, - struct xpath_element ***xpnext) -{ - int retval = -1; - struct xpath_element *xe; - char *str1 = NULL; - char *pred; - char *local; - - if ((xe = malloc(sizeof(*xe))) == NULL){ - clicon_err(OE_UNIX, errno, "malloc"); - goto done; - } - memset(xe, 0, sizeof(*xe)); - xe->xe_type = atype; - if (str){ - if ((str1 = strdup(str)) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - if (xpath_split(str1, &pred) < 0) /* Can be more predicates */ - goto done; - if (strlen(str1)){ - /* Split into prefix and localname */ - if ((local = index(str1, ':')) != NULL){ - *local = '\0'; - local++; - if ((xe->xe_prefix = strdup(str1)) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - } - else - local = str1; - if ((xe->xe_str = strdup(local)) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - } - else{ - if ((xe->xe_str = strdup("*")) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - } - if (pred && strlen(pred)){ - if (xpath_parse_predicate(xe, pred) < 0) - goto done; - } - } - (**xpnext) = xe; - *xpnext = &xe->xe_next; - retval = 0; - done: - if (str1) - free(str1); - return retval; -} - -static int -xpath_element_free(struct xpath_element *xe) -{ - struct xpath_predicate *xp; - - if (xe->xe_str) - free(xe->xe_str); - if (xe->xe_prefix) - free(xe->xe_prefix); - while ((xp = xe->xe_predicate) != NULL){ - xe->xe_predicate = xp->xp_next; - if (xp->xp_expr) - free(xp->xp_expr); - free(xp); - } - free(xe); - return 0; -} - -static int -xpath_free(struct xpath_element *xplist) -{ - struct xpath_element *xe, *xe_next; - - for (xe=xplist; xe; xe=xe_next){ - xe_next = xe->xe_next; - xpath_element_free(xe); - } - return 0; -} - -/*! Parse xpath to xpath_element structure - - * - * [1] LocationPath ::= RelativeLocationPath - * | AbsoluteLocationPath - * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? - * | AbbreviatedAbsoluteLocationPath - * [3] RelativeLocationPath ::= Step - | RelativeLocationPath '/' Step - | AbbreviatedRelativeLocationPath - * @see https://www.w3.org/TR/xpath-10/#NT-LocationPath - */ -static int -xpath_parse(char *xpath, - struct xpath_element **xplist0) -{ - int retval = -1; - int nvec = 0; - char *s; - char *s0; - int i; - struct xpath_element *xplist = NULL; - struct xpath_element **xpnext = &xplist; - int esc = 0; - - if ((s0 = strdup(xpath)) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - s = s0; - if (strlen(s)) - nvec = 1; - /* Chop up LocationPath in Steps delimited by '/' (unless [] predicate) - * Eg, "/a/b[/c]/d" -> "a" "b[/c]" "d" - */ - esc = 0; - while (*s != '\0'){ - switch (*s){ - case '/': - if (esc) - break; - nvec++; - *s = '\0'; - break; - case '[': - esc++; - break; - case ']': - esc--; - break; - default: - break; - } - s++; - } - /* Iterate through steps (s), see https://www.w3.org/TR/xpath-10/#NT-Step */ - s = s0; - for (i=0; i= - * - - * - = # RelationalExpr '=' RelationalExpr - * - =current() XXX - * @see https://www.w3.org/TR/xpath/#predicates - */ -static int -xpath_expr(cxobj *xcur, - char *predicate_expression, - uint16_t flags, - cxobj ***vec0, - size_t *vec0len) -{ - char *e_a; - char *e_v; - int i; - int j; - int retval = -1; - cxobj *x; - cxobj *xv; - cxobj **vec = NULL; - size_t veclen = 0; - int oplen; - char *tag; - char *val; - char *e0; - char *e; - char *name; - - if ((e0 = strdup(predicate_expression)) == NULL){ - clicon_err(OE_UNIX, errno, "strdup"); - goto done; - } - e = e0; - if (*e == '@'){ /* @ attribute */ - e++; - e_v=e; - e_a = strsep(&e_v, "="); - if (e_a == NULL){ - clicon_err(OE_XML, errno, "malformed expression: [@%s]", e); - goto done; - } - for (i=0; i<*vec0len; i++){ - xv = (*vec0)[i]; - if ((x = xml_find(xv, e_a)) != NULL && - (xml_type(x) == CX_ATTR)){ - if (!e_v || strcmp(xml_value(x), e_v) == 0){ - clicon_debug(2, "%s %x %x", __FUNCTION__, flags, xml_flag(xv, flags)); - if (flags==0x0 || xml_flag(xv, flags)){ - if (cxvec_append(xv, &vec, &veclen) < 0) - goto done; - break; /* xv added */ - } - } - } - } - } - else{ /* either or , where ='=' for now */ - oplen = strcspn(e, "="); - if (strlen(e+oplen)==0){ /* no operator */ - if (sscanf(e, "%d", &i) == 1){ /* number */ - if (i < *vec0len){ - xv = (*vec0)[i]; /* XXX: cant compress: gcc breaks */ - clicon_debug(2, "%s %x %x", __FUNCTION__, flags, xml_flag(xv, flags)); - if (flags==0x0 || xml_flag(xv, flags)) - if (cxvec_append(xv, &vec, &veclen) < 0) - goto done; - } - } - else{ - clicon_err(OE_XML, errno, "malformed expression: [%s]", e); - goto done; - } - } - else{ /* name = expr */ - if ((tag = strsep(&e, "=")) == NULL){ - clicon_err(OE_XML, errno, "malformed expression: [%s]", e); - goto done; - } - /* Strip trailing spaces */ - while (tag[strlen(tag)-1] == ' ') - tag[strlen(tag)-1] = '\0'; - /* Strip heading spaces */ - while (e[0]==' ') - e++; - if (strncmp(e, "current()", strlen("current()")) == 0){ - /* name = current()xpath */ - cxobj **svec0 = NULL; - size_t svec0len = 0; - cxobj **svec1 = NULL; - size_t svec1len = 0; - char *ebody; - - e += strlen("current("); /* e is path expression */ - *e = '.'; - if ((svec0 = calloc(1, sizeof(cxobj *))) == NULL){ - clicon_err(OE_UNIX, errno, "calloc"); - goto done; - } - svec0[0] = xcur; - svec0len++; - /* Recursive invocation */ - if (xpath_exec(xcur, e, svec0, svec0len, - flags, &svec1, &svec1len) < 0) - goto done; - for (j=0; jxe_type), xe->xe_str?xe->xe_str:""); -#endif - switch (xe->xe_type){ - case A_SELF: - break; - case A_PARENT: - j = 0; - for (i=0; ixe_str, CX_ELMNT, flags, &vec1, &vec1len) < 0) - goto done; - } - } - else{ - for (i=0; ixe_str, name, 0) == 0) { - clicon_debug(2, "%s %x %x", __FUNCTION__, flags, xml_flag(x, flags)); - if (flags==0x0 || xml_flag(x, flags)) - if (cxvec_append(x, &vec1, &vec1len) < 0) - goto done; - } - } - } - } - free(vec0); - vec0 = vec1; - vec0len = vec1len; - break; - case A_DESCENDANT_OR_SELF: - /* Instead of collecting all descendants (which we could) - just set a flag and treat that in the next operation */ - descendants++; - break; - default: - break; - } - /* remove duplicates - * This is cycle-heavy and I dont know when it is needed? - */ - if (0) - for (i=0; ixe_predicate; xp; xp = xp->xp_next){ - if (xpath_expr(xcur, xp->xp_expr, flags, &vec0, &vec0len) < 0) - goto done; - } - - if (xpath_find(xcur, xe->xe_next, descendants, - vec0, vec0len, flags, - vec2, vec2len) < 0) - goto done; - retval = 0; - done: - return retval; -} - -/*! Transform eg "a/b[kalle]" -> "a/b" e="kalle" - * @param[in,out] xpathstr Eg "a/b[kalle]" -> "a/b" - * @param[out] pathexpr Eg "kalle" - * Which also means: - * "a/b[foo][bar]" -> pathexpr: "foo][bar" - * @note destructively modify xpathstr, no new strings allocated - */ -static int -xpath_split(char *xpathstr, - char **pathexpr) -{ - int retval = -1; - int last; - char *pe = NULL; - - if (strlen(xpathstr)){ - last = strlen(xpathstr) - 1; /* XXX: this could be -1.. */ - if (xpathstr[last] == ']'){ - xpathstr[last] = '\0'; - if (strlen(xpathstr)){ - if ((pe = index(xpathstr,'[')) != NULL){ - *pe = '\0'; - pe++; - } - } - if (pe==NULL){ - clicon_err(OE_XML, errno, "mismatched []: %s", xpathstr); - goto done; - } - } - } - retval = 0; - done: - *pathexpr = pe; - return retval; -} - -/*! Process single xpath expression on xml tree - * @param[in] xcur xml-tree where to search - * @param[in] xpath string with XPATH syntax - * @param[in] vec0 vector of XML trees - * @param[in] vec0len length of XML trees - * @param[in] flags if != 0, only match xml nodes matching flags - * @param[out] vec2 Result XML node vector - * @param[out] vec2len Length of result vector. - * @see https://www.w3.org/TR/xpath-10/#NT-LocationPath - */ -static int -xpath_exec(cxobj *xcur, - char *xpath, - cxobj **vec0, - size_t vec0len, - uint16_t flags, - cxobj ***vec2, - size_t *vec2len) -{ - struct xpath_element *xplist; - cxobj **vec1; - size_t vec1len; - - if (cxvec_dup(vec0, vec0len, &vec1, &vec1len) < 0) - goto done; - if (xpath_parse(xpath, &xplist) < 0) - goto done; - if (debug > 1) - xpath_print(stderr, xplist); - if (xpath_find(xcur, xplist, 0, vec1, vec1len, flags, vec2, vec2len) < 0) - goto done; - if (xpath_free(xplist) < 0) - goto done; - done: - return 0; -} /* xpath_exec */ - - -/*! Intermediate xpath function to handle 'conditional' cases. - * @param[in] xcur xml-tree where to search - * @param[in] xpath string with XPATH syntax - * @param[in] flags if != 0, only match xml nodes matching flags - * @param[out] vec1 vector of XML trees - * @param[out] vec1len length of XML trees - * For example: xpath = //a | //b. - * xpath_first+ splits xpath up in several subcalls - * (eg xpath=//a and xpath=//b) and collects the results. - * Note: if a match is found in both, two (or more) same results will be - * returned. - * Note, this could be 'folded' into xpath1 but I judged it too complex. - * @see https://www.w3.org/TR/xpath-10/#NT-Expr - * An 'Expr' is composed of compositions of and, or, =, +, -, down to: - * PathExpr ::= LocationPath - * | FilterExpr - * | FilterExpr '/' RelativeLocationPath - * | FilterExpr '//' RelativeLocationPath - */ -static int -xpath_choice(cxobj *xcur, - char *xpath0, - uint16_t flags, - cxobj ***vec1, - size_t *vec1len) -{ - int retval = -1; - char *s0 = NULL; - char *s1; - char *s2; - char *xpath; - cxobj **vec0 = NULL; - size_t vec0len = 0; - - if ((s0 = strdup(xpath0)) == NULL){ - clicon_err(OE_XML, errno, "strdup"); - goto done; - } - s2 = s1 = s0; - if ((vec0 = calloc(1, sizeof(cxobj *))) == NULL){ - clicon_err(OE_UNIX, errno, "calloc"); - goto done; - } - vec0[0] = xcur; - vec0len++; - while (s1 != NULL){ - s2 = strstr(s1, " | "); - if (s2 != NULL){ - *s2 = '\0'; /* terminate xpath */ - s2 += 3; - } - xpath = s1; - s1 = s2; - if (xpath_exec(xcur, xpath, vec0, vec0len, flags, vec1, vec1len) < 0) - goto done; - } - retval = 0; - done: - if (s0) - free(s0); - if (vec0) - free(vec0); - return retval; -} - -/*! Xpath nodeset function where only the first matching entry is returned - * args: - * @param[in] xcur xml-tree where to search - * @param[in] xpath string with XPATH syntax - * @retval 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 fter use. - * @note return value does not see difference between error and not found - * @see xpath_first. This is obsolete and only enabled with COMPAT_XSL - */ -cxobj * -xpath_first_xsl(cxobj *xcur, - char *xpath) -{ - cxobj **vec1 = NULL; - size_t vec1len = 0; - cxobj *xn = NULL; - - if (xpath_choice(xcur, xpath, 0, &vec1, &vec1len) < 0) - goto done; - if (vec1len) - xn = vec1[0]; - else - xn = NULL; - done: - if (vec1) - free(vec1); - return xn; -} - -#ifdef COMPAT_XSL -/*! A restricted xpath iterator that loops over all matching entries. Dont use. - * - * See xpath1() on details for subset. - * @param[in] xcur xml-tree where to search - * @param[in] xpath string with XPATH syntax - * @param[in] xprev iterator/result should be initiated to NULL - * @retval xml-tree of n:th match, or NULL on error. - * - * @code - * cxobj *x = NULL; - * while ((x = xpath_each(xcur, "//symbol/foo", x)) != NULL) { - * ... - * } - * @endcode - * - * @note The returned pointer points into the original tree so should not be freed - * after use. - * @note obsolete. Dont use - */ -cxobj * -xpath_each(cxobj *xcur, - char *xpath, - cxobj *xprev) -{ - static cxobj **vec1 = NULL; /* XXX */ - static size_t vec1len = 0; - cxobj *xn = NULL; - int i; - - if (xprev == NULL){ - if (vec1) { - free(vec1); - vec1 = NULL; - } - vec1len = 0; - if (xpath_choice(xcur, xpath, 0, &vec1, &vec1len) < 0) - goto done; - } - if (vec1len){ - if (xprev==NULL) - xn = vec1[0]; - else{ - for (i=0; i=vec1len-1) - xn = NULL; - else - xn = vec1[i+1]; - } - } - else - xn = NULL; - done: - return xn; -} -#endif - -/*! A restricted xpath that returns a vector of matches - * - * See xpath1() on details for subset - * @param[in] xcur xml-tree where to search - * @param[in] xpath string with 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 **xvec = NULL; - * size_t xlen; - * if (xpath_vec(xcur, "//symbol/foo", &xvec, &xlen) < 0) - * goto err; - * for (i=0; ieth/0/0ex:ethnone ]]>]]>' "^]]>]]>$" # Too many quotes, (single inside double inside single) need to fool bash -if [ -z "$COMPAT_XSL" ]; then cat < $tmp # new ]]>]]> EOF -else # old -cat < $tmp -]]>]]> -EOF -fi + new "Check eth/0/0 added using xpath" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "$(cat $tmp)" "^eth/0/0ex:ethtrue]]>]]>$" @@ -122,29 +117,17 @@ new "netconf edit config" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "eth/0/0eth1true
9.2.3.424
]]>]]>" "^]]>]]>$" # Too many quotes -if [ -z "$COMPAT_XSL" ]; then cat < $tmp # new ]]>]]> EOF -else -cat < $tmp # old -]]>]]> -EOF -fi new "netconf get config xpath" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "$(cat $tmp)" "^eth1true]]>]]>$" # Too many quotes -if [ -z "$COMPAT_XSL" ]; then cat < $tmp # new ]]>]]> EOF -else -cat < $tmp # old -]]>]]> -EOF -fi new "netconf get config xpath parent" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "$(cat $tmp)" "^eth/0/0trueeth1truetruefalse
9.2.3.424
]]>]]>$" diff --git a/test/test_order.sh b/test/test_order.sh index 848e839a..5d292c1f 100755 --- a/test/test_order.sh +++ b/test/test_order.sh @@ -121,8 +121,6 @@ fi new "verify running from start, should be: l,c,y0,y1,y2,y3; y1 and y3 sorted. Note this fails if XML_SORT set to false" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^hejhoppdbcaabcddbarabarcbarbbarabarbbarcbardbar]]>]]>$" -if [ -z "$COMPAT_XSL" ]; then #new - new "get each ordered-by user leaf-list" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^abar]]>]]>$" @@ -135,22 +133,6 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^bbar]]>]]>$" -else # old - -new "get each ordered-by user leaf-list" -expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^abar]]>]]>$" - -new "get each ordered-by user leaf-list" -expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^abar]]>]]>$" - -new "get each ordered-by user leaf-list" -expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^bbar]]>]]>$" - -new "get each ordered-by user leaf-list" -expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^bbar]]>]]>$" - -fi - new "delete candidate" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" diff --git a/test/test_yang.sh b/test/test_yang.sh index 7ebbbf12..3b59cfa7 100755 --- a/test/test_yang.sh +++ b/test/test_yang.sh @@ -136,13 +136,8 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^hejhopp]]>]]>$" -if [ -z "$COMPAT_XSL" ]; then # new new "netconf get leaf-list path" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^hejhopp]]>]]>$" -else # old -new "netconf get leaf-list path" -expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^hejhopp]]>]]>$" -fi new "netconf get (should be some)" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^125one]]>]]>$"