17#include <private/qdbusintrospection_p.h>
22#define PROGRAMNAME "qdbusxml2cpp"
23#define PROGRAMVERSION "0.8"
24#define PROGRAMCOPYRIGHT QT_COPYRIGHT
26#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
40 bool hadErrors()
const {
return m_hadErrors; }
51 bool m_hadErrors =
false;
57 enum ClassType { Proxy, Adaptor };
84 bool skipNamespaces =
false;
85 bool includeMocs =
false;
91 DiagnosticsReporter reporter;
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";
103 "#include <QtCore/qcontainerfwd.h>\n";
106 const char *msg, ...)
110 report(
location, msg, ap,
"warning");
115 const char *msg, ...)
125 const char *msg, ...)
135 const char *msg, va_list ap,
const char *
severity)
137 fprintf(stderr,
"%s:%lld:%lld: %s: ",
qPrintable(m_fileName),
139 vfprintf(stderr, msg, ap);
145 if (inputFile.
isEmpty() || inputFile ==
"-"_L1) {
146 reporter.setFileName(
"<standard input>"_L1);
149 reporter.setFileName(inputFile);
155 if (reporter.hadErrors())
163 if (!wantedInterfaces.isEmpty()) {
165 while (
it != interfaces.
end())
166 if (!wantedInterfaces.contains(
it.key()))
181 for (
auto candidate : candidates)
182 if (suffix == candidate)
192 QString retval = parts.front();
194 if (retval.
isEmpty() || retval ==
"-"_L1)
210 if (retval.
isEmpty() || retval ==
"-"_L1)
242 if (sourceName.
isEmpty() || sourceName ==
"-"_L1) {
249 retval +=
source.completeBaseName();
252 fprintf(stderr,
"warning: no header name is provided, assuming it to be \"%s\"\n",
259 retval +=
header.completeBaseName();
271 " * Command line was: " << commandLine <<
"\n"
275 " * This is an auto-generated file.\n";
277 if (changesWillBeLost)
278 ts <<
" * Do not edit! All changes made to it will be lost.\n";
280 ts <<
" * This file may have been hand-edited. Look for HAND-EDIT comments\n"
281 " * before re-generating it.\n";
289 QDBusXmlToCpp::ClassType classType)
291 if (!globalClassName.
isEmpty())
292 return globalClassName;
297 if (classType == Proxy) {
298 for (
const auto &part : parts) {
300 retval += part.
mid(1);
306 if (classType == Proxy)
307 retval +=
"Interface"_L1;
309 retval +=
"Adaptor"_L1;
321 QString annotationName = u
"org.qtproject.QtDBus.QtTypeName"_s;
324 auto annotation = annotations.
value(annotationName);
325 QString qttype = annotation.value;
327 return std::move(qttype).
toLatin1();
329 QString oldAnnotationName = u
"com.trolltech.QtDBus.QtTypeName"_s;
332 annotation = annotations.
value(oldAnnotationName);
333 qttype = annotation.value;
337 reporter.note(
location,
"you should add <annotation name=\"%s\" value=\"<type>\"/>\n",
343 reporter.warning(annotation.location,
"deprecated annotation '%s' found\n",
345 reporter.note(annotation.location,
"suggest updating to '%s'\n",
347 return std::move(qttype).toLatin1();
360 if (!
arg.endsWith(
'>'))
368 if (!
arg.startsWith(
'Q'))
380 const qsizetype numOutputArgs = outputArgs.size();
381 retval.reserve(numInputArgs + numOutputArgs);
386 name = u
"in%1"_s.arg(
i);
388 name.replace(u
'-', u
'_');
389 while (retval.contains(
name))
397 name = u
"out%1"_s.arg(
i);
399 name.replace(u
'-', u
'_');
400 while (retval.contains(
name))
421 ts <<
type << argNames.at(argPos++);
435 << argNames.at(argPos++);
452 ts <<
type << argNames.at(argPos++);
459 auto annotation =
property.annotations.value(
"org.qtproject.QtDBus.PropertyGetter"_L1);
460 if (!annotation.value.isEmpty())
461 return annotation.value;
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;
479 auto annotation =
property.annotations.value(
"org.qtproject.QtDBus.PropertySetter"_L1);
480 if (!annotation.value.isEmpty())
481 return annotation.value;
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;
499 QString name =
method.annotations.value(u
"org.qtproject.QtDBus.MethodName"_s).value;
510 for (
i = 0;
i <
data.size(); ++
i) {
513 if (
data[
i] == u
'\"')
519 retval +=
"\\n\"\n"_L1;
538 fprintf(stderr,
"%s: Unable to open '%s': %s\n",
543void QDBusXmlToCpp::writeProxy(
const QString &filename,
556 writeHeader(hs,
true);
558 writeHeader(cs,
false);
575 hs <<
"#include <QtCore/QObject>\n"
577#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
578 hs <<
"#include <QtDBus/QtDBus>\n";
580 hs <<
"#include <QtDBus/QDBusAbstractInterface>\n"
581 "#include <QtDBus/QDBusPendingReply>\n";
584 for (
const QString &include :
std::as_const(includes)) {
585 hs <<
"#include \"" << include <<
"\"\n";
587 cs <<
"#include \"" << include <<
"\"\n";
590 for (
const QString &include :
std::as_const(globalIncludes)) {
591 hs <<
"#include <" << include <<
">\n";
593 cs <<
"#include <" << include <<
">\n";
600 cs <<
"#include \"" <<
headerName <<
"\"\n\n";
608 " * Proxy class for interface " <<
interface->name <<
"\n"
611 " * Implementation of interface class " <<
className <<
"\n"
615 hs <<
"class " <<
className <<
": public QDBusAbstractInterface\n"
621 " static inline const char *staticInterfaceName()\n"
622 " { return \"" <<
interface->name <<
"\"; }\n\n";
626 " " <<
className <<
"(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);\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"
642 hs <<
" Q_PROPERTY(" <<
type <<
" " <<
property.name;
652 hs <<
" WRITE " <<
setter;
658 hs <<
" inline " <<
type <<
" " <<
getter <<
"() const\n"
659 " { return qvariant_cast< " <<
type <<
" >(property(\""
660 <<
property.name <<
"\")); }\n";
666 " { setProperty(\"" <<
property.name
667 <<
"\", QVariant::fromValue(value)); }\n";
674 hs <<
"public Q_SLOTS: // METHODS\n";
676 bool isDeprecated =
method.annotations.value(
"org.freedesktop.DBus.Deprecated"_L1).value
679 if (isNoReply && !
method.outputArgs.isEmpty()) {
680 reporter.warning(
method.location,
681 "method %s in interface %s is marked 'no-reply' but has output "
688 hs <<
" Q_DECL_DEPRECATED ";
693 hs <<
"Q_NOREPLY inline void ";
695 hs <<
"inline QDBusPendingReply<";
697 hs << (
i > 0 ?
", " :
"")
707 writeArgList(hs, argNames,
method.annotations,
method.inputArgs);
711 " QList<QVariant> argumentList;\n";
713 if (!
method.inputArgs.isEmpty()) {
714 hs <<
" argumentList";
716 hs <<
" << QVariant::fromValue(" << argNames.at(argPos) <<
')';
721 hs <<
" callWithArgumentList(QDBus::NoBlock, "
722 "QStringLiteral(\"" <<
method.name <<
"\"), argumentList);\n";
724 hs <<
" return asyncCallWithArgumentList(QStringLiteral(\""
725 <<
method.name <<
"\"), argumentList);\n";
730 if (
method.outputArgs.size() > 1) {
732 hs << (isDeprecated ?
" Q_DECL_DEPRECATED " :
" ") <<
"inline QDBusReply<"
744 " QList<QVariant> argumentList;\n";
747 if (!
method.inputArgs.isEmpty()) {
748 hs <<
" argumentList";
749 for (argPos = 0; argPos <
method.inputArgs.size(); ++argPos)
750 hs <<
" << QVariant::fromValue(" << argNames.at(argPos) <<
')';
754 hs <<
" QDBusMessage reply = callWithArgumentList(QDBus::Block, "
755 "QStringLiteral(\"" <<
method.name <<
"\"), argumentList);\n";
758 hs <<
" if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().size() == "
759 <<
method.outputArgs.size() <<
") {\n";
763 hs <<
" " << argNames.at(argPos++) <<
" = qdbus_cast<"
767 <<
">(reply.arguments().at(" <<
i <<
"));\n";
776 hs <<
"Q_SIGNALS: // SIGNALS\n";
779 if (
signal.annotations.value(
"org.freedesktop.DBus.Deprecated"_L1).value ==
"true"_L1)
780 hs <<
"Q_DECL_DEPRECATED ";
782 hs <<
"void " <<
signal.name <<
"(";
785 writeSignalArgList(hs, argNames,
signal.annotations,
signal.outputArgs);
794 if (!skipNamespaces) {
802 current =
it->constData()->name.split(u
'.');
803 name = current.takeLast();
807 while (
i < current.size() &&
i < last.size() && current.at(
i) == last.at(
i))
813 hs <<
QString((last.size() -
j - 1 +
i) * 2, u
' ') <<
"}\n";
817 hs <<
QString(
j * 2, u
' ') <<
"namespace " << current.at(
j) <<
" {\n";
820 if (!
name.isEmpty()) {
821 hs <<
QString(current.size() * 2, u
' ')
822 <<
"using " <<
name <<
" = ::" << classNameForInterface(
it->constData()->name, Proxy)
837 if (includeMocs && !mocName.
isEmpty())
839 "#include \"" << mocName <<
"\"\n";
855 cppFile.
write(cppData);
859void QDBusXmlToCpp::writeAdaptor(
const QString &filename,
872 writeHeader(hs,
false);
874 writeHeader(cs,
true);
891 hs <<
"#include <QtCore/QObject>\n";
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";
898 hs <<
"#include <QtDBus/QDBusAbstractAdaptor>\n"
899 "#include <QtDBus/QDBusObjectPath>\n";
902 for (
const QString &include :
std::as_const(includes)) {
903 hs <<
"#include \"" << include <<
"\"\n";
905 cs <<
"#include \"" << include <<
"\"\n";
908 for (
const QString &include :
std::as_const(globalIncludes)) {
909 hs <<
"#include <" << include <<
">\n";
911 cs <<
"#include <" << include <<
">\n";
918 cs <<
"#include <QtCore/QMetaObject>\n"
937 " * Adaptor class for interface " <<
interface->name <<
"\n"
940 " * Implementation of adaptor class " <<
className <<
"\n"
944 hs <<
"class " <<
className <<
": public QDBusAbstractAdaptor\n"
947 " Q_CLASSINFO(\"D-Bus Interface\", \"" <<
interface->name <<
"\")\n"
948 " Q_CLASSINFO(\"D-Bus Introspection\", \"\"\n"
955 if (!parentClassName.
isEmpty())
956 hs <<
" inline " <<
parent <<
" *parent() const\n"
957 " { return static_cast<" <<
parent <<
" *>(QObject::parent()); }\n\n";
961 " : QDBusAbstractAdaptor(parent)\n"
964 " setAutoRelaySignals(true);\n"
971 hs <<
"public: // PROPERTIES\n";
978 hs <<
" Q_PROPERTY(" <<
type <<
" " <<
property.name;
982 hs <<
" WRITE " <<
setter;
987 hs <<
" " <<
type <<
" " <<
getter <<
"() const;\n";
991 " // get the value of property " <<
property.name <<
"\n"
992 " return qvariant_cast< " <<
type <<
" >(parent()->property(\"" <<
property.name <<
"\"));\n"
998 hs <<
" void " <<
setter <<
"(" << constRefType <<
"value);\n";
999 cs <<
"void " <<
className <<
"::" <<
setter <<
"(" << constRefType <<
"value)\n"
1001 " // set the value of property " <<
property.name <<
"\n"
1002 " parent()->setProperty(\"" <<
property.name <<
"\", QVariant::fromValue(value";
1003 if (constRefType.contains(
"QDBusVariant"_L1))
1012 hs <<
"public Q_SLOTS: // METHODS\n";
1015 if (isNoReply && !
method.outputArgs.isEmpty()) {
1016 reporter.warning(
method.location,
1017 "method %s in interface %s is marked 'no-reply' but has output "
1026 hs <<
"Q_NOREPLY void ";
1028 }
else if (
method.outputArgs.isEmpty()) {
1033 qtTypeName(
method.outputArgs.first().location,
1034 method.outputArgs.first().type,
method.annotations, 0,
"Out");
1035 hs << returnType <<
" ";
1036 cs << returnType <<
" ";
1053 bool usingInvokeMethod =
false;
1054 if (parentClassName.
isEmpty() &&
method.inputArgs.size() <= 10
1055 &&
method.outputArgs.size() <= 1)
1056 usingInvokeMethod =
true;
1058 if (usingInvokeMethod) {
1061 cs <<
" " << returnType <<
" " << argNames.at(
method.inputArgs.size())
1064 static const char invoke[] =
" QMetaObject::invokeMethod(parent(), \"";
1065 cs << invoke <<
name <<
"\"";
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()) <<
")";
1075 << qtTypeName(
method.inputArgs.at(
i).location,
method.inputArgs.at(
i).type,
1077 <<
", " << argNames.at(
i) <<
")";
1082 cs <<
" return " << argNames.at(
method.inputArgs.size()) <<
";\n";
1084 if (parentClassName.
isEmpty())
1089 if (!
method.outputArgs.isEmpty())
1092 if (parentClassName.
isEmpty())
1093 cs <<
"static_cast<YourObjectType *>(parent())->";
1101 cs << (
first ?
"" :
", ") << argNames.at(argPos++);
1106 cs << (
first ?
"" :
", ") << argNames.at(argPos++);
1115 hs <<
"Q_SIGNALS: // SIGNALS\n";
1117 hs <<
" void " <<
signal.name <<
"(";
1120 writeSignalArgList(hs, argNames,
signal.annotations,
signal.outputArgs);
1133 if (includeMocs && !mocName.
isEmpty())
1135 "#include \"" << mocName <<
"\"\n";
1151 cppFile.
write(cppData);
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);
1171 u
"[interfaces ...]"_s);
1174 u
"Write the adaptor code to <filename>"_s, u
"filename"_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,
1184 u
"Add #include \"filename\" to the output"_s, u
"filename"_s);
1188 u
"Add #include <filename> to the output"_s, u
"filename"_s);
1189 parser.
addOption(addGlobalIncludeOption);
1192 u
"When generating an adaptor, use <classname> as the parent class"_s, u
"classname"_s);
1196 u
"Generate #include \"filename.moc\" statements in the .cpp files"_s);
1200 u
"Don't use namespaces"_s);
1204 u
"Write the proxy code to <filename>"_s, u
"filename"_s);
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);
1221 bool verbose = parser.
isSet(verboseOption);
1224 if (!wantedInterfaces.isEmpty()) {
1225 inputFile = wantedInterfaces.takeFirst();
1229 qCritical(
"Error: Input %s is not a file or cannot be accessed\n",
qPrintable(inputFile));
1238 cleanInterfaces(interfaces);
1240 if (!globalClassName.
isEmpty() && interfaces.
count() != 1) {
1241 qCritical(
"Option -c/--classname can only be used with a single interface.\n");
1250 writeProxy(proxyFile, interfaces);
1253 writeAdaptor(adaptorFile, interfaces);
static JNINativeMethod methods[]
QByteArray toUpper() const &
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
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...
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.
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.
int run(const QCoreApplication &app)
\inmodule QtCore \reentrant
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.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
void setFileName(const QString &name)
Sets the name of the file.
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
void removeFirst() noexcept
const_reference at(qsizetype i) const noexcept
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
iterator erase(const_iterator it)
size_type count(const Key &key) const
const_iterator ConstIterator
const_iterator constBegin() const
const_iterator constEnd() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
QString last(qsizetype n) const
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString & append(QChar c)
QString toUpper() const &
QSet< QString >::iterator it
QString includeGuard(const QString &filename)
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
static const char includeList[]
static bool isSupportedSuffix(QStringView suffix)
static QString stringify(const QString &data)
static QString moc(const QString &name)
#define ANNOTATION_NO_WAIT
static QString templateArg(const QByteArray &arg)
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)
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei GLsizei GLchar * source
GLenum GLenum GLenum input
#define qPrintable(string)
#define QStringLiteral(str)
const char className[16]
[1]
ASSERT failure in file div cpp
file setFileName("readme.txt")
QFileInfo fi("c:/temp/foo")
[newstuff]
QApplication app(argc, argv)
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent