summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Rauter <[email protected]>2025-02-18 17:20:09 +0100
committerMatthias Rauter <[email protected]>2025-03-05 10:06:19 +0100
commit351b7a31aa24a704dba09121d91cb34190892315 (patch)
treec5c1976f16eddcbb481cc77caa1123fbd84ae3d0
parent611031e4f069aea6a0312b5c459247094204d5eb (diff)
Add namespaces to qdbusxml2cpp
[ChangeLog][QtDBus][qdbusxml2cpp] The Qt D-Bus XML compiler (qdbusxml2cpp) now supports the command-line argument -namespace <namespace>, which encapsulates all generated classes within the specified namespace to prevent class name conflicts. Fixes: QTBUG-133611 Change-Id: Ic3473dfc33dcf22f5be727236fe546b70b2b015b Reviewed-by: Ivan Solovev <[email protected]>
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp41
-rw-r--r--tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp47
2 files changed, 86 insertions, 2 deletions
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index d637854d2bb..7ab7241c962 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -80,6 +80,7 @@ private:
QString globalClassName;
QString parentClassName;
+ QString customNamespace;
QString inputFile;
bool skipNamespaces = false;
bool includeMocs = false;
@@ -608,6 +609,13 @@ void QDBusXmlToCpp::writeProxy(const QString &filename,
cs << "#include \"" << headerName << "\"\n\n";
}
+ if (!customNamespace.isEmpty()) {
+ hs << "namespace " << customNamespace << " { \n"
+ "\n";
+ cs << "namespace " << customNamespace << " { \n"
+ "\n";
+ }
+
for (const QDBusIntrospection::Interface *interface : interfaces) {
QString className = classNameForInterface(interface->name, Proxy);
@@ -799,6 +807,13 @@ void QDBusXmlToCpp::writeProxy(const QString &filename,
hs << "};\n\n";
}
+ if (!customNamespace.isEmpty()) {
+ hs << "} // end of namespace " << customNamespace << "\n"
+ << "\n";
+ cs << "} // end of namespace " << customNamespace << "\n"
+ << "\n";
+ }
+
if (!skipNamespaces) {
QStringList last;
QDBusIntrospection::Interfaces::ConstIterator it = interfaces.constBegin();
@@ -827,7 +842,8 @@ void QDBusXmlToCpp::writeProxy(const QString &filename,
// add this class:
if (!name.isEmpty()) {
hs << QString(current.size() * 2, u' ')
- << "using " << name << " = ::" << classNameForInterface(it->constData()->name, Proxy)
+ << "using " << name << " = " << (customNamespace.isEmpty() ? "" : "::")
+ << customNamespace << "::" << classNameForInterface(it->constData()->name, Proxy)
<< ";\n";
}
@@ -836,6 +852,8 @@ void QDBusXmlToCpp::writeProxy(const QString &filename,
++it;
last = current;
} while (true);
+
+ hs << "\n";
}
// close the include guard
@@ -937,6 +955,13 @@ void QDBusXmlToCpp::writeAdaptor(const QString &filename,
if (parentClassName.isEmpty())
parent = u"QObject"_s;
+ if (!customNamespace.isEmpty()) {
+ hs << "namespace " << customNamespace << " { \n"
+ "\n";
+ cs << "namespace " << customNamespace << " { \n"
+ "\n";
+ }
+
for (const QDBusIntrospection::Interface *interface : interfaces) {
QString className = classNameForInterface(interface->name, Adaptor);
@@ -1134,6 +1159,13 @@ void QDBusXmlToCpp::writeAdaptor(const QString &filename,
hs << "};\n\n";
}
+ if (!customNamespace.isEmpty()) {
+ hs << "} // end of namespace " << customNamespace << "\n"
+ << "\n";
+ cs << "} // end of namespace " << customNamespace << "\n"
+ << "\n";
+ }
+
// close the include guard
hs << "#endif\n";
@@ -1188,6 +1220,10 @@ int QDBusXmlToCpp::run(const QCoreApplication &app)
u"classname"_s);
parser.addOption(classNameOption);
+ QCommandLineOption namespaceOption(QStringList{u"namespace"_s},
+ u"Put all generated classes into the namespace <namespace>. "_s, u"namespace"_s);
+ parser.addOption(namespaceOption);
+
QCommandLineOption addIncludeOption(QStringList{u"i"_s, u"include"_s},
u"Add #include \"filename\" to the output"_s, u"filename"_s);
parser.addOption(addIncludeOption);
@@ -1205,7 +1241,7 @@ int QDBusXmlToCpp::run(const QCoreApplication &app)
parser.addOption(mocIncludeOption);
QCommandLineOption noNamespaceOption(QStringList{u"N"_s, u"no-namespaces"_s},
- u"Don't use namespaces"_s);
+ u"Do not export the generated class into the D-Bus specific namespace"_s);
parser.addOption(noNamespaceOption);
QCommandLineOption proxyCodeOption(QStringList{u"p"_s, u"proxy"_s},
@@ -1223,6 +1259,7 @@ int QDBusXmlToCpp::run(const QCoreApplication &app)
includes = parser.values(addIncludeOption);
globalIncludes = parser.values(addGlobalIncludeOption);
parentClassName = parser.value(adapterParentOption);
+ customNamespace = parser.value(namespaceOption);
includeMocs = parser.isSet(mocIncludeOption);
skipNamespaces = parser.isSet(noNamespaceOption);
QString proxyFile = parser.value(proxyCodeOption);
diff --git a/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp b/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp
index c51a0909f8d..5474c4f7470 100644
--- a/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp
+++ b/tests/auto/tools/qdbusxml2cpp/tst_qdbusxml2cpp.cpp
@@ -25,6 +25,8 @@ private slots:
void missingAnnotation();
void includeMoc_data();
void includeMoc();
+ void customNamespace_data();
+ void customNamespace();
};
struct BasicTypeList {
@@ -482,6 +484,51 @@ void tst_qdbusxml2cpp::includeMoc()
}
}
+void tst_qdbusxml2cpp::customNamespace_data()
+{
+ QTest::addColumn<QByteArray>("namesp");
+
+ QTest::newRow("simple") << QByteArray("lancetest");
+ QTest::newRow("double") << QByteArray("lance::test");
+}
+
+void tst_qdbusxml2cpp::customNamespace()
+{
+ QFETCH(QByteArray, namesp);
+
+ QProcess process;
+ QStringList flags = {"-", "--namespace", namesp};
+
+ runTool(process,QByteArray{},flags);
+ QCOMPARE(process.exitCode(), 0);
+
+ QByteArray errOutput = process.readAllStandardError();
+ QVERIFY2(errOutput.isEmpty(), errOutput);
+
+ QByteArray fullOutput = process.readAll();
+ QVERIFY(!fullOutput.isEmpty());
+
+ // twice: once in the header, once in the implementation
+ static constexpr qsizetype requiredNameSpaceCount = 2;
+ QCOMPARE(fullOutput.count("namespace " + namesp + " {"), requiredNameSpaceCount);
+
+ static constexpr QByteArrayView endMarker("} // end of namespace ");
+ qsizetype startFrom = 0;
+ for (qsizetype i = 0; i < requiredNameSpaceCount; ++i) {
+ // make sure the namespace is there
+ qsizetype namespaceStart = fullOutput.indexOf("namespace " + namesp + " {", startFrom);
+ qsizetype namespaceEnd = fullOutput.indexOf(endMarker + namesp, namespaceStart);
+ QCOMPARE_GE(namespaceStart, 0);
+ QCOMPARE_GT(namespaceEnd, namespaceStart);
+ startFrom = namespaceEnd + endMarker.size() + namesp.size();
+
+ // make sure we cover a useful part of the source code with the namespace:
+ auto partOutput = QByteArrayView(fullOutput)
+ .slice(namespaceStart, startFrom - namespaceStart);
+ QCOMPARE(partOutput.count("{"), partOutput.count("}"));
+ }
+}
+
QTEST_MAIN(tst_qdbusxml2cpp)
#include "tst_qdbusxml2cpp.moc"