Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions generator/generator.pri
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,6 @@ SOURCES += \

QT += core xml

greaterThan(QT_MAJOR_VERSION, 5) {
QT += core5compat
message("WARNING: Qt module core5compat for XML handling in typesystem.cpp")
}

win32-msvc.net {
QMAKE_CXXFLAGS += /Zm500
QMAKE_CXXFLAGS -= -Zm200
Expand Down
156 changes: 100 additions & 56 deletions generator/typesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,11 @@

#include <memory>

#include <QtXml>
#include <QFile>
#include <QTextStream>
#include <QXmlStreamReader>
#include <qcompilerdetection.h> // Q_FALLTHROUGH

/* This file needs to be rewritten as documented here:
*
* See: https://doc.qt.io/qt-6/xml-changes-qt6.html
*
* The rewrite may be backward compatible to Qt4.3 APIs because the base
* facilites (QXmlStreamReader) used to relace the 'SAX' parser were apparently
* available then. Use of Xml5Compat is a work round until such a rewrite has
* been done.
*/
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
# if defined(__GNUC__)
# pragma GCC warning "Qt6: implement Qt6 compatible XML reading"
# endif
# include <QtCore5Compat/QXmlDefaultHandler>
#endif

QString strings_Object = QLatin1String("Object");
QString strings_String = QLatin1String("String");
QString strings_Thread = QLatin1String("Thread");
Expand Down Expand Up @@ -150,9 +136,48 @@ class StackElement
} value;
};

class Handler : public QXmlDefaultHandler
class Handler
{
public:
class Attributes
{
public:
Attributes() = default;
explicit Attributes(const QXmlStreamAttributes &attributes)
: m_attributes(attributes) {}

int length() const { return m_attributes.size(); }

QString localName(int index) const
{
return m_attributes.at(index).name().toString();
}

QString value(int index) const
{
return m_attributes.at(index).value().toString();
}

QString value(const QString &qualifiedName) const
{
return m_attributes.hasAttribute(qualifiedName)
? m_attributes.value(qualifiedName).toString()
: QString();
}

int index(const QString &qualifiedName) const
{
for (int i = 0; i < m_attributes.size(); ++i) {
if (m_attributes.at(i).name().toString() == qualifiedName)
return i;
}
return -1;
}

private:
QXmlStreamAttributes m_attributes;
};

Handler(TypeDatabase *database, unsigned int qtVersion, bool generate)
: m_database(database)
, m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
Expand Down Expand Up @@ -197,25 +222,23 @@ class Handler : public QXmlDefaultHandler
tagNames["reference-count"] = StackElement::ReferenceCount;
}

bool parse(QXmlStreamReader &reader);
bool startDocument() { m_nestingLevel = 0; m_disabledLevel = -1; return true; }
bool startElement(const QString &namespaceURI, const QString &localName,
const QString &qName, const QXmlAttributes &atts);
const QString &qName, const Attributes &atts);
bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);

QString errorString() const { return m_error; }
bool error(const QXmlParseException &exception);
bool fatalError(const QXmlParseException &exception);
bool warning(const QXmlParseException &exception);

bool characters(const QString &ch);

private:
void fetchAttributeValues(const QString &name, const QXmlAttributes &atts,
void fetchAttributeValues(const QString &name, const Attributes &atts,
QHash<QString, QString> *acceptedAttributes);

bool importFileElement(const QXmlAttributes &atts);
bool importFileElement(const Attributes &atts);
bool convertBoolean(const QString &, const QString &, bool);
bool qtVersionMatches(const QXmlAttributes& atts, bool& ok);
bool qtVersionMatches(const Attributes& atts, bool& ok);

TypeDatabase *m_database;
StackElement* current;
Expand All @@ -237,31 +260,55 @@ class Handler : public QXmlDefaultHandler
int m_disabledLevel{}; // if this is != 0, elements should be ignored
};

bool Handler::error(const QXmlParseException &e)
bool Handler::parse(QXmlStreamReader &reader)
{
qWarning() << "Error: line=" << e.lineNumber()
<< ", column=" << e.columnNumber()
<< ", message=" << e.message() << "\n";
return false;
}
if (!startDocument())
return false;

bool Handler::fatalError(const QXmlParseException &e)
{
qWarning() << "Fatal error: line=" << e.lineNumber()
<< ", column=" << e.columnNumber()
<< ", message=" << e.message() << "\n";
return false;
}
while (!reader.atEnd()) {
const auto token = reader.readNext();
switch (token) {
case QXmlStreamReader::StartElement: {
Attributes attributes(reader.attributes());
if (!startElement(reader.namespaceUri().toString(),
reader.name().toString(),
reader.qualifiedName().toString(),
attributes)) {
return false;
}
break;
}
case QXmlStreamReader::EndElement:
if (!endElement(reader.namespaceUri().toString(),
reader.name().toString(),
reader.qualifiedName().toString())) {
return false;
}
break;
case QXmlStreamReader::Characters:
case QXmlStreamReader::EntityReference:
if (!characters(reader.text().toString())) {
return false;
}
break;
default:
break;
}
}

bool Handler::warning(const QXmlParseException &e)
{
qWarning() << "Warning: line=" << e.lineNumber()
<< ", column=" << e.columnNumber()
<< ", message=" << e.message() << "\n";
return false;
if (reader.hasError()) {
m_error = QStringLiteral("Parse error at line %1, column %2: %3")
.arg(reader.lineNumber())
.arg(reader.columnNumber())
.arg(reader.errorString());
qWarning() << m_error;
return false;
}

return true;
}

void Handler::fetchAttributeValues(const QString &name, const QXmlAttributes &atts,
void Handler::fetchAttributeValues(const QString &name, const Attributes &atts,
QHash<QString, QString> *acceptedAttributes)
{
Q_ASSERT(acceptedAttributes != 0);
Expand Down Expand Up @@ -398,7 +445,7 @@ bool Handler::characters(const QString &ch)
return true;
}

bool Handler::importFileElement(const QXmlAttributes &atts)
bool Handler::importFileElement(const Attributes &atts)
{
QString fileName = atts.value("name");
if(fileName.isEmpty()){
Expand Down Expand Up @@ -470,7 +517,7 @@ bool Handler::convertBoolean(const QString &_value, const QString &attributeName
}
}

bool Handler::qtVersionMatches(const QXmlAttributes& atts, bool& ok)
bool Handler::qtVersionMatches(const Attributes& atts, bool& ok)
{
ok = true;
int beforeIndex = atts.index("before-version");
Expand Down Expand Up @@ -501,7 +548,7 @@ bool Handler::qtVersionMatches(const QXmlAttributes& atts, bool& ok)
}

bool Handler::startElement(const QString &, const QString &n,
const QString &, const QXmlAttributes &atts)
const QString &, const Attributes &atts)
{
QString tagName = n.toLower();
m_nestingLevel++;
Expand Down Expand Up @@ -1605,22 +1652,19 @@ bool TypeDatabase::parseFile(const QString &filename, unsigned int qtVersion, bo
// If opening fails, attempt to load from Qt resources
file.setFileName(":/trolltech/generator/" + filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Could not open file:" << filename;
ReportHandler::warning(QString::fromLatin1("Could not open typesystem file: '%1'").arg(filename));
return false;
}
}

QXmlInputSource source(&file);

int count = m_entries.size();

QXmlSimpleReader reader;
Handler handler(this, qtVersion, generate);
QXmlStreamReader reader(&file);

reader.setContentHandler(&handler);
reader.setErrorHandler(&handler);

bool ok = reader.parse(&source, false);
bool ok = handler.parse(reader);
if (!ok && !handler.errorString().isEmpty())
ReportHandler::warning(handler.errorString());

int newCount = m_entries.size();

Expand Down