diff options
| -rw-r--r-- | sources/shiboken6/ApiExtractor/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/apiextractor.cpp | 5 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/apiextractor.h | 1 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp | 122 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/conditionalstreamreader.h | 100 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp | 72 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h | 2 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/typedatabase.cpp | 12 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/typedatabase.h | 4 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/typesystemparser.cpp | 101 | ||||
| -rw-r--r-- | sources/shiboken6/ApiExtractor/typesystemparser.h | 84 | ||||
| -rw-r--r-- | sources/shiboken6/doc/shibokengenerator.rst | 6 | ||||
| -rw-r--r-- | sources/shiboken6/doc/typesystem_specifying_types.rst | 24 | ||||
| -rw-r--r-- | sources/shiboken6/generator/main.cpp | 15 |
14 files changed, 457 insertions, 92 deletions
diff --git a/sources/shiboken6/ApiExtractor/CMakeLists.txt b/sources/shiboken6/ApiExtractor/CMakeLists.txt index 48bc3abbc..494881464 100644 --- a/sources/shiboken6/ApiExtractor/CMakeLists.txt +++ b/sources/shiboken6/ApiExtractor/CMakeLists.txt @@ -15,6 +15,7 @@ abstractmetafield.cpp abstractmetafunction.cpp abstractmetatype.cpp abstractmetalang.cpp +conditionalstreamreader.cpp documentation.cpp enclosingclassmixin.cpp fileout.cpp diff --git a/sources/shiboken6/ApiExtractor/apiextractor.cpp b/sources/shiboken6/ApiExtractor/apiextractor.cpp index f91844126..cee8bbdcd 100644 --- a/sources/shiboken6/ApiExtractor/apiextractor.cpp +++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp @@ -72,6 +72,11 @@ void ApiExtractor::addTypesystemSearchPath(const QStringList& paths) addTypesystemSearchPath(path); } +void ApiExtractor::setTypesystemKeywords(const QStringList &keywords) +{ + TypeDatabase::instance()->setTypesystemKeywords(keywords); +} + void ApiExtractor::addIncludePath(const HeaderPath& path) { m_includePaths << path; diff --git a/sources/shiboken6/ApiExtractor/apiextractor.h b/sources/shiboken6/ApiExtractor/apiextractor.h index c0788462f..f7e3685f5 100644 --- a/sources/shiboken6/ApiExtractor/apiextractor.h +++ b/sources/shiboken6/ApiExtractor/apiextractor.h @@ -73,6 +73,7 @@ public: static void setSilent(bool value); static void addTypesystemSearchPath(const QString &path); static void addTypesystemSearchPath(const QStringList& paths); + static void setTypesystemKeywords(const QStringList& keywords); void addIncludePath(const HeaderPath& path); void addIncludePath(const HeaderPaths& paths); HeaderPaths includePaths() const { return m_includePaths; } diff --git a/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp new file mode 100644 index 000000000..2380ee892 --- /dev/null +++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "conditionalstreamreader.h" + +#include <QtCore/QDebug> + +QXmlStreamReader::TokenType ConditionalStreamReader::readNext() +{ + auto exToken = readNextInternal(); + if (exToken.second != PiTokens::If || conditionMatches()) + return exToken.first; + + // Condition does not match - search for endif + int nestingLevel = 1; + while (true) { + exToken = readNextInternal(); + if (exToken.first == QXmlStreamReader::NoToken + || exToken.first == QXmlStreamReader::Invalid + || exToken.first == QXmlStreamReader::EndDocument) { + break; + } + + if (exToken.second == PiTokens::If) + ++nestingLevel; + else if (exToken.second == PiTokens::Endif && --nestingLevel == 0) + break; + } + return exToken.first; +} + +bool ConditionalStreamReader::conditionMatches() const +{ + const auto keywords = m_reader.processingInstructionData().split(u' ', Qt::SkipEmptyParts); + + bool matches = false; + for (const auto &keyword : keywords) { + if (keyword.startsWith(u'!')) { // exclusion '!windows' takes preference + if (m_conditions.contains(keyword.mid(1))) + return false; + } else { + matches |= m_conditions.contains(keyword); + } + } + return matches; +} + +void ConditionalStreamReader::setConditions(const QStringList &newConditions) +{ + m_conditions = newConditions + platformConditions(); +} + +QStringList ConditionalStreamReader::platformConditions() +{ + QStringList result; +#if defined (Q_OS_UNIX) + result << QStringLiteral("unix"); +#endif + +#if defined (Q_OS_LINUX) + result << QStringLiteral("linux"); +#elif defined (Q_OS_MACOS) + result << QStringLiteral("darwin"); +#elif defined (Q_OS_WINDOWS) + result << QStringLiteral("windows"); +#endif + return result; +} + +ConditionalStreamReader::ExtendedToken ConditionalStreamReader::readNextInternal() +{ + const auto token = m_reader.readNext(); + PiTokens piToken = PiTokens::None; + if (token == QXmlStreamReader::ProcessingInstruction) { + const auto target = m_reader.processingInstructionTarget(); + if (target == u"if") + piToken = PiTokens::If; + else if (target == u"endif") + piToken = PiTokens::Endif; + } + return {token, piToken}; +} + +QDebug operator<<(QDebug dbg, const QXmlStreamAttributes &attrs) +{ + QDebugStateSaver saver(dbg); + dbg.noquote(); + dbg.nospace(); + dbg << "QXmlStreamAttributes("; + for (qsizetype i = 0, size = attrs.size(); i < size; ++i ) { + if (i) + dbg << ", "; + dbg << attrs.at(i).name() << "=\"" << attrs.at(i).value() << '"'; + } + dbg << ')'; + return dbg; +} diff --git a/sources/shiboken6/ApiExtractor/conditionalstreamreader.h b/sources/shiboken6/ApiExtractor/conditionalstreamreader.h new file mode 100644 index 000000000..691c5e21d --- /dev/null +++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CONDITIONALSTREAMREADER_H +#define CONDITIONALSTREAMREADER_H + +#include <QtCore/QXmlStreamReader> + +#include <utility> + +QT_FORWARD_DECLARE_CLASS(QDebug) + +/// ConditionalStreamReader encapsulates QXmlStreamReader, offering the same +/// API (except readNextStartElement() and similar conveniences) and internally +/// uses Processing Instructions like: +/// <?if keyword1 !keyword2?> ... <?endif?> +/// to exclude/include sections depending on a list of condition keywords, +/// containing for example the OS. +/// It should be possible to use it as a drop-in replacement for +/// QXmlStreamReader for any parsing code based on readNext(). +class ConditionalStreamReader +{ +public: + using TokenType = QXmlStreamReader::TokenType; + explicit ConditionalStreamReader(QIODevice *iod) : m_reader(iod) { } + explicit ConditionalStreamReader(const QString &s) : m_reader(s) { } + + QIODevice *device() const { return m_reader.device(); } + + void setEntityResolver(QXmlStreamEntityResolver *resolver) { m_reader.setEntityResolver(resolver); } + QXmlStreamEntityResolver *entityResolver() const { return m_reader.entityResolver(); } + + bool atEnd() const { return m_reader.atEnd(); } + TokenType readNext(); + + TokenType tokenType() const { return m_reader.tokenType(); } + + qint64 lineNumber() const { return m_reader.lineNumber(); } + qint64 columnNumber() const { return m_reader.columnNumber(); } + + QXmlStreamAttributes attributes() const { return m_reader.attributes(); } + + QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour = QXmlStreamReader::ErrorOnUnexpectedElement) + { return m_reader.readElementText(behaviour); } + + QStringView name() const { return m_reader.name(); } + QStringView qualifiedName() const { return m_reader.qualifiedName(); } + + QStringView text() const { return m_reader.text(); } + + QString errorString() const { return m_reader.errorString(); } + QXmlStreamReader::Error error() const { return m_reader.error(); } + + bool hasError() const { return m_reader.hasError(); } + + const QStringList &conditions() const { return m_conditions; } + void setConditions(const QStringList &newConditions); + + static QStringList platformConditions(); + +private: + enum class PiTokens { None, If, Endif }; + + using ExtendedToken = std::pair<TokenType, PiTokens>; + ExtendedToken readNextInternal(); + + bool conditionMatches() const; + + QXmlStreamReader m_reader; + QStringList m_conditions = ConditionalStreamReader::platformConditions(); +}; + +QDebug operator<<(QDebug dbg, const QXmlStreamAttributes &a); + +#endif // CONDITIONALSTREAMREADER_H diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp index c47c7232f..1b03f9353 100644 --- a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp +++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp @@ -32,6 +32,7 @@ #include <abstractmetaenum.h> #include <abstractmetalang.h> #include <typesystem.h> +#include <conditionalstreamreader.h> static const char* cppCode ="\ struct ValueA {};\n\ @@ -146,4 +147,75 @@ void TestDropTypeEntries::testDontDropEntryWithChildTags() QVERIFY(AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA"))); } +void TestDropTypeEntries::testConditionalParsing_data() +{ + const QString xml = QStringLiteral(R"(<?xml version="1.0" encoding="UTF-8"?> +<root> + <tag1>text</tag1> + <?if keyword1?> + <tag2>text</tag2> + <?if keyword2?> + <tag3>text</tag3> + <?endif?> + <?if keyword1 !keyword2?> + <tag4>text</tag4> + <?endif?> + <?endif?> + <tag5>text</tag5> +</root>)"); + + const QString root = QStringLiteral("root"); + const QString tag1 = QStringLiteral("tag1"); + const QString tag2 = QStringLiteral("tag2"); + const QString tag3 = QStringLiteral("tag3"); + const QString tag4 = QStringLiteral("tag4"); + const QString tag5 = QStringLiteral("tag5"); + const QString keyword1 = QStringLiteral("keyword1"); + const QString keyword2 = QStringLiteral("keyword2"); + + QTest::addColumn<QString>("xml"); + QTest::addColumn<QStringList>("keywords"); + QTest::addColumn<QStringList>("expectedTags"); + + QTest::newRow("no-keywords") + << xml << QStringList{} << QStringList{root, tag1, tag5}; + + QTest::newRow("skip-nested-condition") + << xml << QStringList{keyword1} + << QStringList{root, tag1, tag2, tag4, tag5}; + + QTest::newRow("both/check-not") + << xml << QStringList{keyword1, keyword2} + << QStringList{root, tag1, tag2, tag3, tag5}; +} + +// Parse XML and return a list of tags encountered +static QStringList parseXml(const QString &xml, const QStringList &keywords) +{ + QStringList tags; + ConditionalStreamReader reader(xml); + reader.setConditions(keywords); + while (!reader.atEnd()) { + auto t = reader.readNext(); + switch (t) { + case QXmlStreamReader::StartElement: + tags.append(reader.name().toString()); + break; + default: + break; + } + } + return tags; +} + +void TestDropTypeEntries::testConditionalParsing() +{ + QFETCH(QString, xml); + QFETCH(QStringList, keywords); + QFETCH(QStringList, expectedTags); + + const QStringList actualTags = parseXml(xml, keywords); + QCOMPARE(actualTags, expectedTags); +} + QTEST_APPLESS_MAIN(TestDropTypeEntries) diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h index 3023a1120..7746234ba 100644 --- a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h +++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h @@ -39,6 +39,8 @@ class TestDropTypeEntries : public QObject void testDontDropEntries(); void testDropEntryWithChildTags(); void testDontDropEntryWithChildTags(); + void testConditionalParsing_data(); + void testConditionalParsing(); }; #endif diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp index f7399fe6d..8a4e6d2f1 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp @@ -29,6 +29,7 @@ #include "typedatabase.h" #include "typesystem.h" #include "typesystemparser.h" +#include "conditionalstreamreader.h" #include <QtCore/QFile> #include <QtCore/QDebug> @@ -138,6 +139,14 @@ void TypeDatabase::addTypesystemPath(const QString& typesystem_paths) m_typesystemPaths += typesystem_paths.split(QLatin1Char(path_splitter)); } +QStringList TypeDatabase::typesystemKeywords() const +{ + QStringList result = m_typesystemKeywords; + for (const auto &d : m_dropTypeEntries) + result.append(QStringLiteral("no_") + d); + return result; +} + IncludeList TypeDatabase::extraIncludes(const QString& className) const { ComplexTypeEntry* typeEntry = findComplexType(className); @@ -634,7 +643,8 @@ bool TypeDatabase::parseFile(const QString &filename, const QString ¤tPath bool TypeDatabase::parseFile(QIODevice* device, bool generate) { - QXmlStreamReader reader(device); + ConditionalStreamReader reader(device); + reader.setConditions(TypeDatabase::instance()->typesystemKeywords()); TypeSystemParser handler(this, generate); const bool result = handler.parse(reader); if (!result) diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h index c49addb3e..082d833b5 100644 --- a/sources/shiboken6/ApiExtractor/typedatabase.h +++ b/sources/shiboken6/ApiExtractor/typedatabase.h @@ -114,6 +114,9 @@ public: void addTypesystemPath(const QString &typesystem_paths); + void setTypesystemKeywords(const QStringList &keywords) { m_typesystemKeywords = keywords; } + QStringList typesystemKeywords() const; + IncludeList extraIncludes(const QString &className) const; const QByteArrayList &systemIncludes() const { return m_systemIncludes; } @@ -229,6 +232,7 @@ private: QStringList m_requiredTargetImports; QStringList m_typesystemPaths; + QStringList m_typesystemKeywords; QHash<QString, bool> m_parsedTypesystemFiles; QList<TypeRejection> m_rejections; diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp index e21b97602..42a4015fc 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp +++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp @@ -31,6 +31,7 @@ #include "messages.h" #include "reporthandler.h" #include "sourcelocation.h" +#include "conditionalstreamreader.h" #include <QtCore/QDir> #include <QtCore/QFile> @@ -533,13 +534,13 @@ TypeSystemParser::TypeSystemParser(TypeDatabase *database, bool generate) : TypeSystemParser::~TypeSystemParser() = default; -static QString readerFileName(const QXmlStreamReader &reader) +static QString readerFileName(const ConditionalStreamReader &reader) { const auto *file = qobject_cast<const QFile *>(reader.device()); return file != nullptr ? file->fileName() : QString(); } -static QString msgReaderMessage(const QXmlStreamReader &reader, +static QString msgReaderMessage(const ConditionalStreamReader &reader, const char *type, const QString &what) { @@ -556,17 +557,17 @@ static QString msgReaderMessage(const QXmlStreamReader &reader, return message; } -static QString msgReaderWarning(const QXmlStreamReader &reader, const QString &what) +static QString msgReaderWarning(const ConditionalStreamReader &reader, const QString &what) { return msgReaderMessage(reader, "Warning", what); } -static QString msgReaderError(const QXmlStreamReader &reader, const QString &what) +static QString msgReaderError(const ConditionalStreamReader &reader, const QString &what) { return msgReaderMessage(reader, "Error", what); } -static QString msgUnimplementedElementWarning(const QXmlStreamReader &reader, +static QString msgUnimplementedElementWarning(const ConditionalStreamReader &reader, QStringView name) { QString message; @@ -575,7 +576,7 @@ static QString msgUnimplementedElementWarning(const QXmlStreamReader &reader, return msgReaderMessage(reader, "Warning", message); } -static QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader, +static QString msgUnimplementedAttributeWarning(const ConditionalStreamReader &reader, QStringView name) { QString message; @@ -584,14 +585,14 @@ static QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader, return msgReaderMessage(reader, "Warning", message); } -static inline QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader, +static inline QString msgUnimplementedAttributeWarning(const ConditionalStreamReader &reader, const QXmlStreamAttribute &attribute) { return msgUnimplementedAttributeWarning(reader, attribute.qualifiedName()); } static QString - msgUnimplementedAttributeValueWarning(const QXmlStreamReader &reader, + msgUnimplementedAttributeValueWarning(const ConditionalStreamReader &reader, QStringView name, QStringView value) { QString message; @@ -601,7 +602,7 @@ static QString } static inline - QString msgUnimplementedAttributeValueWarning(const QXmlStreamReader &reader, + QString msgUnimplementedAttributeValueWarning(const ConditionalStreamReader &reader, const QXmlStreamAttribute &attribute) { return msgUnimplementedAttributeValueWarning(reader, @@ -660,7 +661,7 @@ static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attribute return true; } -bool TypeSystemParser::parse(QXmlStreamReader &reader) +bool TypeSystemParser::parse(ConditionalStreamReader &reader) { m_error.clear(); m_currentPath.clear(); @@ -671,7 +672,7 @@ bool TypeSystemParser::parse(QXmlStreamReader &reader) return result; } -bool TypeSystemParser::parseXml(QXmlStreamReader &reader) +bool TypeSystemParser::parseXml(ConditionalStreamReader &reader) { const QString fileName = readerFileName(reader); if (!fileName.isEmpty()) { @@ -1153,7 +1154,7 @@ static TypeEntry *findViewedType(const QString &name) return nullptr; } -bool TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, +bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &reader, TypeEntry *type, QXmlStreamAttributes *attributes) { type->setSourceLocation(SourceLocation(m_currentFile, @@ -1177,7 +1178,7 @@ bool TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, Typ } FlagsTypeEntry * - TypeSystemParser::parseFlagsEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseFlagsEntry(const ConditionalStreamReader &reader, EnumTypeEntry *enumEntry, QString flagName, const QVersionNumber &since, QXmlStreamAttributes *attributes) @@ -1225,7 +1226,7 @@ FlagsTypeEntry * } SmartPointerTypeEntry * - TypeSystemParser::parseSmartPointerEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseSmartPointerEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1285,7 +1286,7 @@ SmartPointerTypeEntry * } PrimitiveTypeEntry * - TypeSystemParser::parsePrimitiveTypeEntry(const QXmlStreamReader &reader, + TypeSystemParser::parsePrimitiveTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1319,7 +1320,7 @@ PrimitiveTypeEntry * } ContainerTypeEntry * - TypeSystemParser::parseContainerTypeEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseContainerTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1344,7 +1345,7 @@ ContainerTypeEntry * } EnumTypeEntry * - TypeSystemParser::parseEnumTypeEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseEnumTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1385,7 +1386,7 @@ EnumTypeEntry * NamespaceTypeEntry * - TypeSystemParser::parseNamespaceTypeEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseNamespaceTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1446,7 +1447,7 @@ NamespaceTypeEntry * } ValueTypeEntry * - TypeSystemParser::parseValueTypeEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseValueTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1462,7 +1463,7 @@ ValueTypeEntry * } FunctionTypeEntry * - TypeSystemParser::parseFunctionTypeEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseFunctionTypeEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1513,7 +1514,7 @@ FunctionTypeEntry * } TypedefEntry * - TypeSystemParser::parseTypedefEntry(const QXmlStreamReader &reader, + TypeSystemParser::parseTypedefEntry(const ConditionalStreamReader &reader, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes) @@ -1536,7 +1537,7 @@ TypedefEntry * return result; } -void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader, +void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader &reader, ComplexTypeEntry *ctype, QXmlStreamAttributes *attributes) const { @@ -1634,7 +1635,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader ctype->setCodeGeneration(TypeEntry::GenerationDisabled); } -bool TypeSystemParser::parseRenameFunction(const QXmlStreamReader &, +bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &, QString *name, QXmlStreamAttributes *attributes) { QString signature; @@ -1680,7 +1681,7 @@ bool TypeSystemParser::parseRenameFunction(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseInjectDocumentation(const QXmlStreamReader &, +bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &, QXmlStreamAttributes *attributes) { const int validParent = StackElement::TypeEntryMask @@ -1723,7 +1724,7 @@ bool TypeSystemParser::parseInjectDocumentation(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseModifyDocumentation(const QXmlStreamReader &, +bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &, QXmlStreamAttributes *attributes) { const int validParent = StackElement::TypeEntryMask @@ -1749,7 +1750,7 @@ bool TypeSystemParser::parseModifyDocumentation(const QXmlStreamReader &, } // m_exceptionHandling -TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const QXmlStreamReader &, +TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamReader &, const QVersionNumber &since, QXmlStreamAttributes *attributes) { @@ -1810,7 +1811,7 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const QXmlStreamReader & return moduleEntry; } -bool TypeSystemParser::loadTypesystem(const QXmlStreamReader &, +bool TypeSystemParser::loadTypesystem(const ConditionalStreamReader &, QXmlStreamAttributes *attributes) { QString typeSystemName; @@ -1834,7 +1835,7 @@ bool TypeSystemParser::loadTypesystem(const QXmlStreamReader &, return result; } -bool TypeSystemParser::parseRejectEnumValue(const QXmlStreamReader &, +bool TypeSystemParser::parseRejectEnumValue(const ConditionalStreamReader &, QXmlStreamAttributes *attributes) { if (!m_currentEnum) { @@ -1850,7 +1851,7 @@ bool TypeSystemParser::parseRejectEnumValue(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseReplaceArgumentType(const QXmlStreamReader &, +bool TypeSystemParser::parseReplaceArgumentType(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -1868,7 +1869,7 @@ bool TypeSystemParser::parseReplaceArgumentType(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseCustomConversion(const QXmlStreamReader &, +bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -1943,7 +1944,7 @@ bool TypeSystemParser::parseCustomConversion(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseNativeToTarget(const QXmlStreamReader &, +bool TypeSystemParser::parseNativeToTarget(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -1958,7 +1959,7 @@ bool TypeSystemParser::parseNativeToTarget(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseAddConversion(const QXmlStreamReader &, +bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2009,7 +2010,7 @@ static bool parseArgumentIndex(const QString &index, int *result, QString *error return parseIndex(index, result, errorMessage); } -bool TypeSystemParser::parseModifyArgument(const QXmlStreamReader &, +bool TypeSystemParser::parseModifyArgument(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { if (topElement.type != StackElement::ModifyFunction @@ -2051,7 +2052,7 @@ bool TypeSystemParser::parseModifyArgument(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseNoNullPointer(const QXmlStreamReader &reader, +bool TypeSystemParser::parseNoNullPointer(const ConditionalStreamReader &reader, const StackElement &topElement, QXmlStreamAttributes *attributes) { if (topElement.type != StackElement::ModifyArgument) { @@ -2072,7 +2073,7 @@ bool TypeSystemParser::parseNoNullPointer(const QXmlStreamReader &reader, return true; } -bool TypeSystemParser::parseDefineOwnership(const QXmlStreamReader &, +bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2122,7 +2123,7 @@ bool TypeSystemParser::parseDefineOwnership(const QXmlStreamReader &, } // ### fixme PySide7: remove (replaced by attribute). -bool TypeSystemParser::parseRename(const QXmlStreamReader &, +bool TypeSystemParser::parseRename(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2141,7 +2142,7 @@ bool TypeSystemParser::parseRename(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseModifyField(const QXmlStreamReader &, +bool TypeSystemParser::parseModifyField(const ConditionalStreamReader &, QXmlStreamAttributes *attributes) { FieldModification fm; @@ -2188,7 +2189,7 @@ static bool parseOverloadNumber(const QXmlStreamAttribute &attribute, int *overl return true; } -bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &, +bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &, const StackElement &topElement, StackElement::ElementType t, QXmlStreamAttributes *attributes) @@ -2267,7 +2268,7 @@ bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseProperty(const QXmlStreamReader &, const StackElement &topElement, +bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { if ((topElement.type & StackElement::ComplexTypeEntryMask) == 0) { @@ -2301,7 +2302,7 @@ bool TypeSystemParser::parseProperty(const QXmlStreamReader &, const StackElemen return true; } -bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader, +bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2432,7 +2433,7 @@ bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader, return true; } -bool TypeSystemParser::parseReplaceDefaultExpression(const QXmlStreamReader &, +bool TypeSystemParser::parseReplaceDefaultExpression(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2452,7 +2453,7 @@ bool TypeSystemParser::parseReplaceDefaultExpression(const QXmlStreamReader &, } CustomFunction * - TypeSystemParser::parseCustomMetaConstructor(const QXmlStreamReader &, + TypeSystemParser::parseCustomMetaConstructor(const ConditionalStreamReader &, StackElement::ElementType type, const StackElement &topElement, QXmlStreamAttributes *attributes) @@ -2473,7 +2474,7 @@ CustomFunction * return func; } -bool TypeSystemParser::parseReferenceCount(const QXmlStreamReader &reader, +bool TypeSystemParser::parseReferenceCount(const ConditionalStreamReader &reader, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2511,7 +2512,7 @@ bool TypeSystemParser::parseReferenceCount(const QXmlStreamReader &reader, return true; } -bool TypeSystemParser::parseParentOwner(const QXmlStreamReader &, +bool TypeSystemParser::parseParentOwner(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2586,7 +2587,7 @@ bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSni return true; } -bool TypeSystemParser::parseInjectCode(const QXmlStreamReader &, +bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &, const StackElement &topElement, StackElement* element, QXmlStreamAttributes *attributes) { @@ -2642,7 +2643,7 @@ bool TypeSystemParser::parseInjectCode(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseInclude(const QXmlStreamReader &, +bool TypeSystemParser::parseInclude(const ConditionalStreamReader &, const StackElement &topElement, TypeEntry *entry, QXmlStreamAttributes *attributes) { @@ -2676,7 +2677,7 @@ bool TypeSystemParser::parseInclude(const QXmlStreamReader &, return true; } -bool TypeSystemParser::parseSystemInclude(const QXmlStreamReader &, +bool TypeSystemParser::parseSystemInclude(const ConditionalStreamReader &, QXmlStreamAttributes *attributes) { const int index = indexOfAttribute(*attributes, fileNameAttribute()); @@ -2689,7 +2690,7 @@ bool TypeSystemParser::parseSystemInclude(const QXmlStreamReader &, } TemplateInstance * - TypeSystemParser::parseTemplateInstanceEnum(const QXmlStreamReader &, + TypeSystemParser::parseTemplateInstanceEnum(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes) { @@ -2712,7 +2713,7 @@ TemplateInstance * return new TemplateInstance(attributes->takeAt(nameIndex).value().toString()); } -bool TypeSystemParser::parseReplace(const QXmlStreamReader &, +bool TypeSystemParser::parseReplace(const ConditionalStreamReader &, const StackElement &topElement, StackElement *element, QXmlStreamAttributes *attributes) { @@ -2744,7 +2745,7 @@ static bool parseVersion(const QString &versionSpec, const QString &package, return true; } -bool TypeSystemParser::startElement(const QXmlStreamReader &reader) +bool TypeSystemParser::startElement(const ConditionalStreamReader &reader) { if (m_ignoreDepth) { ++m_ignoreDepth; diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.h b/sources/shiboken6/ApiExtractor/typesystemparser.h index efb7e2d8f..585210dca 100644 --- a/sources/shiboken6/ApiExtractor/typesystemparser.h +++ b/sources/shiboken6/ApiExtractor/typesystemparser.h @@ -39,6 +39,8 @@ QT_FORWARD_DECLARE_CLASS(QVersionNumber) QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes) QT_FORWARD_DECLARE_CLASS(QXmlStreamReader) +class ConditionalStreamReader; + class TypeSystemEntityResolver; class TypeDatabase; class StackElement @@ -149,15 +151,15 @@ public: TypeSystemParser(TypeDatabase* database, bool generate); ~TypeSystemParser(); - bool parse(QXmlStreamReader &reader); + bool parse(ConditionalStreamReader &reader); QString errorString() const { return m_error; } private: - bool parseXml(QXmlStreamReader &reader); + bool parseXml(ConditionalStreamReader &reader); bool setupSmartPointerInstantiations(); - bool startElement(const QXmlStreamReader &reader); - SmartPointerTypeEntry *parseSmartPointerEntry(const QXmlStreamReader &, + bool startElement(const ConditionalStreamReader &reader); + SmartPointerTypeEntry *parseSmartPointerEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes); @@ -169,90 +171,90 @@ private: const TypeEntry *currentParentTypeEntry() const; bool checkRootElement(); - bool applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, + bool applyCommonAttributes(const ConditionalStreamReader &reader, TypeEntry *type, QXmlStreamAttributes *attributes); PrimitiveTypeEntry * - parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name, + parsePrimitiveTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); ContainerTypeEntry * - parseContainerTypeEntry(const QXmlStreamReader &, const QString &name, + parseContainerTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); EnumTypeEntry * - parseEnumTypeEntry(const QXmlStreamReader &, const QString &name, + parseEnumTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); FlagsTypeEntry * - parseFlagsEntry(const QXmlStreamReader &, EnumTypeEntry *enumEntry, + parseFlagsEntry(const ConditionalStreamReader &, EnumTypeEntry *enumEntry, QString flagName, const QVersionNumber &since, QXmlStreamAttributes *); NamespaceTypeEntry * - parseNamespaceTypeEntry(const QXmlStreamReader &, + parseNamespaceTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *attributes); ValueTypeEntry * - parseValueTypeEntry(const QXmlStreamReader &, const QString &name, + parseValueTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); FunctionTypeEntry * - parseFunctionTypeEntry(const QXmlStreamReader &, const QString &name, + parseFunctionTypeEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); TypedefEntry * - parseTypedefEntry(const QXmlStreamReader &, const QString &name, + parseTypedefEntry(const ConditionalStreamReader &, const QString &name, const QVersionNumber &since, QXmlStreamAttributes *); - void applyComplexTypeAttributes(const QXmlStreamReader &, ComplexTypeEntry *ctype, + void applyComplexTypeAttributes(const ConditionalStreamReader &, ComplexTypeEntry *ctype, QXmlStreamAttributes *) const; - bool parseRenameFunction(const QXmlStreamReader &, QString *name, + bool parseRenameFunction(const ConditionalStreamReader &, QString *name, QXmlStreamAttributes *); - bool parseInjectDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseModifyDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *); + bool parseInjectDocumentation(const ConditionalStreamReader &, QXmlStreamAttributes *); + bool parseModifyDocumentation(const ConditionalStreamReader &, QXmlStreamAttributes *); TypeSystemTypeEntry * - parseRootElement(const QXmlStreamReader &, const QVersionNumber &since, + parseRootElement(const ConditionalStreamReader &, const QVersionNumber &since, QXmlStreamAttributes *); - bool loadTypesystem(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseRejectEnumValue(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseReplaceArgumentType(const QXmlStreamReader &, const StackElement &topElement, + bool loadTypesystem(const ConditionalStreamReader &, QXmlStreamAttributes *); + bool parseRejectEnumValue(const ConditionalStreamReader &, QXmlStreamAttributes *); + bool parseReplaceArgumentType(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseCustomConversion(const QXmlStreamReader &, const StackElement &topElement, + bool parseCustomConversion(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseAddConversion(const QXmlStreamReader &, const StackElement &topElement, + bool parseAddConversion(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseNativeToTarget(const QXmlStreamReader &, const StackElement &topElement, + bool parseNativeToTarget(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes); - bool parseModifyArgument(const QXmlStreamReader &, const StackElement &topElement, + bool parseModifyArgument(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes); - bool parseNoNullPointer(const QXmlStreamReader &, const StackElement &topElement, + bool parseNoNullPointer(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *attributes); - bool parseDefineOwnership(const QXmlStreamReader &, const StackElement &topElement, + bool parseDefineOwnership(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseRename(const QXmlStreamReader &, const StackElement &topElement, + bool parseRename(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseModifyField(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseAddFunction(const QXmlStreamReader &, const StackElement &topElement, + bool parseModifyField(const ConditionalStreamReader &, QXmlStreamAttributes *); + bool parseAddFunction(const ConditionalStreamReader &, const StackElement &topElement, StackElement::ElementType t, QXmlStreamAttributes *); - bool parseProperty(const QXmlStreamReader &, const StackElement &topElement, + bool parseProperty(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseModifyFunction(const QXmlStreamReader &, const StackElement &topElement, + bool parseModifyFunction(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseReplaceDefaultExpression(const QXmlStreamReader &, + bool parseReplaceDefaultExpression(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); static CustomFunction * - parseCustomMetaConstructor(const QXmlStreamReader &, + parseCustomMetaConstructor(const ConditionalStreamReader &, StackElement::ElementType type, const StackElement &topElement, QXmlStreamAttributes *); - bool parseReferenceCount(const QXmlStreamReader &, const StackElement &topElement, + bool parseReferenceCount(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseParentOwner(const QXmlStreamReader &, const StackElement &topElement, + bool parseParentOwner(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); bool readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip); - bool parseInjectCode(const QXmlStreamReader &, const StackElement &topElement, + bool parseInjectCode(const ConditionalStreamReader &, const StackElement &topElement, StackElement* element, QXmlStreamAttributes *); - bool parseInclude(const QXmlStreamReader &, const StackElement &topElement, + bool parseInclude(const ConditionalStreamReader &, const StackElement &topElement, TypeEntry *entry, QXmlStreamAttributes *); - bool parseSystemInclude(const QXmlStreamReader &, QXmlStreamAttributes *); + bool parseSystemInclude(const ConditionalStreamReader &, QXmlStreamAttributes *); TemplateInstance - *parseTemplateInstanceEnum(const QXmlStreamReader &, const StackElement &topElement, + *parseTemplateInstanceEnum(const ConditionalStreamReader &, const StackElement &topElement, QXmlStreamAttributes *); - bool parseReplace(const QXmlStreamReader &, const StackElement &topElement, + bool parseReplace(const ConditionalStreamReader &, const StackElement &topElement, StackElement *element, QXmlStreamAttributes *); TypeDatabase* m_database; diff --git a/sources/shiboken6/doc/shibokengenerator.rst b/sources/shiboken6/doc/shibokengenerator.rst index d811ee25f..bf7e06f0b 100644 --- a/sources/shiboken6/doc/shibokengenerator.rst +++ b/sources/shiboken6/doc/shibokengenerator.rst @@ -136,6 +136,12 @@ Options fully qualified Python type names ('Module.Class'), but the module can be omitted ('Class'). +.. _conditional_keywords: + +``-keywords=keyword1[,keyword2,...]`` + A comma-separated list of keywords for conditional typesystem parsing + (see :ref:`conditional_processing`). + ``--use-global-header`` Use the global headers passed on the command line in generated code. diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst index 1172b3f15..fadc78cd2 100644 --- a/sources/shiboken6/doc/typesystem_specifying_types.rst +++ b/sources/shiboken6/doc/typesystem_specifying_types.rst @@ -577,3 +577,27 @@ system-include <system-include file-name="memory"/> <system-include file-name="/usr/include/Qt/"/> </typesystem> + +.. _conditional_processing: + +Conditional Processing +^^^^^^^^^^^^^^^^^^^^^^ + + Simple processing instructions are provided for including or excluding + sections depending on the presence of keywords. The syntax is: + + .. code-block:: xml + + <?if keyword !excluded_keyword ?> + ... + <?endif?> + + There are predefined keywords indicating the operating system (``windows``, + ``unix`` and ``darwin``). The class names passed to the + :ref:`--drop-type-entries <drop-type-entries>` command line option + are also predefined, prefixed by ``no_``. This allows for example + for enclosing added functions referring to those classes within + ``<?if !no_ClassName?>``, ``<?endif?>``. + + Other keywords can be specified using the + :ref:`--keywords <conditional_keywords>` command line option. diff --git a/sources/shiboken6/generator/main.cpp b/sources/shiboken6/generator/main.cpp index dbb25d796..315e963c4 100644 --- a/sources/shiboken6/generator/main.cpp +++ b/sources/shiboken6/generator/main.cpp @@ -47,9 +47,11 @@ #include <exception> static const QChar clangOptionsSplitter = u','; +static const QChar keywordsSplitter = u','; static const QChar dropTypeEntriesSplitter = u';'; static const QChar apiVersionSplitter = u'|'; +static inline QString keywordsOption() { return QStringLiteral("keywords"); } static inline QString clangOptionOption() { return QStringLiteral("clang-option"); } static inline QString clangOptionsOption() { return QStringLiteral("clang-options"); } static inline QString apiVersionOption() { return QStringLiteral("api-version"); } @@ -191,6 +193,9 @@ static std::optional<CommandLineArguments> } else if (key == "api-version") { args.addToOptionsList(apiVersionOption(), value, apiVersionSplitter); + } else if (key == "keywords") { + args.addToOptionsList(keywordsOption(), + value, keywordsSplitter); } else if (key == "drop-type-entries") { args.addToOptionsList(dropTypeEntriesOption(), value, dropTypeEntriesSplitter); @@ -263,6 +268,8 @@ static void getCommandLineArg(QString arg, int &argNum, CommandLineArguments &ar args.addToOptionsList(clangOptionsOption(), value); } else if (option == clangOptionsOption()) { args.addToOptionsList(clangOptionsOption(), value, clangOptionsSplitter); + } else if (option == keywordsOption()) { + args.addToOptionsList(keywordsOption(), value, keywordsSplitter); } else { args.options.insert(option, value); } @@ -344,6 +351,8 @@ void printUsage() {QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""), QLatin1String("Semicolon separated list of type system entries (classes, namespaces,\n" "global functions and enums) to be dropped from generation.")}, + {keywordsOption() + QStringLiteral("=keyword1[,keyword2,...]"), + QLatin1String("A comma-separated list of keywords for conditional typesystem parsing")}, {clangOptionOption(), QLatin1String("Option to be passed to clang")}, {clangOptionsOption(), @@ -584,6 +593,12 @@ int shibokenMain(int argc, char *argv[]) args.options.erase(ait); } + ait = args.options.find(keywordsOption()); + if (ait != args.options.end()) { + extractor.setTypesystemKeywords(ait.value().toStringList()); + args.options.erase(ait); + } + ait = args.options.find(typesystemPathOption()); if (ait != args.options.end()) { extractor.addTypesystemSearchPath(ait.value().toStringList()); |
