- New netconf-specific uint32 parse functions

- Added failure handling to xpath traverse_canonical
- Started pagination cli code
This commit is contained in:
Olof hagsand 2021-08-30 14:43:24 +02:00
parent 390b0886ed
commit a046306270
16 changed files with 410 additions and 241 deletions

View file

@ -930,37 +930,64 @@ xpath_vec_bool(cxobj *xcur,
return retval;
}
/*!
/*! Translate an xpath/nsc pair to a "canonical" form using yang prefixes
*
* @param[in] xs Parsed xpath - xpath_tree
* @param[in] yspec Yang spec containing all modules, associated with namespaces
* @param[in] nsc0 Input namespace context
* @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free
* @param[out] reason Error reason if result is 0 - failed
* @retval 1 OK with nsc1 containing the transformed nsc
* @retval 0 XPath failure with reason set to why
* @retval -1 Fatal Error
*/
static int
traverse_canonical(xpath_tree *xs,
yang_stmt *yspec,
cvec *nsc0,
cvec *nsc1)
cvec *nsc1,
cbuf **reason)
{
int retval = -1;
char *prefix0;
char *prefix1;
char *namespace;
yang_stmt *ymod;
cbuf *cb = NULL;
int ret;
switch (xs->xs_type){
case XP_NODE: /* s0 is namespace prefix, s1 is name */
prefix0 = xs->xs_s0;
if ((namespace = xml_nsctx_get(nsc0, prefix0)) == NULL){
clicon_err(OE_XML, ENOENT, "No namespace found for prefix: %s",
prefix0);
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cb, "No namespace found for prefix: %s", prefix0);
if (reason)
*reason = cb;
goto failed;
}
if ((ymod = yang_find_module_by_namespace(yspec, namespace)) == NULL){
clicon_err(OE_XML, ENOENT, "No modules found for namespace: %s",
namespace);
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cb, "No modules found for namespace: %s", namespace);
if (reason)
*reason = cb;
goto failed;
}
if ((prefix1 = yang_find_myprefix(ymod)) == NULL){
clicon_err(OE_XML, ENOENT, "No prefix found in module: %s",
yang_argument_get(ymod));
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
cprintf(cb, "No prefix found in module: %s", yang_argument_get(ymod));
if (reason)
*reason = cb;
goto failed;
}
if (xml_nsctx_get(nsc1, prefix1) == NULL)
if (xml_nsctx_add(nsc1, prefix1, namespace) < 0)
@ -977,25 +1004,36 @@ traverse_canonical(xpath_tree *xs,
default:
break;
}
if (xs->xs_c0)
if (traverse_canonical(xs->xs_c0, yspec, nsc0, nsc1) < 0)
if (xs->xs_c0){
if ((ret = traverse_canonical(xs->xs_c0, yspec, nsc0, nsc1, reason)) < 0)
goto done;
if (xs->xs_c1)
if (traverse_canonical(xs->xs_c1, yspec, nsc0, nsc1) < 0)
if (ret == 0)
goto failed;
}
if (xs->xs_c1){
if ((ret = traverse_canonical(xs->xs_c1, yspec, nsc0, nsc1, reason)) < 0)
goto done;
retval = 0;
if (ret == 0)
goto failed;
}
retval = 1;
done:
return retval;
failed:
retval = 0;
goto done;
}
/*! Translate an xpath/nsc pair to a "canonical" form using yang prefixes
*
* @param[in] xpath0 Input xpath
* @param[in] nsc0 Input namespace context
* @param[in] yspec Yang spec containing all modules, associated with namespaces
* @param[out] xpath1 Output xpath. Free after use with free
* @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free
* @retval 0 OK, xpath1 and nsc1 allocated
* @retval -1 Error
* @retval 1 OK, xpath1 and nsc1 allocated
* @retval 0 XPath failure with reason set to why
* @retval -1 Fatal Error
* Example:
* Module A has prefix a and namespace urn:example:a and symbols x
* Module B with prefix b and namespace urn:example:b and symbols y
@ -1008,7 +1046,8 @@ traverse_canonical(xpath_tree *xs,
* @code
* char *xpath1 = NULL;
* cvec *nsc1 = NULL;
* if (xpath2canonical(xpath0, nsc0, yspec, &xpath1, &nsc1) < 0)
* cbuf *reason = NULL;
* if ((ret = xpath2canonical(xpath0, nsc0, yspec, &xpath1, &nsc1, &reason)) < 0)
* err;
* ...
* if (xpath1) free(xpath1);
@ -1017,15 +1056,17 @@ traverse_canonical(xpath_tree *xs,
*/
int
xpath2canonical(const char *xpath0,
cvec *nsc0,
yang_stmt *yspec,
char **xpath1,
cvec **nsc1p)
cvec *nsc0,
yang_stmt *yspec,
char **xpath1,
cvec **nsc1p,
cbuf **cbreason)
{
int retval = -1;
xpath_tree *xpt = NULL;
cvec *nsc1 = NULL;
cbuf *xcb = NULL;
int ret;
/* Parse input xpath into an xpath-tree */
if (xpath_parse(xpath0, &xpt) < 0)
@ -1036,8 +1077,10 @@ xpath2canonical(const char *xpath0,
/* Traverse tree to find prefixes, transform them to canonical form and
* create a canonical network namespace
*/
if (traverse_canonical(xpt, yspec, nsc0, nsc1) < 0)
if ((ret = traverse_canonical(xpt, yspec, nsc0, nsc1, cbreason)) < 0)
goto done;
if (ret == 0)
goto failed;
/* Print tree with new prefixes */
if ((xcb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
@ -1055,7 +1098,7 @@ xpath2canonical(const char *xpath0,
*nsc1p = nsc1;
nsc1 = NULL;
}
retval = 0;
retval = 1;
done:
if (xcb)
cbuf_free(xcb);
@ -1064,6 +1107,9 @@ xpath2canonical(const char *xpath0,
if (xpt)
xpath_tree_free(xpt);
return retval;
failed:
retval = 0;
goto done;
}
/*! Return a count(xpath)