Added XPATH function boolean()
* This caused problem for new NTP YANG in RFC 9249 Fixed segv on anydata for http parser
This commit is contained in:
parent
19b210b1b6
commit
38027c8331
7 changed files with 76 additions and 11 deletions
|
|
@ -99,6 +99,8 @@ Developers may need to change their code
|
|||
|
||||
### Minor features
|
||||
|
||||
* Added XPATH function `boolean()`
|
||||
* This caused problem for new NTP YANG in RFC 9249
|
||||
* Full RFC 7950 if-feature-expr support (Section 7.20.2)
|
||||
* Previous implementation did not handle nested if-feature expressions
|
||||
* As part of fixing: [YANG if-feature does not support nested boolean expression](https://github.com/clicon/clixon/issues/341)
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ xml2txt1(cxobj *xn,
|
|||
xc = NULL;
|
||||
while ((xc = xml_child_each(xn, xc, -1)) != NULL){
|
||||
if (xml_type(xc) == CX_ELMNT || xml_type(xc) == CX_BODY){
|
||||
if (yang_key_match(yn, xml_name(xc), NULL))
|
||||
if (yn && yang_key_match(yn, xml_name(xc), NULL))
|
||||
continue; /* Skip keys, already printed */
|
||||
if (xml2txt1(xc, fn, f, level+1, leafl, leaflname) < 0)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1070,6 +1070,11 @@ xp_eval(xp_ctx *xc,
|
|||
goto done;
|
||||
goto ok;
|
||||
break;
|
||||
case XPATHFN_BOOLEAN:
|
||||
if (xp_function_boolean(xc, xs->xs_c0, nsc, localonly, xrp) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
break;
|
||||
case XPATHFN_NOT:
|
||||
if (xp_function_not(xc, xs->xs_c0, nsc, localonly, xrp) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -635,12 +635,18 @@ xp_function_contains(xp_ctx *xc,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! The not function returns true if its argument is false, and false otherwise.
|
||||
/*! The boolean function converts its argument to a boolean
|
||||
*
|
||||
* Signature: boolean not(boolean)
|
||||
* Conversion is as follows:
|
||||
* - a number is true if and only if it is neither positive or negative zero nor NaN
|
||||
* - a node-set is true if and only if it is non-empty
|
||||
* - a string is true if and only if its length is non-zero
|
||||
* - an object of a type other than the four basic types is converted to a boolean in a way that
|
||||
* is dependent on that type
|
||||
* Signature: boolean boolean(object)
|
||||
*/
|
||||
int
|
||||
xp_function_not(xp_ctx *xc,
|
||||
xp_function_boolean(xp_ctx *xc,
|
||||
struct xpath_tree *xs,
|
||||
cvec *nsc,
|
||||
int localonly,
|
||||
|
|
@ -664,7 +670,7 @@ xp_function_not(xp_ctx *xc,
|
|||
}
|
||||
memset(xr, 0, sizeof(*xr));
|
||||
xr->xc_type = XT_BOOL;
|
||||
xr->xc_bool = !bool;
|
||||
xr->xc_bool = bool;
|
||||
*xrp = xr;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -673,6 +679,23 @@ xp_function_not(xp_ctx *xc,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! The not function returns true if its argument is false, and false otherwise.
|
||||
*
|
||||
* Signature: boolean not(boolean)
|
||||
*/
|
||||
int
|
||||
xp_function_not(xp_ctx *xc,
|
||||
struct xpath_tree *xs,
|
||||
cvec *nsc,
|
||||
int localonly,
|
||||
xp_ctx **xrp)
|
||||
{
|
||||
if (xp_function_boolean(xc, xs, nsc, localonly, xrp) < 0)
|
||||
return -1;
|
||||
(*xrp)->xc_bool = !(*xrp)->xc_bool;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! The true function returns true.
|
||||
*
|
||||
* Signature: boolean true()
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ enum clixon_xpath_function{
|
|||
XPATHFN_STRING_LENGTH, /* XPATH 1.0 4.2 NYI */
|
||||
XPATHFN_NORMALIZE_SPACE, /* XPATH 1.0 4.2 NYI */
|
||||
XPATHFN_TRANSLATE, /* XPATH 1.0 4.2 NYI */
|
||||
XPATHFN_BOOLEAN, /* XPATH 1.0 4.3 NYI */
|
||||
XPATHFN_BOOLEAN, /* XPATH 1.0 4.3 */
|
||||
XPATHFN_NOT, /* XPATH 1.0 4.3 */
|
||||
XPATHFN_TRUE, /* XPATH 1.0 4.3 */
|
||||
XPATHFN_FALSE, /* XPATH 1.0 4.3 */
|
||||
|
|
@ -101,6 +101,7 @@ int xp_function_position(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int local
|
|||
int xp_function_count(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
int xp_function_name(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
int xp_function_contains(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
int xp_function_boolean(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
int xp_function_not(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
int xp_function_true(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
int xp_function_false(xp_ctx *xc, struct xpath_tree *xs, cvec *nsc, int localonly, xp_ctx **xrp);
|
||||
|
|
|
|||
|
|
@ -266,7 +266,6 @@ xp_primary_function(clixon_xpath_yacc *xpy,
|
|||
case XPATHFN_STRING_LENGTH:
|
||||
case XPATHFN_NORMALIZE_SPACE:
|
||||
case XPATHFN_TRANSLATE:
|
||||
case XPATHFN_BOOLEAN:
|
||||
case XPATHFN_LANG:
|
||||
case XPATHFN_NUMBER:
|
||||
case XPATHFN_SUM:
|
||||
|
|
@ -290,6 +289,7 @@ xp_primary_function(clixon_xpath_yacc *xpy,
|
|||
case XPATHFN_COUNT:
|
||||
case XPATHFN_NAME:
|
||||
case XPATHFN_CONTAINS:
|
||||
case XPATHFN_BOOLEAN:
|
||||
case XPATHFN_NOT:
|
||||
case XPATHFN_TRUE:
|
||||
case XPATHFN_FALSE:
|
||||
|
|
|
|||
|
|
@ -123,6 +123,28 @@ module $APPNAME{
|
|||
}
|
||||
}
|
||||
}
|
||||
/* This is from ietf-ntp@2022-07-05.yang for testing boolean()
|
||||
* But note I reversed true/false
|
||||
*/
|
||||
container system {
|
||||
container ntp {
|
||||
presence
|
||||
"Enables the NTP client unless the 'enabled' leaf
|
||||
(which defaults to 'true') is set to 'false'";
|
||||
}
|
||||
}
|
||||
container ntp {
|
||||
when 'true() = boolean(/sys:system/sys:ntp)' {
|
||||
description
|
||||
"Applicable when the system /sys/ntp/ is not used.";
|
||||
}
|
||||
presence "NTP is enabled and system should attempt to
|
||||
synchronize the system clock with an NTP server
|
||||
from the 'ntp/associations' list.";
|
||||
leaf port {
|
||||
type int16;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
|
|
@ -207,6 +229,18 @@ expecteof_netconf "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLO" "<rpc $DE
|
|||
new "netconf bit-is-set"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/ex:interface[bit-is-set(ex:flags, 'PROMISCUOUS')]\" xmlns:ex=\"urn:example:clixon\" /></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interface xmlns=\"urn:example:clixon\"><name>e1</name><flags>UP PROMISCUOUS</flags></interface><interface xmlns=\"urn:example:clixon\"><name>e2</name><flags>PROMISCUOUS</flags></interface></data></rpc-reply>"
|
||||
|
||||
new "netconf set ntp port"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><ntp xmlns=\"urn:example:clixon\"><port>99</port></ntp></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate fail"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>Failed WHEN condition of ntp in module example (WHEN xpath is true() = boolean(/sys:system/sys:ntp))</error-message></rpc-error></rpc-reply>"
|
||||
|
||||
new "netconf set system boolean"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg -D $DBG" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:clixon\"><ntp/></system></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate ok"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "Kill backend"
|
||||
# Check if premature kill
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue