diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index 0a0139aaed..5fe5a60a3a 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -53,14 +53,14 @@ void QDBusMetaTypeId::init() // reentrancy is not a problem since everything else is locked on their own // set the guard variable at the end if (!initialized.loadRelaxed()) { - // register our types with Qt Core (calling qMetaTypeId() does this implicitly) - (void)message(); - (void)argument(); - (void)variant(); - (void)objectpath(); - (void)signature(); - (void)error(); - (void)unixfd(); + // register our types with Qt Core + message().registerType(); + argument().registerType(); + variant().registerType(); + objectpath().registerType(); + signature().registerType(); + error().registerType(); + unixfd().registerType(); #ifndef QDBUS_NO_SPECIALTYPES // and register Qt Core's with us @@ -78,7 +78,6 @@ void QDBusMetaTypeId::init() qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); - qDBusRegisterMetaType(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); @@ -88,6 +87,9 @@ void QDBusMetaTypeId::init() qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); + + // plus lists of our own types + qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 295a60c01a..7182e923f3 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -433,12 +433,20 @@ int main(int argc, char **argv) QList classes; + if (args.isEmpty()) + args << u"-"_s; for (const auto &arg: std::as_const(args)) { - if (arg.startsWith(u'-')) + if (arg.startsWith(u'-') && arg.size() > 1) continue; - QFile f(arg); - if (!f.open(QIODevice::ReadOnly|QIODevice::Text)) { + QFile f; + if (arg == u'-') { + f.open(stdin, QIODevice::ReadOnly | QIODevice::Text); + } else { + f.setFileName(arg); + f.open(QIODevice::ReadOnly | QIODevice::Text); + } + if (!f.isOpen()) { fprintf(stderr, PROGRAMNAME ": could not open '%s': %s\n", qPrintable(arg), qPrintable(f.errorString())); return 1; diff --git a/tests/auto/tools/qdbuscpp2xml/CMakeLists.txt b/tests/auto/tools/qdbuscpp2xml/CMakeLists.txt index 557cf57537..ef35bcd34d 100644 --- a/tests/auto/tools/qdbuscpp2xml/CMakeLists.txt +++ b/tests/auto/tools/qdbuscpp2xml/CMakeLists.txt @@ -16,7 +16,7 @@ qt_internal_add_test(tst_qdbuscpp2xml test1.h tst_qdbuscpp2xml.cpp LIBRARIES - Qt::DBus + Qt::DBusPrivate ) # Resources: diff --git a/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp b/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp index 7282ff85b0..973c3587d2 100644 --- a/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp +++ b/tests/auto/tools/qdbuscpp2xml/tst_qdbuscpp2xml.cpp @@ -5,9 +5,11 @@ #include #include +#include +#include + #include "test1.h" -#include // in qdbusxmlgenerator.cpp QT_BEGIN_NAMESPACE @@ -32,6 +34,8 @@ class tst_qdbuscpp2xml : public QObject private slots: void qdbuscpp2xml_data(); void qdbuscpp2xml(); + void qtdbusTypes_data(); + void qtdbusTypes(); void initTestCase(); void cleanupTestCase(); @@ -138,6 +142,77 @@ void tst_qdbuscpp2xml::qdbuscpp2xml() QCOMPARE(out, expected); } +void tst_qdbuscpp2xml::qtdbusTypes_data() +{ + QTest::addColumn("type"); + QTest::addColumn("expectedSignature"); + auto addRow = [](QByteArray type, QByteArray signature) { + QTest::addRow("%s", type.constData()) << type << signature; + + // lists and vectors + QTest::addRow("QList-%s", type.constData()) + << "QList<" + type + '>' << DBUS_TYPE_ARRAY + signature; + QTest::addRow("QVector-%s", type.constData()) + << "QVector<" + type + '>' << DBUS_TYPE_ARRAY + signature; + }; + addRow("QDBusVariant", DBUS_TYPE_VARIANT_AS_STRING); + addRow("QDBusObjectPath", DBUS_TYPE_OBJECT_PATH_AS_STRING); + addRow("QDBusSignature", DBUS_TYPE_SIGNATURE_AS_STRING); + addRow("QDBusUnixFileDescriptor", DBUS_TYPE_UNIX_FD_AS_STRING); + + // QDBusMessage is not a type, but must be recognized + QTest::newRow("QDBusMessage") << QByteArray("QDBusMessage") << QByteArray(); +} + +void tst_qdbuscpp2xml::qtdbusTypes() +{ + static const char cppSkeleton[] = R"( +class QDBusVariantBugRepro : public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.qtproject.test") +public Q_SLOTS: + void method(const @TYPE@ &); +};)"; + static const char methodXml[] = R"()"; + + QFETCH(QByteArray, type); + QFETCH(QByteArray, expectedSignature); + + const QString binpath = QLibraryInfo::path(QLibraryInfo::BinariesPath); + const QString command = binpath + QLatin1String("/qdbuscpp2xml"); + QProcess process; + process.start(command); + + process.write(QByteArray(cppSkeleton).replace("@TYPE@", type)); + process.closeWriteChannel(); + + if (!process.waitForStarted()) { + const QString path = QString::fromLocal8Bit(qgetenv("PATH")); + QString message = QString::fromLatin1("'%1' could not be found when run from '%2'. Path: '%3' "). + arg(command, QDir::currentPath(), path); + QFAIL(qPrintable(message)); + } + QVERIFY2(process.waitForFinished(), qPrintable(process.errorString())); + + // verify nothing was printed on stderr + QCOMPARE(process.readAllStandardError(), QString()); + + // we don't do a full XML parsing here... + QByteArray output = process.readAll().simplified(); + QVERIFY2(output.contains("") && output.contains(""), "Output was: " + output); + output = output.mid(output.indexOf("") + strlen("")); + output = output.left(output.indexOf("")); + + QVERIFY2(output.contains(methodXml), "Output was: " + output); + + if (!expectedSignature.isEmpty()) { + QByteArray expected = QByteArray(expectedSkeleton).replace("@S@", expectedSignature); + QVERIFY2(output.contains(expected), "Expected: '" + expected + "'; got: '" + output + '\''); + } +} + QTEST_APPLESS_MAIN(tst_qdbuscpp2xml) #include "tst_qdbuscpp2xml.moc"