Backward compatible XPATH via symbols, not macros

This commit is contained in:
Olof hagsand 2018-07-20 10:51:12 +02:00
parent c71791f168
commit 226c59f25a
10 changed files with 114 additions and 164 deletions

View file

@ -62,6 +62,7 @@
#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"
@ -1091,10 +1092,27 @@ xpath_vec_ctx(cxobj *xcur,
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 also xpath_vec.
*/
cxobj *
xpath_first_nodeset(cxobj *xcur,
char *format,
...)
xpath_first(cxobj *xcur,
char *format,
...)
{
cxobj *cx = NULL;
va_list ap;
@ -1118,10 +1136,16 @@ xpath_first_nodeset(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);
@ -1140,11 +1164,11 @@ xpath_first_nodeset(cxobj *xcur,
* @retval -1 Error
*/
int
xpath_vec_nodeset(cxobj *xcur,
char *format,
cxobj ***vec,
size_t *veclen,
...)
xpath_vec(cxobj *xcur,
char *format,
cxobj ***vec,
size_t *veclen,
...)
{
int retval = -1;
va_list ap;
@ -1168,6 +1192,10 @@ xpath_vec_nodeset(cxobj *xcur,
goto done;
}
va_end(ap);
#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){
@ -1175,6 +1203,7 @@ xpath_vec_nodeset(cxobj *xcur,
xr->xc_nodeset = NULL;
*veclen = xr->xc_size;
}
#endif
retval = 0;
done:
if (xr)
@ -1184,7 +1213,7 @@ xpath_vec_nodeset(cxobj *xcur,
return retval;
}
/* A restricted xpath that returns a vector of matches (only nodes marked with flags)
/* 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] flags Set of flags that return nodes must match (0 if all)
@ -1208,20 +1237,22 @@ xpath_vec_nodeset(cxobj *xcur,
* @see also xpath_vec This is a specialized version.
*/
int
xpath_vec_nodeset_flag(cxobj *xcur,
char *format,
uint16_t flags,
cxobj ***vec,
size_t *veclen,
...)
xpath_vec_flag(cxobj *xcur,
char *format,
uint16_t flags,
cxobj ***vec,
size_t *veclen,
...)
{
int retval = -1;
va_list ap;
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);
@ -1239,6 +1270,10 @@ xpath_vec_nodeset_flag(cxobj *xcur,
goto done;
}
va_end(ap);
#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;
@ -1250,6 +1285,8 @@ xpath_vec_nodeset_flag(cxobj *xcur,
goto done;
}
}
#endif
retval = 0;
done:
if (xr)

View file

@ -859,11 +859,26 @@ xpath_choice(cxobj *xcur,
return retval;
}
/*! Help function to xpath_first
/*! 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
*/
static cxobj *
xpath_first0(cxobj *xcur,
char *xpath)
cxobj *
xpath_first_xsl(cxobj *xcur,
char *xpath)
{
cxobj **vec1 = NULL;
size_t vec1len = 0;
@ -881,57 +896,6 @@ xpath_first0(cxobj *xcur,
return xn;
}
/*! A restricted xpath function where the first matching entry is returned
* See xpath1() on details for subset.
* 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 after use.
* @note return value does not see difference between error and not found
* @see also xpath_vec.
*/
cxobj *
xpath_first_xsl(cxobj *xcur,
char *format,
...)
{
cxobj *retval = NULL;
va_list ap;
size_t len;
char *xpath;
va_start(ap, format);
len = vsnprintf(NULL, 0, format, 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, format);
if (vsnprintf(xpath, len+1, format, ap) < 0){
clicon_err(OE_UNIX, errno, "vsnprintf");
va_end(ap);
goto done;
}
va_end(ap);
retval = xpath_first0(xcur, xpath);
done:
if (xpath)
free(xpath);
return retval;
}
/*! A restricted xpath iterator that loops over all matching entries. Dont use.
*
* See xpath1() on details for subset.
@ -949,8 +913,7 @@ xpath_first_xsl(cxobj *xcur,
*
* @note The returned pointer points into the original tree so should not be freed
* after use.
* @see also xpath, xpath_vec.
* @note uses a static variable: consider replacing with xpath_vec() instead
* @note obsolete. Dont use
*/
cxobj *
xpath_each(cxobj *xcur,
@ -1014,41 +977,22 @@ xpath_each(cxobj *xcur,
* @note Although the returned vector must be freed after use,
* the returned xml trees should not.
* @see also xpath_first, xpath_each.
* @see xpath_vec. This is obsolete and only enabled with COMPAT_XSL
*/
int
xpath_vec_xsl(cxobj *xcur,
char *format,
cxobj ***vec,
size_t *veclen,
...)
char *xpath,
cxobj ***vec,
size_t *veclen)
{
int retval = -1;
va_list ap;
size_t len;
char *xpath = NULL;
va_start(ap, veclen);
len = vsnprintf(NULL, 0, format, 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, format, ap) < 0){
clicon_err(OE_UNIX, errno, "vsnprintf");
va_end(ap);
goto done;
}
va_end(ap);
*vec = NULL;
*veclen = 0;
retval = xpath_choice(xcur, xpath, 0x0, vec, veclen);
if (xpath_choice(xcur, xpath, 0x0, vec, veclen) < 0)
goto done;
retval = 0;
done:
if (xpath)
free(xpath);
return retval;
}
@ -1073,43 +1017,23 @@ xpath_vec_xsl(cxobj *xcur,
* @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.
* @see xpath_vec_flag. This is obsolete and only enabled with COMPAT_XSL
*/
int
xpath_vec_flag_xsl(cxobj *xcur,
char *format,
char *xpath,
uint16_t flags,
cxobj ***vec,
size_t *veclen,
...)
size_t *veclen)
{
int retval = -1;
va_list ap;
size_t len;
char *xpath;
va_start(ap, veclen);
len = vsnprintf(NULL, 0, format, 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, format, ap) < 0){
clicon_err(OE_UNIX, errno, "vsnprintf");
va_end(ap);
goto done;
}
va_end(ap);
*vec=NULL;
*veclen = 0;
retval = xpath_choice(xcur, xpath, flags, vec, veclen);
if (xpath_choice(xcur, xpath, flags, vec, veclen) < 0)
goto done;
retval = 0;
done:
if (xpath)
free(xpath);
return retval;
}