From aa55db84eec2be1b9e7236e2de0eb6903a2a4a29 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 19 May 2017 16:01:59 +0200 Subject: Port the suppression mechanism to use QRegularExpression Change-Id: I686308207c03de2216cd6a5143b2c66f3014a896 Reviewed-by: Alexandru Croitor --- sources/shiboken2/ApiExtractor/typedatabase.cpp | 58 +++++++++++++++++-------- sources/shiboken2/ApiExtractor/typedatabase.h | 5 ++- sources/shiboken2/ApiExtractor/typesystem.cpp | 15 ++++--- 3 files changed, 54 insertions(+), 24 deletions(-) (limited to 'sources/shiboken2/ApiExtractor') diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index a1b28070b..76f8d0f77 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -397,9 +397,45 @@ FunctionModificationList TypeDatabase::functionModifications(const QString& sign return lst; } -void TypeDatabase::addSuppressedWarning(const QString &s) +bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMessage) { - m_suppressedWarnings.append(s); + QString pattern; + if (warning.startsWith(QLatin1Char('^')) && warning.endsWith(QLatin1Char('$'))) { + pattern = warning; + } else { + // Legacy syntax: Use wildcards '*' (unless escaped by '\') + QVector asteriskPositions; + const int warningSize = warning.size(); + for (int i = 0; i < warningSize; ++i) { + if (warning.at(i) == QLatin1Char('\\')) + ++i; + else if (warning.at(i) == QLatin1Char('*')) + asteriskPositions.append(i); + } + asteriskPositions.append(warningSize); + + pattern.append(QLatin1Char('^')); + int lastPos = 0; + for (int a = 0, aSize = asteriskPositions.size(); a < aSize; ++a) { + if (a) + pattern.append(QStringLiteral(".*")); + const int nextPos = asteriskPositions.at(a); + if (nextPos > lastPos) + pattern.append(QRegularExpression::escape(warning.mid(lastPos, nextPos - lastPos))); + lastPos = nextPos + 1; + } + pattern.append(QLatin1Char('$')); + } + + const QRegularExpression expression(pattern); + if (!expression.isValid()) { + *errorMessage = QLatin1String("Invalid message pattern \"") + warning + + QLatin1String("\": ") + expression.errorString(); + return false; + } + + m_suppressedWarnings.append(expression); + return true; } bool TypeDatabase::isSuppressedWarning(const QString& s) const @@ -407,21 +443,9 @@ bool TypeDatabase::isSuppressedWarning(const QString& s) const if (!m_suppressWarnings) return false; - for (QString warning : m_suppressedWarnings) { - warning.replace(QLatin1String("\\*"), QLatin1String("&place_holder_for_asterisk;")); - - QStringList segs = warning.split(QLatin1Char('*'), QString::SkipEmptyParts); - if (!segs.size()) - continue; - - int i = 0; - int pos = s.indexOf(QString(segs.at(i++)).replace(QLatin1String("&place_holder_for_asterisk;"), QLatin1String("*"))); - //qDebug() << "s == " << s << ", warning == " << segs; - while (pos != -1) { - if (i == segs.size()) - return true; - pos = s.indexOf(QString(segs.at(i++)).replace(QLatin1String("&place_holder_for_asterisk;"), QLatin1String("*")), pos); - } + for (const QRegularExpression &warning : m_suppressedWarnings) { + if (warning.match(s).hasMatch()) + return true; } return false; diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h index 86f933448..603a43ba4 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.h +++ b/sources/shiboken2/ApiExtractor/typedatabase.h @@ -35,6 +35,7 @@ #include "typesystem_enums.h" #include "typesystem_typedefs.h" +#include #include QT_FORWARD_DECLARE_CLASS(QIODevice) @@ -134,7 +135,7 @@ public: void setSuppressWarnings(bool on) { m_suppressWarnings = on; } - void addSuppressedWarning(const QString &s); + bool addSuppressedWarning(const QString &warning, QString *errorMessage); bool isSuppressedWarning(const QString& s) const; @@ -164,7 +165,7 @@ private: TypeEntryHash m_entries; SingleTypeEntryHash m_flagsEntries; TemplateEntryHash m_templates; - QStringList m_suppressedWarnings; + QVector m_suppressedWarnings; AddedFunctionList m_globalUserFunctions; FunctionModificationList m_functionMods; diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index 3ec82c56d..9adc5107b 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -45,6 +45,7 @@ static QString strings_jobject = QLatin1String("jobject"); static inline QString colonColon() { return QStringLiteral("::"); } static inline QString quoteAfterLineAttribute() { return QStringLiteral("quote-after-line"); } static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote-before-line"); } +static inline QString textAttribute() { return QStringLiteral("text"); } static inline QString nameAttribute() { return QStringLiteral("name"); } static inline QString sinceAttribute() { return QStringLiteral("since"); } static inline QString flagsAttribute() { return QStringLiteral("flags"); } @@ -1173,7 +1174,7 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts attributes.insert(QLatin1String("default-value"), QString()); break; case StackElement::SuppressedWarning: - attributes.insert(QLatin1String("text"), QString()); + attributes.insert(textAttribute(), QString()); break; case StackElement::ReplaceDefaultExpression: attributes.insert(QLatin1String("with"), QString()); @@ -1524,11 +1525,15 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts m_contextStack.top()->functionMods.last().argument_mods.last().ownerships[lang] = owner; } break; - case StackElement::SuppressedWarning: - if (attributes[QLatin1String("text")].isEmpty()) + case StackElement::SuppressedWarning: { + const QString suppressedWarning = attributes.value(textAttribute()); + if (suppressedWarning.isEmpty()) { qCWarning(lcShiboken) << "Suppressed warning with no text specified"; - else - m_database->addSuppressedWarning(attributes[QLatin1String("text")]); + } else { + if (!m_database->addSuppressedWarning(suppressedWarning, &m_error)) + return false; + } + } break; case StackElement::ArgumentMap: { if (!(topElement.type & StackElement::CodeSnipMask)) { -- cgit v1.2.3