diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor/docparser.cpp')
-rw-r--r-- | sources/shiboken2/ApiExtractor/docparser.cpp | 183 |
1 files changed, 28 insertions, 155 deletions
diff --git a/sources/shiboken2/ApiExtractor/docparser.cpp b/sources/shiboken2/ApiExtractor/docparser.cpp index 99921e7d3..532956d1a 100644 --- a/sources/shiboken2/ApiExtractor/docparser.cpp +++ b/sources/shiboken2/ApiExtractor/docparser.cpp @@ -30,10 +30,10 @@ #include "messages.h" #include "reporthandler.h" #include "typesystem.h" +#include "xmlutils.h" #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QTextStream> -#include <QtXmlPatterns/QXmlQuery> #include <QBuffer> #include <cstdlib> @@ -53,27 +53,19 @@ DocParser::DocParser() DocParser::~DocParser() = default; -QString DocParser::getDocumentation(QXmlQuery& xquery, const QString& query, +QString DocParser::getDocumentation(const XQueryPtr &xquery, const QString& query, const DocModificationList& mods) const { QString doc = execXQuery(xquery, query); return applyDocModifications(mods, doc.trimmed()); } -QString DocParser::execXQuery(QXmlQuery& xquery, const QString& query) const +QString DocParser::execXQuery(const XQueryPtr &xquery, const QString& query) const { - QString escapedQuery(query); - // XQuery can't have invalid XML characters - escapedQuery.replace(QLatin1Char('&'), QLatin1String("&")); - escapedQuery.replace(QLatin1Char('<'), QLatin1String("<")); - xquery.setQuery(escapedQuery); - if (!xquery.isValid()) { - qWarning() << "Bad XQuery: " << escapedQuery; - return QString(); - } - - QString result; - xquery.evaluateTo(&result); + QString errorMessage; + const QString result = xquery->evaluate(query, &errorMessage); + if (!errorMessage.isEmpty()) + qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); return result; } @@ -108,41 +100,6 @@ AbstractMetaFunctionList DocParser::documentableFunctions(const AbstractMetaClas return result; } - -#ifdef HAVE_LIBXSLT -namespace -{ - -class XslResources -{ - Q_DISABLE_COPY(XslResources) - -public: - xmlDocPtr xmlDoc = nullptr; - xsltStylesheetPtr xslt = nullptr; - xmlDocPtr xslResult = nullptr; - - XslResources() = default; - - ~XslResources() - { - if (xslt) - xsltFreeStylesheet(xslt); - - if (xslResult) - xmlFreeDoc(xslResult); - - if (xmlDoc) - xmlFreeDoc(xmlDoc); - - xsltCleanupGlobals(); - xmlCleanupParser(); - } -}; - -} // namespace -#endif // HAVE_LIBXSLT - static inline bool isXpathDocModification(const DocModification &mod) { return mod.mode() == TypeSystem::DocModificationXPathReplace; @@ -150,102 +107,22 @@ static inline bool isXpathDocModification(const DocModification &mod) QString DocParser::applyDocModifications(const DocModificationList& mods, const QString& xml) const { + const char xslPrefix[] = +R"(<xsl:template match="/"> + <xsl:apply-templates /> +</xsl:template> +<xsl:template match="*"> +<xsl:copy> + <xsl:copy-of select="@*"/> + <xsl:apply-templates/> +</xsl:copy> +</xsl:template> +)"; + if (mods.isEmpty() || xml.isEmpty() || !std::any_of(mods.cbegin(), mods.cend(), isXpathDocModification)) { return xml; } -#ifdef HAVE_LIBXSLT - const QString result = applyDocModificationsLibXsl(mods, xml); -#else - const QString result = applyDocModificationsQt(mods, xml); -#endif - if (result == xml) { - const QString message = QLatin1String("Query did not result in any modifications to \"") - + xml + QLatin1Char('"'); - qCWarning(lcShiboken, "%s", - qPrintable(msgXpathDocModificationError(mods, message))); - } - return result; -} - -QString DocParser::applyDocModificationsLibXsl(const DocModificationList& mods, const QString& xml) const -{ -#ifdef HAVE_LIBXSLT - QString xsl = QLatin1String("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" - "<xsl:transform version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" - "<xsl:template match=\"/\">\n" - " <xsl:apply-templates />\n" - "</xsl:template>\n" - "<xsl:template match=\"*\">\n" - "<xsl:copy>\n" - " <xsl:copy-of select=\"@*\"/>\n" - " <xsl:apply-templates/>\n" - "</xsl:copy>\n" - "</xsl:template>\n" - ); - for (const DocModification &mod : mods) { - if (isXpathDocModification(mod)) { - QString xpath = mod.xpath(); - xpath.replace(QLatin1Char('"'), QLatin1String(""")); - xsl += QLatin1String("<xsl:template match=\"") - + xpath + QLatin1String("\">") - + mod.code() + QLatin1String("</xsl:template>\n"); - } - } - xsl += QLatin1String("</xsl:transform>"); - - XslResources res; - // Read XML data - QByteArray xmlData = xml.toUtf8(); - res.xmlDoc = xmlParseMemory(xmlData.constData(), xmlData.size()); - if (!res.xmlDoc) - return xml; - - // Read XSL data as a XML file - QByteArray xslData = xsl.toUtf8(); - // xsltFreeStylesheet will delete this pointer - xmlDocPtr xslDoc = xmlParseMemory(xslData.constData(), xslData.size()); - if (!xslDoc) - return xml; - - // Parse XSL data - res.xslt = xsltParseStylesheetDoc(xslDoc); - if (!res.xslt) - return xml; - - // Apply XSL - res.xslResult = xsltApplyStylesheet(res.xslt, res.xmlDoc, 0); - xmlChar* buffer = 0; - int bufferSize; - QString result; - if (!xsltSaveResultToString(&buffer, &bufferSize, res.xslResult, res.xslt)) { - result = QString::fromUtf8(reinterpret_cast<char*>(buffer), bufferSize); - std::free(buffer); - } else { - result = xml; - } - return result.trimmed(); -#else // HAVE_LIBXSLT - Q_UNUSED(mods) - return xml; -#endif // !HAVE_LIBXSLT -} - -QString DocParser::applyDocModificationsQt(const DocModificationList& mods, const QString& xml) const -{ - const char xslPrefix[] = -R"(<?xml version="1.0" encoding="UTF-8"?> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> - <xsl:template match="/"> - <xsl:apply-templates/>\n" - </xsl:template> - <xsl:template match="*"> - <xsl:copy> - <xsl:copy-of select="@*"/> - <xsl:apply-templates/> - </xsl:copy> - </xsl:template> -)"; QString xsl = QLatin1String(xslPrefix); for (const DocModification &mod : mods) { @@ -257,21 +134,17 @@ R"(<?xml version="1.0" encoding="UTF-8"?> + mod.code() + QLatin1String("</xsl:template>\n"); } } - xsl += QLatin1String("</xsl:stylesheet>"); - QXmlQuery query(QXmlQuery::XSLT20); - query.setFocus(xml); - query.setQuery(xsl); - if (!query.isValid()) { + QString errorMessage; + const QString result = xsl_transform(xml, xsl, &errorMessage); + if (!errorMessage.isEmpty()) qCWarning(lcShiboken, "%s", - qPrintable(msgXpathDocModificationError(mods, QLatin1String("Invalid query.")))); - return xml; - } - QString result; - if (!query.evaluateTo(&result)) { + qPrintable(msgXpathDocModificationError(mods, errorMessage))); + if (result == xml) { + const QString message = QLatin1String("Query did not result in any modifications to \"") + + xml + QLatin1Char('"'); qCWarning(lcShiboken, "%s", - qPrintable(msgXpathDocModificationError(mods, QLatin1String("evaluate() failed.")))); - return xml; + qPrintable(msgXpathDocModificationError(mods, message))); } - return result.trimmed(); + return result; } |