From 6c8b56553d396ad5b9920cfb0475c576b7f54163 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Tue, 28 May 2024 14:58:15 +1200 Subject: [PATCH 1/3] Added support for libxml2 2.12. --- src/printer.cpp | 2 -- src/xmldoc.cpp | 12 +++++++++++- src/xmlnode.cpp | 1 - tests/CMakeLists.txt | 2 ++ tests/libxml2issues.2.12.h | 12 ++++++++++++ tests/parser/libxml_user.cpp | 12 +++++++++++- tests/parser/parser.cpp | 28 ++++++++++++++++++++++------ 7 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 tests/libxml2issues.2.12.h diff --git a/src/printer.cpp b/src/printer.cpp index db5ca8727..6307c8e61 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -140,7 +140,6 @@ std::string Printer::PrinterImpl::printMath(const std::string &math) static const std::regex xmlDeclaration(R"|(<\?xml[[:space:]]+version=.*\?>)|"); XmlDocPtr xmlDoc = std::make_shared(); - xmlKeepBlanksDefault(0); // Remove any XML declarations from the string. std::string normalisedMath = std::regex_replace(math, xmlDeclaration, ""); xmlDoc->parse("<" + wrapElementName + ">" + normalisedMath + ""); @@ -592,7 +591,6 @@ std::string Printer::printModel(const ModelPtr &model, bool autoIds) // See http://www.xmlsoft.org/html/libxml-tree.html#xmlDocDumpFormatMemoryEnc // for details. XmlDocPtr xmlDoc = std::make_shared(); - xmlKeepBlanksDefault(0); xmlDoc->parse(repr); return xmlDoc->prettyPrint(); } diff --git a/src/xmldoc.cpp b/src/xmldoc.cpp index 450fa256a..5cf86180b 100644 --- a/src/xmldoc.cpp +++ b/src/xmldoc.cpp @@ -42,7 +42,13 @@ namespace libcellml { * * @param error The @c xmlErrorPtr to the error raised by libxml. */ -void structuredErrorCallback(void *userData, xmlErrorPtr error) +#if LIBXML_VERSION >= 21200 +# define XmlErrorPtr const xmlError * +#else +# define XmlErrorPtr xmlErrorPtr +#endif + +void structuredErrorCallback(void *userData, XmlErrorPtr error) { static const std::regex newLineRegex("\\n"); // Swap libxml2 carriage return for a period. @@ -89,7 +95,9 @@ void XmlDoc::parse(const std::string &input) xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); +#if LIBXML_VERSION < 21200 xmlCleanupGlobals(); +#endif } std::string decompressMathMLDTD() @@ -129,7 +137,9 @@ void XmlDoc::parseMathML(const std::string &input) xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); +#if LIBXML_VERSION < 21200 xmlCleanupGlobals(); +#endif } std::string XmlDoc::prettyPrint() const diff --git a/src/xmlnode.cpp b/src/xmlnode.cpp index 93a273ac0..bb8c3ac0a 100644 --- a/src/xmlnode.cpp +++ b/src/xmlnode.cpp @@ -310,7 +310,6 @@ XmlNodePtr XmlNode::parent() const std::string XmlNode::convertToString() const { - xmlKeepBlanksDefault(1); xmlBufferPtr buffer = xmlBufferCreate(); xmlNodeDump(buffer, mPimpl->mXmlNodePtr->doc, mPimpl->mXmlNodePtr, 0, 0); std::string contentString = std::string(reinterpret_cast(buffer->content)); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cf64a66c2..6875a9ce2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -55,6 +55,8 @@ set(TEST_UTILS_HDR ${CMAKE_CURRENT_SOURCE_DIR}/test_utils.h) if(NOT DEFINED LIBXML2_VERSION_STRING) set(LIBXML2_VERSION_STRING "2.9.10") +elseif(LIBXML2_VERSION_STRING VERSION_GREATER_EQUAL "2.12") + set(LIBXML2_VERSION_STRING "2.12") elseif(LIBXML2_VERSION_STRING VERSION_GREATER_EQUAL "2.9.13") set(LIBXML2_VERSION_STRING "2.9.13") elseif(LIBXML2_VERSION_STRING VERSION_GREATER_EQUAL "2.9.11") diff --git a/tests/libxml2issues.2.12.h b/tests/libxml2issues.2.12.h new file mode 100644 index 000000000..9fa7816b4 --- /dev/null +++ b/tests/libxml2issues.2.12.h @@ -0,0 +1,12 @@ +#pragma once + +#include "string" +#include "vector" + +// Version 2.12(.7) of LibXml2 reports the following errors, +// used on Windows CI machines. +const std::vector expectedLibXml2Issues = { + "LibXml2 error: Opening and ending tag mismatch: ci line 6 and apply.", + "LibXml2 error: Opening and ending tag mismatch: ci line 6 and math.", + "LibXml2 error: Opening and ending tag mismatch: apply line 3 and math_wrap_as_single_root_element.", +}; diff --git a/tests/parser/libxml_user.cpp b/tests/parser/libxml_user.cpp index 8cb0eb2ef..937282882 100644 --- a/tests/parser/libxml_user.cpp +++ b/tests/parser/libxml_user.cpp @@ -24,7 +24,13 @@ limitations under the License. #include -void structuredErrorCallback(void *userData, xmlErrorPtr error) +#if LIBXML_VERSION >= 21200 +# define XmlErrorPtr const xmlError * +#else +# define XmlErrorPtr xmlErrorPtr +#endif + +void structuredErrorCallback(void *userData, XmlErrorPtr error) { if (userData != nullptr && error != nullptr) { // Suppress any error messages raised from using LibXml2. @@ -54,7 +60,9 @@ TEST(Parser, parseValidXmlDirectlyUsingLibxml) xmlFreeDoc(doc); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); +#if LIBXML_VERSION < 21200 xmlCleanupGlobals(); +#endif } TEST(Parser, parseInvalidXmlDirectlyUsingLibxml) @@ -76,7 +84,9 @@ TEST(Parser, parseInvalidXmlDirectlyUsingLibxml) xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); +#if LIBXML_VERSION < 21200 xmlCleanupGlobals(); +#endif EXPECT_EQ(nullptr, doc); } diff --git a/tests/parser/parser.cpp b/tests/parser/parser.cpp index 531cb3c67..913a43e3e 100644 --- a/tests/parser/parser.cpp +++ b/tests/parser/parser.cpp @@ -53,15 +53,27 @@ TEST(Parser, invalidXMLElements) "LibXml2 error: EndTag: ' expectedIssues_2_12 = { + "LibXml2 error: Specification mandates value for attribute bearded.", + "LibXml2 error: Opening and ending tag mismatch: Dwarf line 3 and ShortGuy.", + "LibXml2 error: Opening and ending tag mismatch: Hobbit line 4 and EvenShorterGuy.", + "LibXml2 error: Opening and ending tag mismatch: Wizard line 5 and SomeGuyWithAStaff.", + "LibXml2 error: Opening and ending tag mismatch: Elf line 6 and fellows.", + "Could not get a valid XML root node from the provided input.", + }; libcellml::ParserPtr p = libcellml::Parser::create(); p->parseModel(in); - EXPECT_EQ(expectedIssues_2_2.size(), p->issueCount()); + EXPECT_TRUE((expectedIssues_2_2.size() == p->issueCount()) + || (expectedIssues_2_9_10.size() == p->issueCount()) + || (expectedIssues_2_12.size() == p->issueCount())); for (size_t i = 0; i < p->issueCount(); ++i) { auto message = p->issue(i)->description(); - EXPECT_TRUE((expectedIssues_2_2.at(i) == message) || (expectedIssues_2_9_10.at(i) == message)); + EXPECT_TRUE((expectedIssues_2_2.at(i) == message) + || (expectedIssues_2_9_10.at(i) == message) + || (expectedIssues_2_12.at(i) == message)); } } @@ -1861,13 +1873,17 @@ TEST(Parser, parseResets) EXPECT_EQ("variable2", v2->name()); std::string testValueString = r->testValue(); - std::string t = - "\n"; + const std::string t = + "\n" + " \n" + " \n"; EXPECT_EQ(t, testValueString); std::string resetValueString = r->resetValue(); - std::string rt = - "\n"; + const std::string rt = + "\n" + " \n" + " \n"; EXPECT_EQ(rt, resetValueString); } From 78ce208bf29bca55980130ffdced107e67809927 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Tue, 28 May 2024 16:24:49 +1200 Subject: [PATCH 2/3] Make codespell happy. --- .codespellexclude | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.codespellexclude b/.codespellexclude index 2de0f331f..f675ea310 100644 --- a/.codespellexclude +++ b/.codespellexclude @@ -13,3 +13,5 @@ if (index < pFunc()->mErrors.size()) { issue = pFunc()->mIssues.at(pFunc()->mErrors.at(index)); return pFunc()->mErrors.size(); +identity and expression, level of experience, education, socio-economic status, + "W3C MathML DTD error: Element apply content does not follow the DTD, expecting (csymbol | ci | cn | apply | reln | lambda | condition | declare | sep | semantics | annotation | annotation-xml | integers | reals | rationals | naturalnumbers | complexes | primes | exponentiale | imaginaryi | notanumber | true | false | emptyset | pi | eulergamma | infinity | interval | list | matrix | matrixrow | set | vector | piecewise | lowlimit | uplimit | bvar | degree | logbase | momentabout | domainofapplication | inverse | ident | domain | codomain | image | abs | conjugate | exp | factorial | arg | real | imaginary | floor | ceiling | not | ln | sin | cos | tan | sec | csc | cot | sinh | cosh | tanh | sech | csch | coth | arcsin | arccos | arctan | arccosh | arccot | arccoth | arccsc | arccsch | arcsec | arcsech | arcsinh | arctanh | determinant | transpose | card | quotient | divide | power | rem | implies | vectorproduct | scalarproduct | outerproduct | setdiff | fn | compose | plus | times | max | min | gcd | lcm | and | or | xor | union | intersect | cartesianproduct | mean | sdev | variance | median | mode | selector | root | minus | log | int | diff | partialdiff | divergence | grad | curl | laplacian | sum | product | limit | moment | exists | forall | neq | factorof | in | notin | notsubset | notprsubset | tendsto | eq | leq | lt | geq | gt | equivalent | approx | subset | prsubset | mi | mn | mo | mtext | ms | mspace | mrow | mfrac | msqrt | mroot | menclose | mstyle | merror | mpadded | mphantom | mfenced | msub | msup | msubsup | munder | mover | munderover | mmultiscripts | mtable | mtr | mlabeledtr | mtd | maligngroup | malignmark | maction)*, got (CDATA bvar ).", From f63e38f09a76b71dc696fee00571bdc06b1d556e Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Tue, 28 May 2024 22:36:44 +1200 Subject: [PATCH 3/3] Removed calls to xmlCleanupGlobals(). --- src/xmldoc.cpp | 6 ------ tests/parser/libxml_user.cpp | 6 ------ 2 files changed, 12 deletions(-) diff --git a/src/xmldoc.cpp b/src/xmldoc.cpp index 5cf86180b..294877042 100644 --- a/src/xmldoc.cpp +++ b/src/xmldoc.cpp @@ -95,9 +95,6 @@ void XmlDoc::parse(const std::string &input) xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); -#if LIBXML_VERSION < 21200 - xmlCleanupGlobals(); -#endif } std::string decompressMathMLDTD() @@ -137,9 +134,6 @@ void XmlDoc::parseMathML(const std::string &input) xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); -#if LIBXML_VERSION < 21200 - xmlCleanupGlobals(); -#endif } std::string XmlDoc::prettyPrint() const diff --git a/tests/parser/libxml_user.cpp b/tests/parser/libxml_user.cpp index 937282882..0db953c78 100644 --- a/tests/parser/libxml_user.cpp +++ b/tests/parser/libxml_user.cpp @@ -60,9 +60,6 @@ TEST(Parser, parseValidXmlDirectlyUsingLibxml) xmlFreeDoc(doc); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); -#if LIBXML_VERSION < 21200 - xmlCleanupGlobals(); -#endif } TEST(Parser, parseInvalidXmlDirectlyUsingLibxml) @@ -84,9 +81,6 @@ TEST(Parser, parseInvalidXmlDirectlyUsingLibxml) xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); -#if LIBXML_VERSION < 21200 - xmlCleanupGlobals(); -#endif EXPECT_EQ(nullptr, doc); }