Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdbusxml2cpp.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include <qbytearray.h>
6#include <qcoreapplication.h>
7#include <qdebug.h>
8#include <qfile.h>
9#include <qfileinfo.h>
10#include <qloggingcategory.h>
11#include <qstring.h>
12#include <qstringlist.h>
13#include <qtextstream.h>
14#include <qset.h>
15
16#include <qdbusmetatype.h>
17#include <private/qdbusintrospection_p.h>
18
19#include <stdio.h>
20#include <stdlib.h>
21
22#define PROGRAMNAME "qdbusxml2cpp"
23#define PROGRAMVERSION "0.8"
24#define PROGRAMCOPYRIGHT QT_COPYRIGHT
25
26#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
27
28using namespace Qt::StringLiterals;
29
30class QDBusXmlToCpp final
31{
32public:
33 int run(const QCoreApplication &app);
34
35private:
36 class DiagnosticsReporter final : public QDBusIntrospection::DiagnosticsReporter
37 {
38 public:
39 void setFileName(const QString &fileName) { m_fileName = fileName; }
40 bool hadErrors() const { return m_hadErrors; }
41
42 void warning(const QDBusIntrospection::SourceLocation &location, const char *msg,
43 ...) override;
44 void error(const QDBusIntrospection::SourceLocation &location, const char *msg,
45 ...) override;
46 void note(const QDBusIntrospection::SourceLocation &location, const char *msg, ...)
48
49 private:
50 QString m_fileName;
51 bool m_hadErrors = false;
52
53 void report(const QDBusIntrospection::SourceLocation &location, const char *msg, va_list ap,
54 const char *severity);
55 };
56
57 enum ClassType { Proxy, Adaptor };
58
59 void writeAdaptor(const QString &filename, const QDBusIntrospection::Interfaces &interfaces);
60 void writeProxy(const QString &filename, const QDBusIntrospection::Interfaces &interfaces);
61
63 void cleanInterfaces(QDBusIntrospection::Interfaces &interfaces);
64 QTextStream &writeHeader(QTextStream &ts, bool changesWillBeLost);
65 QString classNameForInterface(const QString &interface, ClassType classType);
67 const QString &signature,
68 const QDBusIntrospection::Annotations &annotations,
69 qsizetype paramId = -1, const char *direction = "Out");
70 void
71 writeArgList(QTextStream &ts, const QStringList &argNames,
72 const QDBusIntrospection::Annotations &annotations,
73 const QDBusIntrospection::Arguments &inputArgs,
75 void writeSignalArgList(QTextStream &ts, const QStringList &argNames,
76 const QDBusIntrospection::Annotations &annotations,
77 const QDBusIntrospection::Arguments &outputArgs);
78 QString propertyGetter(const QDBusIntrospection::Property &property);
79 QString propertySetter(const QDBusIntrospection::Property &property);
80
81 QString globalClassName;
82 QString parentClassName;
83 QString inputFile;
84 bool skipNamespaces = false;
85 bool includeMocs = false;
86 QString commandLine;
87 QStringList includes;
88 QStringList globalIncludes;
89 QStringList wantedInterfaces;
90
91 DiagnosticsReporter reporter;
92};
93
94static const char includeList[] =
95 "#include <QtCore/QByteArray>\n"
96 "#include <QtCore/QList>\n"
97 "#include <QtCore/QMap>\n"
98 "#include <QtCore/QString>\n"
99 "#include <QtCore/QStringList>\n"
100 "#include <QtCore/QVariant>\n";
101
102static const char forwardDeclarations[] =
103 "#include <QtCore/qcontainerfwd.h>\n";
104
105void QDBusXmlToCpp::DiagnosticsReporter::warning(const QDBusIntrospection::SourceLocation &location,
106 const char *msg, ...)
107{
108 va_list ap;
109 va_start(ap, msg);
110 report(location, msg, ap, "warning");
111 va_end(ap);
112}
113
114void QDBusXmlToCpp::DiagnosticsReporter::error(const QDBusIntrospection::SourceLocation &location,
115 const char *msg, ...)
116{
117 va_list ap;
118 va_start(ap, msg);
119 report(location, msg, ap, "error");
120 va_end(ap);
121 m_hadErrors = true;
122}
123
124void QDBusXmlToCpp::DiagnosticsReporter::note(const QDBusIntrospection::SourceLocation &location,
125 const char *msg, ...)
126{
127 va_list ap;
128 va_start(ap, msg);
129 report(location, msg, ap, "note");
130 va_end(ap);
131 m_hadErrors = true;
132}
133
134void QDBusXmlToCpp::DiagnosticsReporter::report(const QDBusIntrospection::SourceLocation &location,
135 const char *msg, va_list ap, const char *severity)
136{
137 fprintf(stderr, "%s:%lld:%lld: %s: ", qPrintable(m_fileName),
138 (long long int)location.lineNumber, (long long int)location.columnNumber + 1, severity);
139 vfprintf(stderr, msg, ap);
140}
141
142QDBusIntrospection::Interfaces QDBusXmlToCpp::readInput()
143{
144 QFile input(inputFile);
145 if (inputFile.isEmpty() || inputFile == "-"_L1) {
146 reporter.setFileName("<standard input>"_L1);
147 input.open(stdin, QIODevice::ReadOnly);
148 } else {
149 reporter.setFileName(inputFile);
151 }
152
153 QByteArray data = input.readAll();
154 auto interfaces = QDBusIntrospection::parseInterfaces(QString::fromUtf8(data), &reporter);
155 if (reporter.hadErrors())
156 exit(1);
157
158 return interfaces;
159}
160
161void QDBusXmlToCpp::cleanInterfaces(QDBusIntrospection::Interfaces &interfaces)
162{
163 if (!wantedInterfaces.isEmpty()) {
165 while (it != interfaces.end())
166 if (!wantedInterfaces.contains(it.key()))
167 it = interfaces.erase(it);
168 else
169 ++it;
170 }
171}
172
174{
175 const QLatin1StringView candidates[] = {
176 "h"_L1,
177 "cpp"_L1,
178 "cc"_L1
179 };
180
181 for (auto candidate : candidates)
182 if (suffix == candidate)
183 return true;
184
185 return false;
186}
187
188// produce a header name from the file name
190{
191 QStringList parts = name.split(u':');
192 QString retval = parts.front();
193
194 if (retval.isEmpty() || retval == "-"_L1)
195 return retval;
196
197 QFileInfo header{retval};
198 if (!isSupportedSuffix(header.suffix()))
199 retval.append(".h"_L1);
200
201 return retval;
202}
203
204// produce a cpp name from the file name
205static QString cpp(const QString &name)
206{
207 QStringList parts = name.split(u':');
208 QString retval = parts.back();
209
210 if (retval.isEmpty() || retval == "-"_L1)
211 return retval;
212
213 QFileInfo source{retval};
214 if (!isSupportedSuffix(source.suffix()))
215 retval.append(".cpp"_L1);
216
217 return retval;
218}
219
220// produce a moc name from the file name
221static QString moc(const QString &name)
222{
223 QString retval;
224 const QStringList fileNames = name.split(u':');
225
226 if (fileNames.size() == 1) {
227 QFileInfo fi{fileNames.front()};
228 if (isSupportedSuffix(fi.suffix())) {
229 // Generates a file that contains the header and the implementation: include "filename.moc"
230 retval += fi.completeBaseName();
231 retval += ".moc"_L1;
232 } else {
233 // Separate source and header files are generated: include "moc_filename.cpp"
234 retval += "moc_"_L1;
235 retval += fi.fileName();
236 retval += ".cpp"_L1;
237 }
238 } else {
239 QString headerName = fileNames.front();
240 QString sourceName = fileNames.back();
241
242 if (sourceName.isEmpty() || sourceName == "-"_L1) {
243 // If only a header is generated, don't include anything
244 } else if (headerName.isEmpty() || headerName == "-"_L1) {
245 // If only source file is generated: include "moc_sourcename.cpp"
246 QFileInfo source{sourceName};
247
248 retval += "moc_"_L1;
249 retval += source.completeBaseName();
250 retval += ".cpp"_L1;
251
252 fprintf(stderr, "warning: no header name is provided, assuming it to be \"%s\"\n",
253 qPrintable(source.completeBaseName() + ".h"_L1));
254 } else {
255 // Both source and header generated: include "moc_headername.cpp"
257
258 retval += "moc_"_L1;
259 retval += header.completeBaseName();
260 retval += ".cpp"_L1;
261 }
262 }
263
264 return retval;
265}
266
267QTextStream &QDBusXmlToCpp::writeHeader(QTextStream &ts, bool changesWillBeLost)
268{
269 ts << "/*\n"
270 " * This file was generated by " PROGRAMNAME " version " PROGRAMVERSION "\n"
271 " * Command line was: " << commandLine << "\n"
272 " *\n"
273 " * " PROGRAMNAME " is " PROGRAMCOPYRIGHT "\n"
274 " *\n"
275 " * This is an auto-generated file.\n";
276
277 if (changesWillBeLost)
278 ts << " * Do not edit! All changes made to it will be lost.\n";
279 else
280 ts << " * This file may have been hand-edited. Look for HAND-EDIT comments\n"
281 " * before re-generating it.\n";
282
283 ts << " */\n\n";
284
285 return ts;
286}
287
288QString QDBusXmlToCpp::classNameForInterface(const QString &interface,
289 QDBusXmlToCpp::ClassType classType)
290{
291 if (!globalClassName.isEmpty())
292 return globalClassName;
293
294 const auto parts = QStringView{interface}.split(u'.');
295
296 QString retval;
297 if (classType == Proxy) {
298 for (const auto &part : parts) {
299 retval += part[0].toUpper();
300 retval += part.mid(1);
301 }
302 } else {
303 retval += parts.last()[0].toUpper() + parts.last().mid(1);
304 }
305
306 if (classType == Proxy)
307 retval += "Interface"_L1;
308 else
309 retval += "Adaptor"_L1;
310
311 return retval;
312}
313
314QByteArray QDBusXmlToCpp::qtTypeName(const QDBusIntrospection::SourceLocation &location,
315 const QString &signature,
316 const QDBusIntrospection::Annotations &annotations,
317 qsizetype paramId, const char *direction)
318{
321 QString annotationName = u"org.qtproject.QtDBus.QtTypeName"_s;
322 if (paramId >= 0)
323 annotationName += ".%1%2"_L1.arg(QLatin1StringView(direction)).arg(paramId);
324 auto annotation = annotations.value(annotationName);
325 QString qttype = annotation.value;
326 if (!qttype.isEmpty())
327 return std::move(qttype).toLatin1();
328
329 QString oldAnnotationName = u"com.trolltech.QtDBus.QtTypeName"_s;
330 if (paramId >= 0)
331 oldAnnotationName += ".%1%2"_L1.arg(QLatin1StringView(direction)).arg(paramId);
332 annotation = annotations.value(oldAnnotationName);
333 qttype = annotation.value;
334
335 if (qttype.isEmpty()) {
336 reporter.error(location, "unknown type `%s'\n", qPrintable(signature));
337 reporter.note(location, "you should add <annotation name=\"%s\" value=\"<type>\"/>\n",
338 qPrintable(annotationName));
339
340 exit(1);
341 }
342
343 reporter.warning(annotation.location, "deprecated annotation '%s' found\n",
344 qPrintable(oldAnnotationName));
345 reporter.note(annotation.location, "suggest updating to '%s'\n",
346 qPrintable(annotationName));
347 return std::move(qttype).toLatin1();
348 }
349
350 return QMetaType(type).name();
351}
352
354{
355 return QLatin1StringView(arg) + " &"_L1;
356}
357
359{
360 if (!arg.endsWith('>'))
361 return QLatin1StringView(arg);
362
363 return QLatin1StringView(arg) + " "_L1;
364}
365
367{
368 if (!arg.startsWith('Q'))
369 return QLatin1StringView(arg) + " "_L1;
370 else
371 return "const %1 &"_L1.arg(QLatin1StringView(arg));
372}
373
375 const QDBusIntrospection::Arguments &outputArgs =
377{
378 QStringList retval;
379 const qsizetype numInputArgs = inputArgs.size();
380 const qsizetype numOutputArgs = outputArgs.size();
381 retval.reserve(numInputArgs + numOutputArgs);
382 for (qsizetype i = 0; i < numInputArgs; ++i) {
383 const QDBusIntrospection::Argument &arg = inputArgs.at(i);
384 QString name = arg.name;
385 if (name.isEmpty())
386 name = u"in%1"_s.arg(i);
387 else
388 name.replace(u'-', u'_');
389 while (retval.contains(name))
390 name += "_"_L1;
391 retval << name;
392 }
393 for (qsizetype i = 0; i < numOutputArgs; ++i) {
394 const QDBusIntrospection::Argument &arg = outputArgs.at(i);
395 QString name = arg.name;
396 if (name.isEmpty())
397 name = u"out%1"_s.arg(i);
398 else
399 name.replace(u'-', u'_');
400 while (retval.contains(name))
401 name += "_"_L1;
402 retval << name;
403 }
404 return retval;
405}
406
407void QDBusXmlToCpp::writeArgList(QTextStream &ts, const QStringList &argNames,
408 const QDBusIntrospection::Annotations &annotations,
409 const QDBusIntrospection::Arguments &inputArgs,
410 const QDBusIntrospection::Arguments &outputArgs)
411{
412 // input args:
413 bool first = true;
414 qsizetype argPos = 0;
415 for (qsizetype i = 0; i < inputArgs.size(); ++i) {
416 const QDBusIntrospection::Argument &arg = inputArgs.at(i);
417 QString type = constRefArg(qtTypeName(arg.location, arg.type, annotations, i, "In"));
418
419 if (!first)
420 ts << ", ";
421 ts << type << argNames.at(argPos++);
422 first = false;
423 }
424
425 argPos++;
426
427 // output args
428 // yes, starting from 1
429 for (qsizetype i = 1; i < outputArgs.size(); ++i) {
430 const QDBusIntrospection::Argument &arg = outputArgs.at(i);
431
432 if (!first)
433 ts << ", ";
434 ts << nonConstRefArg(qtTypeName(arg.location, arg.type, annotations, i, "Out"))
435 << argNames.at(argPos++);
436 first = false;
437 }
438}
439
440void QDBusXmlToCpp::writeSignalArgList(QTextStream &ts, const QStringList &argNames,
441 const QDBusIntrospection::Annotations &annotations,
442 const QDBusIntrospection::Arguments &outputArgs)
443{
444 bool first = true;
445 qsizetype argPos = 0;
446 for (qsizetype i = 0; i < outputArgs.size(); ++i) {
447 const QDBusIntrospection::Argument &arg = outputArgs.at(i);
448 QString type = constRefArg(qtTypeName(arg.location, arg.type, annotations, i, "Out"));
449
450 if (!first)
451 ts << ", ";
452 ts << type << argNames.at(argPos++);
453 first = false;
454 }
455}
456
457QString QDBusXmlToCpp::propertyGetter(const QDBusIntrospection::Property &property)
458{
459 auto annotation = property.annotations.value("org.qtproject.QtDBus.PropertyGetter"_L1);
460 if (!annotation.value.isEmpty())
461 return annotation.value;
462
463 annotation = property.annotations.value("com.trolltech.QtDBus.propertyGetter"_L1);
464 if (!annotation.value.isEmpty()) {
465 reporter.warning(annotation.location,
466 "deprecated annotation 'com.trolltech.QtDBus.propertyGetter' found\n");
467 reporter.note(annotation.location,
468 "suggest updating to 'org.qtproject.QtDBus.PropertyGetter'\n");
469 return annotation.value;
470 }
471
472 QString getter = property.name;
473 getter[0] = getter[0].toLower();
474 return getter;
475}
476
477QString QDBusXmlToCpp::propertySetter(const QDBusIntrospection::Property &property)
478{
479 auto annotation = property.annotations.value("org.qtproject.QtDBus.PropertySetter"_L1);
480 if (!annotation.value.isEmpty())
481 return annotation.value;
482
483 annotation = property.annotations.value("com.trolltech.QtDBus.propertySetter"_L1);
484 if (!annotation.value.isEmpty()) {
485 reporter.warning(annotation.location,
486 "deprecated annotation 'com.trolltech.QtDBus.propertySetter' found\n");
487 reporter.note(annotation.location,
488 "suggest updating to 'org.qtproject.QtDBus.PropertySetter'\n");
489 return annotation.value;
490 }
491
492 QString setter = "set"_L1 + property.name;
493 setter[3] = setter[3].toUpper();
494 return setter;
495}
496
498{
499 QString name = method.annotations.value(u"org.qtproject.QtDBus.MethodName"_s).value;
500 if (!name.isEmpty())
501 return name;
502
503 return method.name;
504}
505
507{
508 QString retval;
509 qsizetype i;
510 for (i = 0; i < data.size(); ++i) {
511 retval += u'\"';
512 for ( ; i < data.size() && data[i] != u'\n' && data[i] != u'\r'; ++i)
513 if (data[i] == u'\"')
514 retval += "\\\""_L1;
515 else
516 retval += data[i];
517 if (i+1 < data.size() && data[i] == u'\r' && data[i+1] == u'\n')
518 i++;
519 retval += "\\n\"\n"_L1;
520 }
521 return retval;
522}
523
524static bool openFile(const QString &fileName, QFile &file)
525{
526 if (fileName.isEmpty())
527 return false;
528
529 bool isOk = false;
530 if (fileName == "-"_L1) {
532 } else {
535 }
536
537 if (!isOk)
538 fprintf(stderr, "%s: Unable to open '%s': %s\n",
540 return isOk;
541}
542
543void QDBusXmlToCpp::writeProxy(const QString &filename,
544 const QDBusIntrospection::Interfaces &interfaces)
545{
546 // open the file
547 QString headerName = header(filename);
548 QByteArray headerData;
549 QTextStream hs(&headerData);
550
551 QString cppName = cpp(filename);
552 QByteArray cppData;
553 QTextStream cs(&cppData);
554
555 // write the header:
556 writeHeader(hs, true);
557 if (cppName != headerName)
558 writeHeader(cs, false);
559
560 // include guards:
562 if (!headerName.isEmpty() && headerName != "-"_L1) {
563 includeGuard = headerName.toUpper().replace(u'.', u'_');
565 if (pos != -1)
567 } else {
568 includeGuard = u"QDBUSXML2CPP_PROXY"_s;
569 }
570
571 hs << "#ifndef " << includeGuard << "\n"
572 "#define " << includeGuard << "\n\n";
573
574 // include our stuff:
575 hs << "#include <QtCore/QObject>\n"
576 << includeList;
577#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
578 hs << "#include <QtDBus/QtDBus>\n";
579#else
580 hs << "#include <QtDBus/QDBusAbstractInterface>\n"
581 "#include <QtDBus/QDBusPendingReply>\n";
582#endif
583
584 for (const QString &include : std::as_const(includes)) {
585 hs << "#include \"" << include << "\"\n";
586 if (headerName.isEmpty())
587 cs << "#include \"" << include << "\"\n";
588 }
589
590 for (const QString &include : std::as_const(globalIncludes)) {
591 hs << "#include <" << include << ">\n";
592 if (headerName.isEmpty())
593 cs << "#include <" << include << ">\n";
594 }
595
596 hs << "\n";
597
598 if (cppName != headerName) {
599 if (!headerName.isEmpty() && headerName != "-"_L1)
600 cs << "#include \"" << headerName << "\"\n\n";
601 }
602
603 for (const QDBusIntrospection::Interface *interface : interfaces) {
604 QString className = classNameForInterface(interface->name, Proxy);
605
606 // comment:
607 hs << "/*\n"
608 " * Proxy class for interface " << interface->name << "\n"
609 " */\n";
610 cs << "/*\n"
611 " * Implementation of interface class " << className << "\n"
612 " */\n\n";
613
614 // class header:
615 hs << "class " << className << ": public QDBusAbstractInterface\n"
616 "{\n"
617 " Q_OBJECT\n";
618
619 // the interface name
620 hs << "public:\n"
621 " static inline const char *staticInterfaceName()\n"
622 " { return \"" << interface->name << "\"; }\n\n";
623
624 // constructors/destructors:
625 hs << "public:\n"
626 " " << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);\n\n"
627 " ~" << className << "();\n\n";
628 cs << className << "::" << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)\n"
629 " : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)\n"
630 "{\n"
631 "}\n\n"
632 << className << "::~" << className << "()\n"
633 "{\n"
634 "}\n\n";
635
636 // properties:
638 QByteArray type = qtTypeName(property.location, property.type, property.annotations);
639 QString getter = propertyGetter(property);
640 QString setter = propertySetter(property);
641
642 hs << " Q_PROPERTY(" << type << " " << property.name;
643
644 // getter:
646 // it's readable
647 hs << " READ " << getter;
648
649 // setter
651 // it's writeable
652 hs << " WRITE " << setter;
653
654 hs << ")\n";
655
656 // getter:
658 hs << " inline " << type << " " << getter << "() const\n"
659 " { return qvariant_cast< " << type << " >(property(\""
660 << property.name << "\")); }\n";
661 }
662
663 // setter:
665 hs << " inline void " << setter << "(" << constRefArg(type) << "value)\n"
666 " { setProperty(\"" << property.name
667 << "\", QVariant::fromValue(value)); }\n";
668 }
669
670 hs << "\n";
671 }
672
673 // methods:
674 hs << "public Q_SLOTS: // METHODS\n";
676 bool isDeprecated = method.annotations.value("org.freedesktop.DBus.Deprecated"_L1).value
677 == "true"_L1;
678 bool isNoReply = method.annotations.value(ANNOTATION_NO_WAIT ""_L1).value == "true"_L1;
679 if (isNoReply && !method.outputArgs.isEmpty()) {
680 reporter.warning(method.location,
681 "method %s in interface %s is marked 'no-reply' but has output "
682 "arguments.\n",
683 qPrintable(method.name), qPrintable(interface->name));
684 continue;
685 }
686
687 if (isDeprecated)
688 hs << " Q_DECL_DEPRECATED ";
689 else
690 hs << " ";
691
692 if (isNoReply) {
693 hs << "Q_NOREPLY inline void ";
694 } else {
695 hs << "inline QDBusPendingReply<";
696 for (qsizetype i = 0; i < method.outputArgs.size(); ++i)
697 hs << (i > 0 ? ", " : "")
698 << templateArg(qtTypeName(method.outputArgs.at(i).location,
699 method.outputArgs.at(i).type, method.annotations,
700 i, "Out"));
701 hs << "> ";
702 }
703
704 hs << methodName(method) << "(";
705
706 QStringList argNames = makeArgNames(method.inputArgs);
707 writeArgList(hs, argNames, method.annotations, method.inputArgs);
708
709 hs << ")\n"
710 " {\n"
711 " QList<QVariant> argumentList;\n";
712
713 if (!method.inputArgs.isEmpty()) {
714 hs << " argumentList";
715 for (qsizetype argPos = 0; argPos < method.inputArgs.size(); ++argPos)
716 hs << " << QVariant::fromValue(" << argNames.at(argPos) << ')';
717 hs << ";\n";
718 }
719
720 if (isNoReply)
721 hs << " callWithArgumentList(QDBus::NoBlock, "
722 "QStringLiteral(\"" << method.name << "\"), argumentList);\n";
723 else
724 hs << " return asyncCallWithArgumentList(QStringLiteral(\""
725 << method.name << "\"), argumentList);\n";
726
727 // close the function:
728 hs << " }\n";
729
730 if (method.outputArgs.size() > 1) {
731 // generate the old-form QDBusReply methods with multiple incoming parameters
732 hs << (isDeprecated ? " Q_DECL_DEPRECATED " : " ") << "inline QDBusReply<"
733 << templateArg(qtTypeName(method.outputArgs.first().location,
734 method.outputArgs.first().type, method.annotations, 0,
735 "Out"))
736 << "> ";
737 hs << method.name << "(";
738
739 QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs);
740 writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs);
741
742 hs << ")\n"
743 " {\n"
744 " QList<QVariant> argumentList;\n";
745
746 qsizetype argPos = 0;
747 if (!method.inputArgs.isEmpty()) {
748 hs << " argumentList";
749 for (argPos = 0; argPos < method.inputArgs.size(); ++argPos)
750 hs << " << QVariant::fromValue(" << argNames.at(argPos) << ')';
751 hs << ";\n";
752 }
753
754 hs << " QDBusMessage reply = callWithArgumentList(QDBus::Block, "
755 "QStringLiteral(\"" << method.name << "\"), argumentList);\n";
756
757 argPos++;
758 hs << " if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().size() == "
759 << method.outputArgs.size() << ") {\n";
760
761 // yes, starting from 1
762 for (qsizetype i = 1; i < method.outputArgs.size(); ++i)
763 hs << " " << argNames.at(argPos++) << " = qdbus_cast<"
764 << templateArg(qtTypeName(method.outputArgs.at(i).location,
765 method.outputArgs.at(i).type, method.annotations,
766 i, "Out"))
767 << ">(reply.arguments().at(" << i << "));\n";
768 hs << " }\n"
769 " return reply;\n"
770 " }\n";
771 }
772
773 hs << "\n";
774 }
775
776 hs << "Q_SIGNALS: // SIGNALS\n";
777 for (const QDBusIntrospection::Signal &signal : interface->signals_) {
778 hs << " ";
779 if (signal.annotations.value("org.freedesktop.DBus.Deprecated"_L1).value == "true"_L1)
780 hs << "Q_DECL_DEPRECATED ";
781
782 hs << "void " << signal.name << "(";
783
784 QStringList argNames = makeArgNames(signal.outputArgs);
785 writeSignalArgList(hs, argNames, signal.annotations, signal.outputArgs);
786
787 hs << ");\n"; // finished for header
788 }
789
790 // close the class:
791 hs << "};\n\n";
792 }
793
794 if (!skipNamespaces) {
795 QStringList last;
797 do
798 {
799 QStringList current;
801 if (it != interfaces.constEnd()) {
802 current = it->constData()->name.split(u'.');
803 name = current.takeLast();
804 }
805
806 qsizetype i = 0;
807 while (i < current.size() && i < last.size() && current.at(i) == last.at(i))
808 ++i;
809
810 // i parts matched
811 // close last.arguments().size() - i namespaces:
812 for (qsizetype j = i; j < last.size(); ++j)
813 hs << QString((last.size() - j - 1 + i) * 2, u' ') << "}\n";
814
815 // open current.arguments().size() - i namespaces
816 for (qsizetype j = i; j < current.size(); ++j)
817 hs << QString(j * 2, u' ') << "namespace " << current.at(j) << " {\n";
818
819 // add this class:
820 if (!name.isEmpty()) {
821 hs << QString(current.size() * 2, u' ')
822 << "using " << name << " = ::" << classNameForInterface(it->constData()->name, Proxy)
823 << ";\n";
824 }
825
826 if (it == interfaces.constEnd())
827 break;
828 ++it;
829 last = current;
830 } while (true);
831 }
832
833 // close the include guard
834 hs << "#endif\n";
835
836 QString mocName = moc(filename);
837 if (includeMocs && !mocName.isEmpty())
838 cs << "\n"
839 "#include \"" << mocName << "\"\n";
840
841 cs.flush();
842 hs.flush();
843
844 QFile file;
845 const bool headerOpen = openFile(headerName, file);
846 if (headerOpen)
847 file.write(headerData);
848
849 if (headerName == cppName) {
850 if (headerOpen)
851 file.write(cppData);
852 } else {
853 QFile cppFile;
854 if (openFile(cppName, cppFile))
855 cppFile.write(cppData);
856 }
857}
858
859void QDBusXmlToCpp::writeAdaptor(const QString &filename,
860 const QDBusIntrospection::Interfaces &interfaces)
861{
862 // open the file
863 QString headerName = header(filename);
864 QByteArray headerData;
865 QTextStream hs(&headerData);
866
867 QString cppName = cpp(filename);
868 QByteArray cppData;
869 QTextStream cs(&cppData);
870
871 // write the headers
872 writeHeader(hs, false);
873 if (cppName != headerName)
874 writeHeader(cs, true);
875
876 // include guards:
878 if (!headerName.isEmpty() && headerName != "-"_L1) {
879 includeGuard = headerName.toUpper().replace(u'.', u'_');
881 if (pos != -1)
883 } else {
884 includeGuard = u"QDBUSXML2CPP_ADAPTOR"_s;
885 }
886
887 hs << "#ifndef " << includeGuard << "\n"
888 "#define " << includeGuard << "\n\n";
889
890 // include our stuff:
891 hs << "#include <QtCore/QObject>\n";
892 if (cppName == headerName)
893 hs << "#include <QtCore/QMetaObject>\n"
894 "#include <QtCore/QVariant>\n";
895#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
896 hs << "#include <QtDBus/QtDBus>\n";
897#else
898 hs << "#include <QtDBus/QDBusAbstractAdaptor>\n"
899 "#include <QtDBus/QDBusObjectPath>\n";
900#endif
901
902 for (const QString &include : std::as_const(includes)) {
903 hs << "#include \"" << include << "\"\n";
904 if (headerName.isEmpty())
905 cs << "#include \"" << include << "\"\n";
906 }
907
908 for (const QString &include : std::as_const(globalIncludes)) {
909 hs << "#include <" << include << ">\n";
910 if (headerName.isEmpty())
911 cs << "#include <" << include << ">\n";
912 }
913
914 if (cppName != headerName) {
915 if (!headerName.isEmpty() && headerName != "-"_L1)
916 cs << "#include \"" << headerName << "\"\n";
917
918 cs << "#include <QtCore/QMetaObject>\n"
919 << includeList
920 << "\n";
922 } else {
923 hs << includeList;
924 }
925
926 hs << "\n";
927
928 QString parent = parentClassName;
929 if (parentClassName.isEmpty())
930 parent = u"QObject"_s;
931
932 for (const QDBusIntrospection::Interface *interface : interfaces) {
933 QString className = classNameForInterface(interface->name, Adaptor);
934
935 // comment:
936 hs << "/*\n"
937 " * Adaptor class for interface " << interface->name << "\n"
938 " */\n";
939 cs << "/*\n"
940 " * Implementation of adaptor class " << className << "\n"
941 " */\n\n";
942
943 // class header:
944 hs << "class " << className << ": public QDBusAbstractAdaptor\n"
945 "{\n"
946 " Q_OBJECT\n"
947 " Q_CLASSINFO(\"D-Bus Interface\", \"" << interface->name << "\")\n"
948 " Q_CLASSINFO(\"D-Bus Introspection\", \"\"\n"
949 << stringify(interface->introspection)
950 << " \"\")\n"
951 "public:\n"
952 " " << className << "(" << parent << " *parent);\n"
953 " virtual ~" << className << "();\n\n";
954
955 if (!parentClassName.isEmpty())
956 hs << " inline " << parent << " *parent() const\n"
957 " { return static_cast<" << parent << " *>(QObject::parent()); }\n\n";
958
959 // constructor/destructor
960 cs << className << "::" << className << "(" << parent << " *parent)\n"
961 " : QDBusAbstractAdaptor(parent)\n"
962 "{\n"
963 " // constructor\n"
964 " setAutoRelaySignals(true);\n"
965 "}\n\n"
966 << className << "::~" << className << "()\n"
967 "{\n"
968 " // destructor\n"
969 "}\n\n";
970
971 hs << "public: // PROPERTIES\n";
973 QByteArray type = qtTypeName(property.location, property.type, property.annotations);
974 QString constRefType = constRefArg(type);
975 QString getter = propertyGetter(property);
976 QString setter = propertySetter(property);
977
978 hs << " Q_PROPERTY(" << type << " " << property.name;
980 hs << " READ " << getter;
982 hs << " WRITE " << setter;
983 hs << ")\n";
984
985 // getter:
987 hs << " " << type << " " << getter << "() const;\n";
988 cs << type << " "
989 << className << "::" << getter << "() const\n"
990 "{\n"
991 " // get the value of property " << property.name << "\n"
992 " return qvariant_cast< " << type <<" >(parent()->property(\"" << property.name << "\"));\n"
993 "}\n\n";
994 }
995
996 // setter
998 hs << " void " << setter << "(" << constRefType << "value);\n";
999 cs << "void " << className << "::" << setter << "(" << constRefType << "value)\n"
1000 "{\n"
1001 " // set the value of property " << property.name << "\n"
1002 " parent()->setProperty(\"" << property.name << "\", QVariant::fromValue(value";
1003 if (constRefType.contains("QDBusVariant"_L1))
1004 cs << ".variant()";
1005 cs << "));\n"
1006 "}\n\n";
1007 }
1008
1009 hs << "\n";
1010 }
1011
1012 hs << "public Q_SLOTS: // METHODS\n";
1014 bool isNoReply = method.annotations.value(ANNOTATION_NO_WAIT ""_L1).value == "true"_L1;
1015 if (isNoReply && !method.outputArgs.isEmpty()) {
1016 reporter.warning(method.location,
1017 "method %s in interface %s is marked 'no-reply' but has output "
1018 "arguments.\n",
1019 qPrintable(method.name), qPrintable(interface->name));
1020 continue;
1021 }
1022
1023 hs << " ";
1024 QByteArray returnType;
1025 if (isNoReply) {
1026 hs << "Q_NOREPLY void ";
1027 cs << "void ";
1028 } else if (method.outputArgs.isEmpty()) {
1029 hs << "void ";
1030 cs << "void ";
1031 } else {
1032 returnType =
1033 qtTypeName(method.outputArgs.first().location,
1034 method.outputArgs.first().type, method.annotations, 0, "Out");
1035 hs << returnType << " ";
1036 cs << returnType << " ";
1037 }
1038
1040 hs << name << "(";
1041 cs << className << "::" << name << "(";
1042
1043 QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs);
1044 writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs);
1045 writeArgList(cs, argNames, method.annotations, method.inputArgs, method.outputArgs);
1046
1047 hs << ");\n"; // finished for header
1048 cs << ")\n"
1049 "{\n"
1050 " // handle method call " << interface->name << "." << methodName(method) << "\n";
1051
1052 // make the call
1053 bool usingInvokeMethod = false;
1054 if (parentClassName.isEmpty() && method.inputArgs.size() <= 10
1055 && method.outputArgs.size() <= 1)
1056 usingInvokeMethod = true;
1057
1058 if (usingInvokeMethod) {
1059 // we are using QMetaObject::invokeMethod
1060 if (!returnType.isEmpty())
1061 cs << " " << returnType << " " << argNames.at(method.inputArgs.size())
1062 << ";\n";
1063
1064 static const char invoke[] = " QMetaObject::invokeMethod(parent(), \"";
1065 cs << invoke << name << "\"";
1066
1067 if (!method.outputArgs.isEmpty())
1068 cs << ", Q_RETURN_ARG("
1069 << qtTypeName(method.outputArgs.at(0).location, method.outputArgs.at(0).type,
1070 method.annotations, 0, "Out")
1071 << ", " << argNames.at(method.inputArgs.size()) << ")";
1072
1073 for (qsizetype i = 0; i < method.inputArgs.size(); ++i)
1074 cs << ", Q_ARG("
1075 << qtTypeName(method.inputArgs.at(i).location, method.inputArgs.at(i).type,
1076 method.annotations, i, "In")
1077 << ", " << argNames.at(i) << ")";
1078
1079 cs << ");\n";
1080
1081 if (!returnType.isEmpty())
1082 cs << " return " << argNames.at(method.inputArgs.size()) << ";\n";
1083 } else {
1084 if (parentClassName.isEmpty())
1085 cs << " //";
1086 else
1087 cs << " ";
1088
1089 if (!method.outputArgs.isEmpty())
1090 cs << "return ";
1091
1092 if (parentClassName.isEmpty())
1093 cs << "static_cast<YourObjectType *>(parent())->";
1094 else
1095 cs << "parent()->";
1096 cs << name << "(";
1097
1098 qsizetype argPos = 0;
1099 bool first = true;
1100 for (qsizetype i = 0; i < method.inputArgs.size(); ++i) {
1101 cs << (first ? "" : ", ") << argNames.at(argPos++);
1102 first = false;
1103 }
1104 ++argPos; // skip retval, if any
1105 for (qsizetype i = 1; i < method.outputArgs.size(); ++i) {
1106 cs << (first ? "" : ", ") << argNames.at(argPos++);
1107 first = false;
1108 }
1109
1110 cs << ");\n";
1111 }
1112 cs << "}\n\n";
1113 }
1114
1115 hs << "Q_SIGNALS: // SIGNALS\n";
1116 for (const QDBusIntrospection::Signal &signal : interface->signals_) {
1117 hs << " void " << signal.name << "(";
1118
1119 QStringList argNames = makeArgNames(signal.outputArgs);
1120 writeSignalArgList(hs, argNames, signal.annotations, signal.outputArgs);
1121
1122 hs << ");\n"; // finished for header
1123 }
1124
1125 // close the class:
1126 hs << "};\n\n";
1127 }
1128
1129 // close the include guard
1130 hs << "#endif\n";
1131
1132 QString mocName = moc(filename);
1133 if (includeMocs && !mocName.isEmpty())
1134 cs << "\n"
1135 "#include \"" << mocName << "\"\n";
1136
1137 cs.flush();
1138 hs.flush();
1139
1140 QFile file;
1141 const bool headerOpen = openFile(headerName, file);
1142 if (headerOpen)
1143 file.write(headerData);
1144
1145 if (headerName == cppName) {
1146 if (headerOpen)
1147 file.write(cppData);
1148 } else {
1149 QFile cppFile;
1150 if (openFile(cppName, cppFile))
1151 cppFile.write(cppData);
1152 }
1153}
1154
1156{
1157 QCommandLineParser parser;
1159 "Produces the C++ code to implement the interfaces defined in the input file.\n\n"
1160 "If the file name given to the options -a and -p does not end in .cpp or .h, the\n"
1161 "program will automatically append the suffixes and produce both files.\n"
1162 "You can also use a colon (:) to separate the header name from the source file\n"
1163 "name, as in '-a filename_p.h:filename.cpp'.\n\n"
1164 "If you pass a dash (-) as the argument to either -p or -a, the output is written\n"
1165 "to the standard output."_L1);
1166
1167 parser.addHelpOption();
1168 parser.addVersionOption();
1169 parser.addPositionalArgument(u"xml-or-xml-file"_s, u"XML file to use."_s);
1170 parser.addPositionalArgument(u"interfaces"_s, u"List of interfaces to use."_s,
1171 u"[interfaces ...]"_s);
1172
1173 QCommandLineOption adapterCodeOption(QStringList{u"a"_s, u"adaptor"_s},
1174 u"Write the adaptor code to <filename>"_s, u"filename"_s);
1175 parser.addOption(adapterCodeOption);
1176
1177 QCommandLineOption classNameOption(QStringList{u"c"_s, u"classname"_s},
1178 u"Use <classname> as the class name for the generated classes. "
1179 u"This option can only be used when processing a single interface."_s,
1180 u"classname"_s);
1181 parser.addOption(classNameOption);
1182
1183 QCommandLineOption addIncludeOption(QStringList{u"i"_s, u"include"_s},
1184 u"Add #include \"filename\" to the output"_s, u"filename"_s);
1185 parser.addOption(addIncludeOption);
1186
1187 QCommandLineOption addGlobalIncludeOption(QStringList{u"I"_s, u"global-include"_s},
1188 u"Add #include <filename> to the output"_s, u"filename"_s);
1189 parser.addOption(addGlobalIncludeOption);
1190
1191 QCommandLineOption adapterParentOption(u"l"_s,
1192 u"When generating an adaptor, use <classname> as the parent class"_s, u"classname"_s);
1193 parser.addOption(adapterParentOption);
1194
1195 QCommandLineOption mocIncludeOption(QStringList{u"m"_s, u"moc"_s},
1196 u"Generate #include \"filename.moc\" statements in the .cpp files"_s);
1197 parser.addOption(mocIncludeOption);
1198
1199 QCommandLineOption noNamespaceOption(QStringList{u"N"_s, u"no-namespaces"_s},
1200 u"Don't use namespaces"_s);
1201 parser.addOption(noNamespaceOption);
1202
1203 QCommandLineOption proxyCodeOption(QStringList{u"p"_s, u"proxy"_s},
1204 u"Write the proxy code to <filename>"_s, u"filename"_s);
1205 parser.addOption(proxyCodeOption);
1206
1207 QCommandLineOption verboseOption(QStringList{u"V"_s, u"verbose"_s},
1208 u"Be verbose."_s);
1209 parser.addOption(verboseOption);
1210
1211 parser.process(app);
1212
1213 QString adaptorFile = parser.value(adapterCodeOption);
1214 globalClassName = parser.value(classNameOption);
1215 includes = parser.values(addIncludeOption);
1216 globalIncludes = parser.values(addGlobalIncludeOption);
1217 parentClassName = parser.value(adapterParentOption);
1218 includeMocs = parser.isSet(mocIncludeOption);
1219 skipNamespaces = parser.isSet(noNamespaceOption);
1220 QString proxyFile = parser.value(proxyCodeOption);
1221 bool verbose = parser.isSet(verboseOption);
1222
1223 wantedInterfaces = parser.positionalArguments();
1224 if (!wantedInterfaces.isEmpty()) {
1225 inputFile = wantedInterfaces.takeFirst();
1226
1227 QFileInfo inputInfo(inputFile);
1228 if (!inputInfo.exists() || !inputInfo.isFile() || !inputInfo.isReadable()) {
1229 qCritical("Error: Input %s is not a file or cannot be accessed\n", qPrintable(inputFile));
1230 return 1;
1231 }
1232 }
1233
1234 if (verbose)
1235 QLoggingCategory::setFilterRules(u"dbus.parser.debug=true"_s);
1236
1237 QDBusIntrospection::Interfaces interfaces = readInput();
1238 cleanInterfaces(interfaces);
1239
1240 if (!globalClassName.isEmpty() && interfaces.count() != 1) {
1241 qCritical("Option -c/--classname can only be used with a single interface.\n");
1242 return 1;
1243 }
1244
1246 args.removeFirst();
1247 commandLine = PROGRAMNAME " "_L1 + args.join(u' ');
1248
1249 if (!proxyFile.isEmpty() || adaptorFile.isEmpty())
1250 writeProxy(proxyFile, interfaces);
1251
1252 if (!adaptorFile.isEmpty())
1253 writeAdaptor(adaptorFile, interfaces);
1254
1255 return 0;
1256}
1257
1258int main(int argc, char **argv)
1259{
1260 QCoreApplication app(argc, argv);
1263
1264 return QDBusXmlToCpp().run(app);
1265}
static JNINativeMethod methods[]
\inmodule QtCore
Definition qbytearray.h:57
QByteArray toUpper() const &
Definition qbytearray.h:194
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:275
The QCommandLineOption class defines a possible command-line option. \inmodule QtCore.
The QCommandLineParser class provides a means for handling the command line options.
QString value(const QString &name) const
Returns the option value found for the given option name optionName, or an empty string if not found.
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax=QString())
Defines an additional argument to the application, for the benefit of the help text.
QStringList positionalArguments() const
Returns a list of positional arguments.
QStringList values(const QString &name) const
Returns a list of option values found for the given option name optionName, or an empty list if not f...
void setApplicationDescription(const QString &description)
Sets the application description shown by helpText().
bool addOption(const QCommandLineOption &commandLineOption)
Adds the option option to look for while parsing.
bool isSet(const QString &name) const
Checks whether the option name was passed to the application.
void process(const QStringList &arguments)
Processes the command line arguments.
QCommandLineOption addVersionOption()
Adds the {-v} / {–version} option, which displays the version string of the application.
QCommandLineOption addHelpOption()
Adds help options to the command-line parser.
\inmodule QtCore
static void setApplicationName(const QString &application)
static void setApplicationVersion(const QString &version)
static QStringList arguments()
static Interfaces parseInterfaces(const QString &xml, DiagnosticsReporter *reporter=nullptr)
Parses the XML document fragment (given by xml) containing several interfaces.
static QMetaType signatureToMetaType(const char *signature)
int run(const QCoreApplication &app)
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
QString suffix() const
Returns the suffix (extension) of the file.
QString fileName() const
Returns the name of the file, excluding the path.
bool isFile() const
Returns true if this object points to a file or to a symbolic link to a file.
QString completeBaseName() const
Returns the complete base name of the file without the path.
bool exists() const
Returns true if the file exists; otherwise returns false.
bool isReadable() const
Returns true if the user can read the file; otherwise returns false.
\inmodule QtCore
Definition qfile.h:93
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:881
void setFileName(const QString &name)
Sets the name of the file.
Definition qfile.cpp:302
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
QString errorString() const
Returns a human-readable description of the last device error that occurred.
QString arg(Args &&...args) const
qsizetype size() const noexcept
Definition qlist.h:386
void removeFirst() noexcept
Definition qlist.h:800
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
static void setFilterRules(const QString &rules)
Configures which categories and message types should be enabled through a set of rules.
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:356
iterator erase(const_iterator it)
Definition qmap.h:618
size_type count(const Key &key) const
Definition qmap.h:403
iterator begin()
Definition qmap.h:597
iterator end()
Definition qmap.h:601
const_iterator constBegin() const
Definition qmap.h:599
const_iterator constEnd() const
Definition qmap.h:603
\inmodule QtCore
Definition qmetatype.h:320
int id(int=0) const
Definition qmetatype.h:454
constexpr const char * name() const
Definition qmetatype.h:2650
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QByteArray toLatin1() const &
Definition qstring.h:559
QString last(qsizetype n) const
Definition qstring.h:339
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.h:279
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8606
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString & append(QChar c)
Definition qstring.cpp:3227
QString toUpper() const &
Definition qstring.h:372
\inmodule QtCore
int main()
[0]
QSet< QString >::iterator it
auto signal
direction
QString includeGuard(const QString &filename)
Definition helpers.cpp:20
QMetaType signature()
void getter(const QUntypedPropertyData *d, void *value)
void setter(QUntypedPropertyData *d, const void *value)
#define Q_ATTRIBUTE_FORMAT_PRINTF(A, B)
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
#define PROGRAMNAME
static const char includeList[]
static bool isSupportedSuffix(QStringView suffix)
static QString stringify(const QString &data)
#define PROGRAMCOPYRIGHT
static QString moc(const QString &name)
#define ANNOTATION_NO_WAIT
static QString templateArg(const QByteArray &arg)
#define PROGRAMVERSION
static const char forwardDeclarations[]
static QString methodName(const QDBusIntrospection::Method &method)
static QString header(const QString &name)
static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs, const QDBusIntrospection::Arguments &outputArgs=QDBusIntrospection::Arguments())
static QString constRefArg(const QByteArray &arg)
static bool openFile(const QString &fileName, QFile &file)
static QString nonConstRefArg(const QByteArray &arg)
#define qCritical
Definition qlogging.h:163
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
GLint location
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum severity
GLuint name
GLint first
GLsizei GLsizei GLchar * source
GLenum GLenum GLenum input
SSL_CTX int(*) void arg)
#define qPrintable(string)
Definition qstring.h:1391
#define QStringLiteral(str)
ptrdiff_t qsizetype
Definition qtypes.h:70
const char property[13]
Definition qwizard.cpp:101
const char className[16]
[1]
Definition qwizard.cpp:100
ASSERT failure in file div cpp
QFile file
[0]
file setFileName("readme.txt")
QFileInfo fi("c:/temp/foo")
[newstuff]
QStringList fileNames
[4]
QApplication app(argc, argv)
[0]
QAction * at
QJSValueList args
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent