📄 qdbusxml2cpp.cpp
字号:
/******************************************************************************** Copyright (C) 2006-2006 Trolltech ASA. All rights reserved.**** This file is part of the tools applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <QtCore/qbytearray.h>#include <QtCore/qcoreapplication.h>#include <QtCore/qdatetime.h>#include <QtCore/qdebug.h>#include <QtCore/qfile.h>#include <QtCore/qstring.h>#include <QtCore/qstringlist.h>#include <QtCore/qtextstream.h>#include <QtCore/qset.h>#include <QtDBus>#include "private/qdbusmetaobject_p.h"#include "private/qdbusintrospection_p.h"#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#define PROGRAMNAME "dbusxml2cpp"#define PROGRAMVERSION "0.6"#define PROGRAMCOPYRIGHT "Copyright (C) 2006 Trolltech ASA. All rights reserved."#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"static QString globalClassName;static QString parentClassName;static QString proxyFile;static QString adaptorFile;static QString inputFile;static bool skipNamespaces;static bool verbose;static bool includeMocs;static QString commandLine;static QStringList includes;static QStringList wantedInterfaces;static const char help[] = "Usage: " PROGRAMNAME " [options...] [xml-or-xml-file] [interfaces...]\n" "Produces the C++ code to implement the interfaces defined in the input file.\n" "If no options are given, the code is written to the standard output.\n" "\n" "Options:\n" " -a <filename> Write the adaptor code to <filename>\n" " -c <classname> Use <classname> as the class name for the generated classes\n" " -h Show this information\n" " -i <filename> Add #include to the output\n" " -l <classname> When generating an adaptor, use <classname> as the parent class\n" " -m Generate #include \"filename.moc\" statements in the .cpp files\n" " -N Don't use namespaces\n" " -p <filename> Write the proxy code to <filename>\n" " -v Be verbose.\n" " -V Show the program version and quit.\n" "\n" "If the file name given to the options -a and -p does not end in .cpp or .h, the\n" "program will automatically append the suffixes and produce both files.\n" "You can also use a colon (:) to separate the header name from the source file\n" "name, as in '-a filename_p.h:filename.cpp'.\n";static const char includeList[] = "#include <QtCore/QByteArray>\n" "#include <QtCore/QList>\n" "#include <QtCore/QMap>\n" "#include <QtCore/QString>\n" "#include <QtCore/QStringList>\n" "#include <QtCore/QVariant>\n";static const char forwardDeclarations[] = "class QByteArray;\n" "template<class T> class QList;\n" "template<class Key, class Value> class QMap;\n" "class QString;\n" "class QStringList;\n" "class QVariant;\n";static void showHelp(){ printf("%s", help); exit(0);}static void showVersion(){ printf("%s version %s\n", PROGRAMNAME, PROGRAMVERSION); printf("D-Bus binding tool for Qt\n"); exit(0);}static QString nextArg(QStringList &args, int i, char opt){ QString arg = args.value(i); if (arg.isEmpty()) { printf("-%c needs at least one argument\n", opt); exit(1); } return args.takeAt(i);}static void parseCmdLine(QStringList args){ args.takeFirst(); commandLine = QLatin1String(PROGRAMNAME " "); commandLine += args.join(QLatin1String(" ")); int i = 0; while (i < args.count()) { if (!args.at(i).startsWith(QLatin1Char('-'))) { ++i; continue; } QString arg = args.takeAt(i); char c = '\0'; if (arg.length() == 2) c = arg.at(1).toLatin1(); else if (arg == QLatin1String("--help")) c = 'h'; switch (c) { case 'a': adaptorFile = nextArg(args, i, 'a'); break; case 'c': globalClassName = nextArg(args, i, 'c'); break; case 'v': verbose = true; break; case 'i': includes << nextArg(args, i, 'i'); break; case 'l': parentClassName = nextArg(args, i, 'l'); break; case 'm': includeMocs = true; break; case 'N': skipNamespaces = true; break; case '?': case 'h': showHelp(); break; case 'V': showVersion(); break; case 'p': proxyFile = nextArg(args, i, 'p'); break; default: printf("unknown option: '%s'\n", qPrintable(arg)); exit(1); } } if (!args.isEmpty()) inputFile = args.takeFirst(); wantedInterfaces << args;}static QDBusIntrospection::Interfaces readInput(){ QFile input(inputFile); if (inputFile.isEmpty() || inputFile == QLatin1String("-")) input.open(stdin, QIODevice::ReadOnly); else input.open(QIODevice::ReadOnly); QByteArray data = input.readAll(); // check if the input is already XML data = data.trimmed(); if (data.startsWith("<!DOCTYPE ") || data.startsWith("<?xml") || data.startsWith("<node") || data.startsWith("<interface")) // already XML return QDBusIntrospection::parseInterfaces(QString::fromUtf8(data)); fprintf(stderr, "Cannot process input. Stop.\n"); exit(1);}static void cleanInterfaces(QDBusIntrospection::Interfaces &interfaces){ if (!wantedInterfaces.isEmpty()) { QDBusIntrospection::Interfaces::Iterator it = interfaces.begin(); while (it != interfaces.end()) if (!wantedInterfaces.contains(it.key())) it = interfaces.erase(it); else ++it; }}// produce a header name from the file namestatic QString header(const QString &name){ QStringList parts = name.split(QLatin1Char(':')); QString retval = parts.first(); if (retval.isEmpty() || retval == QLatin1String("-")) return retval; if (!retval.endsWith(QLatin1String(".h")) && !retval.endsWith(QLatin1String(".cpp")) && !retval.endsWith(QLatin1String(".cc"))) retval.append(QLatin1String(".h")); return retval;}// produce a cpp name from the file namestatic QString cpp(const QString &name){ QStringList parts = name.split(QLatin1Char(':')); QString retval = parts.last(); if (retval.isEmpty() || retval == QLatin1String("-")) return retval; if (!retval.endsWith(QLatin1String(".h")) && !retval.endsWith(QLatin1String(".cpp")) && !retval.endsWith(QLatin1String(".cc"))) retval.append(QLatin1String(".cpp")); return retval;}// produce a moc name from the file namestatic QString moc(const QString &name){ QString retval = header(name); if (retval.isEmpty()) return retval; retval.truncate(retval.length() - 1); // drop the h in .h retval += QLatin1String("moc"); return retval;}static QTextStream &writeHeader(QTextStream &ts, bool changesWillBeLost){ ts << "/*" << endl << " * This file was generated by " PROGRAMNAME " version " PROGRAMVERSION << endl << " * Command line was: " << commandLine << endl << " *" << endl << " * " PROGRAMNAME " is " PROGRAMCOPYRIGHT << endl << " *" << endl << " * This is an auto-generated file." << endl; if (changesWillBeLost) ts << " * Do not edit! All changes made to it will be lost." << endl; else ts << " * This file may have been hand-edited. Look for HAND-EDIT comments" << endl << " * before re-generating it." << endl; ts << " */" << endl << endl; return ts;}enum ClassType { Proxy, Adaptor };static QString classNameForInterface(const QString &interface, ClassType classType){ if (!globalClassName.isEmpty()) return globalClassName; QStringList parts = interface.split(QLatin1Char('.')); QString retval; if (classType == Proxy) foreach (QString part, parts) { part[0] = part[0].toUpper(); retval += part; } else { retval = parts.last(); retval[0] = retval[0].toUpper(); } if (classType == Proxy) retval += QLatin1String("Interface"); else retval += QLatin1String("Adaptor"); return retval;}static QByteArray qtTypeName(const QString &signature, const QDBusIntrospection::Annotations &annotations, int paramId = -1, const char *direction = "Out"){ int type = QDBusMetaType::signatureToType(signature.toLatin1()); if (type == QVariant::Invalid) { QString annotationName = QString::fromLatin1("com.trolltech.QtDBus.QtTypeName"); if (paramId >= 0) annotationName += QString::fromLatin1(".%1%2").arg(direction).arg(paramId); QString qttype = annotations.value(annotationName); if (!qttype.isEmpty()) return qttype.toLatin1(); fprintf(stderr, "Got unknown type `%s'\n", qPrintable(signature)); fprintf(stderr, "You should add <annotation name=\"%s\" value=\"<type>\"/> to the XML description\n", qPrintable(annotationName)); exit(1); } return QVariant::typeToName(QVariant::Type(type));}static QString nonConstRefArg(const QByteArray &arg){ return QLatin1String(arg + " &");}static QString templateArg(const QByteArray &arg){ if (!arg.endsWith('>')) return QLatin1String(arg); return QLatin1String(arg + ' ');}static QString constRefArg(const QByteArray &arg){ if (!arg.startsWith('Q')) return QLatin1String(arg + ' '); else return QString( QLatin1String("const %1 &") ).arg( QLatin1String(arg) );}static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs, const QDBusIntrospection::Arguments &outputArgs = QDBusIntrospection::Arguments()){ QStringList retval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -