diff --git a/doc/APIchunk2.html b/doc/APIchunk2.html
index d5d363b12b5c073096e4c1361d185ac97fe967d9..94a32dbaef8357d011c28c84f494c5d46be8b1f4 100644
--- a/doc/APIchunk2.html
+++ b/doc/APIchunk2.html
@@ -267,6 +267,8 @@ A:link, A:visited, A:active { text-decoration: underline }
xmlParseTextDecl
void xmlXPathStartsWithFunction (xmlXPathParserContextPtr ctxt,
int nargs)
Implement the starts-with() XPath function boolean starts-with(string, string) The starts-with function returns true if the first argument string starts with the second argument string, and otherwise returns false.
+ctxt: | the XPath Parser context |
nargs: | the number of arguments |
void xmlXPathEndsWithFunction (xmlXPathParserContextPtr ctxt,
int nargs)
+
Implement the ends-with() XPath function boolean starts-with(string, string) The ends-with function returns true if the first argument string ends with the second argument string, and otherwise returns false.
+ctxt: | the XPath Parser context |
nargs: | the number of arguments |
void xmlXPathEndsWithFunction (xmlXPathParserContextPtr ctxt,
int nargs)
+
Implement the ends-with() XPath function boolean ends-with(string, string) The ends-with function returns true if the first argument string ends with the second argument string, and otherwise returns false.
ctxt: | the XPath Parser context |
nargs: | the number of arguments |
double xmlXPathStringEvalNumber (const xmlChar * str)
diff --git a/doc/devhelp/libxml2.devhelp b/doc/devhelp/libxml2.devhelp index 51b6f26272e9e3baf41c18ed034174be98b72549..15001cdb135f6d9271b57b69e38ee327d1e2aca9 100644 --- a/doc/devhelp/libxml2.devhelp +++ b/doc/devhelp/libxml2.devhelp @@ -3532,6 +3532,7 @@+ diff --git a/doc/html/libxml-xpathInternals.html b/doc/html/libxml-xpathInternals.html index 8b894af7e7dfbca1946e7f034033b09db3c2deee..a4ac6aec45dfc7b4dc3abd4d20561cebe87b8811 100644 --- a/doc/html/libxml-xpathInternals.html +++ b/doc/html/libxml-xpathInternals.html @@ -107,6 +107,7 @@ A:link, A:visited, A:active { text-decoration: underline } void xmlXPathRoot (xmlXPathParserContextPtr ctxt)void xmlXPathRoundFunction (xmlXPathParserContextPtr ctxt,
int nargs)void xmlXPathStartsWithFunction (xmlXPathParserContextPtr ctxt,+
int nargs)void xmlXPathEndsWithFunction (xmlXPathParserContextPtr ctxt,
int nargs)double xmlXPathStringEvalNumber (const xmlChar * str)void xmlXPathStringFunction (xmlXPathParserContextPtr ctxt,
int nargs)void xmlXPathStringLengthFunction (xmlXPathParserContextPtr ctxt,@@ -349,8 +350,8 @@ A:link, A:visited, A:active { text-decoration: underline }
int nargs)
Initialize the context to the root of the document
ctxt: | the XPath Parser context |
void xmlXPathRoundFunction (xmlXPathParserContextPtr ctxt,
int nargs)
Implement the round() XPath function number round(number) The round function returns the number that is closest to the argument and that is an integer. If there are two such numbers, then the one that is closest to positive infinity is returned.
-ctxt: | the XPath Parser context |
nargs: | the number of arguments |
void xmlXPathStartsWithFunction (xmlXPathParserContextPtr ctxt,
int nargs)
-
Implement the starts-with() XPath function boolean starts-with(string, string) The starts-with function returns true if the first argument string starts with the second argument string, and otherwise returns false.
+ctxt: | the XPath Parser context |
nargs: | the number of arguments |
void xmlXPathEndsWithFunction (xmlXPathParserContextPtr ctxt,
int nargs)
+
Implement the ends-with() XPath function boolean ends-with(string, string) The ends-with function returns true if the first argument string ends with the second argument string, and otherwise returns false.
ctxt: | the XPath Parser context |
nargs: | the number of arguments |
double xmlXPathStringEvalNumber (const xmlChar * str)
[30a] Float ::= Number ('e' Digits?)? [30] Number ::= Digits ('.' Digits?)? | '.' Digits [31] Digits ::= [0-9]+ Compile a Number in the string In complement of the Number expression, this function also handles negative values : '-' Number.
str: | A string to scan |
Returns: | the double value. |
void xmlXPathStringFunction (xmlXPathParserContextPtr ctxt,
int nargs)
diff --git a/doc/libxml2-api.xml b/doc/libxml2-api.xml index f264a298619b3412944805ca4de7b8b473057443..4829c87f9b280c8b2cc821f052c0547d6e317a9b 100644 --- a/doc/libxml2-api.xml +++ b/doc/libxml2-api.xml @@ -3707,6 +3707,7 @@+ @@ -18238,6 +18239,13 @@ Could we use @subtypes for this?'/> + + defined(LIBXML_XPATH_ENABLED) +Implement the ends-with() XPath function boolean ends-with(string, string) The ends-with function returns true if the first argument string ends with the second argument string, and otherwise returns false. ++ + + defined(LIBXML_XPATH_ENABLED) [30a] Float ::= Number ('e' Digits?)? [30] Number ::= Digits ('.' Digits?)? | '.' Digits [31] Digits ::= [0-9]+ Compile a Number in the string In complement of the Number expression, this function also handles negative values : '-' Number. diff --git a/doc/libxml2-refs.xml b/doc/libxml2-refs.xml index ade2ab7c054a8191cf4255bed951e2cc8f0fe60b..72b0e075053962f05be79948515ddda60793047c 100644 --- a/doc/libxml2-refs.xml +++ b/doc/libxml2-refs.xml @@ -3535,6 +3535,7 @@+ @@ -7176,6 +7177,7 @@ + @@ -10739,6 +10741,7 @@ + @@ -14389,6 +14392,7 @@ + @@ -22356,6 +22360,10 @@ + + ++ diff --git a/doc/symbols.xml b/doc/symbols.xml index a52202a2ffcd4d6578330f4ffe5e33bf4b85ed16..7e572ef34bb2723d3209c2ae9c0fe588ac33d951 100644 --- a/doc/symbols.xml +++ b/doc/symbols.xml @@ -328,6 +328,7 @@ xmlXPathRoot xmlXPathRoundFunction xmlXPathStartsWithFunction +xmlXPathEndsWithFunction xmlXPathStringEvalNumber xmlXPathStringFunction xmlXPathStringLengthFunction diff --git a/elfgcchack.h b/elfgcchack.h index af8ad1148d25dd4bfe86e868d351fcada3d63333..1c33883fe3969de0c8cbca81850eeebf487723ff 100644 --- a/elfgcchack.h +++ b/elfgcchack.h @@ -17317,6 +17317,18 @@ extern __typeof (xmlXPathStartsWithFunction) xmlXPathStartsWithFunction__interna #endif #endif +#if defined(LIBXML_XPATH_ENABLED) +#ifdef bottom_xpath +#undef xmlXPathEndsWithFunction +extern __typeof (xmlXPathEndsWithFunction) xmlXPathEndsWithFunction __attribute((alias("xmlXPathEndsWithFunction__internal_alias"))); +#else +#ifndef xmlXPathEndsWithFunction +extern __typeof (xmlXPathEndsWithFunction) xmlXPathEndsWithFunction__internal_alias __attribute((visibility("hidden"))); +#define xmlXPathEndsWithFunction xmlXPathEndsWithFunction__internal_alias +#endif +#endif +#endif + #if defined(LIBXML_XPATH_ENABLED) #ifdef bottom_xpath #undef xmlXPathStringEvalNumber diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h index 76a6b481572d72a06c778ef949b0bf0df30382af..d7cfb9433258def8846699760a60c6572cdd88b9 100644 --- a/include/libxml/xpathInternals.h +++ b/include/libxml/xpathInternals.h @@ -603,6 +603,7 @@ XMLPUBFUN void XMLCALL xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctx XMLPUBFUN void XMLCALL xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs); XMLPUBFUN void XMLCALL xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs); XMLPUBFUN void XMLCALL xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void XMLCALL xmlXPathEndsWithFunction(xmlXPathParserContextPtr ctxt, int nargs); XMLPUBFUN void XMLCALL xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs); XMLPUBFUN void XMLCALL xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs); XMLPUBFUN void XMLCALL xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs); diff --git a/libxml2.syms b/libxml2.syms index 33bc112c14f026b6a71c8dc36fd9199b55796245..e195bfb862252204a1dc7090e37abf5bc810b14c 100644 --- a/libxml2.syms +++ b/libxml2.syms @@ -372,6 +372,7 @@ LIBXML2_2.4.30 { xmlXPathRoot; xmlXPathRoundFunction; xmlXPathStartsWithFunction; + xmlXPathEndsWithFunction; xmlXPathStringEvalNumber; xmlXPathStringFunction; xmlXPathStringLengthFunction; diff --git a/os400/libxmlrpg/xpathInternals.rpgle b/os400/libxmlrpg/xpathInternals.rpgle index a6d12e150d1102e266badb4410a027c61eb2ae4d..e9455898af84adb246eea2fb71fc495a3ea354f0 100644 --- a/os400/libxmlrpg/xpathInternals.rpgle +++ b/os400/libxmlrpg/xpathInternals.rpgle @@ -605,6 +605,11 @@ d ctxt value like(xmlXPathParserContextPtr) d nargs value like(xmlCint) + d xmlXPathEndsWithFunction... + d pr extproc('xmlXPathEndsWithFunction') + d ctxt value like(xmlXPathParserContextPtr) + d nargs value like(xmlCint) + d xmlXPathSubstringFunction... d pr extproc('xmlXPathSubstringFunction') d ctxt value like(xmlXPathParserContextPtr) diff --git a/result/XPath/expr/strings b/result/XPath/expr/strings index 4b0125cf7bc4575669c0bc6cc71b7daa10e6eea6..1cac6a57e14c4193c5797bc226171b694a9f30b4 100644 --- a/result/XPath/expr/strings +++ b/result/XPath/expr/strings @@ -51,6 +51,14 @@ Object is a Boolean : true Expression: starts-with("tititoto","to") Object is a Boolean : false +======================== +Expression: ends-with("tititoto","toto") +Object is a Boolean : true + +======================== +Expression: ends-with("tititoto","ti") +Object is a Boolean : false + ======================== Expression: contains("tititototata","titi") Object is a Boolean : true diff --git a/test/XPath/expr/strings b/test/XPath/expr/strings index c741ee2519cc075a7dbddae3e0bc93d6463bf16c..308dfdabe2c8d4a9cc35bf1ccc4e2d3389282d84 100644 --- a/test/XPath/expr/strings +++ b/test/XPath/expr/strings @@ -11,6 +11,8 @@ concat("titi",'toto') concat("titi",'toto',"tata","last") starts-with("tititoto","titi") starts-with("tititoto","to") +ends-with("tititoto","toto") +ends-with("tititoto","ti") contains("tititototata","titi") contains("tititototata","toto") contains("tititototata","tata") diff --git a/testapi.c b/testapi.c index 8a4e23e332523bc5d35eedb78cc414877847f52f..be09cd3eaed143dc0fb1b1ba4f0e2b17df521918 100644 --- a/testapi.c +++ b/testapi.c @@ -50709,6 +50709,45 @@ test_xmlXPathStartsWithFunction(void) { } +static int +test_xmlXPathEndsWithFunction(void) { + int test_ret = 0; + +#if defined(LIBXML_XPATH_ENABLED) + int mem_base; + xmlXPathParserContextPtr ctxt; /* the XPath Parser context */ + int n_ctxt; + int nargs; /* the number of arguments */ + int n_nargs; + + for (n_ctxt = 0;n_ctxt < gen_nb_xmlXPathParserContextPtr;n_ctxt++) { + for (n_nargs = 0;n_nargs < gen_nb_int;n_nargs++) { + mem_base = xmlMemBlocks(); + ctxt = gen_xmlXPathParserContextPtr(n_ctxt, 0); + nargs = gen_int(n_nargs, 1); + + xmlXPathEndsWithFunction(ctxt, nargs); + call_tests++; + des_xmlXPathParserContextPtr(n_ctxt, ctxt, 0); + des_int(n_nargs, nargs, 1); + xmlResetLastError(); + if (mem_base != xmlMemBlocks()) { + printf("Leak of %d blocks found in xmlXPathEndsWithFunction", + xmlMemBlocks() - mem_base); + test_ret++; + printf(" %d", n_ctxt); + printf(" %d", n_nargs); + printf("\n"); + } + } + } + function_tests++; +#endif + + return(test_ret); +} + + static int test_xmlXPathStringEvalNumber(void) { int test_ret = 0; @@ -51543,6 +51582,7 @@ test_xpathInternals(void) { test_ret += test_xmlXPathRoot(); test_ret += test_xmlXPathRoundFunction(); test_ret += test_xmlXPathStartsWithFunction(); + test_ret += test_xmlXPathEndsWithFunction(); test_ret += test_xmlXPathStringEvalNumber(); test_ret += test_xmlXPathStringFunction(); test_ret += test_xmlXPathStringLengthFunction(); diff --git a/win32/libxml2.def.src b/win32/libxml2.def.src index 1e771e850415d959a9d47e3396472f5e45ddd771..2947025cf99ba23bb6f7f2c061ed28c629167e5b 100644 --- a/win32/libxml2.def.src +++ b/win32/libxml2.def.src @@ -3067,6 +3067,9 @@ xmlXPathSetContextNode xmlXPathStartsWithFunction #endif #ifdef LIBXML_XPATH_ENABLED +xmlXPathEndsWithFunction +#endif +#ifdef LIBXML_XPATH_ENABLED xmlXPathStringEvalNumber #endif #ifdef LIBXML_XPATH_ENABLED diff --git a/xpath.c b/xpath.c index 6ee7e57ef90895968c79dbeaf597b3170dc07a6d..2885e5918a87e6090bd8821848132130ac93c287 100644 --- a/xpath.c +++ b/xpath.c @@ -9065,6 +9065,42 @@ xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathReleaseObject(ctxt->context, needle); } +/** + * xmlXPathEndsWithFunction: + * @ctxt: the XPath Parser context + * @nargs: the number of arguments + * + * Implement the ends-with() XPath function + * boolean ends-with(string, string) + * The ends-with function returns true if the first argument string + * ends with the second argument string, and otherwise returns false. + */ +void +xmlXPathEndsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) { + xmlXPathObjectPtr hay, needle; + int n; + + CHECK_ARITY(2); + CAST_TO_STRING; + CHECK_TYPE(XPATH_STRING); + needle = valuePop(ctxt); + CAST_TO_STRING; + hay = valuePop(ctxt); + + if ((hay == NULL) || (hay->type != XPATH_STRING)) { + xmlXPathReleaseObject(ctxt->context, hay); + xmlXPathReleaseObject(ctxt->context, needle); + XP_ERROR(XPATH_INVALID_TYPE); + } + n = xmlStrlen(needle->stringval); + if (xmlStrncmp(hay->stringval, needle->stringval, n)) + valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 0)); + else + valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, 1)); + xmlXPathReleaseObject(ctxt->context, hay); + xmlXPathReleaseObject(ctxt->context, needle); +} + /** * xmlXPathSubstringFunction: * @ctxt: the XPath Parser context @@ -14716,6 +14752,8 @@ xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt) xmlXPathStringLengthFunction); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with", xmlXPathStartsWithFunction); + xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ends-with", + xmlXPathEndsWithFunction); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring", xmlXPathSubstringFunction); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before", diff --git a/xstc/xstc.py b/xstc/xstc.py index 21c1f41914dce28e7343ca67a9912d52045cc312..2f9eac4670c3ca44a04dc83a39c3ca98cc3125c9 100755 --- a/xstc/xstc.py +++ b/xstc/xstc.py @@ -47,6 +47,10 @@ opa.add_option("--tsw", "--test-starts-with", type="string", dest="testStartsWit default=None, help="Runs the specified test(s), starting with the given string") +opa.add_option("--tsw", "--test-ends-with", type="string", dest="testEndsWith", + default=None, + help="Runs the specified test(s), starting with the given string") + opa.add_option("--rieo", "--report-internal-errors-only", action="store_true", dest="reportInternalErrOnly", default=False, help="Display erroneous tests of type 'internal' only") @@ -67,6 +71,10 @@ opa.add_option("--csw", "--csw", type="string", dest="combineStartsWith", default=None, help="Combines to be run (all if omitted)") +opa.add_option("--csw", "--csw", type="string", dest="combineEndsWith", + default=None, + help="Combines to be run (all if omitted)") + opa.add_option("--rc", "--report-combines", action="store_true", dest="reportCombines", default=False, help="Display combine reports") @@ -647,9 +655,15 @@ class XSTCTestRunner: elif options.testStartsWith is not None: if not test.name.startswith(options.testStartsWith): continue + elif options.testEndsWith is not None: + if not test.name.startswith(options.testEndsWith): + continue elif options.combineStartsWith is not None: if not test.combineName.startswith(options.combineStartsWith): continue + elif options.combineEndsWith is not None: + if not test.combineName.startswith(options.combineEndsWith): + continue if options.maxTestCount != -1 and self.counters[self.CNT_RAN] >= options.maxTestCount: break