Merge branch 'master' into native-http

This commit is contained in:
Olof hagsand 2020-05-29 13:49:37 +02:00
commit a5ef243225
7 changed files with 92 additions and 14 deletions

View file

@ -27,6 +27,7 @@ Expected: July 2020
### Minor changes ### Minor changes
* Added new function `clicon_xml2str()` to complement xml_print and others that returns a malloced string.
* Added new function `xml_child_index_each()` to iterate over the children of an XML node according to the order defined by an explicit index variable. This is a complement to `xml_child_each()` which iterates using the default order. * Added new function `xml_child_index_each()` to iterate over the children of an XML node according to the order defined by an explicit index variable. This is a complement to `xml_child_each()` which iterates using the default order.
## 4.5.0 ## 4.5.0

View file

@ -46,6 +46,7 @@
int clicon_xml2file(FILE *f, cxobj *x, int level, int prettyprint); int clicon_xml2file(FILE *f, cxobj *x, int level, int prettyprint);
int xml_print(FILE *f, cxobj *xn); int xml_print(FILE *f, cxobj *xn);
int clicon_xml2cbuf(cbuf *cb, cxobj *x, int level, int prettyprint, int32_t depth); int clicon_xml2cbuf(cbuf *cb, cxobj *x, int level, int prettyprint, int32_t depth);
char *clicon_xml2str(cxobj *x);
int xmltree2cbuf(cbuf *cb, cxobj *x, int level); int xmltree2cbuf(cbuf *cb, cxobj *x, int level);
int clixon_xml_parse_file(int fd, yang_bind yb, yang_stmt *yspec, char *endtag, cxobj **xt, cxobj **xerr); int clixon_xml_parse_file(int fd, yang_bind yb, yang_stmt *yspec, char *endtag, cxobj **xt, cxobj **xerr);

View file

@ -325,6 +325,30 @@ clicon_xml2cbuf(cbuf *cb,
return retval; return retval;
} }
/*! Return an xml tree as a pretty-printed malloced string.
* @param[in] x XML tree
* @retval str Malloced pretty-printed string (should be free:d after use)
* @retval NULL Error
*/
char *
clicon_xml2str(cxobj *x)
{
cbuf *cb;
char *str;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
return NULL;
}
if (clicon_xml2cbuf(cb, x, 0, 1, -1) < 0)
return NULL;
if ((str = strdup(cbuf_get(cb))) == NULL){
clicon_err(OE_XML, errno, "strdup");
return NULL;
}
return str;
}
/*! Print actual xml tree datastructures (not xml), mainly for debugging /*! Print actual xml tree datastructures (not xml), mainly for debugging
* @param[in,out] cb Cligen buffer to write to * @param[in,out] cb Cligen buffer to write to
* @param[in] xn Clicon xml tree * @param[in] xn Clicon xml tree

View file

@ -530,7 +530,7 @@ ys_dup(yang_stmt *old)
return new; return new;
} }
/*! Insert yang statement as child of a parent yang_statement, last in list /*! Append yang statement as child of a parent yang_statement, last in list
* *
* @param[in] ys_parent Add child to this parent * @param[in] ys_parent Add child to this parent
* @param[in] ys_child Add this child * @param[in] ys_child Add this child

View file

@ -465,9 +465,9 @@ yang_expand_grouping(yang_stmt *yn)
/*! Parse a string containing a YANG spec into a parse-tree /*! Parse a string containing a YANG spec into a parse-tree
* *
* Syntax parsing. A string is input and a syntax-tree is returned (or error). * Syntax parsing. A string is input and a YANG syntax-tree is returned (or error).
* A variable record is also returned containing a list of (global) variable values. * As a side-effect, Yang modules present in the text will be inserted under the global Yang
* (cloned from cligen) * specification
* @param[in] str String of yang statements * @param[in] str String of yang statements
* @param[in] name Log string, typically filename * @param[in] name Log string, typically filename
* @param[in] yspec Yang specification. * @param[in] yspec Yang specification.
@ -523,7 +523,7 @@ yang_parse_str(char *str,
/*! Parse yang spec from an open file descriptor /*! Parse yang spec from an open file descriptor
* @param[in] fd File descriptor containing the YANG file as ASCII characters * @param[in] fd File descriptor containing the YANG file as ASCII characters
* @param[in] name For debug, eg filename * @param[in] name For debug, eg filename
* @param[in] ysp Yang specification. Should have been created by caller using yspec_new * @param[in] yspec Yang specification. Should have been created by caller using yspec_new
* @retval ymod Top-level yang (sub)module * @retval ymod Top-level yang (sub)module
* @retval NULL Error * @retval NULL Error
* @note this function simply parse a yang spec, no dependencies or checks * @note this function simply parse a yang spec, no dependencies or checks
@ -531,7 +531,7 @@ yang_parse_str(char *str,
yang_stmt * yang_stmt *
yang_parse_file(int fd, yang_parse_file(int fd,
const char *name, const char *name,
yang_stmt *ysp) yang_stmt *yspec)
{ {
char *buf = NULL; char *buf = NULL;
int i; int i;
@ -564,7 +564,7 @@ yang_parse_file(int fd,
} }
buf[i++] = (char)(c&0xff); buf[i++] = (char)(c&0xff);
} /* read a line */ } /* read a line */
if ((ymod = yang_parse_str(buf, name, ysp)) < 0) if ((ymod = yang_parse_str(buf, name, yspec)) < 0)
goto done; goto done;
done: done:
if (buf) if (buf)
@ -685,7 +685,7 @@ yang_parse_find_match(clicon_handle h,
* *
* Similar to clicon_yang_str(), just read a file first * Similar to clicon_yang_str(), just read a file first
* @param[in] filename Name of file * @param[in] filename Name of file
* @param[in] ysp Yang specification. Should have been created by caller using yspec_new * @param[in] yspec Yang specification. Should have been created by caller using yspec_new
* @retval ymod Top-level yang (sub)module * @retval ymod Top-level yang (sub)module
* @retval NULL Error encountered * @retval NULL Error encountered
@ -694,7 +694,7 @@ yang_parse_find_match(clicon_handle h,
*/ */
yang_stmt * yang_stmt *
yang_parse_filename(const char *filename, yang_parse_filename(const char *filename,
yang_stmt *ysp) yang_stmt *yspec)
{ {
yang_stmt *ymod = NULL; yang_stmt *ymod = NULL;
int fd = -1; int fd = -1;
@ -709,7 +709,7 @@ yang_parse_filename(const char *filename,
clicon_err(OE_YANG, errno, "open(%s)", filename); clicon_err(OE_YANG, errno, "open(%s)", filename);
goto done; goto done;
} }
if ((ymod = yang_parse_file(fd, filename, ysp)) < 0) if ((ymod = yang_parse_file(fd, filename, yspec)) < 0)
goto done; goto done;
done: done:
if (fd != -1) if (fd != -1)
@ -723,7 +723,7 @@ yang_parse_filename(const char *filename,
* @param[in] h CLICON handle * @param[in] h CLICON handle
* @param[in] module Module name * @param[in] module Module name
* @param[in] revision Revision (or NULL) * @param[in] revision Revision (or NULL)
* @param[in] ysp Yang statement * @param[in] yspec Yang statement
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* *
@ -733,7 +733,7 @@ static yang_stmt *
yang_parse_module(clicon_handle h, yang_parse_module(clicon_handle h,
const char *module, const char *module,
const char *revision, const char *revision,
yang_stmt *ysp) yang_stmt *yspec)
{ {
cbuf *fbuf = NULL; cbuf *fbuf = NULL;
char *filename; char *filename;
@ -759,7 +759,7 @@ yang_parse_module(clicon_handle h,
goto done; goto done;
} }
filename = cbuf_get(fbuf); filename = cbuf_get(fbuf);
if ((ymod = yang_parse_filename(filename, ysp)) == NULL) if ((ymod = yang_parse_filename(filename, yspec)) == NULL)
goto done; goto done;
if ((yrev = yang_find(ymod, Y_REVISION, NULL)) != NULL) if ((yrev = yang_find(ymod, Y_REVISION, NULL)) != NULL)
revm = cv_uint32_get(yang_cv_get(yrev)); revm = cv_uint32_get(yang_cv_get(yrev));

View file

@ -162,6 +162,12 @@ err(){
# Test is previous test had valgrind errors if so quit # Test is previous test had valgrind errors if so quit
checkvalgrind(){ checkvalgrind(){
if [ -f $valgrindfile ]; then if [ -f $valgrindfile ]; then
res=$(cat $valgrindfile | grep -e "Invalid" |awk '{print $4}' | grep -v '^0$')
if [ -n "$res" ]; then
>&2 cat $valgrindfile
sudo rm -f $valgrindfile
exit -1
fi
res=$(cat $valgrindfile | grep -e "reachable" -e "lost:"|awk '{print $4}' | grep -v '^0$') res=$(cat $valgrindfile | grep -e "reachable" -e "lost:"|awk '{print $4}' | grep -v '^0$')
if [ -n "$res" ]; then if [ -n "$res" ]; then
>&2 cat $valgrindfile >&2 cat $valgrindfile

View file

@ -349,6 +349,12 @@ module pattern{
pattern 'Z|[\+\-]\d{2}:\d{2}'; pattern 'Z|[\+\-]\d{2}:\d{2}';
} }
} }
leaf p45 {
description "Recognizing a CDATA pattern";
type string {
pattern "<!\[CDATA\[.{1,10}\]\]>";
}
}
} }
} }
EOF EOF
@ -356,6 +362,10 @@ EOF
# Send a string via netconf for pattern matching # Send a string via netconf for pattern matching
# It assumes a yang with a hardcoded container <c><p$pnr> to work properly # It assumes a yang with a hardcoded container <c><p$pnr> to work properly
# The function can expect matching or fail (negative test) # The function can expect matching or fail (negative test)
# Arguments:
# 1: leaf tag in yang
# 2: expected match(1) or fail(0)
# 3: match string
testrun(){ testrun(){
leaf="$1" # leaf tag under <c> with pattern to test leaf="$1" # leaf tag under <c> with pattern to test
mat="$2" # expected match (1) or fail (0) mat="$2" # expected match (1) or fail (0)
@ -694,6 +704,21 @@ testrun "p$pnr" 1 '+12:07'
testrun "p$pnr" 1 'Z' testrun "p$pnr" 1 'Z'
testrun "p$pnr" 1 '-01:38' testrun "p$pnr" 1 '-01:38'
let pnr=45
new "Test for pattern leaf p$pnr CDATA matcher"
testrun "p$pnr" 1 '<![CDATA[foobar]]>'
testrun "p$pnr" 0 '<![CDATA[]]>'
testrun "p$pnr" 1 '<![CDATA[0123456789]]>'
testrun "p$pnr" 0 '<![CDATA[01234567890]]>' # too long
# Negative tests where one char at a time is removed
testrun "p$pnr" 0 '![CDATA[0123456789]]>'
testrun "p$pnr" 0 '<[CDATA[0123456789]]>'
testrun "p$pnr" 0 '<!CDATA[01234567890]]>'
testrun "p$pnr" 0 '<![DATA[01234567890]]>'
testrun "p$pnr" 0 '<![CDATA01234567890]]>'
#testrun "p$pnr" 0 '<![CDATA[01234567890]>' # XML parse error
#testrun "p$pnr" 0 '<![CDATA[0123456789]]' # XML parse error
# CLI tests # CLI tests
new "CLI tests for RFC7950 Sec 9.4.7 ex 2 AB" new "CLI tests for RFC7950 Sec 9.4.7 ex 2 AB"
@ -738,6 +763,27 @@ expectfn "$clixon_cli -1f $cfg -l o set c threematch gks" 0 '^$'
new "CLI tests for three patterns abcg (should fail)" new "CLI tests for three patterns abcg (should fail)"
expectfn "$clixon_cli -1f $cfg -l o set c threematch abcg" 255 '^CLI syntax error:' expectfn "$clixon_cli -1f $cfg -l o set c threematch abcg" 255 '^CLI syntax error:'
# Need to have failures first so there are no matches with existing entries
new "CLI tests for CDATA, should fail"
expectfn "$clixon_cli -1f $cfg -l o set c p45 <![CDATA[foo" 255 'CLI syntax error'
new "CLI tests for CDATA, should fail"
expectfn "$clixon_cli -1f $cfg -l o set c p45 <!CDATA[foo]]" 255 'CLI syntax error'
new "CLI tests for CDATA, should fail"
expectfn "$clixon_cli -1f $cfg -l o set c p45 <!CDATA[foo]>" 255 'CLI syntax error'
new "CLI tests for CDATA, should fail"
expectfn "$clixon_cli -1f $cfg -l o set c p45 <![CDATA[]]>" 255 'CLI syntax error'
new "CLI tests for CDATA, should fail"
expectfn "$clixon_cli -1f $cfg -l o set c p45 ![CDATA[foo]]>" 255 'CLI syntax error'
new "CLI tests for CDATA, should fail"
expectfn "$clixon_cli -1f $cfg -l o set c p45 <![CDATA[foo]]" 255 'CLI syntax error'
new "CLI tests for CDATA OK"
expectfn "$clixon_cli -1f $cfg -l o set c p45 <![CDATA[foobar]]>" 0 '^$'
if [ $BE -ne 0 ]; then if [ $BE -ne 0 ]; then
new "Kill backend" new "Kill backend"