summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/androiddeployqt/main.cpp1390
-rw-r--r--src/tools/androidtestrunner/androidtestrunner.pro13
-rw-r--r--src/tools/androidtestrunner/main.cpp490
-rw-r--r--src/tools/bootstrap/bootstrap.pro48
-rw-r--r--src/tools/moc/generator.cpp17
-rw-r--r--src/tools/moc/generator.h2
-rw-r--r--src/tools/moc/keywords.cpp357
-rw-r--r--src/tools/moc/moc.cpp85
-rw-r--r--src/tools/moc/moc.h4
-rw-r--r--src/tools/moc/parser.h6
-rw-r--r--src/tools/moc/token.h1
-rw-r--r--src/tools/moc/util/generate_keywords.cpp1
-rw-r--r--src/tools/moc/util/generate_keywords.pro1
-rw-r--r--src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp1
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp330
-rw-r--r--src/tools/qfloat16-tables/gen_qfloat16_tables.cpp163
-rw-r--r--src/tools/qfloat16-tables/qfloat16-tables.pro9
-rw-r--r--src/tools/qlalr/cppgenerator.cpp209
-rw-r--r--src/tools/qlalr/dotgraph.cpp22
-rw-r--r--src/tools/qlalr/lalr.cpp32
-rw-r--r--src/tools/qlalr/lalr.g12
-rw-r--r--src/tools/qlalr/lalr.h130
-rw-r--r--src/tools/qlalr/main.cpp26
-rw-r--r--src/tools/qlalr/parsetable.cpp26
-rw-r--r--src/tools/qlalr/recognizer.cpp12
-rw-r--r--src/tools/qvkgen/qvkgen.cpp45
-rw-r--r--src/tools/rcc/main.cpp77
-rw-r--r--src/tools/rcc/rcc.cpp196
-rw-r--r--src/tools/rcc/rcc.h4
-rw-r--r--src/tools/tracegen/etw.cpp1
-rw-r--r--src/tools/tracegen/lttng.cpp1
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.cpp2
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.h10
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp945
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.h41
-rw-r--r--src/tools/uic/customwidgetsinfo.cpp4
-rw-r--r--src/tools/uic/customwidgetsinfo.h2
-rw-r--r--src/tools/uic/databaseinfo.cpp9
-rw-r--r--src/tools/uic/driver.cpp61
-rw-r--r--src/tools/uic/driver.h22
-rw-r--r--src/tools/uic/main.cpp17
-rw-r--r--src/tools/uic/python/python.pri8
-rw-r--r--src/tools/uic/python/pythonwritedeclaration.cpp73
-rw-r--r--src/tools/uic/python/pythonwritedeclaration.h62
-rw-r--r--src/tools/uic/python/pythonwriteimports.cpp94
-rw-r--r--src/tools/uic/python/pythonwriteimports.h58
-rw-r--r--src/tools/uic/qclass_lib_map.h2
-rw-r--r--src/tools/uic/shared/language.cpp282
-rw-r--r--src/tools/uic/shared/language.h127
-rw-r--r--src/tools/uic/treewalker.h5
-rw-r--r--src/tools/uic/ui4.cpp7
-rw-r--r--src/tools/uic/ui4.h8
-rw-r--r--src/tools/uic/uic.cpp99
-rw-r--r--src/tools/uic/uic.h3
-rw-r--r--src/tools/uic/uic.pro1
-rw-r--r--src/tools/uic/utils.h49
56 files changed, 3510 insertions, 2192 deletions
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 01c392f8f9..7101a2bf3c 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -52,6 +52,21 @@
#define QT_POPEN_READ "r"
#endif
+class ActionTimer
+{
+ qint64 started;
+public:
+ ActionTimer() = default;
+ void start()
+ {
+ started = QDateTime::currentMSecsSinceEpoch();
+ }
+ int elapsed()
+ {
+ return int(QDateTime::currentMSecsSinceEpoch() - started);
+ }
+};
+
static const bool mustReadOutputAnyway = true; // pclose seems to return the wrong error code unless we read the output
void deleteRecursively(const QString &dirName)
@@ -76,7 +91,7 @@ FILE *openProcess(const QString &command)
#if defined(Q_OS_WIN32)
QString processedCommand = QLatin1Char('\"') + command + QLatin1Char('\"');
#else
- QString processedCommand = command;
+ const QString& processedCommand = command;
#endif
return popen(processedCommand.toLocal8Bit().constData(), QT_POPEN_READ);
@@ -84,7 +99,7 @@ FILE *openProcess(const QString &command)
struct QtDependency
{
- QtDependency(QString rpath, QString apath) : relativePath(rpath), absolutePath(apath) {}
+ QtDependency(const QString &rpath, const QString &apath) : relativePath(rpath), absolutePath(apath) {}
bool operator==(const QtDependency &other) const
{
@@ -101,19 +116,16 @@ struct Options
: helpRequested(false)
, verbose(false)
, timing(false)
- , generateAssetsFileList(true)
, build(true)
- , gradle(false)
, auxMode(false)
, deploymentMechanism(Bundled)
, releasePackage(false)
- , digestAlg(QLatin1String("SHA1"))
- , sigAlg(QLatin1String("SHA1withRSA"))
+ , digestAlg(QLatin1String("SHA-256"))
+ , sigAlg(QLatin1String("SHA256withRSA"))
, internalSf(false)
, sectionsOnly(false)
, protectedAuthenticationPath(false)
, jarSigner(false)
- , gdbServer(Auto)
, installApk(false)
, uninstallApk(false)
{}
@@ -133,18 +145,14 @@ struct Options
bool helpRequested;
bool verbose;
bool timing;
- bool generateAssetsFileList;
bool build;
- bool gradle;
bool auxMode;
- bool stripLibraries = true;
- QTime timer;
+ ActionTimer timer;
// External tools
QString sdkPath;
QString sdkBuildToolsVersion;
QString ndkPath;
- QString antTool;
QString jdkPath;
// Build paths
@@ -163,22 +171,24 @@ struct Options
// lib c++ path
QString stdCppPath;
- QString stdCppName = QStringLiteral("gnustl_shared");
+ QString stdCppName = QStringLiteral("c++_shared");
// Build information
QString androidPlatform;
- QString architecture;
- QString toolchainVersion;
+ QHash<QString, QString> architectures;
+ QString currentArchitecture;
QString toolchainPrefix;
- QString toolPrefix;
- bool useLLVM = false;
QString ndkHost;
+ bool buildAAB = false;
+
// Package information
DeploymentMechanism deploymentMechanism;
QString packageName;
QStringList extraLibs;
+ QHash<QString, QStringList> archExtraLibs;
QStringList extraPlugins;
+ QHash<QString, QStringList> archExtraPlugins;
// Signing information
bool releasePackage;
@@ -197,26 +207,38 @@ struct Options
bool sectionsOnly;
bool protectedAuthenticationPath;
bool jarSigner;
-
- // Gdbserver
- TriState gdbServer;
+ QString apkPath;
// Installation information
bool installApk;
bool uninstallApk;
QString installLocation;
- // Collected information
+ // Per architecture collected information
+ void clear(const QString &arch)
+ {
+ currentArchitecture = arch;
+ }
typedef QPair<QString, QString> BundledFile;
- QList<BundledFile> bundledFiles;
- QList<QtDependency> qtDependencies;
- QStringList localLibs;
+ QHash<QString, QList<BundledFile>> bundledFiles;
+ QHash<QString, QList<QtDependency>> qtDependencies;
+ QHash<QString, QStringList> localLibs;
+ bool usesOpenGL = false;
+
+ // Per package collected information
QStringList localJars;
QStringList initClasses;
QStringList permissions;
QStringList features;
};
+static const QHash<QByteArray, QByteArray> elfArchitecures = {
+ {"aarch64", "arm64-v8a"},
+ {"arm", "armeabi-v7a"},
+ {"i386", "x86"},
+ {"x86_64", "x86_64"}
+};
+
// Copy-pasted from qmake/library/ioutil.cpp
inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
{
@@ -237,7 +259,7 @@ static QString shellQuoteUnix(const QString &arg)
}; // 0-32 \'"$`<>|;&(){}*?#!~[]
if (!arg.length())
- return QString::fromLatin1("\"\"");
+ return QLatin1String("\"\"");
QString ret(arg);
if (hasSpecialChars(ret, iqm)) {
@@ -260,7 +282,7 @@ static QString shellQuoteWin(const QString &arg)
};
if (!arg.length())
- return QString::fromLatin1("\"\"");
+ return QLatin1String("\"\"");
QString ret(arg);
if (hasSpecialChars(ret, iqm)) {
@@ -288,6 +310,59 @@ static QString shellQuote(const QString &arg)
return shellQuoteUnix(arg);
}
+QString architecureFromName(const QString &name)
+{
+ QRegExp architecture(QStringLiteral(".*_(armeabi-v7a|arm64-v8a|x86|x86_64).so"));
+ if (!architecture.exactMatch(name))
+ return {};
+ return architecture.capturedTexts().last();
+}
+
+QString fileArchitecture(const Options &options, const QString &path)
+{
+ auto arch = architecureFromName(path);
+ if (!arch.isEmpty())
+ return arch;
+
+ QString readElf = QLatin1String("%1/toolchains/%2/prebuilt/%3/bin/llvm-readobj").arg(options.ndkPath,
+ options.toolchainPrefix,
+ options.ndkHost);
+#if defined(Q_OS_WIN32)
+ readElf += QLatin1String(".exe");
+#endif
+
+ if (!QFile::exists(readElf)) {
+ fprintf(stderr, "Command does not exist: %s\n", qPrintable(readElf));
+ return {};
+ }
+
+ readElf = QLatin1String("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(path));
+
+ FILE *readElfCommand = openProcess(readElf);
+ if (!readElfCommand) {
+ fprintf(stderr, "Cannot execute command %s\n", qPrintable(readElf));
+ return {};
+ }
+
+ char buffer[512];
+ while (fgets(buffer, sizeof(buffer), readElfCommand) != nullptr) {
+ QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
+ QString library;
+ line = line.trimmed();
+ if (line.startsWith("Arch: ")) {
+ auto it = elfArchitecures.find(line.mid(6));
+ pclose(readElfCommand);
+ return it != elfArchitecures.constEnd() ? QString::fromLatin1(it.value()) : QString{};
+ }
+ }
+ pclose(readElfCommand);
+ return {};
+}
+
+bool checkArchitecture(const Options &options, const QString &fileName)
+{
+ return fileArchitecture(options, fileName) == options.currentArchitecture;
+}
void deleteMissingFiles(const Options &options, const QDir &srcDir, const QDir &dstDir)
{
@@ -337,7 +412,10 @@ Options parseOptions()
options.helpRequested = true;
else
options.inputFileName = arguments.at(++i);
- } else if (argument.compare(QLatin1String("--no-build"), Qt::CaseInsensitive) == 0) {
+ } else if (argument.compare(QLatin1String("--aab"), Qt::CaseInsensitive) == 0) {
+ options.buildAAB = true;
+ options.build = true;
+ } else if (options.buildAAB && argument.compare(QLatin1String("--no-build"), Qt::CaseInsensitive) == 0) {
options.build = false;
} else if (argument.compare(QLatin1String("--install"), Qt::CaseInsensitive) == 0) {
options.installApk = true;
@@ -354,13 +432,6 @@ Options parseOptions()
options.helpRequested = true;
} else if (argument.compare(QLatin1String("--verbose"), Qt::CaseInsensitive) == 0) {
options.verbose = true;
- } else if (argument.compare(QLatin1String("--gradle"), Qt::CaseInsensitive) == 0) {
- options.gradle = true;
- } else if (argument.compare(QLatin1String("--ant"), Qt::CaseInsensitive) == 0) {
- if (i + 1 == arguments.size())
- options.helpRequested = true;
- else
- options.antTool = arguments.at(++i);
} else if (argument.compare(QLatin1String("--deployment"), Qt::CaseInsensitive) == 0) {
if (i + 1 == arguments.size()) {
options.helpRequested = true;
@@ -382,15 +453,16 @@ Options parseOptions()
options.installLocation = arguments.at(++i);
} else if (argument.compare(QLatin1String("--release"), Qt::CaseInsensitive) == 0) {
options.releasePackage = true;
- } else if (argument.compare(QLatin1String("--gdbserver"), Qt::CaseInsensitive) == 0) {
- options.gdbServer = Options::True;
- } else if (argument.compare(QLatin1String("--no-gdbserver"), Qt::CaseInsensitive) == 0) {
- options.gdbServer = Options::False;
} else if (argument.compare(QLatin1String("--jdk"), Qt::CaseInsensitive) == 0) {
if (i + 1 == arguments.size())
options.helpRequested = true;
else
options.jdkPath = arguments.at(++i);
+ } else if (argument.compare(QLatin1String("--apk"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ options.helpRequested = true;
+ else
+ options.apkPath = arguments.at(++i);
} else if (argument.compare(QLatin1String("--sign"), Qt::CaseInsensitive) == 0) {
if (i + 2 >= arguments.size()) {
options.helpRequested = true;
@@ -447,17 +519,13 @@ Options parseOptions()
options.protectedAuthenticationPath = true;
} else if (argument.compare(QLatin1String("--jarsigner"), Qt::CaseInsensitive) == 0) {
options.jarSigner = true;
- } else if (argument.compare(QLatin1String("--no-generated-assets-cache"), Qt::CaseInsensitive) == 0) {
- options.generateAssetsFileList = false;
} else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) {
options.auxMode = true;
- } else if (argument.compare(QLatin1String("--no-strip"), Qt::CaseInsensitive) == 0) {
- options.stripLibraries = false;
}
}
if (options.inputFileName.isEmpty())
- options.inputFileName = QString::fromLatin1("android-lib%1.so-deployment-settings.json").arg(QDir::current().dirName());
+ options.inputFileName = QLatin1String("android-lib%1.so-deployment-settings.json").arg(QDir::current().dirName());
options.timing = qEnvironmentVariableIsSet("ANDROIDDEPLOYQT_TIMING_OUTPUT");
@@ -486,6 +554,7 @@ void printHelp()
" --deployment <mechanism>: Supported deployment mechanisms:\n"
" bundled (default): Include Qt files in stand-alone package.\n"
" ministro: Use the Ministro service to manage Qt files.\n"
+ " --aab: Build an Android App Bundle.\n"
" --no-build: Do not build the package, it is useful to just install\n"
" a package previously built.\n"
" --install: Installs apk to device/emulator. By default this step is\n"
@@ -500,9 +569,6 @@ void printHelp()
" --android-platform <platform>: Builds against the given android\n"
" platform. By default, the highest available version will be\n"
" used.\n"
- " --gradle. Use gradle instead of ant to create and install the apk.\n"
- " --ant <path/to/ant>: If unspecified, ant from the PATH will be\n"
- " used.\n"
" --release: Builds a package ready for release. By default, the\n"
" package will be signed with a debug key.\n"
" --sign <url/to/keystore> <alias>: Signs the package with the\n"
@@ -525,10 +591,6 @@ void printHelp()
" --protected: Keystore has protected authentication path.\n"
" --jarsigner: Force jarsigner usage, otherwise apksigner will be\n"
" used if available.\n"
- " --gdbserver: Adds the gdbserver to the package. By default the gdbserver\n"
- " is bundled for debug pacakges.\n"
- " --no-gdbserver: Prevents the gdbserver from being added to the package\n"
- " By default the gdbserver is bundled for debug pacakges.\n"
" --jdk <path/to/jdk>: Used to find the jarsigner tool when used\n"
" in combination with the --release argument. By default,\n"
" an attempt is made to detect the tool using the JAVA_HOME and\n"
@@ -541,7 +603,7 @@ void printHelp()
" --aux-mode: Operate in auxiliary mode. This will only copy the\n"
" dependencies into the build directory and update the XML templates.\n"
" The project will not be built or installed.\n"
- " --no-strip: Do not strip debug symbols from libraries.\n"
+ " --apk <path/where/to/copy/the/apk>: Path where to copy the built apk.\n"
" --help: Displays this information.\n\n",
qPrintable(QCoreApplication::arguments().at(0))
);
@@ -571,9 +633,10 @@ bool alwaysOverwritableFile(const QString &fileName)
|| fileName.endsWith(QLatin1String("/src/org/qtproject/qt5/android/bindings/QtActivity.java")));
}
+
bool copyFileIfNewer(const QString &sourceFileName,
const QString &destinationFileName,
- bool verbose,
+ const Options &options,
bool forceOverwrite = false)
{
if (QFile::exists(destinationFileName)) {
@@ -583,7 +646,7 @@ bool copyFileIfNewer(const QString &sourceFileName,
if (!forceOverwrite
&& sourceFileInfo.lastModified() <= destinationFileInfo.lastModified()
&& !alwaysOverwritableFile(destinationFileName)) {
- if (verbose)
+ if (options.verbose)
fprintf(stdout, " -- Skipping file %s. Same or newer file already in place.\n", qPrintable(sourceFileName));
return true;
} else {
@@ -602,11 +665,10 @@ bool copyFileIfNewer(const QString &sourceFileName,
if (!QFile::exists(destinationFileName) && !QFile::copy(sourceFileName, destinationFileName)) {
fprintf(stderr, "Failed to copy %s to %s.\n", qPrintable(sourceFileName), qPrintable(destinationFileName));
return false;
- } else if (verbose) {
+ } else if (options.verbose) {
fprintf(stdout, " -- Copied %s\n", qPrintable(destinationFileName));
fflush(stdout);
}
-
return true;
}
@@ -699,7 +761,7 @@ QString packageNameFromAndroidManifest(const QString &androidManifestPath)
reader.attributes().value(QLatin1String("package")).toString());
}
}
- return QString();
+ return {};
}
bool readInputFile(Options *options)
@@ -741,13 +803,13 @@ bool readInputFile(Options *options)
{
- const QJsonValue value = jsonObject.value(QStringLiteral("sdkBuildToolsRevision"));
+ const QJsonValue value = jsonObject.value(QLatin1String("sdkBuildToolsRevision"));
if (!value.isUndefined())
options->sdkBuildToolsVersion = value.toString();
}
{
- const QJsonValue qtInstallDirectory = jsonObject.value(QStringLiteral("qt"));
+ const QJsonValue qtInstallDirectory = jsonObject.value(QLatin1String("qt"));
if (qtInstallDirectory.isUndefined()) {
fprintf(stderr, "No Qt directory in json file %s\n", qPrintable(options->inputFileName));
return false;
@@ -764,13 +826,13 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue androidSourcesDirectory = jsonObject.value(QStringLiteral("android-package-source-directory"));
+ const QJsonValue androidSourcesDirectory = jsonObject.value(QLatin1String("android-package-source-directory"));
if (!androidSourcesDirectory.isUndefined())
options->androidSourceDirectory = androidSourcesDirectory.toString();
}
{
- const QJsonValue androidVersionName = jsonObject.value(QStringLiteral("android-version-name"));
+ const QJsonValue androidVersionName = jsonObject.value(QLatin1String("android-version-name"));
if (!androidVersionName.isUndefined())
options->versionName = androidVersionName.toString();
else
@@ -778,7 +840,7 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue androidVersionCode = jsonObject.value(QStringLiteral("android-version-code"));
+ const QJsonValue androidVersionCode = jsonObject.value(QLatin1String("android-version-code"));
if (!androidVersionCode.isUndefined())
options->versionCode = androidVersionCode.toString();
else
@@ -786,55 +848,24 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue applicationBinary = jsonObject.value(QStringLiteral("application-binary"));
- if (applicationBinary.isUndefined()) {
- fprintf(stderr, "No application binary defined in json file.\n");
- return false;
- }
- options->applicationBinary = applicationBinary.toString();
-
- if (!QFile::exists(options->applicationBinary)) {
- fprintf(stderr, "Cannot find application binary %s.\n", qPrintable(options->applicationBinary));
+ const QJsonObject targetArchitectures = jsonObject.value(QLatin1String("architectures")).toObject();
+ if (targetArchitectures.isEmpty()) {
+ fprintf(stderr, "No target architecture defined in json file.\n");
return false;
}
- }
-
- {
- const QJsonValue deploymentDependencies = jsonObject.value(QStringLiteral("deployment-dependencies"));
- if (!deploymentDependencies.isUndefined()) {
- QString deploymentDependenciesString = deploymentDependencies.toString();
- const auto dependencies = deploymentDependenciesString.splitRef(QLatin1Char(','));
- for (const QStringRef &dependency : dependencies) {
- QString path = options->qtInstallDirectory + QLatin1Char('/') + dependency;
- if (QFileInfo(path).isDir()) {
- QDirIterator iterator(path, QDirIterator::Subdirectories);
- while (iterator.hasNext()) {
- iterator.next();
- if (iterator.fileInfo().isFile()) {
- QString subPath = iterator.filePath();
- options->qtDependencies.append(QtDependency(subPath.mid(options->qtInstallDirectory.length() + 1),
- subPath));
- }
- }
- } else {
- options->qtDependencies.append(QtDependency(dependency.toString(), path));
- }
+ for (auto it = targetArchitectures.constBegin(); it != targetArchitectures.constEnd(); ++it) {
+ if (it.value().isUndefined()) {
+ fprintf(stderr, "Invalid architecure.\n");
+ return false;
}
+ if (it.value().isNull())
+ continue;
+ options->architectures.insert(it.key(), it.value().toString());
}
}
-
- {
- const QJsonValue targetArchitecture = jsonObject.value(QStringLiteral("target-architecture"));
- if (targetArchitecture.isUndefined()) {
- fprintf(stderr, "No target architecture defined in json file.\n");
- return false;
- }
- options->architecture = targetArchitecture.toString();
- }
-
{
- const QJsonValue ndk = jsonObject.value(QStringLiteral("ndk"));
+ const QJsonValue ndk = jsonObject.value(QLatin1String("ndk"));
if (ndk.isUndefined()) {
fprintf(stderr, "No NDK path defined in json file.\n");
return false;
@@ -843,12 +874,7 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue value = jsonObject.value(QStringLiteral("useLLVM"));
- options->useLLVM = value.toBool(false);
- }
-
- {
- const QJsonValue toolchainPrefix = jsonObject.value(QStringLiteral("toolchain-prefix"));
+ const QJsonValue toolchainPrefix = jsonObject.value(QLatin1String("toolchain-prefix"));
if (toolchainPrefix.isUndefined()) {
fprintf(stderr, "No toolchain prefix defined in json file.\n");
return false;
@@ -857,26 +883,7 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue toolPrefix = jsonObject.value(QStringLiteral("tool-prefix"));
- if (toolPrefix.isUndefined()) {
- fprintf(stderr, "Warning: No tool prefix defined in json file.\n");
- options->toolPrefix = options->toolchainPrefix;
- } else {
- options->toolPrefix = toolPrefix.toString();
- }
- }
-
- if (!options->useLLVM) {
- const QJsonValue toolchainVersion = jsonObject.value(QStringLiteral("toolchain-version"));
- if (toolchainVersion.isUndefined()) {
- fprintf(stderr, "No toolchain version defined in json file.\n");
- return false;
- }
- options->toolchainVersion = toolchainVersion.toString();
- }
-
- {
- const QJsonValue ndkHost = jsonObject.value(QStringLiteral("ndk-host"));
+ const QJsonValue ndkHost = jsonObject.value(QLatin1String("ndk-host"));
if (ndkHost.isUndefined()) {
fprintf(stderr, "No NDK host defined in json file.\n");
return false;
@@ -884,52 +891,100 @@ bool readInputFile(Options *options)
options->ndkHost = ndkHost.toString();
}
- options->packageName = packageNameFromAndroidManifest(options->androidSourceDirectory + QLatin1String("/AndroidManifest.xml"));
- if (options->packageName.isEmpty())
- options->packageName = cleanPackageName(QString::fromLatin1("org.qtproject.example.%1").arg(QFileInfo(options->applicationBinary).baseName().mid(sizeof("lib") - 1)));
-
{
- const QJsonValue extraLibs = jsonObject.value(QStringLiteral("android-extra-libs"));
+ const QJsonValue extraLibs = jsonObject.value(QLatin1String("android-extra-libs"));
if (!extraLibs.isUndefined())
options->extraLibs = extraLibs.toString().split(QLatin1Char(','), QString::SkipEmptyParts);
}
{
- const QJsonValue extraPlugins = jsonObject.value(QStringLiteral("android-extra-plugins"));
+ const QJsonValue extraPlugins = jsonObject.value(QLatin1String("android-extra-plugins"));
if (!extraPlugins.isUndefined())
options->extraPlugins = extraPlugins.toString().split(QLatin1Char(','));
}
{
- const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path"));
+ const QJsonValue stdcppPath = jsonObject.value(QLatin1String("stdcpp-path"));
if (stdcppPath.isUndefined()) {
fprintf(stderr, "No stdcpp-path defined in json file.\n");
return false;
}
options->stdCppPath = stdcppPath.toString();
- auto name = QFileInfo(options->stdCppPath).baseName();
- if (!name.startsWith(QLatin1String("lib"))) {
- fprintf(stderr, "Invalid STD C++ library name.\n");
- return false;
- }
- options->stdCppName = name.mid(3);
}
{
- const QJsonValue qmlRootPath = jsonObject.value(QStringLiteral("qml-root-path"));
+ const QJsonValue qmlRootPath = jsonObject.value(QLatin1String("qml-root-path"));
if (!qmlRootPath.isUndefined())
options->rootPath = qmlRootPath.toString();
}
{
- const QJsonValue qmlImportPaths = jsonObject.value(QStringLiteral("qml-import-paths"));
+ const QJsonValue qmlImportPaths = jsonObject.value(QLatin1String("qml-import-paths"));
if (!qmlImportPaths.isUndefined())
options->qmlImportPaths = qmlImportPaths.toString().split(QLatin1Char(','));
}
+
+ {
+ const QJsonValue applicationBinary = jsonObject.value(QLatin1String("application-binary"));
+ if (applicationBinary.isUndefined()) {
+ fprintf(stderr, "No application binary defined in json file.\n");
+ return false;
+ }
+ options->applicationBinary = applicationBinary.toString();
+ if (options->build) {
+ for (auto it = options->architectures.constBegin(); it != options->architectures.constEnd(); ++it) {
+ if (!QFile::exists(QLatin1String("%1/libs/%2/lib%3_%2.so").arg(options->outputDirectory, it.key(), options->applicationBinary))) {
+ fprintf(stderr, "Cannot find application binary %s.\n", qPrintable(options->applicationBinary));
+ return false;
+ }
+ }
+ }
+ }
+
+ {
+ const QJsonValue deploymentDependencies = jsonObject.value(QLatin1String("deployment-dependencies"));
+ if (!deploymentDependencies.isUndefined()) {
+ QString deploymentDependenciesString = deploymentDependencies.toString();
+ const auto dependencies = deploymentDependenciesString.splitRef(QLatin1Char(','));
+ for (const QStringRef &dependency : dependencies) {
+ QString path = options->qtInstallDirectory + QLatin1Char('/') + dependency;
+ if (QFileInfo(path).isDir()) {
+ QDirIterator iterator(path, QDirIterator::Subdirectories);
+ while (iterator.hasNext()) {
+ iterator.next();
+ if (iterator.fileInfo().isFile()) {
+ QString subPath = iterator.filePath();
+ auto arch = fileArchitecture(*options, subPath);
+ if (!arch.isEmpty()) {
+ options->qtDependencies[arch].append(QtDependency(subPath.mid(options->qtInstallDirectory.length() + 1),
+ subPath));
+ } else if (options->verbose) {
+ fprintf(stderr, "Skipping \"%s\", unknown architecture\n", qPrintable(subPath));
+ fflush(stderr);
+ }
+ }
+ }
+ } else {
+ auto arch = fileArchitecture(*options, path);
+ if (!arch.isEmpty()) {
+ options->qtDependencies[arch].append(QtDependency(dependency.toString(), path));
+ } else if (options->verbose) {
+ fprintf(stderr, "Skipping \"%s\", unknown architecture\n", qPrintable(path));
+ fflush(stderr);
+ }
+ }
+ }
+ }
+ }
+
+ options->packageName = packageNameFromAndroidManifest(options->androidSourceDirectory + QLatin1String("/AndroidManifest.xml"));
+ if (options->packageName.isEmpty())
+ options->packageName = cleanPackageName(QLatin1String("org.qtproject.example.%1").arg(options->applicationBinary));
+
return true;
}
-bool copyFiles(const QDir &sourceDirectory, const QDir &destinationDirectory, bool verbose, bool forceOverwrite = false)
+bool copyFiles(const QDir &sourceDirectory, const QDir &destinationDirectory, const Options &options, bool forceOverwrite = false)
{
const QFileInfoList entries = sourceDirectory.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
for (const QFileInfo &entry : entries) {
@@ -940,11 +995,11 @@ bool copyFiles(const QDir &sourceDirectory, const QDir &destinationDirectory, bo
return false;
}
- if (!copyFiles(dir, QDir(destinationDirectory.path() + QLatin1String("/") + dir.dirName()), verbose, forceOverwrite))
+ if (!copyFiles(dir, QDir(destinationDirectory.path() + QLatin1Char('/') + dir.dirName()), options, forceOverwrite))
return false;
} else {
QString destination = destinationDirectory.absoluteFilePath(entry.fileName());
- if (!copyFileIfNewer(entry.absoluteFilePath(), destination, verbose, forceOverwrite))
+ if (!copyFileIfNewer(entry.absoluteFilePath(), destination, options, forceOverwrite))
return false;
}
}
@@ -984,7 +1039,7 @@ bool copyAndroidTemplate(const Options &options, const QString &androidTemplate,
return false;
}
- return copyFiles(sourceDirectory, QDir(outDir), options.verbose);
+ return copyFiles(sourceDirectory, QDir(outDir), options);
}
bool copyGradleTemplate(const Options &options)
@@ -1001,7 +1056,7 @@ bool copyGradleTemplate(const Options &options)
return false;
}
- return copyFiles(sourceDirectory, QDir(outDir), options.verbose);
+ return copyFiles(sourceDirectory, QDir(outDir), options);
}
bool copyAndroidTemplate(const Options &options)
@@ -1009,16 +1064,13 @@ bool copyAndroidTemplate(const Options &options)
if (options.verbose)
fprintf(stdout, "Copying Android package template.\n");
- if (options.gradle && !copyGradleTemplate(options))
+ if (!copyGradleTemplate(options))
return false;
if (!copyAndroidTemplate(options, QLatin1String("/src/android/templates")))
return false;
- if (options.gradle)
- return true;
-
- return copyAndroidTemplate(options, QLatin1String("/src/android/java"));
+ return true;
}
bool copyAndroidSources(const Options &options)
@@ -1035,38 +1087,42 @@ bool copyAndroidSources(const Options &options)
return false;
}
- return copyFiles(sourceDirectory, QDir(options.outputDirectory), options.verbose, true);
+ return copyFiles(sourceDirectory, QDir(options.outputDirectory), options, true);
}
-bool copyAndroidExtraLibs(const Options &options)
+bool copyAndroidExtraLibs(Options *options)
{
- if (options.extraLibs.isEmpty())
+ if (options->extraLibs.isEmpty())
return true;
- if (options.verbose)
- fprintf(stdout, "Copying %d external libraries to package.\n", options.extraLibs.size());
+ if (options->verbose)
+ fprintf(stdout, "Copying %d external libraries to package.\n", options->extraLibs.size());
- for (const QString &extraLib : options.extraLibs) {
+ for (const QString &extraLib : options->extraLibs) {
QFileInfo extraLibInfo(extraLib);
if (!extraLibInfo.exists()) {
fprintf(stderr, "External library %s does not exist!\n", qPrintable(extraLib));
return false;
}
-
+ if (!checkArchitecture(*options, extraLibInfo.filePath())) {
+ if (options->verbose)
+ fprintf(stdout, "Skipping \"%s\", architecture mismatch.\n", qPrintable(extraLib));
+ continue;
+ }
if (!extraLibInfo.fileName().startsWith(QLatin1String("lib")) || extraLibInfo.suffix() != QLatin1String("so")) {
fprintf(stderr, "The file name of external library %s must begin with \"lib\" and end with the suffix \".so\".\n",
qPrintable(extraLib));
return false;
}
-
- QString destinationFile(options.outputDirectory
+ QString destinationFile(options->outputDirectory
+ QLatin1String("/libs/")
- + options.architecture
+ + options->currentArchitecture
+ QLatin1Char('/')
+ extraLibInfo.fileName());
- if (!copyFileIfNewer(extraLib, destinationFile, options.verbose))
+ if (!copyFileIfNewer(extraLib, destinationFile, *options))
return false;
+ options->archExtraLibs[options->currentArchitecture] += extraLib;
}
return true;
@@ -1087,15 +1143,15 @@ QStringList allFilesInside(const QDir& current, const QDir& rootDir)
return result;
}
-bool copyAndroidExtraResources(const Options &options)
+bool copyAndroidExtraResources(Options *options)
{
- if (options.extraPlugins.isEmpty())
+ if (options->extraPlugins.isEmpty())
return true;
- if (options.verbose)
- fprintf(stdout, "Copying %d external resources to package.\n", options.extraPlugins.size());
+ if (options->verbose)
+ fprintf(stdout, "Copying %d external resources to package.\n", options->extraPlugins.size());
- for (const QString &extraResource : options.extraPlugins) {
+ for (const QString &extraResource : options->extraPlugins) {
QFileInfo extraResourceInfo(extraResource);
if (!extraResourceInfo.exists() || !extraResourceInfo.isDir()) {
fprintf(stderr, "External resource %s does not exist or not a correct directory!\n", qPrintable(extraResource));
@@ -1103,8 +1159,8 @@ bool copyAndroidExtraResources(const Options &options)
}
QDir resourceDir(extraResource);
- QString assetsDir = options.outputDirectory + QStringLiteral("/assets/") + resourceDir.dirName() + QLatin1Char('/');
- QString libsDir = options.outputDirectory + QStringLiteral("/libs/") + options.architecture + QLatin1Char('/');
+ QString assetsDir = options->outputDirectory + QLatin1String("/assets/") + resourceDir.dirName() + QLatin1Char('/');
+ QString libsDir = options->outputDirectory + QLatin1String("/libs/") + options->currentArchitecture + QLatin1Char('/');
const QStringList files = allFilesInside(resourceDir, resourceDir);
for (const QString &resourceFile : files) {
@@ -1113,10 +1169,12 @@ bool copyAndroidExtraResources(const Options &options)
if (!resourceFile.endsWith(QLatin1String(".so"))) {
destinationFile = assetsDir + resourceFile;
} else {
- destinationFile = libsDir + QStringLiteral("/lib") + QString(resourceDir.dirName() + QLatin1Char('/') + resourceFile).replace(QLatin1Char('/'), QLatin1Char('_'));
+ if (!checkArchitecture(*options, originFile))
+ continue;
+ destinationFile = libsDir + resourceFile;
+ options->archExtraPlugins[options->currentArchitecture] += resourceFile;
}
-
- if (!copyFileIfNewer(originFile, destinationFile, options.verbose))
+ if (!copyFileIfNewer(originFile, destinationFile, *options))
return false;
}
}
@@ -1168,75 +1226,88 @@ bool updateFile(const QString &fileName, const QHash<QString, QString> &replacem
}
-bool updateLibsXml(const Options &options)
+bool updateLibsXml(Options *options)
{
- if (options.verbose)
+ if (options->verbose)
fprintf(stdout, " -- res/values/libs.xml\n");
- QString fileName = options.outputDirectory + QLatin1String("/res/values/libs.xml");
+ QString fileName = options->outputDirectory + QLatin1String("/res/values/libs.xml");
if (!QFile::exists(fileName)) {
fprintf(stderr, "Cannot find %s in prepared packaged. This file is required.\n", qPrintable(fileName));
return false;
}
- QString libsPath = QLatin1String("libs/") + options.architecture + QLatin1Char('/');
-
- QString qtLibs = QLatin1String("<item>") + options.stdCppName + QLatin1String("</item>\n");
- QString bundledInLibs;
- QString bundledInAssets;
- for (const Options::BundledFile &bundledFile : options.bundledFiles) {
- if (bundledFile.second.startsWith(QLatin1String("lib/"))) {
- QString s = bundledFile.second.mid(sizeof("lib/lib") - 1);
- s.chop(sizeof(".so") - 1);
- qtLibs += QString::fromLatin1("<item>%1</item>\n").arg(s);
- } else if (bundledFile.first.startsWith(libsPath)) {
- QString s = bundledFile.first.mid(libsPath.length());
- bundledInLibs += QString::fromLatin1("<item>%1:%2</item>\n")
- .arg(s).arg(bundledFile.second);
- } else if (bundledFile.first.startsWith(QLatin1String("assets/"))) {
- QString s = bundledFile.first.mid(sizeof("assets/") - 1);
- bundledInAssets += QString::fromLatin1("<item>%1:%2</item>\n")
- .arg(s).arg(bundledFile.second);
- }
- }
-
- if (!options.extraPlugins.isEmpty()) {
- for (const QString &extraRes : options.extraPlugins) {
- QDir resourceDir(extraRes);
- const QStringList files = allFilesInside(resourceDir, resourceDir);
- for (const QString &file : files) {
- QString destinationPath = resourceDir.dirName() + QLatin1Char('/') + file;
- if (!file.endsWith(QLatin1String(".so"))) {
- bundledInAssets += QStringLiteral("<item>%1:%1</item>\n")
- .arg(destinationPath);
- } else {
- bundledInLibs += QStringLiteral("<item>lib%1:%2</item>\n")
- .arg(QString(destinationPath).replace(QLatin1Char('/'), QLatin1Char('_')))
- .arg(destinationPath);
- }
+ QString qtLibs;
+ QString allLocalLibs;
+ QString extraLibs;
+
+ for (auto it = options->architectures.constBegin(); it != options->architectures.constEnd(); ++it) {
+ QString libsPath = QLatin1String("libs/") + it.key() + QLatin1Char('/');
+
+ qtLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), options->stdCppName);
+ for (const Options::BundledFile &bundledFile : options->bundledFiles[it.key()]) {
+ if (bundledFile.second.startsWith(QLatin1String("lib/"))) {
+ QString s = bundledFile.second.mid(sizeof("lib/lib") - 1);
+ s.chop(sizeof(".so") - 1);
+ qtLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), s);
}
}
- }
- QHash<QString, QString> replacements;
- replacements[QLatin1String("<!-- %%INSERT_QT_LIBS%% -->")] = qtLibs;
+ if (!options->archExtraLibs[it.key()].isEmpty()) {
+ for (const QString &extraLib : options->archExtraLibs[it.key()]) {
+ QFileInfo extraLibInfo(extraLib);
+ QString name = extraLibInfo.fileName().mid(sizeof("lib") - 1);
+ name.chop(sizeof(".so") - 1);
+ extraLibs += QLatin1String(" <item>%1;%2").arg(it.key(), name);
+ }
+ }
- if (options.deploymentMechanism == Options::Bundled) {
- replacements[QLatin1String("<!-- %%INSERT_BUNDLED_IN_LIB%% -->")] = bundledInLibs;
- replacements[QLatin1String("<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->")] = bundledInAssets;
- }
+ QStringList localLibs;
+ localLibs = options->localLibs[it.key()];
+ // If .pro file overrides dependency detection, we need to see which platform plugin they picked
+ if (localLibs.isEmpty()) {
+ QString plugin;
+ for (const QtDependency &qtDependency : options->qtDependencies[it.key()]) {
+ if (qtDependency.relativePath.endsWith(QLatin1String("libqtforandroid.so"))
+ || qtDependency.relativePath.endsWith(QLatin1String("libqtforandroidGL.so"))) {
+ if (!plugin.isEmpty() && plugin != qtDependency.relativePath) {
+ fprintf(stderr, "Both platform plugins libqtforandroid.so and libqtforandroidGL.so included in package. Please include only one.\n");
+ return false;
+ }
- QString extraLibs;
- if (!options.extraLibs.isEmpty()) {
- for (const QString extraLib : options.extraLibs) {
- QFileInfo extraLibInfo(extraLib);
- QString name = extraLibInfo.fileName().mid(sizeof("lib") - 1);
- name.chop(sizeof(".so") - 1);
+ plugin = qtDependency.relativePath;
+ }
+ if (qtDependency.relativePath.contains(QLatin1String("libQt5OpenGL"))
+ || qtDependency.relativePath.contains(QLatin1String("libQt5Quick"))) {
+ options->usesOpenGL |= true;
+ break;
+ }
+ }
- extraLibs += QLatin1String("<item>") + name + QLatin1String("</item>\n");
+ if (plugin.isEmpty()) {
+ fflush(stdout);
+ fprintf(stderr, "No platform plugin, neither libqtforandroid.so or libqtforandroidGL.so, included in package. Please include one.\n");
+ fflush(stderr);
+ return false;
+ }
+
+ localLibs.append(plugin);
+ if (options->verbose)
+ fprintf(stdout, " -- Using platform plugin %s\n", qPrintable(plugin));
}
+
+ // remove all paths
+ for (auto &lib : localLibs) {
+ if (lib.endsWith(QLatin1String(".so")))
+ lib = lib.mid(lib.lastIndexOf(QLatin1Char('/')) + 1);
+ }
+ allLocalLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), localLibs.join(QLatin1Char(':')));
}
- replacements[QLatin1String("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs;
+
+ QHash<QString, QString> replacements;
+ replacements[QStringLiteral("<!-- %%INSERT_QT_LIBS%% -->")] += qtLibs.trimmed();
+ replacements[QStringLiteral("<!-- %%INSERT_LOCAL_LIBS%% -->")] = allLocalLibs.trimmed();
+ replacements[QStringLiteral("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs.trimmed();
if (!updateFile(fileName, replacements))
return false;
@@ -1250,7 +1321,7 @@ bool updateStringsXml(const Options &options)
fprintf(stdout, " -- res/values/strings.xml\n");
QHash<QString, QString> replacements;
- replacements[QStringLiteral("<!-- %%INSERT_APP_NAME%% -->")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
+ replacements[QStringLiteral("<!-- %%INSERT_APP_NAME%% -->")] = options.applicationBinary;
QString fileName = options.outputDirectory + QLatin1String("/res/values/strings.xml");
if (!QFile::exists(fileName)) {
@@ -1262,7 +1333,7 @@ bool updateStringsXml(const Options &options)
return false;
}
file.write(QByteArray("<?xml version='1.0' encoding='utf-8'?><resources><string name=\"app_name\" translatable=\"false\">")
- .append(QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1).toLatin1())
+ .append(options.applicationBinary.toLatin1())
.append("</string></resources>\n"));
return true;
}
@@ -1270,36 +1341,6 @@ bool updateStringsXml(const Options &options)
if (!updateFile(fileName, replacements))
return false;
- if (options.gradle)
- return true;
-
- // ant can't (easily) build multiple res folders,
- // so we need to replace the "<!-- %%INSERT_STRINGS -->" placeholder
- // from the main res folder
- QFile stringsXml(fileName);
- if (!stringsXml.open(QIODevice::ReadOnly)) {
- fprintf(stderr, "Cannot open %s for reading.\n", qPrintable(fileName));
- return false;
- }
-
- QXmlStreamReader reader(&stringsXml);
- while (!reader.atEnd()) {
- reader.readNext();
- if (reader.isStartElement() &&
- reader.name() == QLatin1String("string") &&
- reader.attributes().hasAttribute(QLatin1String("name")) &&
- reader.attributes().value(QLatin1String("name")) == QLatin1String("app_name")) {
- return true;
- }
- }
-
- replacements.clear();
- replacements[QStringLiteral("<!-- %%INSERT_STRINGS -->")] = QString::fromLatin1("<string name=\"app_name\">%1</string>\n")
- .arg(QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1));
-
- if (!updateFile(fileName, replacements))
- return false;
-
return true;
}
@@ -1308,71 +1349,34 @@ bool updateAndroidManifest(Options &options)
if (options.verbose)
fprintf(stdout, " -- AndroidManifest.xml \n");
- QStringList localLibs = options.localLibs;
-
- // If .pro file overrides dependency detection, we need to see which platform plugin they picked
- if (localLibs.isEmpty()) {
- QString plugin;
- for (const QtDependency &qtDependency : qAsConst(options.qtDependencies)) {
- if (qtDependency.relativePath.endsWith(QLatin1String("libqtforandroid.so"))
- || qtDependency.relativePath.endsWith(QLatin1String("libqtforandroidGL.so"))) {
- if (!plugin.isEmpty() && plugin != qtDependency.relativePath) {
- fprintf(stderr, "Both platform plugins libqtforandroid.so and libqtforandroidGL.so included in package. Please include only one.\n");
- return false;
- }
-
- plugin = qtDependency.relativePath;
- }
- }
-
- if (plugin.isEmpty()) {
- fprintf(stderr, "No platform plugin, neither libqtforandroid.so or libqtforandroidGL.so, included in package. Please include one.\n");
- return false;
- }
-
- localLibs.append(plugin);
- if (options.verbose)
- fprintf(stdout, " -- Using platform plugin %s\n", qPrintable(plugin));
- }
-
- bool usesGL = false;
- for (const QtDependency &qtDependency : qAsConst(options.qtDependencies)) {
- if (qtDependency.relativePath.endsWith(QLatin1String("libQt5OpenGL.so"))
- || qtDependency.relativePath.endsWith(QLatin1String("libQt5Quick.so"))) {
- usesGL = true;
- break;
- }
- }
-
options.localJars.removeDuplicates();
options.initClasses.removeDuplicates();
QHash<QString, QString> replacements;
- replacements[QLatin1String("-- %%INSERT_APP_NAME%% --")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
- replacements[QLatin1String("-- %%INSERT_APP_LIB_NAME%% --")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
- replacements[QLatin1String("-- %%INSERT_LOCAL_LIBS%% --")] = localLibs.join(QLatin1Char(':'));
- replacements[QLatin1String("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':'));
- replacements[QLatin1String("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':'));
- replacements[QLatin1String("-- %%INSERT_VERSION_NAME%% --")] = options.versionName;
- replacements[QLatin1String("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
- replacements[QLatin1String("package=\"org.qtproject.example\"")] = QString::fromLatin1("package=\"%1\"").arg(options.packageName);
- replacements[QLatin1String("-- %%BUNDLE_LOCAL_QT_LIBS%% --")]
- = (options.deploymentMechanism == Options::Bundled) ? QString::fromLatin1("1") : QString::fromLatin1("0");
- replacements[QLatin1String("-- %%USE_LOCAL_QT_LIBS%% --")]
- = (options.deploymentMechanism != Options::Ministro) ? QString::fromLatin1("1") : QString::fromLatin1("0");
+ replacements[QStringLiteral("-- %%INSERT_APP_NAME%% --")] = options.applicationBinary;
+ replacements[QStringLiteral("-- %%INSERT_APP_LIB_NAME%% --")] = options.applicationBinary;
+ replacements[QStringLiteral("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':'));
+ replacements[QStringLiteral("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':'));
+ replacements[QStringLiteral("-- %%INSERT_VERSION_NAME%% --")] = options.versionName;
+ replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
+ replacements[QStringLiteral("package=\"org.qtproject.example\"")] = QLatin1String("package=\"%1\"").arg(options.packageName);
+ replacements[QStringLiteral("-- %%BUNDLE_LOCAL_QT_LIBS%% --")]
+ = (options.deploymentMechanism == Options::Bundled) ? QLatin1String("1") : QLatin1String("0");
+ replacements[QStringLiteral("-- %%USE_LOCAL_QT_LIBS%% --")]
+ = (options.deploymentMechanism != Options::Ministro) ? QLatin1String("1") : QLatin1String("0");
QString permissions;
for (const QString &permission : qAsConst(options.permissions))
- permissions += QString::fromLatin1(" <uses-permission android:name=\"%1\" />\n").arg(permission);
- replacements[QLatin1String("<!-- %%INSERT_PERMISSIONS -->")] = permissions;
+ permissions += QLatin1String(" <uses-permission android:name=\"%1\" />\n").arg(permission);
+ replacements[QStringLiteral("<!-- %%INSERT_PERMISSIONS -->")] = permissions.trimmed();
QString features;
for (const QString &feature : qAsConst(options.features))
- features += QStringLiteral(" <uses-feature android:name=\"%1\" android:required=\"false\" />\n").arg(feature);
- if (usesGL)
- features += QStringLiteral(" <uses-feature android:glEsVersion=\"0x00020000\" android:required=\"true\" />");
+ features += QLatin1String(" <uses-feature android:name=\"%1\" android:required=\"false\" />\n").arg(feature);
+ if (options.usesOpenGL)
+ features += QLatin1String(" <uses-feature android:glEsVersion=\"0x00020000\" android:required=\"true\" />");
- replacements[QLatin1String("<!-- %%INSERT_FEATURES -->")] = features;
+ replacements[QStringLiteral("<!-- %%INSERT_FEATURES -->")] = features.trimmed();
QString androidManifestPath = options.outputDirectory + QLatin1String("/AndroidManifest.xml");
if (!updateFile(androidManifestPath, replacements))
@@ -1433,7 +1437,7 @@ bool updateAndroidFiles(Options &options)
if (options.verbose)
fprintf(stdout, "Updating Android package files with project settings.\n");
- if (!updateLibsXml(options))
+ if (!updateLibsXml(&options))
return false;
if (!updateAndroidManifest(options))
@@ -1490,7 +1494,7 @@ bool readAndroidDependencyXml(Options *options,
QSet<QString> *usedDependencies,
QSet<QString> *remainingDependencies)
{
- QString androidDependencyName = absoluteFilePath(options, QString::fromLatin1("/lib/%1-android-dependencies.xml").arg(moduleName));
+ QString androidDependencyName = absoluteFilePath(options, QLatin1String("/lib/%1-android-dependencies.xml").arg(moduleName));
QFile androidDependencyFile(androidDependencyName);
if (androidDependencyFile.exists()) {
@@ -1529,7 +1533,7 @@ bool readAndroidDependencyXml(Options *options,
if (options->verbose)
fprintf(stdout, "Appending dependency from xml: %s\n", qPrintable(fileName.relativePath));
- options->qtDependencies.append(fileName);
+ options->qtDependencies[options->currentArchitecture].append(fileName);
}
} else if (reader.name() == QLatin1String("jar")) {
int bundling = reader.attributes().value(QLatin1String("bundling")).toInt();
@@ -1537,7 +1541,7 @@ bool readAndroidDependencyXml(Options *options,
if (bundling == (options->deploymentMechanism == Options::Bundled)) {
QtDependency dependency(fileName, absoluteFilePath(options, fileName));
if (!usedDependencies->contains(dependency.absolutePath)) {
- options->qtDependencies.append(dependency);
+ options->qtDependencies[options->currentArchitecture].append(dependency);
usedDependencies->insert(dependency.absolutePath);
}
}
@@ -1553,15 +1557,15 @@ bool readAndroidDependencyXml(Options *options,
if (reader.attributes().hasAttribute(QLatin1String("replaces"))) {
QString replaces = reader.attributes().value(QLatin1String("replaces")).toString();
for (int i=0; i<options->localLibs.size(); ++i) {
- if (options->localLibs.at(i) == replaces) {
- options->localLibs[i] = fileName;
+ if (options->localLibs[options->currentArchitecture].at(i) == replaces) {
+ options->localLibs[options->currentArchitecture][i] = fileName;
break;
}
}
} else if (!fileName.isEmpty()) {
- options->localLibs.append(fileName);
+ options->localLibs[options->currentArchitecture].append(fileName);
}
- if (fileName.endsWith(QLatin1String(".so"))) {
+ if (fileName.endsWith(QLatin1String(".so")) && checkArchitecture(*options, fileName)) {
remainingDependencies->insert(fileName);
}
} else if (reader.name() == QLatin1String("permission")) {
@@ -1581,24 +1585,17 @@ bool readAndroidDependencyXml(Options *options,
} else if (options->verbose) {
fprintf(stdout, "No android dependencies for %s\n", qPrintable(moduleName));
}
+ options->permissions.removeDuplicates();
+ options->features.removeDuplicates();
return true;
}
QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
{
- QString readElf = options.ndkPath
- + QLatin1String("/toolchains/")
- + options.toolchainPrefix;
-
- if (!options.useLLVM)
- readElf += QLatin1Char('-') + options.toolchainVersion;
-
- readElf += QLatin1String("/prebuilt/")
- + options.ndkHost
- + QLatin1String("/bin/")
- + options.toolPrefix +
- (options.useLLVM ? QLatin1String("-readobj") : QLatin1String("-readelf"));
+ QString readElf = QLatin1String("%1/toolchains/%2/prebuilt/%3/bin/llvm-readobj").arg(options.ndkPath,
+ options.toolchainPrefix,
+ options.ndkHost);
#if defined(Q_OS_WIN32)
readElf += QLatin1String(".exe");
#endif
@@ -1608,14 +1605,11 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
return QStringList();
}
- if (options.useLLVM)
- readElf = QString::fromLatin1("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName));
- else
- readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf), shellQuote(fileName));
+ readElf = QLatin1String("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName));
FILE *readElfCommand = openProcess(readElf);
if (!readElfCommand) {
- fprintf(stderr, "Cannot execute command %s", qPrintable(readElf));
+ fprintf(stderr, "Cannot execute command %s\n", qPrintable(readElf));
return QStringList();
}
@@ -1623,22 +1617,25 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
bool readLibs = false;
char buffer[512];
- while (fgets(buffer, sizeof(buffer), readElfCommand) != 0) {
+ while (fgets(buffer, sizeof(buffer), readElfCommand) != nullptr) {
QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
QString library;
- if (options.useLLVM) {
- line = line.trimmed();
- if (!readLibs) {
- readLibs = line.startsWith("NeededLibraries");
- continue;
+ line = line.trimmed();
+ if (!readLibs) {
+ if (line.startsWith("Arch: ")) {
+ auto it = elfArchitecures.find(line.mid(6));
+ if (it == elfArchitecures.constEnd() || *it != options.currentArchitecture.toLatin1()) {
+ if (options.verbose)
+ fprintf(stdout, "Skipping \"%s\", architecture mismatch\n", qPrintable(fileName));
+ return {};
+ }
}
- if (!line.startsWith("lib"))
- continue;
- library = QString::fromLatin1(line);
- } else if (line.contains("(NEEDED)") && line.contains("Shared library:")) {
- const int pos = line.lastIndexOf('[') + 1;
- library = QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
+ readLibs = line.startsWith("NeededLibraries");
+ continue;
}
+ if (!line.startsWith("lib"))
+ continue;
+ library = QString::fromLatin1(line);
QString libraryName = QLatin1String("lib/") + library;
if (QFile::exists(absoluteFilePath(&options, libraryName)))
ret += libraryName;
@@ -1677,7 +1674,7 @@ bool readDependenciesFromElf(Options *options,
return false;
}
- options->qtDependencies.append(QtDependency(dependency, absoluteDependencyPath));
+ options->qtDependencies[options->currentArchitecture].append(QtDependency(dependency, absoluteDependencyPath));
if (options->verbose)
fprintf(stdout, "Appending dependency: %s\n", qPrintable(dependency));
dependenciesToCheck.append(dependency);
@@ -1726,9 +1723,8 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
for (const QString &qmlImportPath : qAsConst(options->qmlImportPaths))
importPaths += shellQuote(qmlImportPath);
- qmlImportScanner += QString::fromLatin1(" -rootPath %1 -importPath %2")
- .arg(shellQuote(rootPath))
- .arg(importPaths.join(QLatin1Char(' ')));
+ qmlImportScanner += QLatin1String(" -rootPath %1 -importPath %2")
+ .arg(shellQuote(rootPath), importPaths.join(QLatin1Char(' ')));
if (options->verbose) {
fprintf(stdout, "Running qmlimportscanner with the following command: %s\n",
@@ -1822,9 +1818,9 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
// Put all imports in default import path in assets
fileName.relativePath.prepend(QLatin1String("qml/"));
- options->qtDependencies.append(fileName);
+ options->qtDependencies[options->currentArchitecture].append(fileName);
- if (fileName.absolutePath.endsWith(QLatin1String(".so"))) {
+ if (fileName.absolutePath.endsWith(QLatin1String(".so")) && checkArchitecture(*options, fileName.absolutePath)) {
QSet<QString> remainingDependencies;
if (!readDependenciesFromElf(options, fileName.absolutePath, usedDependencies, &remainingDependencies))
return false;
@@ -1837,13 +1833,77 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
return true;
}
+bool runCommand(const Options &options, const QString &command)
+{
+ if (options.verbose)
+ fprintf(stdout, "Running command '%s'\n", qPrintable(command));
+
+ FILE *runCommand = openProcess(command);
+ if (runCommand == nullptr) {
+ fprintf(stderr, "Cannot run command '%s'\n", qPrintable(command));
+ return false;
+ }
+ char buffer[4096];
+ while (fgets(buffer, sizeof(buffer), runCommand) != nullptr) {
+ if (options.verbose)
+ fprintf(stdout, "%s", buffer);
+ }
+ pclose(runCommand);
+ fflush(stdout);
+ fflush(stderr);
+ return true;
+}
+
+bool createRcc(const Options &options)
+{
+ auto assetsDir = QLatin1String("%1/assets").arg(options.outputDirectory);
+ if (!QDir{QLatin1String("%1/android_rcc_bundle").arg(assetsDir)}.exists()) {
+ fprintf(stdout, "Skipping createRCC\n");
+ return true;
+ }
+
+ if (options.verbose)
+ fprintf(stdout, "Create rcc bundle.\n");
+
+ QString rcc = options.qtInstallDirectory + QLatin1String("/bin/rcc");
+#if defined(Q_OS_WIN32)
+ rcc += QLatin1String(".exe");
+#endif
+
+ if (!QFile::exists(rcc)) {
+ fprintf(stderr, "rcc not found: %s\n", qPrintable(rcc));
+ return false;
+ }
+ auto currentDir = QDir::currentPath();
+ if (!QDir::setCurrent(QLatin1String("%1/android_rcc_bundle").arg(assetsDir))) {
+ fprintf(stderr, "Cannot set current dir to: %s\n", qPrintable(QLatin1String("%1/android_rcc_bundle").arg(assetsDir)));
+ return false;
+ }
+
+ bool res = runCommand(options, QLatin1String("%1 --project -o %2").arg(rcc, shellQuote(QLatin1String("%1/android_rcc_bundle.qrc").arg(assetsDir))));
+ if (!res)
+ return false;
+
+ QFile::rename(QLatin1String("%1/android_rcc_bundle.qrc").arg(assetsDir), QLatin1String("%1/android_rcc_bundle/android_rcc_bundle.qrc").arg(assetsDir));
+
+ res = runCommand(options, QLatin1String("%1 %2 --binary -o %3 android_rcc_bundle.qrc").arg(rcc, shellQuote(QLatin1String("--root=/android_rcc_bundle/")),
+ shellQuote(QLatin1String("%1/android_rcc_bundle.rcc").arg(assetsDir))));
+ if (!QDir::setCurrent(currentDir)) {
+ fprintf(stderr, "Cannot set current dir to: %s\n", qPrintable(currentDir));
+ return false;
+ }
+ QFile::remove(QLatin1String("%1/android_rcc_bundle.qrc").arg(assetsDir));
+ QDir{QLatin1String("%1/android_rcc_bundle").arg(assetsDir)}.removeRecursively();
+ return res;
+}
+
bool readDependencies(Options *options)
{
if (options->verbose)
fprintf(stdout, "Detecting dependencies of application.\n");
// Override set in .pro file
- if (!options->qtDependencies.isEmpty()) {
+ if (!options->qtDependencies[options->currentArchitecture].isEmpty()) {
if (options->verbose)
fprintf(stdout, "\tDependencies explicitly overridden in .pro file. No detection needed.\n");
return true;
@@ -1853,11 +1913,7 @@ bool readDependencies(Options *options)
QSet<QString> remainingDependencies;
// Add dependencies of application binary first
- if (!readDependenciesFromElf(options, options->applicationBinary, &usedDependencies, &remainingDependencies))
- return false;
-
- // Jam in the dependencies of the platform plugin, since the application will crash without it
- if (!readDependenciesFromElf(options, options->qtInstallDirectory + QLatin1String("/plugins/platforms/android/libqtforandroid.so"), &usedDependencies, &remainingDependencies))
+ if (!readDependenciesFromElf(options, QLatin1String("%1/libs/%2/lib%3_%2.so").arg(options->outputDirectory, options->currentArchitecture, options->applicationBinary), &usedDependencies, &remainingDependencies))
return false;
while (!remainingDependencies.isEmpty()) {
@@ -1877,14 +1933,14 @@ bool readDependencies(Options *options)
}
}
- QStringList::iterator it = options->localLibs.begin();
- while (it != options->localLibs.end()) {
+ QStringList::iterator it = options->localLibs[options->currentArchitecture].begin();
+ while (it != options->localLibs[options->currentArchitecture].end()) {
QStringList unmetDependencies;
if (!goodToCopy(options, absoluteFilePath(options, *it), &unmetDependencies)) {
fprintf(stdout, "Skipping %s due to unmet dependencies: %s\n",
qPrintable(*it),
qPrintable(unmetDependencies.join(QLatin1Char(','))));
- it = options->localLibs.erase(it);
+ it = options->localLibs[options->currentArchitecture].erase(it);
} else {
++it;
}
@@ -1896,94 +1952,33 @@ bool readDependencies(Options *options)
return true;
}
-bool stripFile(const Options &options, const QString &fileName)
+bool containsApplicationBinary(Options *options)
{
- QString strip = options.ndkPath
- + QLatin1String("/toolchains/")
- + options.toolchainPrefix;
-
- if (!options.useLLVM)
- strip += QLatin1Char('-') + options.toolchainVersion;
-
- strip += QLatin1String("/prebuilt/")
- + options.ndkHost
- + QLatin1String("/bin/")
- + options.toolPrefix
- + QLatin1String("-strip");
-#if defined(Q_OS_WIN32)
- strip += QLatin1String(".exe");
-#endif
-
- if (!QFile::exists(strip)) {
- fprintf(stderr, "Command does not exist: %s\n", qPrintable(strip));
- return false;
- }
-
- if (options.useLLVM)
- strip = QString::fromLatin1("%1 -strip-all %2").arg(shellQuote(strip), shellQuote(fileName));
- else
- strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip), shellQuote(fileName));
-
- FILE *stripCommand = openProcess(strip);
- if (stripCommand == 0) {
- fprintf(stderr, "Cannot execute command %s", qPrintable(strip));
- return false;
- }
-
- pclose(stripCommand);
-
- return true;
-}
-
-bool stripLibraries(const Options &options)
-{
- if (!options.stripLibraries)
+ if (!options->build)
return true;
- if (options.verbose)
- fprintf(stdout, "Stripping libraries to minimize size.\n");
-
- QString libraryPath = options.outputDirectory
- + QLatin1String("/libs/")
- + options.architecture;
- const QStringList libraries = QDir(libraryPath).entryList(QDir::Files);
- for (const QString &library : libraries) {
- if (library.endsWith(QLatin1String(".so"))) {
- if (!stripFile(options, libraryPath + QLatin1Char('/') + library))
- return false;
- }
- }
-
-
- return true;
-}
-
-bool containsApplicationBinary(const Options &options)
-{
- if (options.verbose)
+ if (options->verbose)
fprintf(stdout, "Checking if application binary is in package.\n");
- QFileInfo applicationBinary(options.applicationBinary);
- QString destinationFileName = options.outputDirectory
- + QLatin1String("/libs/")
- + options.architecture
- + QLatin1Char('/')
- + applicationBinary.fileName();
+ QFileInfo applicationBinary(options->applicationBinary);
+ QString applicationFileName = QLatin1String("lib%1_%2.so").arg(options->applicationBinary,
+ options->currentArchitecture);
- if (!QFile::exists(destinationFileName)) {
+ QString applicationPath = QLatin1String("%1/libs/%2/%3").arg(options->outputDirectory,
+ options->currentArchitecture,
+ applicationFileName);
+ if (!QFile::exists(applicationPath)) {
#if defined(Q_OS_WIN32)
QLatin1String makeTool("mingw32-make"); // Only Mingw host builds supported on Windows currently
#else
QLatin1String makeTool("make");
#endif
-
fprintf(stderr, "Application binary is not in output directory: %s. Please run '%s install INSTALL_ROOT=%s' first.\n",
- qPrintable(destinationFileName),
+ qPrintable(applicationFileName),
qPrintable(makeTool),
- qPrintable(options.outputDirectory));
+ qPrintable(options->outputDirectory));
return false;
}
-
return true;
}
@@ -2002,7 +1997,7 @@ FILE *runAdb(const Options &options, const QString &arguments)
if (!options.installLocation.isEmpty())
installOption = QLatin1String(" -s ") + shellQuote(options.installLocation);
- adb = QString::fromLatin1("%1%2 %3").arg(shellQuote(adb)).arg(installOption).arg(arguments);
+ adb = QLatin1String("%1%2 %3").arg(shellQuote(adb), installOption, arguments);
if (options.verbose)
fprintf(stdout, "Running command \"%s\"\n", adb.toLocal8Bit().constData());
@@ -2021,10 +2016,13 @@ bool goodToCopy(const Options *options, const QString &file, QStringList *unmetD
if (!file.endsWith(QLatin1String(".so")))
return true;
+ if (!checkArchitecture(*options, file))
+ return false;
+
bool ret = true;
const auto libs = getQtLibsFromElf(*options, file);
for (const QString &lib : libs) {
- if (!options->qtDependencies.contains(QtDependency(lib, absoluteFilePath(options, lib)))) {
+ if (!options->qtDependencies[options->currentArchitecture].contains(QtDependency(lib, absoluteFilePath(options, lib)))) {
ret = false;
unmetDependencies->append(lib);
}
@@ -2049,12 +2047,12 @@ bool copyQtFiles(Options *options)
if (!options->build)
return true;
+
QString libsDirectory = QLatin1String("libs/");
// Copy other Qt dependencies
- QString libDestinationDirectory = libsDirectory + options->architecture + QLatin1Char('/');
- QString assetsDestinationDirectory = QLatin1String("assets/--Added-by-androiddeployqt--/");
- for (const QtDependency &qtDependency : qAsConst(options->qtDependencies)) {
+ auto assetsDestinationDirectory = QLatin1String("assets/android_rcc_bundle/");
+ for (const QtDependency &qtDependency : qAsConst(options->qtDependencies[options->currentArchitecture])) {
QString sourceFileName = qtDependency.absolutePath;
QString destinationFileName;
@@ -2063,12 +2061,9 @@ bool copyQtFiles(Options *options)
if (qtDependency.relativePath.startsWith(QLatin1String("lib/"))) {
garbledFileName = qtDependency.relativePath.mid(sizeof("lib/") - 1);
} else {
- garbledFileName = QLatin1String("lib")
- + QString(qtDependency.relativePath).replace(QLatin1Char('/'), QLatin1Char('_'));
-
+ garbledFileName = qtDependency.relativePath.mid(qtDependency.relativePath.lastIndexOf(QLatin1Char('/')) + 1);
}
- destinationFileName = libDestinationDirectory + garbledFileName;
-
+ destinationFileName = libsDirectory + options->currentArchitecture + QLatin1Char('/') + garbledFileName;
} else if (qtDependency.relativePath.startsWith(QLatin1String("jar/"))) {
destinationFileName = libsDirectory + qtDependency.relativePath.mid(sizeof("jar/") - 1);
} else {
@@ -2082,20 +2077,34 @@ bool copyQtFiles(Options *options)
QStringList unmetDependencies;
if (!goodToCopy(options, sourceFileName, &unmetDependencies)) {
- fprintf(stdout, " -- Skipping %s. It has unmet dependencies: %s.\n",
- qPrintable(sourceFileName),
- qPrintable(unmetDependencies.join(QLatin1Char(','))));
+ if (unmetDependencies.isEmpty()) {
+ if (options->verbose) {
+ fprintf(stdout, " -- Skipping %s, architecture mismatch.\n",
+ qPrintable(sourceFileName));
+ }
+ } else {
+ if (unmetDependencies.isEmpty()) {
+ if (options->verbose) {
+ fprintf(stdout, " -- Skipping %s, architecture mismatch.\n",
+ qPrintable(sourceFileName));
+ }
+ } else {
+ fprintf(stdout, " -- Skipping %s. It has unmet dependencies: %s.\n",
+ qPrintable(sourceFileName),
+ qPrintable(unmetDependencies.join(QLatin1Char(','))));
+ }
+ }
continue;
}
if (options->deploymentMechanism == Options::Bundled
&& !copyFileIfNewer(sourceFileName,
options->outputDirectory + QLatin1Char('/') + destinationFileName,
- options->verbose)) {
+ *options)) {
return false;
}
- options->bundledFiles += qMakePair(destinationFileName, qtDependency.relativePath);
+ options->bundledFiles[options->currentArchitecture] += qMakePair(destinationFileName, qtDependency.relativePath);
}
return true;
@@ -2144,7 +2153,7 @@ bool createAndroidProject(const Options &options)
return false;
}
- QString androidTool = QString::fromLatin1("%1 update project --path %2 --target %3 --name QtApp")
+ QString androidTool = QLatin1String("%1 update project --path %2 --target %3 --name QtApp")
.arg(shellQuote(androidToolExecutable))
.arg(shellQuote(options.outputDirectory))
.arg(shellQuote(options.androidPlatform));
@@ -2166,7 +2175,7 @@ bool createAndroidProject(const Options &options)
if (options.verbose)
fprintf(stdout, "Updating subproject %s\n", qPrintable(libraryProject));
- androidTool = QString::fromLatin1("%1 update lib-project --path %2 --target %3")
+ androidTool = QLatin1String("%1 update lib-project --path %2 --target %3")
.arg(shellQuote(androidToolExecutable))
.arg(shellQuote(libraryProject))
.arg(shellQuote(options.androidPlatform));
@@ -2205,64 +2214,6 @@ QString findInPath(const QString &fileName)
return QString();
}
-bool buildAntProject(const Options &options)
-{
- if (options.verbose)
- fprintf(stdout, "Building Android package using ant.\n");
-
- QString antTool = options.antTool;
- if (antTool.isEmpty()) {
-#if defined(Q_OS_WIN32)
- antTool = findInPath(QLatin1String("ant.bat"));
-#else
- antTool = findInPath(QLatin1String("ant"));
-#endif
- }
-
- if (antTool.isEmpty()) {
- fprintf(stderr, "Cannot find ant in PATH. Please use --ant option to pass in the correct path.\n");
- return false;
- }
-
- if (options.verbose)
- fprintf(stdout, "Using ant: %s\n", qPrintable(antTool));
-
- QString oldPath = QDir::currentPath();
- if (!QDir::setCurrent(options.outputDirectory)) {
- fprintf(stderr, "Cannot current path to %s\n", qPrintable(options.outputDirectory));
- return false;
- }
-
- QString ant = QString::fromLatin1("%1 %2").arg(shellQuote(antTool)).arg(options.releasePackage ? QLatin1String(" release") : QLatin1String(" debug"));
-
- FILE *antCommand = openProcess(ant);
- if (antCommand == 0) {
- fprintf(stderr, "Cannot run ant command: %s\n.", qPrintable(ant));
- return false;
- }
-
- char buffer[512];
- while (fgets(buffer, sizeof(buffer), antCommand) != 0) {
- fprintf(stdout, "%s", buffer);
- fflush(stdout);
- }
-
- int errorCode = pclose(antCommand);
- if (errorCode != 0) {
- fprintf(stderr, "Building the android package failed!\n");
- if (!options.verbose)
- fprintf(stderr, " -- For more information, run this command with --verbose.\n");
- return false;
- }
-
- if (!QDir::setCurrent(oldPath)) {
- fprintf(stderr, "Cannot change back to old path: %s\n", qPrintable(oldPath));
- return false;
- }
-
- return true;
-}
-
typedef QMap<QByteArray, QByteArray> GradleProperties;
static GradleProperties readGradleProperties(const QString &path)
@@ -2320,7 +2271,7 @@ static bool mergeGradleProperties(const QString &path, GradleProperties properti
return true;
}
-bool buildGradleProject(const Options &options)
+bool buildAndroidProject(const Options &options)
{
GradleProperties localProperties;
localProperties["sdk.dir"] = options.sdkPath.toLocal8Bit();
@@ -2356,7 +2307,10 @@ bool buildGradleProject(const Options &options)
return false;
}
- QString commandLine = QString::fromLatin1("%1 --no-daemon %2").arg(shellQuote(gradlePath)).arg(options.releasePackage ? QLatin1String(" assembleRelease") : QLatin1String(" assembleDebug"));
+ QString commandLine = QLatin1String("%1 --no-daemon %2").arg(shellQuote(gradlePath), options.releasePackage ? QLatin1String(" assembleRelease") : QLatin1String(" assembleDebug"));
+ if (options.buildAAB)
+ commandLine += QLatin1String(" bundle");
+
if (options.verbose)
commandLine += QLatin1String(" --info");
@@ -2388,12 +2342,6 @@ bool buildGradleProject(const Options &options)
return true;
}
-bool buildAndroidProject(const Options &options)
-{
- return options.gradle ? buildGradleProject(options)
- : buildAntProject(options);
-}
-
bool uninstallApk(const Options &options)
{
if (options.verbose)
@@ -2423,32 +2371,38 @@ bool uninstallApk(const Options &options)
}
enum PackageType {
+ AAB,
UnsignedAPK,
SignedAPK
};
-QString apkPath(const Options &options, PackageType pt)
+QString packagePath(const Options &options, PackageType pt)
{
QString path(options.outputDirectory);
- if (options.gradle) {
- path += QLatin1String("/build/outputs/apk/");
- QString buildType(options.releasePackage ? QLatin1String("release/") : QLatin1String("debug/"));
- if (QDir(path + buildType).exists())
- path += buildType;
- path += QDir(options.outputDirectory).dirName() + QLatin1Char('-');
- } else {
- path += QLatin1String("/bin/QtApp-");
- }
+ path += QLatin1String("/build/outputs/%1/").arg(pt >= UnsignedAPK ? QStringLiteral("apk") : QStringLiteral("bundle"));
+ QString buildType(options.releasePackage ? QLatin1String("release/") : QLatin1String("debug/"));
+ if (QDir(path + buildType).exists())
+ path += buildType;
+ path += QDir(options.outputDirectory).dirName() + QLatin1Char('-');
if (options.releasePackage) {
path += QLatin1String("release-");
- if (pt == UnsignedAPK)
- path += QLatin1String("un");
- path += QLatin1String("signed.apk");
+ if (pt >= UnsignedAPK) {
+ if (pt == UnsignedAPK)
+ path += QLatin1String("un");
+ path += QLatin1String("signed.apk");
+ } else {
+ path.chop(1);
+ path += QLatin1String(".aab");
+ }
} else {
path += QLatin1String("debug");
- if (pt == SignedAPK)
- path += QLatin1String("-signed");
- path += QLatin1String(".apk");
+ if (pt >= UnsignedAPK) {
+ if (pt == SignedAPK)
+ path += QLatin1String("-signed");
+ path += QLatin1String(".apk");
+ } else {
+ path += QLatin1String(".aab");
+ }
}
return shellQuote(path);
}
@@ -2465,7 +2419,7 @@ bool installApk(const Options &options)
FILE *adbCommand = runAdb(options,
QLatin1String(" install -r ")
- + apkPath(options, options.keyStore.isEmpty() ? UnsignedAPK
+ + packagePath(options, options.keyStore.isEmpty() ? UnsignedAPK
: SignedAPK));
if (adbCommand == 0)
return false;
@@ -2488,26 +2442,31 @@ bool installApk(const Options &options)
return true;
}
+bool copyPackage(const Options &options)
+{
+ fflush(stdout);
+ auto from = packagePath(options, options.keyStore.isEmpty() ? UnsignedAPK : SignedAPK);
+ QFile::remove(options.apkPath);
+ return QFile::copy(from, options.apkPath);
+}
+
bool copyStdCpp(Options *options)
{
if (options->verbose)
fprintf(stdout, "Copying STL library\n");
- if (!QFile::exists(options->stdCppPath)) {
- fprintf(stderr, "STL library does not exist at %s\n", qPrintable(options->stdCppPath));
- return false;
- }
-
- const QString destinationDirectory = options->outputDirectory
- + QLatin1String("/libs/") + options->architecture;
-
- if (!copyFileIfNewer(options->stdCppPath, destinationDirectory + QLatin1String("/lib")
- + options->stdCppName + QLatin1String(".so"),
- options->verbose)) {
+ QString stdCppPath = QLatin1String("%1/%2/lib%3.so").arg(options->stdCppPath, options->architectures[options->currentArchitecture], options->stdCppName);
+ if (!QFile::exists(stdCppPath)) {
+ fprintf(stderr, "STL library does not exist at %s\n", qPrintable(stdCppPath));
+ fflush(stdout);
+ fflush(stderr);
return false;
}
- return true;
+ const QString destinationFile = QLatin1String("%1/libs/%2/lib%3.so").arg(options->outputDirectory,
+ options->currentArchitecture,
+ options->stdCppName);
+ return copyFileIfNewer(stdCppPath, destinationFile, *options);
}
bool jarSignerSignPackage(const Options &options)
@@ -2521,9 +2480,9 @@ bool jarSignerSignPackage(const Options &options)
jdkPath = QString::fromLocal8Bit(qgetenv("JAVA_HOME"));
#if defined(Q_OS_WIN32)
- QString jarSignerTool = QString::fromLatin1("jarsigner.exe");
+ QString jarSignerTool = QLatin1String("jarsigner.exe");
#else
- QString jarSignerTool = QString::fromLatin1("jarsigner");
+ QString jarSignerTool = QLatin1String("jarsigner");
#endif
if (jdkPath.isEmpty() || !QFile::exists(jdkPath + QLatin1String("/bin/") + jarSignerTool))
@@ -2536,29 +2495,29 @@ bool jarSignerSignPackage(const Options &options)
return false;
}
- jarSignerTool = QString::fromLatin1("%1 -sigalg %2 -digestalg %3 -keystore %4")
- .arg(shellQuote(jarSignerTool)).arg(shellQuote(options.sigAlg)).arg(shellQuote(options.digestAlg)).arg(shellQuote(options.keyStore));
+ jarSignerTool = QLatin1String("%1 -sigalg %2 -digestalg %3 -keystore %4")
+ .arg(shellQuote(jarSignerTool), shellQuote(options.sigAlg), shellQuote(options.digestAlg), shellQuote(options.keyStore));
if (!options.keyStorePassword.isEmpty())
- jarSignerTool += QString::fromLatin1(" -storepass %1").arg(shellQuote(options.keyStorePassword));
+ jarSignerTool += QLatin1String(" -storepass %1").arg(shellQuote(options.keyStorePassword));
if (!options.storeType.isEmpty())
- jarSignerTool += QString::fromLatin1(" -storetype %1").arg(shellQuote(options.storeType));
+ jarSignerTool += QLatin1String(" -storetype %1").arg(shellQuote(options.storeType));
if (!options.keyPass.isEmpty())
- jarSignerTool += QString::fromLatin1(" -keypass %1").arg(shellQuote(options.keyPass));
+ jarSignerTool += QLatin1String(" -keypass %1").arg(shellQuote(options.keyPass));
if (!options.sigFile.isEmpty())
- jarSignerTool += QString::fromLatin1(" -sigfile %1").arg(shellQuote(options.sigFile));
+ jarSignerTool += QLatin1String(" -sigfile %1").arg(shellQuote(options.sigFile));
if (!options.signedJar.isEmpty())
- jarSignerTool += QString::fromLatin1(" -signedjar %1").arg(shellQuote(options.signedJar));
+ jarSignerTool += QLatin1String(" -signedjar %1").arg(shellQuote(options.signedJar));
if (!options.tsaUrl.isEmpty())
- jarSignerTool += QString::fromLatin1(" -tsa %1").arg(shellQuote(options.tsaUrl));
+ jarSignerTool += QLatin1String(" -tsa %1").arg(shellQuote(options.tsaUrl));
if (!options.tsaCert.isEmpty())
- jarSignerTool += QString::fromLatin1(" -tsacert %1").arg(shellQuote(options.tsaCert));
+ jarSignerTool += QLatin1String(" -tsacert %1").arg(shellQuote(options.tsaCert));
if (options.internalSf)
jarSignerTool += QLatin1String(" -internalsf");
@@ -2569,29 +2528,39 @@ bool jarSignerSignPackage(const Options &options)
if (options.protectedAuthenticationPath)
jarSignerTool += QLatin1String(" -protected");
- jarSignerTool += QString::fromLatin1(" %1 %2")
- .arg(apkPath(options, UnsignedAPK))
- .arg(shellQuote(options.keyStoreAlias));
+ auto signPackage = [&](const QString &file) {
+ fprintf(stdout, "Signing file %s\n", qPrintable(file));
+ fflush(stdout);
+ auto command = jarSignerTool + QLatin1String(" %1 %2")
+ .arg(file)
+ .arg(shellQuote(options.keyStoreAlias));
- FILE *jarSignerCommand = openProcess(jarSignerTool);
- if (jarSignerCommand == 0) {
- fprintf(stderr, "Couldn't run jarsigner.\n");
- return false;
- }
+ FILE *jarSignerCommand = openProcess(command);
+ if (jarSignerCommand == 0) {
+ fprintf(stderr, "Couldn't run jarsigner.\n");
+ return false;
+ }
- if (options.verbose) {
- char buffer[512];
- while (fgets(buffer, sizeof(buffer), jarSignerCommand) != 0)
- fprintf(stdout, "%s", buffer);
- }
+ if (options.verbose) {
+ char buffer[512];
+ while (fgets(buffer, sizeof(buffer), jarSignerCommand) != 0)
+ fprintf(stdout, "%s", buffer);
+ }
- int errorCode = pclose(jarSignerCommand);
- if (errorCode != 0) {
- fprintf(stderr, "jarsigner command failed.\n");
- if (!options.verbose)
- fprintf(stderr, " -- Run with --verbose for more information.\n");
+ int errorCode = pclose(jarSignerCommand);
+ if (errorCode != 0) {
+ fprintf(stderr, "jarsigner command failed.\n");
+ if (!options.verbose)
+ fprintf(stderr, " -- Run with --verbose for more information.\n");
+ return false;
+ }
+ return true;
+ };
+
+ if (!signPackage(packagePath(options, UnsignedAPK)))
+ return false;
+ if (options.buildAAB && !signPackage(packagePath(options, AAB)))
return false;
- }
QString zipAlignTool = options.sdkPath + QLatin1String("/tools/zipalign");
#if defined(Q_OS_WIN32)
@@ -2609,11 +2578,11 @@ bool jarSignerSignPackage(const Options &options)
}
}
- zipAlignTool = QString::fromLatin1("%1%2 -f 4 %3 %4")
- .arg(shellQuote(zipAlignTool))
- .arg(options.verbose ? QString::fromLatin1(" -v") : QString())
- .arg(apkPath(options, UnsignedAPK))
- .arg(apkPath(options, SignedAPK));
+ zipAlignTool = QLatin1String("%1%2 -f 4 %3 %4")
+ .arg(shellQuote(zipAlignTool),
+ options.verbose ? QLatin1String(" -v") : QLatin1String(),
+ packagePath(options, UnsignedAPK),
+ packagePath(options, SignedAPK));
FILE *zipAlignCommand = openProcess(zipAlignTool);
if (zipAlignCommand == 0) {
@@ -2625,7 +2594,7 @@ bool jarSignerSignPackage(const Options &options)
while (fgets(buffer, sizeof(buffer), zipAlignCommand) != 0)
fprintf(stdout, "%s", buffer);
- errorCode = pclose(zipAlignCommand);
+ int errorCode = pclose(zipAlignCommand);
if (errorCode != 0) {
fprintf(stderr, "zipalign command failed.\n");
if (!options.verbose)
@@ -2633,7 +2602,7 @@ bool jarSignerSignPackage(const Options &options)
return false;
}
- return QFile::remove(apkPath(options, UnsignedAPK));
+ return QFile::remove(packagePath(options, UnsignedAPK));
}
bool signPackage(const Options &options)
@@ -2664,11 +2633,11 @@ bool signPackage(const Options &options)
}
}
- zipAlignTool = QString::fromLatin1("%1%2 -f 4 %3 %4")
- .arg(shellQuote(zipAlignTool))
- .arg(options.verbose ? QString::fromLatin1(" -v") : QString())
- .arg(apkPath(options, UnsignedAPK))
- .arg(apkPath(options, SignedAPK));
+ zipAlignTool = QLatin1String("%1%2 -f 4 %3 %4")
+ .arg(shellQuote(zipAlignTool),
+ options.verbose ? QLatin1String(" -v") : QLatin1String(),
+ packagePath(options, UnsignedAPK),
+ packagePath(options, SignedAPK));
FILE *zipAlignCommand = openProcess(zipAlignTool);
if (zipAlignCommand == 0) {
@@ -2688,23 +2657,23 @@ bool signPackage(const Options &options)
return false;
}
- QString apkSignerCommandLine = QString::fromLatin1("%1 sign --ks %2")
- .arg(shellQuote(apksignerTool)).arg(shellQuote(options.keyStore));
+ QString apkSignerCommandLine = QLatin1String("%1 sign --ks %2")
+ .arg(shellQuote(apksignerTool), shellQuote(options.keyStore));
if (!options.keyStorePassword.isEmpty())
- apkSignerCommandLine += QString::fromLatin1(" --ks-pass pass:%1").arg(shellQuote(options.keyStorePassword));
+ apkSignerCommandLine += QLatin1String(" --ks-pass pass:%1").arg(shellQuote(options.keyStorePassword));
if (!options.keyStoreAlias.isEmpty())
- apkSignerCommandLine += QString::fromLatin1(" --ks-key-alias %1").arg(shellQuote(options.keyStoreAlias));
+ apkSignerCommandLine += QLatin1String(" --ks-key-alias %1").arg(shellQuote(options.keyStoreAlias));
if (!options.keyPass.isEmpty())
- apkSignerCommandLine += QString::fromLatin1(" --key-pass pass:%1").arg(shellQuote(options.keyPass));
+ apkSignerCommandLine += QLatin1String(" --key-pass pass:%1").arg(shellQuote(options.keyPass));
if (options.verbose)
apkSignerCommandLine += QLatin1String(" --verbose");
- apkSignerCommandLine += QString::fromLatin1(" %1")
- .arg(apkPath(options, SignedAPK));
+ apkSignerCommandLine += QLatin1String(" %1")
+ .arg(packagePath(options, SignedAPK));
auto apkSignerRunner = [&] {
FILE *apkSignerCommand = openProcess(apkSignerCommandLine);
@@ -2731,111 +2700,11 @@ bool signPackage(const Options &options)
if (!apkSignerRunner())
return false;
- apkSignerCommandLine = QString::fromLatin1("%1 verify --verbose %2")
- .arg(shellQuote(apksignerTool)).arg(apkPath(options, SignedAPK));
+ apkSignerCommandLine = QLatin1String("%1 verify --verbose %2")
+ .arg(shellQuote(apksignerTool), packagePath(options, SignedAPK));
// Verify the package and remove the unsigned apk
- return apkSignerRunner() && QFile::remove(apkPath(options, UnsignedAPK));
-}
-
-bool copyGdbServer(const Options &options)
-{
- if (options.verbose)
- fprintf(stdout, "Copying gdbserver into package.\n");
-
- QString architectureSubDirectory;
- if (options.architecture == QLatin1String("arm64-v8a"))
- architectureSubDirectory = QLatin1String("android-arm64");
- else if (options.architecture.startsWith(QLatin1String("arm")))
- architectureSubDirectory = QLatin1String("android-arm");
- else
- architectureSubDirectory = QLatin1String("android-") + options.architecture;
-
- QString gdbServerBinary = options.ndkPath
- + QLatin1String("/prebuilt/")
- + architectureSubDirectory
- + QLatin1String("/gdbserver/gdbserver");
- if (!QFile::exists(gdbServerBinary)) {
- fprintf(stderr, "Cannot find gdbserver at %s.\n", qPrintable(gdbServerBinary));
- return false;
- }
-
- QString gdbServerTarget = options.outputDirectory + QLatin1String("/libs/") + options.architecture;
-
- if (!copyFileIfNewer(gdbServerBinary,
- gdbServerTarget + QLatin1String("/gdbserver"),
- options.verbose)
- || !copyFileIfNewer(gdbServerBinary,
- gdbServerTarget + QLatin1String("/libgdbserver.so"),
- options.verbose)) {
- return false;
- }
-
- QString addedByAndroidDeployQtPath = options.outputDirectory + QLatin1String("/assets/--Added-by-androiddeployqt--/");
- if (!QDir().mkpath(addedByAndroidDeployQtPath)) {
- fprintf(stderr, "Failed to create directory '%s'", qPrintable(addedByAndroidDeployQtPath));
- return false;
- }
- QFile f(addedByAndroidDeployQtPath + QLatin1String("debugger.command"));
- if (!f.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Failed to create directory '%s'", qPrintable(addedByAndroidDeployQtPath));
- return false;
- }
- f.write("lib/libgdbserver.so --multi +");
- f.close();
-
- return true;
-}
-
-bool generateAssetsFileList(const Options &options)
-{
- if (options.verbose)
- fprintf(stdout, "Pregenerating entry list for assets file engine.\n");
-
- QString assetsPath = options.outputDirectory + QLatin1String("/assets/");
- QString addedByAndroidDeployQtPath = assetsPath + QLatin1String("--Added-by-androiddeployqt--/");
- if (!QDir().mkpath(addedByAndroidDeployQtPath)) {
- fprintf(stderr, "Failed to create directory '%s'", qPrintable(addedByAndroidDeployQtPath));
- return false;
- }
-
- QFile file(addedByAndroidDeployQtPath + QLatin1String("/qt_cache_pregenerated_file_list"));
- if (file.open(QIODevice::WriteOnly)) {
- QDirIterator dirIterator(assetsPath,
- QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot,
- QDirIterator::Subdirectories);
-
- QHash<QString, QStringList> directoryContents;
- while (dirIterator.hasNext()) {
- const QString name = dirIterator.next().mid(assetsPath.length());
-
- int slashIndex = name.lastIndexOf(QLatin1Char('/'));
- QString pathName = slashIndex >= 0 ? name.left(slashIndex) : QString::fromLatin1("/");
- QString fileName = slashIndex >= 0 ? name.mid(pathName.length() + 1) : name;
-
- if (!fileName.isEmpty() && dirIterator.fileInfo().isDir() && !fileName.endsWith(QLatin1Char('/')))
- fileName += QLatin1Char('/');
-
- if (fileName.isEmpty() && !directoryContents.contains(pathName))
- directoryContents[pathName] = QStringList();
- else if (!fileName.isEmpty())
- directoryContents[pathName].append(fileName);
- }
-
- QDataStream stream(&file);
- stream.setVersion(QDataStream::Qt_5_3);
- for (auto it = directoryContents.cbegin(), end = directoryContents.cend(); it != end; ++it) {
- const QStringList &entryList = it.value();
- stream << it.key() << entryList.size();
- for (const QString &entry : entryList)
- stream << entry;
- }
- } else {
- fprintf(stderr, "Pregenerating entry list for assets file engine failed!\n");
- return false;
- }
-
- return true;
+ return apkSignerRunner() && QFile::remove(packagePath(options, UnsignedAPK));
}
enum ErrorCode
@@ -2848,8 +2717,6 @@ enum ErrorCode
CannotCopyGnuStl = 5,
CannotCopyQtFiles = 6,
CannotFindApplicationBinary = 7,
- CannotCopyGdbServer = 8,
- CannotStripLibraries = 9,
CannotCopyAndroidExtraLibs = 10,
CannotCopyAndroidSources = 11,
CannotUpdateAndroidFiles = 12,
@@ -2857,8 +2724,9 @@ enum ErrorCode
CannotBuildAndroidProject = 14,
CannotSignPackage = 15,
CannotInstallApk = 16,
- CannotGenerateAssetsFileList = 18,
- CannotCopyAndroidExtraResources = 19
+ CannotCopyAndroidExtraResources = 19,
+ CannotCopyApk = 20,
+ CannotCreateRcc = 21
};
int main(int argc, char *argv[])
@@ -2896,27 +2764,8 @@ int main(int argc, char *argv[])
: "No"
);
- if (options.auxMode) {
- if (!readDependencies(&options))
- return CannotReadDependencies;
- if (!copyQtFiles(&options))
- return CannotCopyQtFiles;
- if (!copyAndroidExtraResources(options))
- return CannotCopyAndroidExtraResources;
- if (!copyAndroidExtraLibs(options))
- return CannotCopyAndroidExtraLibs;
- if (!stripLibraries(options))
- return CannotStripLibraries;
- if (!updateAndroidFiles(options))
- return CannotUpdateAndroidFiles;
- if (options.generateAssetsFileList && !generateAssetsFileList(options))
- return CannotGenerateAssetsFileList;
- return 0;
- }
-
- if (options.build) {
- if (options.gradle)
- cleanAndroidFiles(options);
+ if (options.build && !options.auxMode) {
+ cleanAndroidFiles(options);
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Cleaned Android file\n", options.timer.elapsed());
@@ -2927,72 +2776,76 @@ int main(int argc, char *argv[])
fprintf(stdout, "[TIMING] %d ms: Copied Android template\n", options.timer.elapsed());
}
- if (!readDependencies(&options))
- return CannotReadDependencies;
-
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
+ for (auto it = options.architectures.constBegin(); it != options.architectures.constEnd(); ++it) {
+ options.clear(it.key());
- if (options.deploymentMechanism != Options::Ministro && !copyStdCpp(&options))
- return CannotCopyGnuStl;
+ if (!readDependencies(&options))
+ return CannotReadDependencies;
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied GNU STL\n", options.timer.elapsed());
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
- if (!copyQtFiles(&options))
- return CannotCopyQtFiles;
+ if (!copyQtFiles(&options))
+ return CannotCopyQtFiles;
- if (options.build) {
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Copied Qt files\n", options.timer.elapsed());
- if (!containsApplicationBinary(options))
- return CannotFindApplicationBinary;
+ if (!copyAndroidExtraLibs(&options))
+ return CannotCopyAndroidExtraLibs;
if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Checked for application binary\n", options.timer.elapsed());
+ fprintf(stdout, "[TIMING] %d ms: Copied extra libs\n", options.timer.elapsed());
- bool needToCopyGdbServer = options.gdbServer == Options::True
- || (options.gdbServer == Options::Auto && !options.releasePackage);
- if (needToCopyGdbServer && !copyGdbServer(options))
- return CannotCopyGdbServer;
+ if (!copyAndroidExtraResources(&options))
+ return CannotCopyAndroidExtraResources;
if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied GDB server\n", options.timer.elapsed());
+ fprintf(stdout, "[TIMING] %d ms: Copied extra resources\n", options.timer.elapsed());
- if (!copyAndroidExtraLibs(options))
- return CannotCopyAndroidExtraLibs;
+ if (!options.auxMode) {
+ if (options.deploymentMechanism != Options::Ministro && !copyStdCpp(&options))
+ return CannotCopyGnuStl;
+
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied GNU STL\n", options.timer.elapsed());
+ }
+
+ if (!containsApplicationBinary(&options))
+ return CannotFindApplicationBinary;
if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied extra libs\n", options.timer.elapsed());
+ fprintf(stdout, "[TIMING] %d ms: Checked for application binary\n", options.timer.elapsed());
- if (!copyAndroidExtraResources(options))
- return CannotCopyAndroidExtraResources;
+ if (options.deploymentMechanism != Options::Ministro) {
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Bundled Qt libs\n", options.timer.elapsed());
+ }
+ }
+ if (!createRcc(options))
+ return CannotCreateRcc;
+
+ if (options.auxMode) {
+ if (!updateAndroidFiles(options))
+ return CannotUpdateAndroidFiles;
+ return 0;
+ }
+
+
+ if (options.build) {
if (!copyAndroidSources(options))
return CannotCopyAndroidSources;
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Copied android sources\n", options.timer.elapsed());
- if (!stripLibraries(options))
- return CannotStripLibraries;
-
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Stripped libraries\n", options.timer.elapsed());
-
if (!updateAndroidFiles(options))
return CannotUpdateAndroidFiles;
- if (options.generateAssetsFileList && !generateAssetsFileList(options))
- return CannotGenerateAssetsFileList;
-
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Updated files\n", options.timer.elapsed());
- if (!options.gradle && !createAndroidProject(options))
- return CannotCreateAndroidProject;
-
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Created project\n", options.timer.elapsed());
@@ -3005,6 +2858,9 @@ int main(int argc, char *argv[])
if (!options.keyStore.isEmpty() && !signPackage(options))
return CannotSignPackage;
+ if (!options.apkPath.isEmpty() && !copyPackage(options))
+ return CannotCopyApk;
+
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Signed package\n", options.timer.elapsed());
}
@@ -3020,7 +2876,7 @@ int main(int argc, char *argv[])
if (options.installApk)
fprintf(stdout, " -- It can now be run from the selected device/emulator.\n");
- fprintf(stdout, " -- File: %s\n", qPrintable(apkPath(options, options.keyStore.isEmpty() ? UnsignedAPK
+ fprintf(stdout, " -- File: %s\n", qPrintable(packagePath(options, options.keyStore.isEmpty() ? UnsignedAPK
: SignedAPK)));
fflush(stdout);
return 0;
diff --git a/src/tools/androidtestrunner/androidtestrunner.pro b/src/tools/androidtestrunner/androidtestrunner.pro
new file mode 100644
index 0000000000..641d3e0003
--- /dev/null
+++ b/src/tools/androidtestrunner/androidtestrunner.pro
@@ -0,0 +1,13 @@
+option(host_build)
+CONFIG += console
+
+SOURCES += \
+ main.cpp
+
+# Required for declarations of popen/pclose on Windows
+windows: QMAKE_CXXFLAGS += -U__STRICT_ANSI__
+
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+DEFINES += QT_NO_FOREACH
+
+load(qt_app)
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
new file mode 100644
index 0000000000..f61d407d4a
--- /dev/null
+++ b/src/tools/androidtestrunner/main.cpp
@@ -0,0 +1,490 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QDir>
+#include <QHash>
+#include <QRegExp>
+#include <QSystemSemaphore>
+#include <QXmlStreamReader>
+
+#include <algorithm>
+#include <chrono>
+#include <functional>
+#include <thread>
+
+#ifdef Q_CC_MSVC
+#define popen _popen
+#define QT_POPEN_READ "rb"
+#define pclose _pclose
+#else
+#define QT_POPEN_READ "r"
+#endif
+
+struct Options
+{
+ bool helpRequested = false;
+ bool verbose = false;
+ std::chrono::seconds timeout{300}; // 5minutes
+ QString androidDeployQtCommand;
+ QString buildPath;
+ QString adbCommand{QStringLiteral("adb")};
+ QString makeCommand;
+ QString package;
+ QString activity;
+ QStringList testArgsList;
+ QHash<QString, QString> outFiles;
+ QString testArgs;
+ QString apkPath;
+ QHash<QString, std::function<bool(const QByteArray &)>> checkFiles = {
+ {QStringLiteral("txt"), [](const QByteArray &data) -> bool {
+ return data.indexOf("\nFAIL! : ") < 0;
+ }},
+ {QStringLiteral("csv"), [](const QByteArray &/*data*/) -> bool {
+ // It seems csv is broken
+ return true;
+ }},
+ {QStringLiteral("xml"), [](const QByteArray &data) -> bool {
+ QXmlStreamReader reader{data};
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.isStartElement() && reader.name() == QStringLiteral("Incident") &&
+ reader.attributes().value(QStringLiteral("type")).toString() == QStringLiteral("fail")) {
+ return false;
+ }
+ }
+ return true;
+ }},
+ {QStringLiteral("lightxml"), [](const QByteArray &data) -> bool {
+ return data.indexOf("\n<Incident type=\"fail\" ") < 0;
+ }},
+ {QStringLiteral("xunitxml"), [](const QByteArray &data) -> bool {
+ QXmlStreamReader reader{data};
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.isStartElement() && reader.name() == QStringLiteral("testcase") &&
+ reader.attributes().value(QStringLiteral("result")).toString() == QStringLiteral("fail")) {
+ return false;
+ }
+ }
+ return true;
+ }},
+ {QStringLiteral("teamcity"), [](const QByteArray &data) -> bool {
+ return data.indexOf("' message='Failure! |[Loc: ") < 0;
+ }},
+ {QStringLiteral("tap"), [](const QByteArray &data) -> bool {
+ return data.indexOf("\nnot ok ") < 0;
+ }},
+ };
+};
+
+static Options g_options;
+
+static bool execCommand(const QString &command, QByteArray *output = nullptr, bool verbose = false)
+{
+ if (verbose)
+ fprintf(stdout, "Execute %s\n", command.toUtf8().constData());
+ FILE *process = popen(command.toUtf8().constData(), QT_POPEN_READ);
+
+ if (!process) {
+ fprintf(stderr, "Cannot execute command %s", qPrintable(command));
+ return false;
+ }
+ char buffer[512];
+ while (fgets(buffer, sizeof(buffer), process)) {
+ if (output)
+ output->append(buffer);
+ if (verbose)
+ fprintf(stdout, "%s", buffer);
+ }
+ return pclose(process) == 0;
+}
+
+// Copy-pasted from qmake/library/ioutil.cpp
+inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
+{
+ for (int x = arg.length() - 1; x >= 0; --x) {
+ ushort c = arg.unicode()[x].unicode();
+ if ((c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7))))
+ return true;
+ }
+ return false;
+}
+
+static QString shellQuoteUnix(const QString &arg)
+{
+ // Chars that should be quoted (TM). This includes:
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
+ 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
+ }; // 0-32 \'"$`<>|;&(){}*?#!~[]
+
+ if (!arg.length())
+ return QStringLiteral("\"\"");
+
+ QString ret(arg);
+ if (hasSpecialChars(ret, iqm)) {
+ ret.replace(QLatin1Char('\''), QStringLiteral("'\\''"));
+ ret.prepend(QLatin1Char('\''));
+ ret.append(QLatin1Char('\''));
+ }
+ return ret;
+}
+
+static QString shellQuoteWin(const QString &arg)
+{
+ // Chars that should be quoted (TM). This includes:
+ // - control chars & space
+ // - the shell meta chars "&()<>^|
+ // - the potential separators ,;=
+ static const uchar iqm[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x45, 0x13, 0x00, 0x78,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10
+ };
+
+ if (!arg.length())
+ return QStringLiteral("\"\"");
+
+ QString ret(arg);
+ if (hasSpecialChars(ret, iqm)) {
+ // Quotes are escaped and their preceding backslashes are doubled.
+ // It's impossible to escape anything inside a quoted string on cmd
+ // level, so the outer quoting must be "suspended".
+ ret.replace(QRegExp(QStringLiteral("(\\\\*)\"")), QStringLiteral("\"\\1\\1\\^\"\""));
+ // The argument must not end with a \ since this would be interpreted
+ // as escaping the quote -- rather put the \ behind the quote: e.g.
+ // rather use "foo"\ than "foo\"
+ int i = ret.length();
+ while (i > 0 && ret.at(i - 1) == QLatin1Char('\\'))
+ --i;
+ ret.insert(i, QLatin1Char('"'));
+ ret.prepend(QLatin1Char('"'));
+ }
+ return ret;
+}
+
+static QString shellQuote(const QString &arg)
+{
+ if (QDir::separator() == QLatin1Char('\\'))
+ return shellQuoteWin(arg);
+ else
+ return shellQuoteUnix(arg);
+}
+
+static bool parseOptions()
+{
+ QStringList arguments = QCoreApplication::arguments();
+ int i = 1;
+ for (; i < arguments.size(); ++i) {
+ const QString &argument = arguments.at(i);
+ if (argument.compare(QStringLiteral("--androiddeployqt"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.androidDeployQtCommand = arguments.at(++i).trimmed();
+ } else if (argument.compare(QStringLiteral("--adb"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.adbCommand = arguments.at(++i);
+ } else if (argument.compare(QStringLiteral("--path"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.buildPath = arguments.at(++i);
+ } else if (argument.compare(QStringLiteral("--make"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.makeCommand = arguments.at(++i);
+ } else if (argument.compare(QStringLiteral("--apk"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.apkPath = arguments.at(++i);
+ } else if (argument.compare(QStringLiteral("--activity"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.activity = arguments.at(++i);
+ } else if (argument.compare(QStringLiteral("--timeout"), Qt::CaseInsensitive) == 0) {
+ if (i + 1 == arguments.size())
+ g_options.helpRequested = true;
+ else
+ g_options.timeout = std::chrono::seconds{arguments.at(++i).toInt()};
+ } else if (argument.compare(QStringLiteral("--help"), Qt::CaseInsensitive) == 0) {
+ g_options.helpRequested = true;
+ } else if (argument.compare(QStringLiteral("--verbose"), Qt::CaseInsensitive) == 0) {
+ g_options.verbose = true;
+ } else if (argument.compare(QStringLiteral("--"), Qt::CaseInsensitive) == 0) {
+ ++i;
+ break;
+ } else {
+ g_options.testArgsList << arguments.at(i);
+ }
+ }
+ for (;i < arguments.size(); ++i)
+ g_options.testArgsList << arguments.at(i);
+
+ if (g_options.helpRequested || g_options.androidDeployQtCommand.isEmpty() || g_options.buildPath.isEmpty())
+ return false;
+
+ QString serial = qEnvironmentVariable("ANDROID_DEVICE_SERIAL");
+ if (!serial.isEmpty())
+ g_options.adbCommand += QStringLiteral(" -s %1").arg(serial);
+ return true;
+}
+
+static void printHelp()
+{// "012345678901234567890123456789012345678901234567890123456789012345678901"
+ fprintf(stderr, "Syntax: %s <options> -- [TESTARGS] \n"
+ "\n"
+ " Creates an Android package in a temp directory <destination> and\n"
+ " runs it on the default emulator/device or on the one specified by\n"
+ " \"ANDROID_DEVICE_SERIAL\" environment variable.\n\n"
+ " Mandatory arguments:\n"
+ " --androiddeployqt <androiddeployqt cmd>: The androiddeployqt:\n"
+ " path including its additional arguments.\n"
+ " --path <path>: The path where androiddeployqt will build the .apk.\n"
+ " Optional arguments:\n"
+ " --adb <adb cmd>: The Android ADB command. If missing the one from\n"
+ " $PATH will be used.\n"
+ " --activity <acitvity>: The Activity to run. If missing the first\n"
+ " activity from AndroidManifest.qml file will be used.\n"
+ " --timout <seconds>: Timeout to run the test.\n"
+ " Default is 5 minutes.\n"
+ " --make <make cmd>: make command, needed to install the qt library.\n"
+ " If make is missing make sure the --path is set.\n"
+ " --apk <apk path>: If the apk is specified and if exists, we'll skip\n"
+ " the package building.\n"
+ " -- arguments that will be passed to the test application.\n"
+ " --verbose: Prints out information during processing.\n"
+ " --help: Displays this information.\n\n",
+ qPrintable(QCoreApplication::arguments().at(0))
+ );
+}
+
+static QString packageNameFromAndroidManifest(const QString &androidManifestPath)
+{
+ QFile androidManifestXml(androidManifestPath);
+ if (androidManifestXml.open(QIODevice::ReadOnly)) {
+ QXmlStreamReader reader(&androidManifestXml);
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.isStartElement() && reader.name() == QStringLiteral("manifest"))
+ return reader.attributes().value(QStringLiteral("package")).toString();
+ }
+ }
+ return {};
+}
+
+static QString activityFromAndroidManifest(const QString &androidManifestPath)
+{
+ QFile androidManifestXml(androidManifestPath);
+ if (androidManifestXml.open(QIODevice::ReadOnly)) {
+ QXmlStreamReader reader(&androidManifestXml);
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.isStartElement() && reader.name() == QStringLiteral("activity"))
+ return reader.attributes().value(QStringLiteral("android:name")).toString();
+ }
+ }
+ return {};
+}
+
+static void setOutputFile(QString file, QString format)
+{
+ if (file.isEmpty())
+ file = QStringLiteral("-");
+ if (format.isEmpty())
+ format = QStringLiteral("txt");
+
+ g_options.outFiles[format] = file;
+}
+
+static bool parseTestArgs()
+{
+ QRegExp newLoggingFormat{QStringLiteral("(.*),(txt|csv|xunitxml|xml|lightxml|teamcity|tap)")};
+ QRegExp oldFormats{QStringLiteral("-(txt|csv|xunitxml|xml|lightxml|teamcity|tap)")};
+
+ QString file;
+ QString logType;
+ QString unhandledArgs;
+ for (int i = 0; i < g_options.testArgsList.size(); ++i) {
+ const QString &arg = g_options.testArgsList[i].trimmed();
+ if (arg == QStringLiteral("-o")) {
+ if (i >= g_options.testArgsList.size() - 1)
+ return false; // missing file argument
+
+ const auto &filePath = g_options.testArgsList[++i];
+ if (!newLoggingFormat.exactMatch(filePath)) {
+ file = filePath;
+ } else {
+ const auto capturedTexts = newLoggingFormat.capturedTexts();
+ setOutputFile(capturedTexts.at(1), capturedTexts.at(2));
+ }
+ } else if (oldFormats.exactMatch(arg)) {
+ logType = oldFormats.capturedTexts().at(1);
+ } else {
+ unhandledArgs += QStringLiteral(" %1").arg(arg);
+ }
+ }
+ if (g_options.outFiles.isEmpty() || !file.isEmpty() || !logType.isEmpty())
+ setOutputFile(file, logType);
+
+ for (const auto &format : g_options.outFiles.keys())
+ g_options.testArgs += QStringLiteral(" -o output.%1,%1").arg(format);
+
+ g_options.testArgs += unhandledArgs;
+ g_options.testArgs = QStringLiteral("shell am start -e applicationArguments \\\"%1\\\" -n %2/%3").arg(shellQuote(g_options.testArgs.trimmed()),
+ g_options.package,
+ g_options.activity);
+ return true;
+}
+
+static bool isRunning() {
+ QByteArray output;
+ if (!execCommand(QStringLiteral("%1 shell \"ps | grep ' %2'\"").arg(g_options.adbCommand,
+ shellQuote(g_options.package)), &output)) {
+
+ return false;
+ }
+ return output.indexOf(" " + g_options.package.toUtf8()) > -1;
+}
+
+static bool waitToFinish()
+{
+ using clock = std::chrono::system_clock;
+ auto start = clock::now();
+ // wait to start
+ while (!isRunning()) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ if ((clock::now() - start) > std::chrono::seconds{10})
+ return false;
+ }
+
+ // Wait to finish
+ while (isRunning()) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ if ((clock::now() - start) > g_options.timeout)
+ return false;
+ }
+ return true;
+}
+
+
+static bool pullFiles()
+{
+ bool ret = true;
+ for (auto it = g_options.outFiles.constBegin(); it != g_options.outFiles.end(); ++it) {
+ QByteArray output;
+ if (!execCommand(QStringLiteral("%1 shell run-as %2 cat files/output.%3")
+ .arg(g_options.adbCommand, g_options.package, it.key()), &output)) {
+ return false;
+ }
+ auto checkerIt = g_options.checkFiles.find(it.key());
+ ret = ret && checkerIt != g_options.checkFiles.end() && checkerIt.value()(output);
+ if (it.value() == QStringLiteral("-")){
+ fprintf(stdout, "%s", output.constData());
+ fflush(stdout);
+ } else {
+ QFile out{it.value()};
+ if (!out.open(QIODevice::WriteOnly))
+ return false;
+ out.write(output);
+ }
+ }
+ return ret;
+}
+
+struct RunnerLocker
+{
+ RunnerLocker()
+ {
+ runner.acquire();
+ }
+ ~RunnerLocker()
+ {
+ runner.release();
+ }
+ QSystemSemaphore runner{QStringLiteral("androidtestrunner"), 1, QSystemSemaphore::Open};
+};
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+ if (!parseOptions()) {
+ printHelp();
+ return 1;
+ }
+
+ RunnerLocker lock; // do not install or run packages while another test is running
+ if (!g_options.apkPath.isEmpty() && QFile::exists(g_options.apkPath)) {
+ if (!execCommand(QStringLiteral("%1 install -r %2")
+ .arg(g_options.adbCommand, g_options.apkPath), nullptr, g_options.verbose)) {
+ return 1;
+ }
+ } else {
+ if (!g_options.makeCommand.isEmpty()) {
+ // we need to run make INSTALL_ROOT=path install to install the application file(s) first
+ if (!execCommand(QStringLiteral("%1 INSTALL_ROOT=%2 install")
+ .arg(g_options.makeCommand, QDir::toNativeSeparators(g_options.buildPath)), nullptr, g_options.verbose)) {
+ return 1;
+ }
+ }
+
+ // Run androiddeployqt
+ static auto verbose = g_options.verbose ? QStringLiteral("--verbose") : QStringLiteral();
+ if (!execCommand(QStringLiteral("%1 %3 --reinstall --output %2 --apk %4").arg(g_options.androidDeployQtCommand,
+ g_options.buildPath,
+ verbose,
+ g_options.apkPath), nullptr, true)) {
+ return 1;
+ }
+ }
+
+ QString manifest = g_options.buildPath + QStringLiteral("/AndroidManifest.xml");
+ g_options.package = packageNameFromAndroidManifest(manifest);
+ if (g_options.activity.isEmpty())
+ g_options.activity = activityFromAndroidManifest(manifest);
+
+ // parseTestArgs depends on g_options.package
+ if (!parseTestArgs())
+ return 1;
+
+ // start the tests
+ bool res = execCommand(QStringLiteral("%1 %2").arg(g_options.adbCommand, g_options.testArgs),
+ nullptr, g_options.verbose) && waitToFinish();
+ if (res)
+ res &= pullFiles();
+ res &= execCommand(QStringLiteral("%1 uninstall %2").arg(g_options.adbCommand, g_options.package),
+ nullptr, g_options.verbose);
+ fflush(stdout);
+ return res ? 0 : 1;
+}
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index 83e44ff9a4..09a1c68001 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -19,8 +19,6 @@ DEFINES += \
QT_NO_FOREACH \
QT_NO_CAST_FROM_ASCII
-DEFINES -= QT_EVAL
-
SOURCES += \
../../corelib/codecs/qlatincodec.cpp \
../../corelib/codecs/qtextcodec.cpp \
@@ -44,6 +42,7 @@ SOURCES += \
../../corelib/io/qfsfileengine.cpp \
../../corelib/io/qfsfileengine_iterator.cpp \
../../corelib/io/qiodevice.cpp \
+ ../../corelib/io/qipaddress.cpp \
../../corelib/io/qfiledevice.cpp \
../../corelib/io/qresource.cpp \
../../corelib/io/qtemporarydir.cpp \
@@ -52,11 +51,17 @@ SOURCES += \
../../corelib/io/qstandardpaths.cpp \
../../corelib/io/qloggingcategory.cpp \
../../corelib/io/qloggingregistry.cpp \
+ ../../corelib/io/qurl.cpp \
+ ../../corelib/io/qurlidna.cpp \
+ ../../corelib/io/qurlquery.cpp \
+ ../../corelib/io/qurlrecode.cpp \
../../corelib/kernel/qcoreapplication.cpp \
../../corelib/kernel/qcoreglobaldata.cpp \
../../corelib/kernel/qmetatype.cpp \
../../corelib/kernel/qvariant.cpp \
../../corelib/kernel/qsystemerror.cpp \
+ ../../corelib/kernel/qsharedmemory.cpp \
+ ../../corelib/kernel/qsystemsemaphore.cpp \
../../corelib/plugin/quuid.cpp \
../../corelib/serialization/qdatastream.cpp \
../../corelib/serialization/qjson.cpp \
@@ -69,36 +74,46 @@ SOURCES += \
../../corelib/serialization/qtextstream.cpp \
../../corelib/serialization/qxmlutils.cpp \
../../corelib/serialization/qxmlstream.cpp \
- ../../corelib/tools/qbitarray.cpp \
- ../../corelib/tools/qbytearray.cpp \
+ ../../corelib/text/qbytearray.cpp \
+ ../../corelib/text/qbytearraylist.cpp \
+ ../../corelib/text/qbytearraymatcher.cpp \
+ ../../corelib/text/qlocale.cpp \
+ ../../corelib/text/qlocale_tools.cpp \
+ ../../corelib/text/qregexp.cpp \
+ ../../corelib/text/qstring.cpp \
+ ../../corelib/text/qstringbuilder.cpp \
+ ../../corelib/text/qstring_compat.cpp \
+ ../../corelib/text/qstringlist.cpp \
+ ../../corelib/text/qstringview.cpp \
+ ../../corelib/text/qvsnprintf.cpp \
+ ../../corelib/time/qcalendar.cpp \
+ ../../corelib/time/qdatetime.cpp \
+ ../../corelib/time/qgregoriancalendar.cpp \
+ ../../corelib/time/qromancalendar.cpp \
../../corelib/tools/qarraydata.cpp \
- ../../corelib/tools/qbytearraymatcher.cpp \
+ ../../corelib/tools/qbitarray.cpp \
../../corelib/tools/qcommandlineparser.cpp \
../../corelib/tools/qcommandlineoption.cpp \
../../corelib/tools/qcryptographichash.cpp \
- ../../corelib/tools/qdatetime.cpp \
../../corelib/tools/qhash.cpp \
../../corelib/tools/qlist.cpp \
- ../../corelib/tools/qlinkedlist.cpp \
- ../../corelib/tools/qlocale.cpp \
- ../../corelib/tools/qlocale_tools.cpp \
../../corelib/tools/qmap.cpp \
- ../../corelib/tools/qregexp.cpp \
../../corelib/tools/qringbuffer.cpp \
../../corelib/tools/qpoint.cpp \
../../corelib/tools/qrect.cpp \
../../corelib/tools/qsize.cpp \
../../corelib/tools/qline.cpp \
- ../../corelib/tools/qstring.cpp \
- ../../corelib/tools/qstringbuilder.cpp \
- ../../corelib/tools/qstring_compat.cpp \
- ../../corelib/tools/qstringlist.cpp \
../../corelib/tools/qversionnumber.cpp \
- ../../corelib/tools/qvsnprintf.cpp \
../../xml/dom/qdom.cpp \
../../xml/sax/qxml.cpp
unix:SOURCES += ../../corelib/kernel/qcore_unix.cpp \
+ ../../corelib/kernel/qsharedmemory_posix.cpp \
+ ../../corelib/kernel/qsharedmemory_systemv.cpp \
+ ../../corelib/kernel/qsharedmemory_unix.cpp \
+ ../../corelib/kernel/qsystemsemaphore_posix.cpp \
+ ../../corelib/kernel/qsystemsemaphore_systemv.cpp \
+ ../../corelib/kernel/qsystemsemaphore_unix.cpp \
../../corelib/io/qfilesystemengine_unix.cpp \
../../corelib/io/qfilesystemiterator_unix.cpp \
../../corelib/io/qfsfileengine_unix.cpp
@@ -108,12 +123,15 @@ win32:SOURCES += ../../corelib/global/qoperatingsystemversion_win.cpp \
../../corelib/io/qfilesystemiterator_win.cpp \
../../corelib/io/qfsfileengine_win.cpp \
../../corelib/kernel/qcoreapplication_win.cpp \
+ ../../corelib/kernel/qsharedmemory_win.cpp \
+ ../../corelib/kernel/qsystemsemaphore_win.cpp \
../../corelib/plugin/qsystemlibrary.cpp \
mac {
SOURCES += \
../../corelib/kernel/qcoreapplication_mac.cpp \
../../corelib/kernel/qcore_mac.cpp
+
OBJECTIVE_SOURCES += \
../../corelib/global/qoperatingsystemversion_darwin.mm \
../../corelib/kernel/qcore_mac_objc.mm \
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 0640e1b603..6a74e739e6 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -518,10 +518,15 @@ void Generator::generateCode()
}
}
+//
+// Generate meta object link to parent meta objects
+//
+
if (!extraList.isEmpty()) {
- fprintf(out, "static const QMetaObject * const qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
+ fprintf(out, "static const QMetaObject::SuperData qt_meta_extradata_%s[] = {\n",
+ qualifiedClassNameIdentifier.constData());
for (int i = 0; i < extraList.count(); ++i) {
- fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData());
+ fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", extraList.at(i).constData());
}
fprintf(out, " nullptr\n};\n\n");
}
@@ -537,7 +542,7 @@ void Generator::generateCode()
if (isQObject)
fprintf(out, " nullptr,\n");
else if (cdef->superclassList.size() && (!cdef->hasQGadget || knownGadgets.contains(purestSuperClass)))
- fprintf(out, " &%s::staticMetaObject,\n", purestSuperClass.constData());
+ fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
else
fprintf(out, " nullptr,\n");
fprintf(out, " qt_meta_stringdata_%s.data,\n"
@@ -1652,6 +1657,12 @@ void Generator::generatePluginMetaData()
jsonObjectToCbor(&map, o);
}
+ if (!cdef->pluginData.uri.isEmpty()) {
+ dev.nextItem("\"URI\"");
+ cbor_encode_int(&map, int(QtPluginMetaDataKeys::URI));
+ cbor_encode_text_string(&map, cdef->pluginData.uri.constData(), cdef->pluginData.uri.size());
+ }
+
// Add -M args from the command line:
for (auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it) {
const QJsonArray &a = it.value();
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index 134166580b..eae0353199 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -39,7 +39,7 @@ class Generator
ClassDef *cdef;
QVector<uint> meta_data;
public:
- Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = 0);
+ Generator(ClassDef *classDef, const QVector<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = nullptr);
void generateCode();
private:
bool registerableMetaType(const QByteArray &propertyType);
diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp
index 07c59d155f..7da8d94efc 100644
--- a/src/tools/moc/keywords.cpp
+++ b/src/tools/moc/keywords.cpp
@@ -30,12 +30,12 @@
// DO NOT EDIT.
static const short keyword_trans[][128] = {
- {0,0,0,0,0,0,0,0,0,561,558,0,0,0,0,0,
+ {0,0,0,0,0,0,0,0,0,568,565,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 561,252,559,562,8,38,239,560,25,26,236,234,30,235,27,237,
+ 568,252,566,569,8,38,239,567,25,26,236,234,30,235,27,237,
22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,21,8,8,8,8,8,8,8,8,8,31,564,32,238,8,
+ 8,21,8,8,8,8,8,8,8,8,8,31,571,32,238,8,
0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -116,7 +116,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,290,222,0,0,490,0,0,0,
+ 0,0,0,0,0,0,0,0,290,222,0,0,497,0,0,0,
0,0,0,0,55,0,0,330,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -155,7 +155,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,514,0,0,0,0,0,0,0,0,0,0,357,
+ 0,0,0,0,521,0,0,0,0,0,0,0,0,0,0,357,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -177,7 +177,7 @@ static const short keyword_trans[][128] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0,
- 567,567,567,567,567,567,567,567,567,567,0,0,0,0,0,0,
+ 574,574,574,574,574,574,574,574,574,574,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -336,7 +336,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,566,0,0,0,0,565,
+ 0,0,0,0,0,0,0,0,0,0,573,0,0,0,0,572,
0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -372,29 +372,29 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,487,0,0,0,300,0,0,0,0,0,0,0,0,0,0,
+ 0,494,0,0,0,300,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,468,417,401,409,373,0,477,0,0,0,0,364,358,
- 379,0,550,465,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,475,424,408,416,380,0,484,0,0,0,0,364,358,
+ 386,0,557,472,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,387,0,0,0,
- 0,0,380,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,394,0,0,0,
+ 0,0,387,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,504,0,0,0,0,0,381,
+ 0,0,0,0,0,0,0,0,0,511,0,0,0,0,0,388,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -403,7 +403,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,405,0,0,0,0,0,0,0,0,0,0,0,406,
+ 0,0,0,412,0,0,0,0,0,0,0,0,0,0,0,413,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -411,14 +411,14 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,413,0,0,0,0,0,0,0,0,0,0,0,414,
+ 0,0,0,420,0,0,0,0,0,0,0,0,0,0,0,421,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,447,425,0,0,430,0,0,0,439,0,0,
+ 0,0,0,0,0,454,432,0,0,437,0,0,0,446,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -426,7 +426,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,533,0,466,0,0,0,494,0,0,500,0,0,0,
+ 0,0,0,540,0,473,0,0,0,501,0,0,507,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -435,7 +435,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,479,0,526,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,486,0,533,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -443,7 +443,7 @@ static const short keyword_trans[][128] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 542,0,0,510,0,0,0,0,0,0,0,0,0,0,0,0,
+ 549,0,0,517,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
@@ -828,197 +828,204 @@ static const struct
{CHARACTER, 0, 65, 370, CHARACTER},
{CHARACTER, 0, 67, 371, CHARACTER},
{CHARACTER, 0, 69, 372, CHARACTER},
- {Q_NAMESPACE_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 65, 374, CHARACTER},
- {CHARACTER, 0, 68, 375, CHARACTER},
- {CHARACTER, 0, 71, 376, CHARACTER},
- {CHARACTER, 0, 69, 377, CHARACTER},
- {CHARACTER, 0, 84, 378, CHARACTER},
+ {Q_NAMESPACE_TOKEN, 0, 95, 373, CHARACTER},
+ {CHARACTER, 0, 69, 374, CHARACTER},
+ {CHARACTER, 0, 88, 375, CHARACTER},
+ {CHARACTER, 0, 80, 376, CHARACTER},
+ {CHARACTER, 0, 79, 377, CHARACTER},
+ {CHARACTER, 0, 82, 378, CHARACTER},
+ {CHARACTER, 0, 84, 379, CHARACTER},
+ {Q_NAMESPACE_EXPORT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 65, 381, CHARACTER},
+ {CHARACTER, 0, 68, 382, CHARACTER},
+ {CHARACTER, 0, 71, 383, CHARACTER},
+ {CHARACTER, 0, 69, 384, CHARACTER},
+ {CHARACTER, 0, 84, 385, CHARACTER},
{Q_GADGET_TOKEN, 0, 0, 0, CHARACTER},
{CHARACTER, 44, 0, 0, CHARACTER},
{CHARACTER, 45, 0, 0, CHARACTER},
- {CHARACTER, 0, 80, 382, CHARACTER},
- {CHARACTER, 0, 69, 383, CHARACTER},
- {CHARACTER, 0, 82, 384, CHARACTER},
- {CHARACTER, 0, 84, 385, CHARACTER},
- {CHARACTER, 0, 89, 386, CHARACTER},
+ {CHARACTER, 0, 80, 389, CHARACTER},
+ {CHARACTER, 0, 69, 390, CHARACTER},
+ {CHARACTER, 0, 82, 391, CHARACTER},
+ {CHARACTER, 0, 84, 392, CHARACTER},
+ {CHARACTER, 0, 89, 393, CHARACTER},
{Q_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 85, 388, CHARACTER},
- {CHARACTER, 0, 71, 389, CHARACTER},
- {CHARACTER, 0, 73, 390, CHARACTER},
- {CHARACTER, 0, 78, 391, CHARACTER},
- {CHARACTER, 0, 95, 392, CHARACTER},
- {CHARACTER, 0, 77, 393, CHARACTER},
- {CHARACTER, 0, 69, 394, CHARACTER},
- {CHARACTER, 0, 84, 395, CHARACTER},
- {CHARACTER, 0, 65, 396, CHARACTER},
- {CHARACTER, 0, 68, 397, CHARACTER},
- {CHARACTER, 0, 65, 398, CHARACTER},
- {CHARACTER, 0, 84, 399, CHARACTER},
- {CHARACTER, 0, 65, 400, CHARACTER},
+ {CHARACTER, 0, 85, 395, CHARACTER},
+ {CHARACTER, 0, 71, 396, CHARACTER},
+ {CHARACTER, 0, 73, 397, CHARACTER},
+ {CHARACTER, 0, 78, 398, CHARACTER},
+ {CHARACTER, 0, 95, 399, CHARACTER},
+ {CHARACTER, 0, 77, 400, CHARACTER},
+ {CHARACTER, 0, 69, 401, CHARACTER},
+ {CHARACTER, 0, 84, 402, CHARACTER},
+ {CHARACTER, 0, 65, 403, CHARACTER},
+ {CHARACTER, 0, 68, 404, CHARACTER},
+ {CHARACTER, 0, 65, 405, CHARACTER},
+ {CHARACTER, 0, 84, 406, CHARACTER},
+ {CHARACTER, 0, 65, 407, CHARACTER},
{Q_PLUGIN_METADATA_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 78, 402, CHARACTER},
- {CHARACTER, 0, 85, 403, CHARACTER},
- {CHARACTER, 0, 77, 404, CHARACTER},
+ {CHARACTER, 0, 78, 409, CHARACTER},
+ {CHARACTER, 0, 85, 410, CHARACTER},
+ {CHARACTER, 0, 77, 411, CHARACTER},
{Q_ENUM_TOKEN, 46, 0, 0, CHARACTER},
{Q_ENUMS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 78, 407, CHARACTER},
- {CHARACTER, 0, 83, 408, CHARACTER},
+ {CHARACTER, 0, 78, 414, CHARACTER},
+ {CHARACTER, 0, 83, 415, CHARACTER},
{Q_ENUM_NS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 76, 410, CHARACTER},
- {CHARACTER, 0, 65, 411, CHARACTER},
- {CHARACTER, 0, 71, 412, CHARACTER},
+ {CHARACTER, 0, 76, 417, CHARACTER},
+ {CHARACTER, 0, 65, 418, CHARACTER},
+ {CHARACTER, 0, 71, 419, CHARACTER},
{Q_FLAG_TOKEN, 47, 0, 0, CHARACTER},
{Q_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 78, 415, CHARACTER},
- {CHARACTER, 0, 83, 416, CHARACTER},
+ {CHARACTER, 0, 78, 422, CHARACTER},
+ {CHARACTER, 0, 83, 423, CHARACTER},
{Q_FLAG_NS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 69, 418, CHARACTER},
- {CHARACTER, 0, 67, 419, CHARACTER},
- {CHARACTER, 0, 76, 420, CHARACTER},
- {CHARACTER, 0, 65, 421, CHARACTER},
- {CHARACTER, 0, 82, 422, CHARACTER},
- {CHARACTER, 0, 69, 423, CHARACTER},
- {CHARACTER, 0, 95, 424, CHARACTER},
+ {CHARACTER, 0, 69, 425, CHARACTER},
+ {CHARACTER, 0, 67, 426, CHARACTER},
+ {CHARACTER, 0, 76, 427, CHARACTER},
+ {CHARACTER, 0, 65, 428, CHARACTER},
+ {CHARACTER, 0, 82, 429, CHARACTER},
+ {CHARACTER, 0, 69, 430, CHARACTER},
+ {CHARACTER, 0, 95, 431, CHARACTER},
{CHARACTER, 48, 0, 0, CHARACTER},
- {CHARACTER, 0, 76, 426, CHARACTER},
- {CHARACTER, 0, 65, 427, CHARACTER},
- {CHARACTER, 0, 71, 428, CHARACTER},
- {CHARACTER, 0, 83, 429, CHARACTER},
+ {CHARACTER, 0, 76, 433, CHARACTER},
+ {CHARACTER, 0, 65, 434, CHARACTER},
+ {CHARACTER, 0, 71, 435, CHARACTER},
+ {CHARACTER, 0, 83, 436, CHARACTER},
{Q_DECLARE_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 78, 431, CHARACTER},
- {CHARACTER, 0, 84, 432, CHARACTER},
- {CHARACTER, 0, 69, 433, CHARACTER},
- {CHARACTER, 0, 82, 434, CHARACTER},
- {CHARACTER, 0, 70, 435, CHARACTER},
- {CHARACTER, 0, 65, 436, CHARACTER},
- {CHARACTER, 0, 67, 437, CHARACTER},
- {CHARACTER, 0, 69, 438, CHARACTER},
- {Q_DECLARE_INTERFACE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 438, CHARACTER},
+ {CHARACTER, 0, 84, 439, CHARACTER},
{CHARACTER, 0, 69, 440, CHARACTER},
- {CHARACTER, 0, 84, 441, CHARACTER},
- {CHARACTER, 0, 65, 442, CHARACTER},
- {CHARACTER, 0, 84, 443, CHARACTER},
- {CHARACTER, 0, 89, 444, CHARACTER},
- {CHARACTER, 0, 80, 445, CHARACTER},
- {CHARACTER, 0, 69, 446, CHARACTER},
+ {CHARACTER, 0, 82, 441, CHARACTER},
+ {CHARACTER, 0, 70, 442, CHARACTER},
+ {CHARACTER, 0, 65, 443, CHARACTER},
+ {CHARACTER, 0, 67, 444, CHARACTER},
+ {CHARACTER, 0, 69, 445, CHARACTER},
+ {Q_DECLARE_INTERFACE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 447, CHARACTER},
+ {CHARACTER, 0, 84, 448, CHARACTER},
+ {CHARACTER, 0, 65, 449, CHARACTER},
+ {CHARACTER, 0, 84, 450, CHARACTER},
+ {CHARACTER, 0, 89, 451, CHARACTER},
+ {CHARACTER, 0, 80, 452, CHARACTER},
+ {CHARACTER, 0, 69, 453, CHARACTER},
{Q_DECLARE_METATYPE_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 88, 448, CHARACTER},
- {CHARACTER, 0, 84, 449, CHARACTER},
- {CHARACTER, 0, 69, 450, CHARACTER},
- {CHARACTER, 0, 78, 451, CHARACTER},
- {CHARACTER, 0, 83, 452, CHARACTER},
- {CHARACTER, 0, 73, 453, CHARACTER},
- {CHARACTER, 0, 79, 454, CHARACTER},
- {CHARACTER, 0, 78, 455, CHARACTER},
- {CHARACTER, 0, 95, 456, CHARACTER},
- {CHARACTER, 0, 73, 457, CHARACTER},
+ {CHARACTER, 0, 88, 455, CHARACTER},
+ {CHARACTER, 0, 84, 456, CHARACTER},
+ {CHARACTER, 0, 69, 457, CHARACTER},
{CHARACTER, 0, 78, 458, CHARACTER},
- {CHARACTER, 0, 84, 459, CHARACTER},
- {CHARACTER, 0, 69, 460, CHARACTER},
- {CHARACTER, 0, 82, 461, CHARACTER},
- {CHARACTER, 0, 70, 462, CHARACTER},
- {CHARACTER, 0, 65, 463, CHARACTER},
- {CHARACTER, 0, 67, 464, CHARACTER},
- {CHARACTER, 0, 69, 438, CHARACTER},
- {CHARACTER, 49, 0, 0, CHARACTER},
- {CHARACTER, 0, 84, 467, CHARACTER},
- {CHARACTER, 0, 83, 413, CHARACTER},
- {CHARACTER, 0, 76, 469, CHARACTER},
+ {CHARACTER, 0, 83, 459, CHARACTER},
+ {CHARACTER, 0, 73, 460, CHARACTER},
+ {CHARACTER, 0, 79, 461, CHARACTER},
+ {CHARACTER, 0, 78, 462, CHARACTER},
+ {CHARACTER, 0, 95, 463, CHARACTER},
+ {CHARACTER, 0, 73, 464, CHARACTER},
+ {CHARACTER, 0, 78, 465, CHARACTER},
+ {CHARACTER, 0, 84, 466, CHARACTER},
+ {CHARACTER, 0, 69, 467, CHARACTER},
+ {CHARACTER, 0, 82, 468, CHARACTER},
+ {CHARACTER, 0, 70, 469, CHARACTER},
{CHARACTER, 0, 65, 470, CHARACTER},
- {CHARACTER, 0, 83, 471, CHARACTER},
- {CHARACTER, 0, 83, 472, CHARACTER},
- {CHARACTER, 0, 73, 473, CHARACTER},
- {CHARACTER, 0, 78, 474, CHARACTER},
- {CHARACTER, 0, 70, 475, CHARACTER},
- {CHARACTER, 0, 79, 476, CHARACTER},
+ {CHARACTER, 0, 67, 471, CHARACTER},
+ {CHARACTER, 0, 69, 445, CHARACTER},
+ {CHARACTER, 49, 0, 0, CHARACTER},
+ {CHARACTER, 0, 84, 474, CHARACTER},
+ {CHARACTER, 0, 83, 420, CHARACTER},
+ {CHARACTER, 0, 76, 476, CHARACTER},
+ {CHARACTER, 0, 65, 477, CHARACTER},
+ {CHARACTER, 0, 83, 478, CHARACTER},
+ {CHARACTER, 0, 83, 479, CHARACTER},
+ {CHARACTER, 0, 73, 480, CHARACTER},
+ {CHARACTER, 0, 78, 481, CHARACTER},
+ {CHARACTER, 0, 70, 482, CHARACTER},
+ {CHARACTER, 0, 79, 483, CHARACTER},
{Q_CLASSINFO_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 78, 478, CHARACTER},
+ {CHARACTER, 0, 78, 485, CHARACTER},
{CHARACTER, 50, 0, 0, CHARACTER},
- {CHARACTER, 0, 69, 480, CHARACTER},
- {CHARACTER, 0, 82, 481, CHARACTER},
- {CHARACTER, 0, 70, 482, CHARACTER},
- {CHARACTER, 0, 65, 483, CHARACTER},
- {CHARACTER, 0, 67, 484, CHARACTER},
- {CHARACTER, 0, 69, 485, CHARACTER},
- {CHARACTER, 0, 83, 486, CHARACTER},
+ {CHARACTER, 0, 69, 487, CHARACTER},
+ {CHARACTER, 0, 82, 488, CHARACTER},
+ {CHARACTER, 0, 70, 489, CHARACTER},
+ {CHARACTER, 0, 65, 490, CHARACTER},
+ {CHARACTER, 0, 67, 491, CHARACTER},
+ {CHARACTER, 0, 69, 492, CHARACTER},
+ {CHARACTER, 0, 83, 493, CHARACTER},
{Q_INTERFACES_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 108, 488, CHARACTER},
- {CHARACTER, 0, 115, 489, CHARACTER},
+ {CHARACTER, 0, 108, 495, CHARACTER},
+ {CHARACTER, 0, 115, 496, CHARACTER},
{SIGNALS, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 111, 491, CHARACTER},
- {CHARACTER, 0, 116, 492, CHARACTER},
- {CHARACTER, 0, 115, 493, CHARACTER},
+ {CHARACTER, 0, 111, 498, CHARACTER},
+ {CHARACTER, 0, 116, 499, CHARACTER},
+ {CHARACTER, 0, 115, 500, CHARACTER},
{SLOTS, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 71, 495, CHARACTER},
- {CHARACTER, 0, 78, 496, CHARACTER},
- {CHARACTER, 0, 65, 497, CHARACTER},
- {CHARACTER, 0, 76, 498, CHARACTER},
- {Q_SIGNAL_TOKEN, 0, 83, 499, CHARACTER},
+ {CHARACTER, 0, 71, 502, CHARACTER},
+ {CHARACTER, 0, 78, 503, CHARACTER},
+ {CHARACTER, 0, 65, 504, CHARACTER},
+ {CHARACTER, 0, 76, 505, CHARACTER},
+ {Q_SIGNAL_TOKEN, 0, 83, 506, CHARACTER},
{Q_SIGNALS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 79, 501, CHARACTER},
- {CHARACTER, 0, 84, 502, CHARACTER},
- {Q_SLOT_TOKEN, 0, 83, 503, CHARACTER},
+ {CHARACTER, 0, 79, 508, CHARACTER},
+ {CHARACTER, 0, 84, 509, CHARACTER},
+ {Q_SLOT_TOKEN, 0, 83, 510, CHARACTER},
{Q_SLOTS_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 86, 505, CHARACTER},
- {CHARACTER, 0, 65, 506, CHARACTER},
- {CHARACTER, 0, 84, 507, CHARACTER},
- {CHARACTER, 0, 69, 508, CHARACTER},
- {CHARACTER, 0, 95, 509, CHARACTER},
+ {CHARACTER, 0, 86, 512, CHARACTER},
+ {CHARACTER, 0, 65, 513, CHARACTER},
+ {CHARACTER, 0, 84, 514, CHARACTER},
+ {CHARACTER, 0, 69, 515, CHARACTER},
+ {CHARACTER, 0, 95, 516, CHARACTER},
{CHARACTER, 51, 0, 0, CHARACTER},
- {CHARACTER, 0, 76, 511, CHARACTER},
- {CHARACTER, 0, 79, 512, CHARACTER},
- {CHARACTER, 0, 84, 513, CHARACTER},
+ {CHARACTER, 0, 76, 518, CHARACTER},
+ {CHARACTER, 0, 79, 519, CHARACTER},
+ {CHARACTER, 0, 84, 520, CHARACTER},
{Q_PRIVATE_SLOT_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 95, 515, CHARACTER},
- {CHARACTER, 0, 77, 516, CHARACTER},
- {CHARACTER, 0, 79, 517, CHARACTER},
- {CHARACTER, 0, 67, 518, CHARACTER},
- {CHARACTER, 0, 95, 519, CHARACTER},
- {CHARACTER, 0, 67, 520, CHARACTER},
- {CHARACTER, 0, 79, 521, CHARACTER},
- {CHARACTER, 0, 77, 522, CHARACTER},
- {CHARACTER, 0, 80, 523, CHARACTER},
- {CHARACTER, 0, 65, 524, CHARACTER},
- {CHARACTER, 0, 84, 525, CHARACTER},
+ {CHARACTER, 0, 95, 522, CHARACTER},
+ {CHARACTER, 0, 77, 523, CHARACTER},
+ {CHARACTER, 0, 79, 524, CHARACTER},
+ {CHARACTER, 0, 67, 525, CHARACTER},
+ {CHARACTER, 0, 95, 526, CHARACTER},
+ {CHARACTER, 0, 67, 527, CHARACTER},
+ {CHARACTER, 0, 79, 528, CHARACTER},
+ {CHARACTER, 0, 77, 529, CHARACTER},
+ {CHARACTER, 0, 80, 530, CHARACTER},
+ {CHARACTER, 0, 65, 531, CHARACTER},
+ {CHARACTER, 0, 84, 532, CHARACTER},
{Q_MOC_COMPAT_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 79, 527, CHARACTER},
- {CHARACTER, 0, 75, 528, CHARACTER},
- {CHARACTER, 0, 65, 529, CHARACTER},
- {CHARACTER, 0, 66, 530, CHARACTER},
- {CHARACTER, 0, 76, 531, CHARACTER},
- {CHARACTER, 0, 69, 532, CHARACTER},
+ {CHARACTER, 0, 79, 534, CHARACTER},
+ {CHARACTER, 0, 75, 535, CHARACTER},
+ {CHARACTER, 0, 65, 536, CHARACTER},
+ {CHARACTER, 0, 66, 537, CHARACTER},
+ {CHARACTER, 0, 76, 538, CHARACTER},
+ {CHARACTER, 0, 69, 539, CHARACTER},
{Q_INVOKABLE_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 82, 534, CHARACTER},
- {CHARACTER, 0, 73, 535, CHARACTER},
- {CHARACTER, 0, 80, 536, CHARACTER},
- {CHARACTER, 0, 84, 537, CHARACTER},
- {CHARACTER, 0, 65, 538, CHARACTER},
- {CHARACTER, 0, 66, 539, CHARACTER},
- {CHARACTER, 0, 76, 540, CHARACTER},
- {CHARACTER, 0, 69, 541, CHARACTER},
+ {CHARACTER, 0, 82, 541, CHARACTER},
+ {CHARACTER, 0, 73, 542, CHARACTER},
+ {CHARACTER, 0, 80, 543, CHARACTER},
+ {CHARACTER, 0, 84, 544, CHARACTER},
+ {CHARACTER, 0, 65, 545, CHARACTER},
+ {CHARACTER, 0, 66, 546, CHARACTER},
+ {CHARACTER, 0, 76, 547, CHARACTER},
+ {CHARACTER, 0, 69, 548, CHARACTER},
{Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 82, 543, CHARACTER},
- {CHARACTER, 0, 79, 544, CHARACTER},
- {CHARACTER, 0, 80, 545, CHARACTER},
- {CHARACTER, 0, 69, 546, CHARACTER},
- {CHARACTER, 0, 82, 547, CHARACTER},
- {CHARACTER, 0, 84, 548, CHARACTER},
- {CHARACTER, 0, 89, 549, CHARACTER},
+ {CHARACTER, 0, 82, 550, CHARACTER},
+ {CHARACTER, 0, 79, 551, CHARACTER},
+ {CHARACTER, 0, 80, 552, CHARACTER},
+ {CHARACTER, 0, 69, 553, CHARACTER},
+ {CHARACTER, 0, 82, 554, CHARACTER},
+ {CHARACTER, 0, 84, 555, CHARACTER},
+ {CHARACTER, 0, 89, 556, CHARACTER},
{Q_PRIVATE_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
- {CHARACTER, 0, 69, 551, CHARACTER},
- {CHARACTER, 0, 86, 552, CHARACTER},
- {CHARACTER, 0, 73, 553, CHARACTER},
- {CHARACTER, 0, 83, 554, CHARACTER},
- {CHARACTER, 0, 73, 555, CHARACTER},
- {CHARACTER, 0, 79, 556, CHARACTER},
- {CHARACTER, 0, 78, 557, CHARACTER},
+ {CHARACTER, 0, 69, 558, CHARACTER},
+ {CHARACTER, 0, 86, 559, CHARACTER},
+ {CHARACTER, 0, 73, 560, CHARACTER},
+ {CHARACTER, 0, 83, 561, CHARACTER},
+ {CHARACTER, 0, 73, 562, CHARACTER},
+ {CHARACTER, 0, 79, 563, CHARACTER},
+ {CHARACTER, 0, 78, 564, CHARACTER},
{Q_REVISION_TOKEN, 0, 0, 0, CHARACTER},
{NEWLINE, 0, 0, 0, NOTOKEN},
{QUOTE, 0, 0, 0, NOTOKEN},
{SINGLEQUOTE, 0, 0, 0, NOTOKEN},
{WHITESPACE, 0, 0, 0, NOTOKEN},
- {HASH, 0, 35, 563, HASH},
+ {HASH, 0, 35, 570, HASH},
{PP_HASHHASH, 0, 0, 0, NOTOKEN},
{BACKSLASH, 0, 0, 0, NOTOKEN},
{CPP_COMMENT, 0, 0, 0, NOTOKEN},
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 5d777ece2e..50946443be 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -159,6 +159,7 @@ Type Moc::parseType()
bool isVoid = false;
type.firstToken = lookup();
for (;;) {
+ skipCxxAttributes();
switch (next()) {
case SIGNED:
case UNSIGNED:
@@ -188,8 +189,11 @@ Type Moc::parseType()
}
break;
}
+
+ skipCxxAttributes();
test(ENUM) || test(CLASS) || test(STRUCT);
for(;;) {
+ skipCxxAttributes();
switch (next()) {
case IDENTIFIER:
// void mySlot(unsigned myArg)
@@ -281,6 +285,7 @@ bool Moc::parseEnum(EnumDef *def)
break;
next(IDENTIFIER);
def->values += lexem();
+ skipCxxAttributes();
} while (test(EQ) ? until(COMMA) : test(COMMA));
next(RBRACE);
if (isTypdefEnum) {
@@ -356,6 +361,15 @@ bool Moc::testFunctionAttribute(Token tok, FunctionDef *def)
return false;
}
+bool Moc::skipCxxAttributes()
+{
+ auto rewind = index;
+ if (test(LBRACK) && test(LBRACK) && until(RBRACK) && test(RBRACK))
+ return true;
+ index = rewind;
+ return false;
+}
+
bool Moc::testFunctionRevision(FunctionDef *def)
{
if (test(Q_REVISION_TOKEN)) {
@@ -381,7 +395,7 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
//skip modifiers and attributes
while (test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) ||
(test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual
- || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ || skipCxxAttributes() || testFunctionAttribute(def) || testFunctionRevision(def)) {}
bool templateFunction = (lookup() == TEMPLATE);
def->type = parseType();
if (def->type.name.isEmpty()) {
@@ -454,10 +468,11 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
until(RBRACE);
else if ((def->isAbstract = test(EQ)))
until(SEMIC);
+ else if (skipCxxAttributes())
+ until(SEMIC);
else
error();
}
-
if (scopedFunctionName) {
const QByteArray msg = "Function declaration " + def->name
+ " contains extra qualification. Ignoring as signal or slot.";
@@ -475,7 +490,7 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
//skip modifiers and attributes
while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) ||
(test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual
- || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ || skipCxxAttributes() || testFunctionAttribute(def) || testFunctionRevision(def)) {}
bool tilde = test(TILDE);
def->type = parseType();
if (def->type.name.isEmpty())
@@ -565,6 +580,7 @@ void Moc::parse()
} else if (!test(SEMIC)) {
NamespaceDef def;
def.classname = nsName;
+ def.doGenerate = currentFilenames.size() <= 1;
next(LBRACE);
def.begin = index - 1;
@@ -572,25 +588,22 @@ void Moc::parse()
def.end = index;
index = def.begin + 1;
- const bool parseNamespace = currentFilenames.size() <= 1;
- if (parseNamespace) {
- for (int i = namespaceList.size() - 1; i >= 0; --i) {
- if (inNamespace(&namespaceList.at(i))) {
- def.qualified.prepend(namespaceList.at(i).classname + "::");
- }
- }
- for (const QByteArray &ns : nested) {
- NamespaceDef parentNs;
- parentNs.classname = ns;
- parentNs.qualified = def.qualified;
- def.qualified += ns + "::";
- parentNs.begin = def.begin;
- parentNs.end = def.end;
- namespaceList += parentNs;
+ for (int i = namespaceList.size() - 1; i >= 0; --i) {
+ if (inNamespace(&namespaceList.at(i))) {
+ def.qualified.prepend(namespaceList.at(i).classname + "::");
}
}
+ for (const QByteArray &ns : nested) {
+ NamespaceDef parentNs;
+ parentNs.classname = ns;
+ parentNs.qualified = def.qualified;
+ def.qualified += ns + "::";
+ parentNs.begin = def.begin;
+ parentNs.end = def.end;
+ namespaceList += parentNs;
+ }
- while (parseNamespace && inNamespace(&def) && hasNext()) {
+ while (inNamespace(&def) && hasNext()) {
switch (next()) {
case NAMESPACE:
if (test(IDENTIFIER)) {
@@ -607,6 +620,13 @@ void Moc::parse()
case Q_NAMESPACE_TOKEN:
def.hasQNamespace = true;
break;
+ case Q_NAMESPACE_EXPORT_TOKEN:
+ next(LPAREN);
+ while (test(IDENTIFIER))
+ {}
+ next(RPAREN);
+ def.hasQNamespace = true;
+ break;
case Q_ENUMS_TOKEN:
case Q_ENUM_NS_TOKEN:
parseEnumOrFlag(&def, false);
@@ -915,7 +935,8 @@ void Moc::parse()
} else {
knownGadgets.insert(def.classname, def.qualified);
knownGadgets.insert(def.qualified, def.qualified);
- classList += def;
+ if (n.doGenerate)
+ classList += def;
}
}
}
@@ -1180,6 +1201,15 @@ void Moc::createPropertyDef(PropertyDef &propDef)
propDef.type = type;
+ auto checkIsFunction = [&](const QByteArray &def, const char *name) {
+ if (def.endsWith(')')) {
+ QByteArray msg = "Providing a function for ";
+ msg += name;
+ msg += " in a property declaration is deprecated and will not be supported in Qt 6 anymore.";
+ warning(msg.constData());
+ }
+ };
+
next();
propDef.name = lexem();
while (test(IDENTIFIER)) {
@@ -1229,11 +1259,13 @@ void Moc::createPropertyDef(PropertyDef &propDef)
error(2);
break;
case 'S':
- if (l == "SCRIPTABLE")
+ if (l == "SCRIPTABLE") {
propDef.scriptable = v + v2;
- else if (l == "STORED")
+ checkIsFunction(propDef.scriptable, "SCRIPTABLE");
+ } else if (l == "STORED") {
propDef.stored = v + v2;
- else
+ checkIsFunction(propDef.stored, "STORED");
+ } else
error(2);
break;
case 'W': if (l != "WRITE") error(2);
@@ -1241,15 +1273,18 @@ void Moc::createPropertyDef(PropertyDef &propDef)
break;
case 'D': if (l != "DESIGNABLE") error(2);
propDef.designable = v + v2;
+ checkIsFunction(propDef.designable, "DESIGNABLE");
break;
case 'E': if (l != "EDITABLE") error(2);
propDef.editable = v + v2;
+ checkIsFunction(propDef.editable, "EDITABLE");
break;
case 'N': if (l != "NOTIFY") error(2);
propDef.notify = v;
break;
case 'U': if (l != "USER") error(2);
propDef.user = v + v2;
+ checkIsFunction(propDef.user, "USER");
break;
default:
error(2);
@@ -1297,6 +1332,9 @@ void Moc::parsePluginData(ClassDef *def)
if (l == "IID") {
next(STRING_LITERAL);
def->pluginData.iid = unquotedLexem();
+ } else if (l == "URI") {
+ next(STRING_LITERAL);
+ def->pluginData.uri = unquotedLexem();
} else if (l == "FILE") {
next(STRING_LITERAL);
QByteArray metaDataFile = unquotedLexem();
@@ -1337,6 +1375,7 @@ void Moc::parsePluginData(ClassDef *def)
+ " does not contain a valid JSON object. Declaration will be ignored";
warning(msg.constData());
def->pluginData.iid = QByteArray();
+ def->pluginData.uri = QByteArray();
return;
}
}
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index d6482f4e44..bb1c9501fe 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -167,6 +167,7 @@ struct ClassDef : BaseDef {
struct PluginData {
QByteArray iid;
+ QByteArray uri;
QMap<QString, QJsonArray> metaArgs;
QJsonDocument metaData;
} pluginData;
@@ -188,6 +189,7 @@ Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE);
struct NamespaceDef : BaseDef {
bool hasQNamespace = false;
+ bool doGenerate = false;
};
Q_DECLARE_TYPEINFO(NamespaceDef, Q_MOVABLE_TYPE);
@@ -256,6 +258,8 @@ public:
bool testFunctionAttribute(Token tok, FunctionDef *def);
bool testFunctionRevision(FunctionDef *def);
+ bool skipCxxAttributes();
+
void checkSuperClasses(ClassDef *def);
void checkProperties(ClassDef* cdef);
};
diff --git a/src/tools/moc/parser.h b/src/tools/moc/parser.h
index bedcbbf7e2..63f4cf0d9a 100644
--- a/src/tools/moc/parser.h
+++ b/src/tools/moc/parser.h
@@ -69,9 +69,9 @@ public:
inline const Symbol &symbol() { return symbols.at(index-1);}
Q_NORETURN void error(int rollback);
- Q_NORETURN void error(const char *msg = 0);
- void warning(const char * = 0);
- void note(const char * = 0);
+ Q_NORETURN void error(const char *msg = nullptr);
+ void warning(const char * = nullptr);
+ void note(const char * = nullptr);
};
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
index db9d319b78..0cc163f9e4 100644
--- a/src/tools/moc/token.h
+++ b/src/tools/moc/token.h
@@ -155,6 +155,7 @@ QT_BEGIN_NAMESPACE
F(Q_OBJECT_TOKEN) \
F(Q_GADGET_TOKEN) \
F(Q_NAMESPACE_TOKEN) \
+ F(Q_NAMESPACE_EXPORT_TOKEN) \
F(Q_PROPERTY_TOKEN) \
F(Q_PLUGIN_METADATA_TOKEN) \
F(Q_ENUMS_TOKEN) \
diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp
index df850c1bdc..9248e9e2e7 100644
--- a/src/tools/moc/util/generate_keywords.cpp
+++ b/src/tools/moc/util/generate_keywords.cpp
@@ -214,6 +214,7 @@ static const Keyword keywords[] = {
{ "return", "RETURN" },
{ "Q_OBJECT", "Q_OBJECT_TOKEN" },
{ "Q_NAMESPACE", "Q_NAMESPACE_TOKEN" },
+ { "Q_NAMESPACE_EXPORT", "Q_NAMESPACE_EXPORT_TOKEN" },
{ "Q_GADGET", "Q_GADGET_TOKEN" },
{ "Q_PROPERTY", "Q_PROPERTY_TOKEN" },
{ "Q_PLUGIN_METADATA", "Q_PLUGIN_METADATA_TOKEN" },
diff --git a/src/tools/moc/util/generate_keywords.pro b/src/tools/moc/util/generate_keywords.pro
index 2bbc3ced61..e29738c18a 100644
--- a/src/tools/moc/util/generate_keywords.pro
+++ b/src/tools/moc/util/generate_keywords.pro
@@ -1,4 +1,5 @@
CONFIG -= moc
CONFIG += cmdline
+QT = core
SOURCES += generate_keywords.cpp
diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
index 7c6f0bdeef..522c55593f 100644
--- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -32,7 +32,6 @@
#include <qfile.h>
#include <qlist.h>
#include <qbuffer.h>
-#include <qregexp.h>
#include <qvector.h>
#include <qdebug.h>
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index ea410cd257..ce4232f3e8 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -161,22 +161,22 @@ static QString moc(const QString &name)
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;
+ ts << "/*" << Qt::endl
+ << " * This file was generated by " PROGRAMNAME " version " PROGRAMVERSION << Qt::endl
+ << " * Command line was: " << commandLine << Qt::endl
+ << " *" << Qt::endl
+ << " * " PROGRAMNAME " is " PROGRAMCOPYRIGHT << Qt::endl
+ << " *" << Qt::endl
+ << " * This is an auto-generated file." << Qt::endl;
if (changesWillBeLost)
- ts << " * Do not edit! All changes made to it will be lost." << endl;
+ ts << " * Do not edit! All changes made to it will be lost." << Qt::endl;
else
- ts << " * This file may have been hand-edited. Look for HAND-EDIT comments" << endl
- << " * before re-generating it." << endl;
+ ts << " * This file may have been hand-edited. Look for HAND-EDIT comments" << Qt::endl
+ << " * before re-generating it." << Qt::endl;
- ts << " */" << endl
- << endl;
+ ts << " */" << Qt::endl
+ << Qt::endl;
return ts;
}
@@ -466,66 +466,66 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
}
includeGuard = QString(QLatin1String("%1"))
.arg(includeGuard);
- hs << "#ifndef " << includeGuard << endl
- << "#define " << includeGuard << endl
- << endl;
+ hs << "#ifndef " << includeGuard << Qt::endl
+ << "#define " << includeGuard << Qt::endl
+ << Qt::endl;
// include our stuff:
- hs << "#include <QtCore/QObject>" << endl
+ hs << "#include <QtCore/QObject>" << Qt::endl
<< includeList
- << "#include <QtDBus/QtDBus>" << endl;
+ << "#include <QtDBus/QtDBus>" << Qt::endl;
for (const QString &include : qAsConst(includes)) {
- hs << "#include \"" << include << "\"" << endl;
+ hs << "#include \"" << include << "\"" << Qt::endl;
if (headerName.isEmpty())
- cs << "#include \"" << include << "\"" << endl;
+ cs << "#include \"" << include << "\"" << Qt::endl;
}
- hs << endl;
+ hs << Qt::endl;
if (cppName != headerName) {
if (!headerName.isEmpty() && headerName != QLatin1String("-"))
- cs << "#include \"" << headerName << "\"" << endl << endl;
+ cs << "#include \"" << headerName << "\"" << Qt::endl << Qt::endl;
}
for (const QDBusIntrospection::Interface *interface : interfaces) {
QString className = classNameForInterface(interface->name, Proxy);
// comment:
- hs << "/*" << endl
- << " * Proxy class for interface " << interface->name << endl
- << " */" << endl;
- cs << "/*" << endl
- << " * Implementation of interface class " << className << endl
- << " */" << endl
- << endl;
+ hs << "/*" << Qt::endl
+ << " * Proxy class for interface " << interface->name << Qt::endl
+ << " */" << Qt::endl;
+ cs << "/*" << Qt::endl
+ << " * Implementation of interface class " << className << Qt::endl
+ << " */" << Qt::endl
+ << Qt::endl;
// class header:
- hs << "class " << className << ": public QDBusAbstractInterface" << endl
- << "{" << endl
- << " Q_OBJECT" << endl;
+ hs << "class " << className << ": public QDBusAbstractInterface" << Qt::endl
+ << "{" << Qt::endl
+ << " Q_OBJECT" << Qt::endl;
// the interface name
- hs << "public:" << endl
- << " static inline const char *staticInterfaceName()" << endl
- << " { return \"" << interface->name << "\"; }" << endl
- << endl;
+ hs << "public:" << Qt::endl
+ << " static inline const char *staticInterfaceName()" << Qt::endl
+ << " { return \"" << interface->name << "\"; }" << Qt::endl
+ << Qt::endl;
// constructors/destructors:
- hs << "public:" << endl
- << " " << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);" << endl
- << endl
- << " ~" << className << "();" << endl
- << endl;
- cs << className << "::" << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)" << endl
- << " : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)" << endl
- << "{" << endl
- << "}" << endl
- << endl
- << className << "::~" << className << "()" << endl
- << "{" << endl
- << "}" << endl
- << endl;
+ hs << "public:" << Qt::endl
+ << " " << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);" << Qt::endl
+ << Qt::endl
+ << " ~" << className << "();" << Qt::endl
+ << Qt::endl;
+ cs << className << "::" << className << "(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)" << Qt::endl
+ << " : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)" << Qt::endl
+ << "{" << Qt::endl
+ << "}" << Qt::endl
+ << Qt::endl
+ << className << "::~" << className << "()" << Qt::endl
+ << "{" << Qt::endl
+ << "}" << Qt::endl
+ << Qt::endl;
// properties:
for (const QDBusIntrospection::Property &property : interface->properties) {
@@ -545,27 +545,27 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
// it's writeable
hs << " WRITE " << setter;
- hs << ")" << endl;
+ hs << ")" << Qt::endl;
// getter:
if (property.access != QDBusIntrospection::Property::Write) {
- hs << " inline " << type << " " << getter << "() const" << endl
+ hs << " inline " << type << " " << getter << "() const" << Qt::endl
<< " { return qvariant_cast< " << type << " >(property(\""
- << property.name << "\")); }" << endl;
+ << property.name << "\")); }" << Qt::endl;
}
// setter:
if (property.access != QDBusIntrospection::Property::Read) {
- hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl
+ hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << Qt::endl
<< " { setProperty(\"" << property.name
- << "\", QVariant::fromValue(value)); }" << endl;
+ << "\", QVariant::fromValue(value)); }" << Qt::endl;
}
- hs << endl;
+ hs << Qt::endl;
}
// methods:
- hs << "public Q_SLOTS: // METHODS" << endl;
+ hs << "public Q_SLOTS: // METHODS" << Qt::endl;
for (const QDBusIntrospection::Method &method : interface->methods) {
bool isDeprecated = method.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) == QLatin1String("true");
bool isNoReply =
@@ -595,26 +595,26 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
QStringList argNames = makeArgNames(method.inputArgs);
writeArgList(hs, argNames, method.annotations, method.inputArgs);
- hs << ")" << endl
- << " {" << endl
- << " QList<QVariant> argumentList;" << endl;
+ hs << ")" << Qt::endl
+ << " {" << Qt::endl
+ << " QList<QVariant> argumentList;" << Qt::endl;
if (!method.inputArgs.isEmpty()) {
hs << " argumentList";
for (int argPos = 0; argPos < method.inputArgs.count(); ++argPos)
hs << " << QVariant::fromValue(" << argNames.at(argPos) << ')';
- hs << ";" << endl;
+ hs << ";" << Qt::endl;
}
if (isNoReply)
hs << " callWithArgumentList(QDBus::NoBlock, "
- << "QStringLiteral(\"" << method.name << "\"), argumentList);" << endl;
+ << "QStringLiteral(\"" << method.name << "\"), argumentList);" << Qt::endl;
else
hs << " return asyncCallWithArgumentList(QStringLiteral(\""
- << method.name << "\"), argumentList);" << endl;
+ << method.name << "\"), argumentList);" << Qt::endl;
// close the function:
- hs << " }" << endl;
+ hs << " }" << Qt::endl;
if (method.outputArgs.count() > 1) {
// generate the old-form QDBusReply methods with multiple incoming parameters
@@ -627,39 +627,39 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs);
writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs);
- hs << ")" << endl
- << " {" << endl
- << " QList<QVariant> argumentList;" << endl;
+ hs << ")" << Qt::endl
+ << " {" << Qt::endl
+ << " QList<QVariant> argumentList;" << Qt::endl;
int argPos = 0;
if (!method.inputArgs.isEmpty()) {
hs << " argumentList";
for (argPos = 0; argPos < method.inputArgs.count(); ++argPos)
hs << " << QVariant::fromValue(" << argNames.at(argPos) << ')';
- hs << ";" << endl;
+ hs << ";" << Qt::endl;
}
hs << " QDBusMessage reply = callWithArgumentList(QDBus::Block, "
- << "QStringLiteral(\"" << method.name << "\"), argumentList);" << endl;
+ << "QStringLiteral(\"" << method.name << "\"), argumentList);" << Qt::endl;
argPos++;
hs << " if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == "
- << method.outputArgs.count() << ") {" << endl;
+ << method.outputArgs.count() << ") {" << Qt::endl;
// yes, starting from 1
for (int i = 1; i < method.outputArgs.count(); ++i)
hs << " " << argNames.at(argPos++) << " = qdbus_cast<"
<< templateArg(qtTypeName(method.outputArgs.at(i).type, method.annotations, i, "Out"))
- << ">(reply.arguments().at(" << i << "));" << endl;
- hs << " }" << endl
- << " return reply;" << endl
- << " }" << endl;
+ << ">(reply.arguments().at(" << i << "));" << Qt::endl;
+ hs << " }" << Qt::endl
+ << " return reply;" << Qt::endl
+ << " }" << Qt::endl;
}
- hs << endl;
+ hs << Qt::endl;
}
- hs << "Q_SIGNALS: // SIGNALS" << endl;
+ hs << "Q_SIGNALS: // SIGNALS" << Qt::endl;
for (const QDBusIntrospection::Signal &signal : interface->signals_) {
hs << " ";
if (signal.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) ==
@@ -671,12 +671,12 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
QStringList argNames = makeArgNames(signal.outputArgs);
writeSignalArgList(hs, argNames, signal.annotations, signal.outputArgs);
- hs << ");" << endl; // finished for header
+ hs << ");" << Qt::endl; // finished for header
}
// close the class:
- hs << "};" << endl
- << endl;
+ hs << "};" << Qt::endl
+ << Qt::endl;
}
if (!skipNamespaces) {
@@ -698,17 +698,17 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
// i parts matched
// close last.arguments().count() - i namespaces:
for (int j = i; j < last.count(); ++j)
- hs << QString((last.count() - j - 1 + i) * 2, QLatin1Char(' ')) << "}" << endl;
+ hs << QString((last.count() - j - 1 + i) * 2, QLatin1Char(' ')) << "}" << Qt::endl;
// open current.arguments().count() - i namespaces
for (int j = i; j < current.count(); ++j)
- hs << QString(j * 2, QLatin1Char(' ')) << "namespace " << current.at(j) << " {" << endl;
+ hs << QString(j * 2, QLatin1Char(' ')) << "namespace " << current.at(j) << " {" << Qt::endl;
// add this class:
if (!name.isEmpty()) {
hs << QString(current.count() * 2, QLatin1Char(' '))
<< "typedef ::" << classNameForInterface(it->constData()->name, Proxy)
- << " " << name << ";" << endl;
+ << " " << name << ";" << Qt::endl;
}
if (it == interfaces.constEnd())
@@ -719,12 +719,12 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
}
// close the include guard
- hs << "#endif" << endl;
+ hs << "#endif" << Qt::endl;
QString mocName = moc(filename);
if (includeMocs && !mocName.isEmpty())
- cs << endl
- << "#include \"" << mocName << "\"" << endl;
+ cs << Qt::endl
+ << "#include \"" << mocName << "\"" << Qt::endl;
cs.flush();
hs.flush();
@@ -772,36 +772,36 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
}
includeGuard = QString(QLatin1String("%1"))
.arg(includeGuard);
- hs << "#ifndef " << includeGuard << endl
- << "#define " << includeGuard << endl
- << endl;
+ hs << "#ifndef " << includeGuard << Qt::endl
+ << "#define " << includeGuard << Qt::endl
+ << Qt::endl;
// include our stuff:
- hs << "#include <QtCore/QObject>" << endl;
+ hs << "#include <QtCore/QObject>" << Qt::endl;
if (cppName == headerName)
- hs << "#include <QtCore/QMetaObject>" << endl
- << "#include <QtCore/QVariant>" << endl;
- hs << "#include <QtDBus/QtDBus>" << endl;
+ hs << "#include <QtCore/QMetaObject>" << Qt::endl
+ << "#include <QtCore/QVariant>" << Qt::endl;
+ hs << "#include <QtDBus/QtDBus>" << Qt::endl;
for (const QString &include : qAsConst(includes)) {
- hs << "#include \"" << include << "\"" << endl;
+ hs << "#include \"" << include << "\"" << Qt::endl;
if (headerName.isEmpty())
- cs << "#include \"" << include << "\"" << endl;
+ cs << "#include \"" << include << "\"" << Qt::endl;
}
if (cppName != headerName) {
if (!headerName.isEmpty() && headerName != QLatin1String("-"))
- cs << "#include \"" << headerName << "\"" << endl;
+ cs << "#include \"" << headerName << "\"" << Qt::endl;
- cs << "#include <QtCore/QMetaObject>" << endl
+ cs << "#include <QtCore/QMetaObject>" << Qt::endl
<< includeList
- << endl;
+ << Qt::endl;
hs << forwardDeclarations;
} else {
hs << includeList;
}
- hs << endl;
+ hs << Qt::endl;
QString parent = parentClassName;
if (parentClassName.isEmpty())
@@ -811,47 +811,47 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
QString className = classNameForInterface(interface->name, Adaptor);
// comment:
- hs << "/*" << endl
- << " * Adaptor class for interface " << interface->name << endl
- << " */" << endl;
- cs << "/*" << endl
- << " * Implementation of adaptor class " << className << endl
- << " */" << endl
- << endl;
+ hs << "/*" << Qt::endl
+ << " * Adaptor class for interface " << interface->name << Qt::endl
+ << " */" << Qt::endl;
+ cs << "/*" << Qt::endl
+ << " * Implementation of adaptor class " << className << Qt::endl
+ << " */" << Qt::endl
+ << Qt::endl;
// class header:
- hs << "class " << className << ": public QDBusAbstractAdaptor" << endl
- << "{" << endl
- << " Q_OBJECT" << endl
- << " Q_CLASSINFO(\"D-Bus Interface\", \"" << interface->name << "\")" << endl
- << " Q_CLASSINFO(\"D-Bus Introspection\", \"\"" << endl
+ hs << "class " << className << ": public QDBusAbstractAdaptor" << Qt::endl
+ << "{" << Qt::endl
+ << " Q_OBJECT" << Qt::endl
+ << " Q_CLASSINFO(\"D-Bus Interface\", \"" << interface->name << "\")" << Qt::endl
+ << " Q_CLASSINFO(\"D-Bus Introspection\", \"\"" << Qt::endl
<< stringify(interface->introspection)
- << " \"\")" << endl
- << "public:" << endl
- << " " << className << "(" << parent << " *parent);" << endl
- << " virtual ~" << className << "();" << endl
- << endl;
+ << " \"\")" << Qt::endl
+ << "public:" << Qt::endl
+ << " " << className << "(" << parent << " *parent);" << Qt::endl
+ << " virtual ~" << className << "();" << Qt::endl
+ << Qt::endl;
if (!parentClassName.isEmpty())
- hs << " inline " << parent << " *parent() const" << endl
- << " { return static_cast<" << parent << " *>(QObject::parent()); }" << endl
- << endl;
+ hs << " inline " << parent << " *parent() const" << Qt::endl
+ << " { return static_cast<" << parent << " *>(QObject::parent()); }" << Qt::endl
+ << Qt::endl;
// constructor/destructor
- cs << className << "::" << className << "(" << parent << " *parent)" << endl
- << " : QDBusAbstractAdaptor(parent)" << endl
- << "{" << endl
- << " // constructor" << endl
- << " setAutoRelaySignals(true);" << endl
- << "}" << endl
- << endl
- << className << "::~" << className << "()" << endl
- << "{" << endl
- << " // destructor" << endl
- << "}" << endl
- << endl;
-
- hs << "public: // PROPERTIES" << endl;
+ cs << className << "::" << className << "(" << parent << " *parent)" << Qt::endl
+ << " : QDBusAbstractAdaptor(parent)" << Qt::endl
+ << "{" << Qt::endl
+ << " // constructor" << Qt::endl
+ << " setAutoRelaySignals(true);" << Qt::endl
+ << "}" << Qt::endl
+ << Qt::endl
+ << className << "::~" << className << "()" << Qt::endl
+ << "{" << Qt::endl
+ << " // destructor" << Qt::endl
+ << "}" << Qt::endl
+ << Qt::endl;
+
+ hs << "public: // PROPERTIES" << Qt::endl;
for (const QDBusIntrospection::Property &property : interface->properties) {
QByteArray type = qtTypeName(property.type, property.annotations);
QString constRefType = constRefArg(type);
@@ -863,38 +863,38 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
hs << " READ " << getter;
if (property.access != QDBusIntrospection::Property::Read)
hs << " WRITE " << setter;
- hs << ")" << endl;
+ hs << ")" << Qt::endl;
// getter:
if (property.access != QDBusIntrospection::Property::Write) {
- hs << " " << type << " " << getter << "() const;" << endl;
+ hs << " " << type << " " << getter << "() const;" << Qt::endl;
cs << type << " "
- << className << "::" << getter << "() const" << endl
- << "{" << endl
- << " // get the value of property " << property.name << endl
- << " return qvariant_cast< " << type <<" >(parent()->property(\"" << property.name << "\"));" << endl
- << "}" << endl
- << endl;
+ << className << "::" << getter << "() const" << Qt::endl
+ << "{" << Qt::endl
+ << " // get the value of property " << property.name << Qt::endl
+ << " return qvariant_cast< " << type <<" >(parent()->property(\"" << property.name << "\"));" << Qt::endl
+ << "}" << Qt::endl
+ << Qt::endl;
}
// setter
if (property.access != QDBusIntrospection::Property::Read) {
- hs << " void " << setter << "(" << constRefType << "value);" << endl;
- cs << "void " << className << "::" << setter << "(" << constRefType << "value)" << endl
- << "{" << endl
- << " // set the value of property " << property.name << endl
+ hs << " void " << setter << "(" << constRefType << "value);" << Qt::endl;
+ cs << "void " << className << "::" << setter << "(" << constRefType << "value)" << Qt::endl
+ << "{" << Qt::endl
+ << " // set the value of property " << property.name << Qt::endl
<< " parent()->setProperty(\"" << property.name << "\", QVariant::fromValue(value";
if (constRefType.contains(QLatin1String("QDBusVariant")))
cs << ".variant()";
- cs << "));" << endl
- << "}" << endl
- << endl;
+ cs << "));" << Qt::endl
+ << "}" << Qt::endl
+ << Qt::endl;
}
- hs << endl;
+ hs << Qt::endl;
}
- hs << "public Q_SLOTS: // METHODS" << endl;
+ hs << "public Q_SLOTS: // METHODS" << Qt::endl;
for (const QDBusIntrospection::Method &method : interface->methods) {
bool isNoReply =
method.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true");
@@ -930,10 +930,10 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
writeArgList(hs, argNames, method.annotations, method.inputArgs, method.outputArgs);
writeArgList(cs, argNames, method.annotations, method.inputArgs, method.outputArgs);
- hs << ");" << endl; // finished for header
- cs << ")" << endl
- << "{" << endl
- << " // handle method call " << interface->name << "." << methodName(method) << endl;
+ hs << ");" << Qt::endl; // finished for header
+ cs << ")" << Qt::endl
+ << "{" << Qt::endl
+ << " // handle method call " << interface->name << "." << methodName(method) << Qt::endl;
// make the call
bool usingInvokeMethod = false;
@@ -945,7 +945,7 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
// we are using QMetaObject::invokeMethod
if (!returnType.isEmpty())
cs << " " << returnType << " " << argNames.at(method.inputArgs.count())
- << ";" << endl;
+ << ";" << Qt::endl;
static const char invoke[] = " QMetaObject::invokeMethod(parent(), \"";
cs << invoke << name << "\"";
@@ -966,10 +966,10 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
<< argNames.at(i)
<< ")";
- cs << ");" << endl;
+ cs << ");" << Qt::endl;
if (!returnType.isEmpty())
- cs << " return " << argNames.at(method.inputArgs.count()) << ";" << endl;
+ cs << " return " << argNames.at(method.inputArgs.count()) << ";" << Qt::endl;
} else {
if (parentClassName.isEmpty())
cs << " //";
@@ -997,13 +997,13 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
first = false;
}
- cs << ");" << endl;
+ cs << ");" << Qt::endl;
}
- cs << "}" << endl
- << endl;
+ cs << "}" << Qt::endl
+ << Qt::endl;
}
- hs << "Q_SIGNALS: // SIGNALS" << endl;
+ hs << "Q_SIGNALS: // SIGNALS" << Qt::endl;
for (const QDBusIntrospection::Signal &signal : interface->signals_) {
hs << " ";
if (signal.annotations.value(QLatin1String("org.freedesktop.DBus.Deprecated")) ==
@@ -1015,21 +1015,21 @@ static void writeAdaptor(const QString &filename, const QDBusIntrospection::Inte
QStringList argNames = makeArgNames(signal.outputArgs);
writeSignalArgList(hs, argNames, signal.annotations, signal.outputArgs);
- hs << ");" << endl; // finished for header
+ hs << ");" << Qt::endl; // finished for header
}
// close the class:
- hs << "};" << endl
- << endl;
+ hs << "};" << Qt::endl
+ << Qt::endl;
}
// close the include guard
- hs << "#endif" << endl;
+ hs << "#endif" << Qt::endl;
QString mocName = moc(filename);
if (includeMocs && !mocName.isEmpty())
- cs << endl
- << "#include \"" << mocName << "\"" << endl;
+ cs << Qt::endl
+ << "#include \"" << mocName << "\"" << Qt::endl;
cs.flush();
hs.flush();
diff --git a/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp b/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp
deleted file mode 100644
index 17fc978039..0000000000
--- a/src/tools/qfloat16-tables/gen_qfloat16_tables.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qfile.h>
-#include <qdebug.h>
-
-quint32 convertmantissa(qint32 i)
-{
- quint32 m = i << 13; // Zero pad mantissa bits
- quint32 e = 0; // Zero exponent
-
- while (!(m & 0x00800000)) { // While not normalized
- e -= 0x00800000; // Decrement exponent (1<<23)
- m <<= 1; // Shift mantissa
- }
- m &= ~0x00800000; // Clear leading 1 bit
- e += 0x38800000; // Adjust bias ((127-14)<<23)
- return m | e; // Return combined number
-}
-
-// we first build these tables up and then print them out as a separate step in order
-// to more closely map the implementation given in the paper.
-quint32 basetable[512];
-quint32 shifttable[512];
-
-#define PRINTHEX(a) "0x" + QByteArray::number(a,16).toUpper() + "U,\n"
-
-qint32 main(qint32 argc, char **argv)
-{
- if (argc < 2) {
- qWarning() << "Must provide output filename as argument.";
- return -1;
- }
-
- QFile fid(QFile::decodeName(argv[1]));
- if (!fid.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning() << "Abort: Failed to open/create file" << fid.fileName();
- return -1;
- }
- quint32 i;
-
- fid.write("/* This file was generated by gen_qfloat16_tables.cpp */\n\n");
- fid.write("#include <QtCore/qfloat16.h>\n\n");
-
- fid.write("QT_BEGIN_NAMESPACE\n\n");
- fid.write("#if !defined(__F16C__) && !defined(__ARM_FP16_FORMAT_IEEE)\n\n");
-
- fid.write("const quint32 qfloat16::mantissatable[2048] = {\n");
- fid.write("0,\n");
- for (i = 1; i < 1024; i++)
- fid.write(PRINTHEX(convertmantissa(i)));
- for (i = 1024; i < 2048; i++)
- fid.write(PRINTHEX(0x38000000U + ((i - 1024) << 13)));
- fid.write("};\n\n");
-
- fid.write("const quint32 qfloat16::exponenttable[64] = {\n");
- fid.write("0,\n");
- for (i = 1; i < 31; i++)
- fid.write(PRINTHEX(i << 23));
- fid.write("0x47800000U,\n"); // 31
- fid.write("0x80000000U,\n"); // 32
- for (i = 33; i < 63; i++)
- fid.write(PRINTHEX(0x80000000U + ((i - 32) << 23)));
- fid.write("0xC7800000U,\n"); // 63
- fid.write("};\n\n");
-
- fid.write("const quint32 qfloat16::offsettable[64] = {\n");
- fid.write("0,\n");
- for (i = 1; i < 32; i++)
- fid.write("1024U,\n");
- fid.write("0,\n");
- for (i = 33; i < 64; i++)
- fid.write("1024U,\n");
- fid.write("};\n\n");
-
- qint32 e;
- for (i = 0; i < 256; ++i) {
- e = i - 127;
- if (e < -24) { // Very small numbers map to zero
- basetable[i | 0x000] = 0x0000;
- basetable[i | 0x100] = 0x8000;
- shifttable[i | 0x000] = 24;
- shifttable[i | 0x100] = 24;
-
- } else if (e < -14) { // Small numbers map to denorms
- basetable[i | 0x000] = (0x0400 >> (-e - 14));
- basetable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;
- shifttable[i | 0x000] = -e - 1;
- shifttable[i | 0x100] = -e - 1;
-
- } else if (e <= 15) { // Normal numbers just lose precision
- basetable[i | 0x000] = ((e + 15) << 10);
- basetable[i | 0x100] = ((e + 15) << 10) | 0x8000;
- shifttable[i | 0x000] = 13;
- shifttable[i | 0x100] = 13;
-
- } else if (e < 128) { // Large numbers map to Infinity
- basetable[i | 0x000] = 0x7C00;
- basetable[i | 0x100] = 0xFC00;
- shifttable[i | 0x000] = 24;
- shifttable[i | 0x100] = 24;
-
- } else { // Infinity and NaN's stay Infinity and NaN's
- basetable[i | 0x000] = 0x7C00;
- basetable[i | 0x100] = 0xFC00;
- shifttable[i | 0x000] = 13;
- shifttable[i | 0x100] = 13;
- }
- }
-
- fid.write("const quint32 qfloat16::basetable[512] = {\n");
- for (i = 0; i < 512; i++)
- fid.write(PRINTHEX(basetable[i]));
-
- fid.write("};\n\n");
-
- fid.write("const quint32 qfloat16::shifttable[512] = {\n");
- for (i = 0; i < 512; i++)
- fid.write(PRINTHEX(shifttable[i]));
-
- fid.write("};\n\n");
-
- fid.write("#endif // !__F16C__ && !__ARM_FP16_FORMAT_IEEE\n\n");
- fid.write("QT_END_NAMESPACE\n");
- fid.close();
- return 0;
-}
diff --git a/src/tools/qfloat16-tables/qfloat16-tables.pro b/src/tools/qfloat16-tables/qfloat16-tables.pro
deleted file mode 100644
index a7d10ac197..0000000000
--- a/src/tools/qfloat16-tables/qfloat16-tables.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-option(host_build)
-
-CONFIG += force_bootstrap
-SOURCES += gen_qfloat16_tables.cpp
-
-load(qt_tool)
-
-lib.CONFIG = dummy_install
-INSTALLS = lib
diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp
index 508db696b1..95f70dc988 100644
--- a/src/tools/qlalr/cppgenerator.cpp
+++ b/src/tools/qlalr/cppgenerator.cpp
@@ -36,6 +36,8 @@
#include <QtCore/qfile.h>
#include <QtCore/qmap.h>
+#include <iterator>
+
namespace {
void generateSeparator(int i, QTextStream &out)
@@ -43,7 +45,7 @@ void generateSeparator(int i, QTextStream &out)
if (!(i % 10)) {
if (i)
out << ",";
- out << endl << " ";
+ out << Qt::endl << " ";
} else {
out << ", ";
}
@@ -126,9 +128,9 @@ QString CppGenerator::endIncludeGuard(const QString &fileName)
void CppGenerator::operator () ()
{
// action table...
- state_count = aut.states.size ();
- terminal_count = grammar.terminals.size ();
- non_terminal_count = grammar.non_terminals.size ();
+ state_count = static_cast<int>(aut.states.size());
+ terminal_count = static_cast<int>(grammar.terminals.size());
+ non_terminal_count = static_cast<int>(grammar.non_terminals.size());
#define ACTION(i, j) table [(i) * terminal_count + (j)]
#define GOTO(i, j) pgoto [(i) * non_terminal_count + (j)]
@@ -156,7 +158,7 @@ void CppGenerator::operator () ()
if (grammar.isNonTerminal (a.key ()))
{
- Q_ASSERT (symbol >= terminal_count && symbol < grammar.names.size ());
+ Q_ASSERT(symbol >= terminal_count && symbol < static_cast<int>(grammar.names.size()));
GOTO (q, symbol - terminal_count) = r;
}
@@ -187,14 +189,14 @@ void CppGenerator::operator () ()
{
if (verbose)
qout() << "*** Warning. Found a reduce/reduce conflict in state " << q << " on token ``" << s << "'' between rule "
- << r << " and " << -u << endl;
+ << r << " and " << -u << Qt::endl;
++reduce_reduce_conflict_count;
u = qMax (u, -r);
if (verbose)
- qout() << "\tresolved using rule " << -u << endl;
+ qout() << "\tresolved using rule " << -u << Qt::endl;
}
else if (u > 0)
@@ -227,7 +229,7 @@ void CppGenerator::operator () ()
++shift_reduce_conflict_count;
if (verbose)
- qout() << "*** Warning. Found a shift/reduce conflict in state " << q << " on token ``" << s << "'' with rule " << r << endl;
+ qout() << "*** Warning. Found a shift/reduce conflict in state " << q << " on token ``" << s << "'' with rule " << r << Qt::endl;
}
}
}
@@ -238,14 +240,14 @@ void CppGenerator::operator () ()
{
if (shift_reduce_conflict_count != grammar.expected_shift_reduce
|| reduce_reduce_conflict_count != grammar.expected_reduce_reduce)
- qerr() << "*** Conflicts: " << shift_reduce_conflict_count << " shift/reduce, " << reduce_reduce_conflict_count << " reduce/reduce" << endl;
+ qerr() << "*** Conflicts: " << shift_reduce_conflict_count << " shift/reduce, " << reduce_reduce_conflict_count << " reduce/reduce" << Qt::endl;
if (verbose)
- qout() << endl << "*** Conflicts: " << shift_reduce_conflict_count << " shift/reduce, " << reduce_reduce_conflict_count << " reduce/reduce" << endl
- << endl;
+ qout() << Qt::endl << "*** Conflicts: " << shift_reduce_conflict_count << " shift/reduce, " << reduce_reduce_conflict_count << " reduce/reduce" << Qt::endl
+ << Qt::endl;
}
- QBitArray used_rules (grammar.rules.count ());
+ QBitArray used_rules{static_cast<int>(grammar.rules.size())};
int q = 0;
for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state, ++q)
@@ -259,14 +261,13 @@ void CppGenerator::operator () ()
}
}
- for (int i = 0; i < used_rules.count (); ++i)
+ auto rule = grammar.rules.begin();
+ for (int i = 0; i < used_rules.count (); ++i, ++rule)
{
if (! used_rules.testBit (i))
{
- RulePointer rule = grammar.rules.begin () + i;
-
if (rule != grammar.goal)
- qerr() << "*** Warning: Rule ``" << *rule << "'' is useless!" << endl;
+ qerr() << "*** Warning: Rule ``" << *rule << "'' is useless!" << Qt::endl;
}
}
@@ -280,7 +281,7 @@ void CppGenerator::operator () ()
if (u >= 0)
continue;
- RulePointer rule = grammar.rules.begin () + (- u - 1);
+ RulePointer rule = std::next(grammar.rules.begin(), - u - 1);
if (state->defaultReduce == rule)
u = 0;
@@ -348,26 +349,26 @@ void CppGenerator::operator () ()
{
out << copyrightHeader()
<< privateCopyrightHeader()
- << endl;
+ << Qt::endl;
}
out << "// This file was generated by qlalr - DO NOT EDIT!\n";
- out << startIncludeGuard(grammar.merged_output) << endl;
+ out << startIncludeGuard(grammar.merged_output) << Qt::endl;
if (copyright) {
- out << "#if defined(ERROR)" << endl
- << "# undef ERROR" << endl
- << "#endif" << endl << endl;
+ out << "#if defined(ERROR)" << Qt::endl
+ << "# undef ERROR" << Qt::endl
+ << "#endif" << Qt::endl << Qt::endl;
}
generateDecl (out);
generateImpl (out);
out << p.decls();
out << p.impls();
- out << endl;
+ out << Qt::endl;
- out << endIncludeGuard(grammar.merged_output) << endl;
+ out << endIncludeGuard(grammar.merged_output) << Qt::endl;
return;
}
@@ -388,24 +389,24 @@ void CppGenerator::operator () ()
{
out << copyrightHeader()
<< privateCopyrightHeader()
- << endl;
+ << Qt::endl;
}
out << "// This file was generated by qlalr - DO NOT EDIT!\n";
- out << "#ifndef " << prot << endl
- << "#define " << prot << endl
- << endl;
+ out << "#ifndef " << prot << Qt::endl
+ << "#define " << prot << Qt::endl
+ << Qt::endl;
if (copyright) {
- out << "#include <QtCore/qglobal.h>" << endl << endl;
- out << "QT_BEGIN_NAMESPACE" << endl << endl;
+ out << "#include <QtCore/qglobal.h>" << Qt::endl << Qt::endl;
+ out << "QT_BEGIN_NAMESPACE" << Qt::endl << Qt::endl;
}
generateDecl (out);
if (copyright)
- out << "QT_END_NAMESPACE" << endl;
+ out << "QT_END_NAMESPACE" << Qt::endl;
- out << "#endif // " << prot << endl << endl;
+ out << "#endif // " << prot << Qt::endl << Qt::endl;
} // end decls
{ // bits...
@@ -419,12 +420,12 @@ void CppGenerator::operator () ()
out << "// This file was generated by qlalr - DO NOT EDIT!\n";
- out << "#include \"" << declFileName << "\"" << endl << endl;
+ out << "#include \"" << declFileName << "\"" << Qt::endl << Qt::endl;
if (copyright)
- out << "QT_BEGIN_NAMESPACE" << endl << endl;
+ out << "QT_BEGIN_NAMESPACE" << Qt::endl << Qt::endl;
generateImpl(out);
if (copyright)
- out << "QT_END_NAMESPACE" << endl;
+ out << "QT_END_NAMESPACE" << Qt::endl;
} // end bits
@@ -455,10 +456,10 @@ QString CppGenerator::debugInfoProt() const
void CppGenerator::generateDecl (QTextStream &out)
{
- out << "class " << grammar.table_name << endl
- << "{" << endl
- << "public:" << endl
- << " enum VariousConstants {" << endl;
+ out << "class " << grammar.table_name << Qt::endl
+ << "{" << Qt::endl
+ << "public:" << Qt::endl
+ << " enum VariousConstants {" << Qt::endl;
for (const Name &t : qAsConst(grammar.terminals))
{
@@ -474,62 +475,62 @@ void CppGenerator::generateDecl (QTextStream &out)
else
name.prepend (grammar.token_prefix);
- out << " " << name << " = " << value << "," << endl;
+ out << " " << name << " = " << value << "," << Qt::endl;
}
- out << endl
- << " ACCEPT_STATE = " << accept_state << "," << endl
- << " RULE_COUNT = " << grammar.rules.size () << "," << endl
- << " STATE_COUNT = " << state_count << "," << endl
- << " TERMINAL_COUNT = " << terminal_count << "," << endl
- << " NON_TERMINAL_COUNT = " << non_terminal_count << "," << endl
- << endl
- << " GOTO_INDEX_OFFSET = " << compressed_action.index.size () << "," << endl
- << " GOTO_INFO_OFFSET = " << compressed_action.info.size () << "," << endl
- << " GOTO_CHECK_OFFSET = " << compressed_action.check.size () << endl
- << " };" << endl
- << endl
- << " static const char *const spell[];" << endl
- << " static const short lhs[];" << endl
- << " static const short rhs[];" << endl;
+ out << Qt::endl
+ << " ACCEPT_STATE = " << accept_state << "," << Qt::endl
+ << " RULE_COUNT = " << grammar.rules.size () << "," << Qt::endl
+ << " STATE_COUNT = " << state_count << "," << Qt::endl
+ << " TERMINAL_COUNT = " << terminal_count << "," << Qt::endl
+ << " NON_TERMINAL_COUNT = " << non_terminal_count << "," << Qt::endl
+ << Qt::endl
+ << " GOTO_INDEX_OFFSET = " << compressed_action.index.size () << "," << Qt::endl
+ << " GOTO_INFO_OFFSET = " << compressed_action.info.size () << "," << Qt::endl
+ << " GOTO_CHECK_OFFSET = " << compressed_action.check.size () << Qt::endl
+ << " };" << Qt::endl
+ << Qt::endl
+ << " static const char *const spell[];" << Qt::endl
+ << " static const short lhs[];" << Qt::endl
+ << " static const short rhs[];" << Qt::endl;
if (debug_info)
{
QString prot = debugInfoProt();
- out << endl << "#ifndef " << prot << endl
- << " static const int rule_index[];" << endl
- << " static const int rule_info[];" << endl
- << "#endif // " << prot << endl << endl;
+ out << Qt::endl << "#ifndef " << prot << Qt::endl
+ << " static const int rule_index[];" << Qt::endl
+ << " static const int rule_info[];" << Qt::endl
+ << "#endif // " << prot << Qt::endl << Qt::endl;
}
- out << " static const short goto_default[];" << endl
- << " static const short action_default[];" << endl
- << " static const short action_index[];" << endl
- << " static const short action_info[];" << endl
- << " static const short action_check[];" << endl
- << endl
- << " static inline int nt_action (int state, int nt)" << endl
- << " {" << endl
- << " const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" << endl
- << " if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" << endl
- << " return goto_default [nt];" << endl
- << endl
- << " return action_info [GOTO_INFO_OFFSET + yyn];" << endl
- << " }" << endl
- << endl
- << " static inline int t_action (int state, int token)" << endl
- << " {" << endl
- << " const int yyn = action_index [state] + token;" << endl
- << endl
- << " if (yyn < 0 || action_check [yyn] != token)" << endl
- << " return - action_default [state];" << endl
- << endl
- << " return action_info [yyn];" << endl
- << " }" << endl
- << "};" << endl
- << endl
- << endl;
+ out << " static const short goto_default[];" << Qt::endl
+ << " static const short action_default[];" << Qt::endl
+ << " static const short action_index[];" << Qt::endl
+ << " static const short action_info[];" << Qt::endl
+ << " static const short action_check[];" << Qt::endl
+ << Qt::endl
+ << " static inline int nt_action (int state, int nt)" << Qt::endl
+ << " {" << Qt::endl
+ << " const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" << Qt::endl
+ << " if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" << Qt::endl
+ << " return goto_default [nt];" << Qt::endl
+ << Qt::endl
+ << " return action_info [GOTO_INFO_OFFSET + yyn];" << Qt::endl
+ << " }" << Qt::endl
+ << Qt::endl
+ << " static inline int t_action (int state, int token)" << Qt::endl
+ << " {" << Qt::endl
+ << " const int yyn = action_index [state] + token;" << Qt::endl
+ << Qt::endl
+ << " if (yyn < 0 || action_check [yyn] != token)" << Qt::endl
+ << " return - action_default [state];" << Qt::endl
+ << Qt::endl
+ << " return action_info [yyn];" << Qt::endl
+ << " }" << Qt::endl
+ << "};" << Qt::endl
+ << Qt::endl
+ << Qt::endl;
}
void CppGenerator::generateImpl (QTextStream &out)
@@ -568,16 +569,16 @@ void CppGenerator::generateImpl (QTextStream &out)
{
first_nt = false;
QString prot = debugInfoProt();
- out << endl << "#ifndef " << prot << endl;
+ out << Qt::endl << "#ifndef " << prot << Qt::endl;
}
out << "\"" << *t << "\"";
}
}
if (debug_info)
- out << endl << "#endif // " << debugInfoProt() << endl;
+ out << Qt::endl << "#endif // " << debugInfoProt() << Qt::endl;
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const short " << grammar.table_name << "::lhs [] = {";
idx = 0;
@@ -587,7 +588,7 @@ void CppGenerator::generateImpl (QTextStream &out)
out << aut.id (rule->lhs);
}
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const short " << grammar.table_name << "::rhs [] = {";
idx = 0;
@@ -597,13 +598,13 @@ void CppGenerator::generateImpl (QTextStream &out)
out << rule->rhs.size ();
}
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
if (debug_info)
{
QString prot = debugInfoProt();
- out << endl << "#ifndef " << prot << endl;
+ out << Qt::endl << "#ifndef " << prot << Qt::endl;
out << "const int " << grammar.table_name << "::rule_info [] = {";
idx = 0;
for (auto rule = grammar.rules.cbegin (); rule != grammar.rules.cend (); ++rule, ++idx)
@@ -615,11 +616,11 @@ void CppGenerator::generateImpl (QTextStream &out)
for (const Name &n : rule->rhs)
out << ", " << name_ids.value (n);
}
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const int " << grammar.table_name << "::rule_index [] = {";
idx = 0;
- int offset = 0;
+ size_t offset = 0;
for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
{
generateSeparator(idx, out);
@@ -627,8 +628,8 @@ void CppGenerator::generateImpl (QTextStream &out)
out << offset;
offset += rule->rhs.size () + 1;
}
- out << endl << "};" << endl
- << "#endif // " << prot << endl << endl;
+ out << Qt::endl << "};" << Qt::endl
+ << "#endif // " << prot << Qt::endl << Qt::endl;
}
out << "const short " << grammar.table_name << "::action_default [] = {";
@@ -642,27 +643,27 @@ void CppGenerator::generateImpl (QTextStream &out)
else
out << "0";
}
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const short " << grammar.table_name << "::goto_default [] = {";
generateList(defgoto, out);
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const short " << grammar.table_name << "::action_index [] = {";
generateList(compressed_action.index, out);
- out << "," << endl;
+ out << "," << Qt::endl;
generateList(compressed_goto.index, out);
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const short " << grammar.table_name << "::action_info [] = {";
generateList(compressed_action.info, out);
- out << "," << endl;
+ out << "," << Qt::endl;
generateList(compressed_goto.info, out);
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
out << "const short " << grammar.table_name << "::action_check [] = {";
generateList(compressed_action.check, out);
- out << "," << endl;
+ out << "," << Qt::endl;
generateList(compressed_goto.check, out);
- out << endl << "};" << endl << endl;
+ out << Qt::endl << "};" << Qt::endl << Qt::endl;
}
diff --git a/src/tools/qlalr/dotgraph.cpp b/src/tools/qlalr/dotgraph.cpp
index 1fa0a1ac77..1d479af2b2 100644
--- a/src/tools/qlalr/dotgraph.cpp
+++ b/src/tools/qlalr/dotgraph.cpp
@@ -41,9 +41,9 @@ void DotGraph::operator () (Automaton *aut)
{
Grammar *g = aut->_M_grammar;
- out << "digraph {" << endl << endl;
+ out << "digraph {" << Qt::endl << Qt::endl;
- out << "subgraph Includes {" << endl;
+ out << "subgraph Includes {" << Qt::endl;
for (Automaton::IncludesGraph::iterator incl = Automaton::IncludesGraph::begin_nodes ();
incl != Automaton::IncludesGraph::end_nodes (); ++incl)
{
@@ -53,14 +53,14 @@ void DotGraph::operator () (Automaton *aut)
out << "\t->\t";
out << "\"(" << aut->id ((*edge)->data.state) << ", " << (*edge)->data.nt << ")\"\t";
out << "[label=\"" << incl->data.state->follows [incl->data.nt] << "\"]";
- out << endl;
+ out << Qt::endl;
}
}
- out << "}" << endl << endl;
+ out << "}" << Qt::endl << Qt::endl;
- out << "subgraph LRA {" << endl;
- //out << "node [shape=record];" << endl << endl;
+ out << "subgraph LRA {" << Qt::endl;
+ //out << "node [shape=record];" << Qt::endl << Qt::endl;
for (StatePointer q = aut->states.begin (); q != aut->states.end (); ++q)
{
@@ -74,16 +74,16 @@ void DotGraph::operator () (Automaton *aut)
for (ItemPointer item = q->kernel.begin (); item != q->kernel.end (); ++item)
out << "| <" << index++ << "> " << *item;
- out << "}\"]" << endl;
+ out << "}\"]" << Qt::endl;
for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
{
const char *clr = g->isTerminal (a.key ()) ? "blue" : "red";
- out << "\t" << state << "\t->\t" << aut->id (*a) << "\t[color=\"" << clr << "\",label=\"" << a.key () << "\"]" << endl;
+ out << "\t" << state << "\t->\t" << aut->id (*a) << "\t[color=\"" << clr << "\",label=\"" << a.key () << "\"]" << Qt::endl;
}
- out << endl;
+ out << Qt::endl;
}
- out << "}" << endl;
- out << endl << endl << "}" << endl;
+ out << "}" << Qt::endl;
+ out << Qt::endl << Qt::endl << "}" << Qt::endl;
}
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
index 541523d49c..c7269bed5f 100644
--- a/src/tools/qlalr/lalr.cpp
+++ b/src/tools/qlalr/lalr.cpp
@@ -51,7 +51,9 @@ QTextStream &qout()
static QTextStream result(stdout, QIODevice::WriteOnly);
return result;
}
+QT_END_NAMESPACE
+namespace std {
bool operator < (Name a, Name b)
{
return *a < *b;
@@ -66,7 +68,7 @@ bool operator < (StatePointer a, StatePointer b)
{
return &*a < &*b;
}
-QT_END_NAMESPACE
+}
bool Read::operator < (const Read &other) const
{
@@ -319,7 +321,7 @@ void Automaton::buildNullables ()
}
#ifndef QLALR_NO_DEBUG_NULLABLES
- qerr() << "nullables = {" << nullables << endl;
+ qerr() << "nullables = {" << nullables << Qt::endl;
#endif
}
@@ -335,7 +337,7 @@ QPair<StatePointer, bool> Automaton::internState (const State &state)
struct _Bucket
{
- QLinkedList<ItemPointer> items;
+ std::list<ItemPointer> items;
void insert (ItemPointer item)
{ items.push_back (item); }
@@ -344,8 +346,8 @@ struct _Bucket
{
State st (aut->_M_grammar);
- for (QLinkedList<ItemPointer>::iterator item = items.begin (); item != items.end (); ++item)
- st.insert ((*item)->next ());
+ for (auto &item : items)
+ st.insert(item->next());
return st;
}
@@ -462,7 +464,7 @@ void Automaton::buildLookbackSets ()
lookbacks.insert (item, Lookback (p, A));
#ifndef QLALR_NO_DEBUG_LOOKBACKS
- qerr() << "*** (" << id (q) << ", " << *rule << ") lookback (" << id (p) << ", " << *A << ")" << endl;
+ qerr() << "*** (" << id (q) << ", " << *rule << ") lookback (" << id (p) << ", " << *A << ")" << Qt::endl;
#endif
}
}
@@ -493,7 +495,7 @@ void Automaton::buildDirectReads ()
#ifndef QLALR_NO_DEBUG_DIRECT_READS
for (QMap<Name, NameSet>::iterator dr = q->reads.begin (); dr != q->reads.end (); ++dr)
- qerr() << "*** DR(" << id (q) << ", " << dr.key () << ") = " << dr.value () << endl;
+ qerr() << "*** DR(" << id (q) << ", " << dr.key () << ") = " << dr.value () << Qt::endl;
#endif
}
}
@@ -526,7 +528,7 @@ void Automaton::buildReadsDigraph ()
dump (qerr(), source);
qerr() << " reads ";
dump (qerr(), target);
- qerr() << endl;
+ qerr() << Qt::endl;
#endif
}
}
@@ -561,7 +563,7 @@ void Automaton::visitReadNode (ReadNode node)
_M_reads_stack.push (node);
#ifndef QLALR_NO_DEBUG_INCLUDES
- // qerr() << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << endl;
+ // qerr() << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << Qt::endl;
#endif
for (ReadsGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
@@ -641,7 +643,7 @@ void Automaton::buildIncludesDigraph ()
source->insertEdge (target);
#ifndef QLALR_NO_DEBUG_INCLUDES
- qerr() << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << endl;
+ qerr() << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << Qt::endl;
#endif // QLALR_NO_DEBUG_INCLUDES
continue;
@@ -663,7 +665,7 @@ void Automaton::buildIncludesDigraph ()
source->insertEdge (target);
#ifndef QLALR_NO_DEBUG_INCLUDES
- qerr() << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << endl;
+ qerr() << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << Qt::endl;
#endif // QLALR_NO_DEBUG_INCLUDES
}
}
@@ -680,7 +682,7 @@ void Automaton::visitIncludeNode (IncludeNode node)
_M_includes_stack.push (node);
#ifndef QLALR_NO_DEBUG_INCLUDES
- // qerr() << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << endl;
+ // qerr() << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << Qt::endl;
#endif
for (IncludesGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
@@ -696,7 +698,7 @@ void Automaton::visitIncludeNode (IncludeNode node)
dump (qerr(), node);
qerr() << " += follows";
dump (qerr(), r);
- qerr() << endl;
+ qerr() << Qt::endl;
#endif
NameSet &dst = node->data.state->follows [node->data.nt];
@@ -732,7 +734,7 @@ void Automaton::buildLookaheads ()
#ifndef QLALR_NO_DEBUG_LOOKAHEADS
qerr() << "(" << id (p) << ", " << *item->rule << ") lookbacks ";
dump (qerr(), lookback);
- qerr() << " with follows (" << id (q) << ", " << lookback.nt << ") = " << q->follows [lookback.nt] << endl;
+ qerr() << " with follows (" << id (q) << ", " << lookback.nt << ") = " << q->follows [lookback.nt] << Qt::endl;
#endif
lookaheads [item].insert (q->follows [lookback.nt].begin (), q->follows [lookback.nt].end ());
@@ -760,7 +762,7 @@ void Automaton::buildDefaultReduceActions ()
if (item->dot != item->end_rhs ())
continue;
- int la = lookaheads.value (item).size ();
+ int la = static_cast<int>(lookaheads.value(item).size());
if (def == state->closure.end () || la > size)
{
def = item;
diff --git a/src/tools/qlalr/lalr.g b/src/tools/qlalr/lalr.g
index 05d30c21fd..a849800dd5 100644
--- a/src/tools/qlalr/lalr.g
+++ b/src/tools/qlalr/lalr.g
@@ -261,7 +261,7 @@ int Recognizer::nextToken()
if (ch == QLatin1Char ('"'))
inp ();
else
- qerr() << _M_input_file << ":" << _M_line << ": Warning. Expected `\"'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Warning. Expected `\"'" << Qt::endl;
_M_current_value = text;
return (token = STRING_LITERAL);
@@ -314,7 +314,7 @@ int Recognizer::nextToken()
return (token = PREC);
else
{
- qerr() << _M_input_file << ":" << _M_line << ": Unknown keyword `" << text << "'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Unknown keyword `" << text << "'" << Qt::endl;
exit (EXIT_FAILURE);
return (token = ERROR);
}
@@ -659,7 +659,7 @@ case $rule_number: {
if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
{
- qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << Qt::endl;
return false;
}
@@ -683,7 +683,7 @@ case $rule_number: {
if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
{
- qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << Qt::endl;
return false;
}
@@ -712,7 +712,7 @@ case $rule_number: {
Name tok = _M_grammar->intern (sym(2));
if (! _M_grammar->isTerminal (tok))
{
- qerr() << _M_input_file << ":" << _M_line << ": `" << *tok << " is not a terminal symbol" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": `" << *tok << " is not a terminal symbol" << Qt::endl;
_M_current_rule->prec = _M_grammar->names.end ();
}
else
@@ -758,7 +758,7 @@ case $rule_number: {
}
}
- qerr() << _M_input_file << ":" << _M_line << ": Syntax error" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Syntax error" << Qt::endl;
return false;
}
diff --git a/src/tools/qlalr/lalr.h b/src/tools/qlalr/lalr.h
index 8eadee400d..473ea89769 100644
--- a/src/tools/qlalr/lalr.h
+++ b/src/tools/qlalr/lalr.h
@@ -39,6 +39,7 @@
#include <algorithm>
#include <functional>
+#include <set>
class Rule;
class State;
@@ -48,121 +49,24 @@ class State;
class Arrow;
class Automaton;
-template <typename _Tp >
-class OrderedSet : protected QMap<_Tp, bool>
-{
- typedef QMap<_Tp, bool> _Base;
-
-public:
- class const_iterator
- {
- typename _Base::const_iterator _M_iterator;
-
- public:
- const_iterator () {}
-
- const_iterator (const typename _Base::iterator &it):
- _M_iterator (typename _Base::const_iterator(it)) {}
- const_iterator (const typename _Base::const_iterator &it):
- _M_iterator (it) {}
-
- const _Tp &operator * () const
- { return _M_iterator.key (); }
-
- const _Tp *operator -> () const
- { return &_M_iterator.key (); }
-
- const_iterator &operator ++ ()
- { ++_M_iterator; return *this; }
-
- const_iterator operator ++ (int) const
- {
- const_iterator me (*this);
- ++_M_iterator;
- return me;
- }
-
- bool operator == (const const_iterator &other) const
- { return _M_iterator == other._M_iterator; }
-
- bool operator != (const const_iterator &other) const
- { return _M_iterator != other._M_iterator; }
- };
-
- typedef const_iterator iterator;
-
-public:
- OrderedSet () {}
-
- const_iterator begin () const
- { return const_iterator (_Base::begin ()); }
-
- const_iterator end () const
- { return const_iterator (_Base::end ()); }
-
- bool isEmpty () const
- { return _Base::isEmpty (); }
-
- int size () const
- { return _Base::size (); }
-
- const_iterator find (const _Tp &elt) const
- { return const_iterator (_Base::find (elt)); }
-
- QPair<const_iterator, bool> insert (const _Tp &elt)
- {
- int elts = _Base::size ();
- const_iterator it (_Base::insert (typename _Base::key_type (elt), true));
- return qMakePair (it, elts != _Base::size ());
- }
-
- QPair<const_iterator, bool> insert (const_iterator, const _Tp &elt)
- {
- int elts = _Base::size ();
- const_iterator it (_Base::insert (typename _Base::key_type (elt), true));
- return qMakePair (it, elts != _Base::size ());
- }
-
- const _Tp &operator [] (const _Tp &elt)
- { return *insert (elt)->first; }
-
- template <typename _InputIterator>
- void insert (_InputIterator first, _InputIterator last)
- {
- for (; first != last; ++first)
- insert (*first);
- }
-};
// names
-typedef QLinkedList<QString>::iterator Name;
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(QLinkedList<QString>::iterator, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
-typedef QLinkedList<Name> NameList;
-typedef OrderedSet<Name> NameSet;
+typedef std::list<QString>::iterator Name;
+typedef std::list<Name> NameList;
+typedef std::set<Name> NameSet;
// items
-typedef QLinkedList<Item> ItemList;
+typedef std::list<Item> ItemList;
typedef ItemList::iterator ItemPointer;
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(ItemList::iterator, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
// rules
-typedef QLinkedList<Rule> debug_infot;
+typedef std::list<Rule> debug_infot;
typedef debug_infot::iterator RulePointer;
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(debug_infot::iterator, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
typedef QMultiMap<Name, RulePointer> RuleMap;
// states
-typedef QLinkedList<State> StateList;
+typedef std::list<State> StateList;
typedef StateList::iterator StatePointer;
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(StateList::iterator, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
// arrows
typedef QMap<Name, StatePointer> Bundle;
@@ -257,9 +161,9 @@ template <typename _Tp>
class Node
{
public:
- typedef OrderedSet<Node<_Tp> > Repository;
+ typedef std::set<Node<_Tp> > Repository;
typedef typename Repository::iterator iterator;
- typedef typename QLinkedList<iterator>::iterator edge_iterator;
+ typedef typename std::list<iterator>::iterator edge_iterator;
public:
static iterator get (_Tp data);
@@ -297,7 +201,7 @@ public: // attributes
mutable bool root;
mutable int dfn;
mutable _Tp data;
- mutable QLinkedList<iterator> outs;
+ mutable std::list<iterator> outs;
protected:
inline Node () {}
@@ -319,7 +223,7 @@ typename Node<_Tp>::iterator Node<_Tp>::get (_Tp data)
}
template <typename _Tp>
-QPair<typename QLinkedList<typename Node<_Tp>::iterator>::iterator, bool> Node<_Tp>::insertEdge (typename Node<_Tp>::iterator other) const
+QPair<typename std::list<typename Node<_Tp>::iterator>::iterator, bool> Node<_Tp>::insertEdge(typename Node<_Tp>::iterator other) const
{
edge_iterator it = std::find (outs.begin (), outs.end (), other);
@@ -356,7 +260,7 @@ public:
QString decl_file_name;
QString impl_file_name;
QString token_prefix;
- QLinkedList<QString> names;
+ std::list<QString> names;
Name start;
NameSet terminals;
NameSet non_terminals;
@@ -406,9 +310,6 @@ public:
StatePointer state;
Name nt;
};
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(OrderedSet<Node<Read> >::const_iterator, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
class Include
{
@@ -430,9 +331,6 @@ public:
StatePointer state;
Name nt;
};
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(OrderedSet<Node<Include> >::const_iterator, Q_PRIMITIVE_TYPE);
-QT_END_NAMESPACE
class Automaton
{
@@ -491,11 +389,11 @@ private:
int _M_includes_dfn;
};
-QT_BEGIN_NAMESPACE
+namespace std {
bool operator < (Name a, Name b);
bool operator < (StatePointer a, StatePointer b);
bool operator < (ItemPointer a, ItemPointer b);
-QT_END_NAMESPACE
+}
QTextStream &operator << (QTextStream &out, const Name &n);
QTextStream &operator << (QTextStream &out, const Rule &r);
diff --git a/src/tools/qlalr/main.cpp b/src/tools/qlalr/main.cpp
index 5971eb201d..6a57c7aa7a 100644
--- a/src/tools/qlalr/main.cpp
+++ b/src/tools/qlalr/main.cpp
@@ -44,15 +44,15 @@
static void help_me ()
{
- qerr() << "Usage: qlalr [options] [input file name]" << endl
- << endl
- << " --help, -h\t\tdisplay this help and exit" << endl
- << " --verbose, -v\t\tverbose output" << endl
- << " --no-debug\t\tno debug information" << endl
- << " --no-lines\t\tno #line directives" << endl
- << " --dot\t\t\tgenerate a graph" << endl
- << " --qt\t\tadd the Qt copyright header and Qt-specific types and macros" << endl
- << endl;
+ qerr() << "Usage: qlalr [options] [input file name]" << Qt::endl
+ << Qt::endl
+ << " --help, -h\t\tdisplay this help and exit" << Qt::endl
+ << " --verbose, -v\t\tverbose output" << Qt::endl
+ << " --no-debug\t\tno debug information" << Qt::endl
+ << " --no-lines\t\tno #line directives" << Qt::endl
+ << " --dot\t\t\tgenerate a graph" << Qt::endl
+ << " --qt\t\tadd the Qt copyright header and Qt-specific types and macros" << Qt::endl
+ << Qt::endl;
exit (0);
}
@@ -91,7 +91,7 @@ int main (int argc, char *argv[])
file_name = arg;
else
- qerr() << "*** Warning. Ignore argument `" << arg << "'" << endl;
+ qerr() << "*** Warning. Ignore argument `" << arg << "'" << Qt::endl;
}
if (file_name.isEmpty ())
@@ -106,15 +106,15 @@ int main (int argc, char *argv[])
if (! p.parse (file_name))
exit (EXIT_FAILURE);
- if (grammar.rules.isEmpty ())
+ if (grammar.rules.empty())
{
- qerr() << "*** Fatal. No rules!" << endl;
+ qerr() << "*** Fatal. No rules!" << Qt::endl;
exit (EXIT_FAILURE);
}
else if (grammar.start == grammar.names.end ())
{
- qerr() << "*** Fatal. No start symbol!" << endl;
+ qerr() << "*** Fatal. No start symbol!" << Qt::endl;
exit (EXIT_FAILURE);
}
diff --git a/src/tools/qlalr/parsetable.cpp b/src/tools/qlalr/parsetable.cpp
index c88ac1291e..9e71acebb4 100644
--- a/src/tools/qlalr/parsetable.cpp
+++ b/src/tools/qlalr/parsetable.cpp
@@ -43,13 +43,13 @@ void ParseTable::operator () (Automaton *aut)
int rindex = 1;
for (RulePointer rule = g->rules.begin (); rule != g->rules.end (); ++rule)
- out << rindex++ << ")\t" << *rule << endl;
- out << endl << endl;
+ out << rindex++ << ")\t" << *rule << Qt::endl;
+ out << Qt::endl << Qt::endl;
int index = 0;
for (StatePointer state = aut->states.begin (); state != aut->states.end (); ++state)
{
- out << "state " << index++ << endl << endl;
+ out << "state " << index++ << Qt::endl << Qt::endl;
for (ItemPointer item = state->kernel.begin (); item != state->kernel.end (); ++item)
{
@@ -58,7 +58,7 @@ void ParseTable::operator () (Automaton *aut)
if (item->dot == item->end_rhs ())
out << " " << aut->lookaheads [item];
- out << endl;
+ out << Qt::endl;
}
bool first = true;
@@ -68,11 +68,11 @@ void ParseTable::operator () (Automaton *aut)
continue;
if (first)
- out << endl;
+ out << Qt::endl;
first = false;
- out << " " << *arrow.key () << " shift, and go to state " << std::distance (aut->states.begin (), *arrow) << endl;
+ out << " " << *arrow.key () << " shift, and go to state " << std::distance (aut->states.begin (), *arrow) << Qt::endl;
}
first = true;
@@ -82,13 +82,13 @@ void ParseTable::operator () (Automaton *aut)
continue;
if (first)
- out << endl;
+ out << Qt::endl;
first = false;
const auto lookaheads = aut->lookaheads.value(item);
for (const Name &la : lookaheads)
- out << " " << *la << " reduce using rule " << aut->id (item->rule) << " (" << *item->rule->lhs << ")" << endl;
+ out << " " << *la << " reduce using rule " << aut->id (item->rule) << " (" << *item->rule->lhs << ")" << Qt::endl;
}
first = true;
@@ -98,19 +98,19 @@ void ParseTable::operator () (Automaton *aut)
continue;
if (first)
- out << endl;
+ out << Qt::endl;
first = false;
- out << " " << *arrow.key () << " go to state " << std::distance (aut->states.begin (), *arrow) << endl;
+ out << " " << *arrow.key () << " go to state " << std::distance (aut->states.begin (), *arrow) << Qt::endl;
}
if (state->defaultReduce != g->rules.end ())
{
- out << endl
- << " $default reduce using rule " << aut->id (state->defaultReduce) << " (" << *state->defaultReduce->lhs << ")" << endl;
+ out << Qt::endl
+ << " $default reduce using rule " << aut->id (state->defaultReduce) << " (" << *state->defaultReduce->lhs << ")" << Qt::endl;
}
- out << endl;
+ out << Qt::endl;
}
}
diff --git a/src/tools/qlalr/recognizer.cpp b/src/tools/qlalr/recognizer.cpp
index ab797c85d0..3da54c0c6a 100644
--- a/src/tools/qlalr/recognizer.cpp
+++ b/src/tools/qlalr/recognizer.cpp
@@ -97,7 +97,7 @@ int Recognizer::nextToken()
if (ch == QLatin1Char ('"'))
inp ();
else
- qerr() << _M_input_file << ":" << _M_line << ": Warning. Expected `\"'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Warning. Expected `\"'" << Qt::endl;
_M_current_value = text;
return (token = STRING_LITERAL);
@@ -150,7 +150,7 @@ int Recognizer::nextToken()
return (token = PREC);
else
{
- qerr() << _M_input_file << ":" << _M_line << ": Unknown keyword `" << text << "'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Unknown keyword `" << text << "'" << Qt::endl;
exit (EXIT_FAILURE);
return (token = ERROR);
}
@@ -405,7 +405,7 @@ case 34: {
if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
{
- qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << Qt::endl;
return false;
}
@@ -420,7 +420,7 @@ case 38: {
if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
{
- qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << Qt::endl;
return false;
}
@@ -443,7 +443,7 @@ case 40: {
Name tok = _M_grammar->intern (sym(2));
if (! _M_grammar->isTerminal (tok))
{
- qerr() << _M_input_file << ":" << _M_line << ": `" << *tok << " is not a terminal symbol" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": `" << *tok << " is not a terminal symbol" << Qt::endl;
_M_current_rule->prec = _M_grammar->names.end ();
}
else
@@ -474,7 +474,7 @@ case 43: {
}
}
- qerr() << _M_input_file << ":" << _M_line << ": Syntax error" << endl;
+ qerr() << _M_input_file << ":" << _M_line << ": Syntax error" << Qt::endl;
return false;
}
diff --git a/src/tools/qvkgen/qvkgen.cpp b/src/tools/qvkgen/qvkgen.cpp
index 059f9413cb..4db3f26161 100644
--- a/src/tools/qvkgen/qvkgen.cpp
+++ b/src/tools/qvkgen/qvkgen.cpp
@@ -192,22 +192,20 @@ QString VkSpecParser::parseName()
QString funcSig(const VkSpecParser::Command &c, const char *className = nullptr)
{
- QString s;
- s.sprintf("%s %s%s%s", qPrintable(c.cmd.type),
- (className ? className : ""), (className ? "::" : ""),
- qPrintable(c.cmd.name));
+ QString s(QString::asprintf("%s %s%s%s", qPrintable(c.cmd.type),
+ (className ? className : ""), (className ? "::" : ""),
+ qPrintable(c.cmd.name)));
if (!c.args.isEmpty()) {
s += QLatin1Char('(');
bool first = true;
for (const VkSpecParser::TypedName &a : c.args) {
- QString argStr;
- argStr.sprintf("%s%s%s%s", qPrintable(a.type), (a.type.endsWith(QLatin1Char('*')) ? "" : " "),
- qPrintable(a.name), qPrintable(a.typeSuffix));
if (!first)
s += QStringLiteral(", ");
else
first = false;
- s += argStr;
+ s += QString::asprintf("%s%s%s%s", qPrintable(a.type),
+ (a.type.endsWith(QLatin1Char('*')) ? "" : " "),
+ qPrintable(a.name), qPrintable(a.typeSuffix));
}
s += QLatin1Char(')');
}
@@ -216,13 +214,12 @@ QString funcSig(const VkSpecParser::Command &c, const char *className = nullptr)
QString funcCall(const VkSpecParser::Command &c, int idx)
{
- QString s;
// template:
// [return] reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(d_ptr->m_funcs[0])(instance, pPhysicalDeviceCount, pPhysicalDevices);
- s.sprintf("%sreinterpret_cast<PFN_%s>(d_ptr->m_funcs[%d])",
- (c.cmd.type == QStringLiteral("void") ? "" : "return "),
- qPrintable(c.cmd.name),
- idx);
+ QString s = QString::asprintf("%sreinterpret_cast<PFN_%s>(d_ptr->m_funcs[%d])",
+ (c.cmd.type == QStringLiteral("void") ? "" : "return "),
+ qPrintable(c.cmd.name),
+ idx);
if (!c.args.isEmpty()) {
s += QLatin1Char('(');
bool first = true;
@@ -338,10 +335,9 @@ bool genVulkanFunctionsH(const QVector<VkSpecParser::Command> &commands, const Q
*dst += QStringLiteral(";\n");
}
- QString str;
- str.sprintf(s, preamble.get(licHeaderFn).constData(), instCmdStr.toUtf8().constData(), devCmdStr.toUtf8().constData());
-
- f.write(str.toUtf8());
+ f.write(QString::asprintf(s, preamble.get(licHeaderFn).constData(),
+ instCmdStr.toUtf8().constData(),
+ devCmdStr.toUtf8().constData()).toUtf8());
return true;
}
@@ -400,10 +396,7 @@ bool genVulkanFunctionsPH(const QVector<VkSpecParser::Command> &commands, const
[](const VkSpecParser::Command &c) { return c.deviceLevel; });
const int instLevelCount = commands.count() - devLevelCount;
- QString str;
- str.sprintf(s, preamble.get(licHeaderFn).constData(), instLevelCount, devLevelCount);
-
- f.write(str.toUtf8());
+ f.write(QString::asprintf(s, preamble.get(licHeaderFn).constData(), instLevelCount, devLevelCount).toUtf8());
return true;
}
@@ -478,10 +471,12 @@ bool genVulkanFunctionsPC(const QVector<VkSpecParser::Command> &commands, const
if (instCmdNamesStr.count() > 2)
instCmdNamesStr = instCmdNamesStr.left(instCmdNamesStr.count() - 2);
- QString str;
- str.sprintf(s, preamble.get(licHeaderFn).constData(),
- instCmdWrapperStr.toUtf8().constData(), instCmdNamesStr.toUtf8().constData(), instIdx,
- devCmdWrapperStr.toUtf8().constData(), devCmdNamesStr.toUtf8().constData(), commands.count() - instIdx);
+ const QString str =
+ QString::asprintf(s, preamble.get(licHeaderFn).constData(),
+ instCmdWrapperStr.toUtf8().constData(),
+ instCmdNamesStr.toUtf8().constData(), instIdx,
+ devCmdWrapperStr.toUtf8().constData(),
+ devCmdNamesStr.toUtf8().constData(), commands.count() - instIdx);
f.write(str.toUtf8());
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index 6e8c13be15..ac87e48e39 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -99,6 +99,37 @@ int createProject(const QString &outFileName)
return 0;
}
+// Escapes a path for use in a Depfile (Makefile syntax)
+QString makefileEscape(const QString &filepath)
+{
+ // Always use forward slashes
+ QString result = QDir::cleanPath(filepath);
+ // Spaces are escaped with a backslash
+ result.replace(QLatin1Char(' '), QLatin1String("\\ "));
+ // Pipes are escaped with a backslash
+ result.replace(QLatin1Char('|'), QLatin1String("\\|"));
+ // Dollars are escaped with a dollar
+ result.replace(QLatin1Char('$'), QLatin1String("$$"));
+
+ return result;
+}
+
+void writeDepFile(QIODevice &iodev, const QStringList &depsList, const QString &targetName)
+{
+ QTextStream out(&iodev);
+ out << qPrintable(makefileEscape(targetName));
+ out << QLatin1Char(':');
+
+ // Write depfile
+ for (int i = 0; i < depsList.size(); ++i) {
+ out << QLatin1Char(' ');
+
+ out << qPrintable(makefileEscape(depsList.at(i)));
+ }
+
+ out << QLatin1Char('\n');
+}
+
int runRcc(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
@@ -155,6 +186,11 @@ int runRcc(int argc, char *argv[])
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
parser.addOption(binaryOption);
+ QCommandLineOption generatorOption(QStringList{QStringLiteral("g"), QStringLiteral("generator")});
+ generatorOption.setDescription(QStringLiteral("Select generator."));
+ generatorOption.setValueName(QStringLiteral("cpp|python|python2"));
+ parser.addOption(generatorOption);
+
QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number"));
parser.addOption(passOption);
@@ -171,6 +207,10 @@ int runRcc(int argc, char *argv[])
QStringLiteral("Only output a mapping of resource paths to file system paths defined in the .qrc file, do not generate code."));
parser.addOption(mapOption);
+ QCommandLineOption depFileOption(QStringList{QStringLiteral("d"), QStringLiteral("depfile")},
+ QStringLiteral("Write a depfile with the .qrc dependencies to <file>."), QStringLiteral("file"));
+ parser.addOption(depFileOption);
+
QCommandLineOption projectOption(QStringLiteral("project"), QStringLiteral("Output a resource file containing all files from the current directory."));
parser.addOption(projectOption);
@@ -220,6 +260,18 @@ int runRcc(int argc, char *argv[])
library.setCompressThreshold(parser.value(thresholdOption).toInt());
if (parser.isSet(binaryOption))
library.setFormat(RCCResourceLibrary::Binary);
+ if (parser.isSet(generatorOption)) {
+ auto value = parser.value(generatorOption);
+ if (value == QLatin1String("cpp"))
+ library.setFormat(RCCResourceLibrary::C_Code);
+ else if (value == QLatin1String("python"))
+ library.setFormat(RCCResourceLibrary::Python3_Code);
+ else if (value == QLatin1String("python2"))
+ library.setFormat(RCCResourceLibrary::Python2_Code);
+ else
+ errorMsg = QLatin1String("Invalid generator: ") + value;
+ }
+
if (parser.isSet(passOption)) {
if (parser.value(passOption) == QLatin1String("1"))
library.setFormat(RCCResourceLibrary::Pass1);
@@ -249,6 +301,7 @@ int runRcc(int argc, char *argv[])
QString outFilename = parser.value(outputOption);
QString tempFilename = parser.value(tempOption);
+ QString depFilename = parser.value(depFileOption);
if (projectRequested) {
return createProject(outFilename);
@@ -280,6 +333,8 @@ int runRcc(int argc, char *argv[])
switch (library.format()) {
case RCCResourceLibrary::C_Code:
case RCCResourceLibrary::Pass1:
+ case RCCResourceLibrary::Python3_Code:
+ case RCCResourceLibrary::Python2_Code:
mode = QIODevice::WriteOnly | QIODevice::Text;
break;
case RCCResourceLibrary::Pass2:
@@ -333,6 +388,28 @@ int runRcc(int argc, char *argv[])
return 0;
}
+ // Write depfile
+ if (!depFilename.isEmpty()) {
+ QFile depout;
+ depout.setFileName(depFilename);
+
+ if (outFilename.isEmpty() || outFilename == QLatin1String("-")) {
+ const QString msg = QString::fromUtf8("Unable to write depfile when outputting to stdout!\n");
+ errorDevice.write(msg.toUtf8());
+ return 1;
+ }
+
+ if (!depout.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ const QString msg = QString::fromUtf8("Unable to open depfile %1 for writing: %2\n")
+ .arg(depout.fileName(), depout.errorString());
+ errorDevice.write(msg.toUtf8());
+ return 1;
+ }
+
+ writeDepFile(depout, library.dataFiles(), outFilename);
+ depout.close();
+ }
+
QFile temp;
if (!tempFilename.isEmpty()) {
temp.setFileName(tempFilename);
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 011a7db810..9acbce25ff 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -37,6 +37,7 @@
#include <qfile.h>
#include <qiodevice.h>
#include <qlocale.h>
+#include <qregexp.h>
#include <qstack.h>
#include <qxmlstream.h>
@@ -66,11 +67,8 @@ enum {
# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::None
#endif
-#define writeString(s) write(s, sizeof(s))
-
void RCCResourceLibrary::write(const char *str, int len)
{
- --len; // trailing \0 on string literals...
int n = m_out.size();
m_out.resize(n + len);
memcpy(m_out.data() + n, str, len);
@@ -176,6 +174,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
{
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
+ const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
+ || lib.m_format == RCCResourceLibrary::Python2_Code;
//some info
if (text || pass1) {
if (m_language != QLocale::C) {
@@ -222,6 +222,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
}
if (text || pass1)
lib.writeChar('\n');
+ else if (python)
+ lib.writeString("\\\n");
if (lib.formatVersion() >= 2) {
// last modified time stamp
@@ -236,6 +238,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
lib.writeNumber8(lastmod);
if (text || pass1)
lib.writeChar('\n');
+ else if (python)
+ lib.writeString("\\\n");
}
}
@@ -246,6 +250,8 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
const bool pass2 = lib.m_format == RCCResourceLibrary::Pass2;
const bool binary = lib.m_format == RCCResourceLibrary::Binary;
+ const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
+ || lib.m_format == RCCResourceLibrary::Python2_Code;
//capture the offset
m_dataOffset = offset;
@@ -343,20 +349,24 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
}
// write the length
-
- if (text || binary || pass2)
+ if (text || binary || pass2 || python)
lib.writeNumber4(data.size());
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
offset += 4;
// write the payload
const char *p = data.constData();
- if (text) {
+ if (text || python) {
for (int i = data.size(), j = 0; --i >= 0; --j) {
lib.writeHex(*p++);
if (j == 0) {
- lib.writeString("\n ");
+ if (text)
+ lib.writeString("\n ");
+ else
+ lib.writeString("\\\n");
j = 16;
}
}
@@ -368,6 +378,9 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
// done
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
+
return offset;
}
@@ -375,6 +388,8 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
{
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
+ const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
+ || lib.m_format == RCCResourceLibrary::Python2_Code;
// capture the offset
m_nameOffset = offset;
@@ -390,12 +405,16 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
lib.writeNumber2(m_name.length());
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
offset += 2;
// write the hash
lib.writeNumber4(qt_hash(m_name));
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
offset += 4;
// write the m_name
@@ -404,12 +423,17 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
lib.writeNumber2(unicode[i].unicode());
if ((text || pass1) && i % 16 == 0)
lib.writeString("\n ");
+ else if (python && i % 16 == 0)
+ lib.writeString("\\\n");
}
offset += m_name.length()*2;
// done
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
+
return offset;
}
@@ -956,21 +980,40 @@ void RCCResourceLibrary::writeDecimal(int value)
Q_ASSERT(m_format != RCCResourceLibrary::Binary);
char buf[std::numeric_limits<int>::digits10 + 2];
int n = snprintf(buf, sizeof(buf), "%d", value);
- write(buf, n + 1); // write() takes a size including terminating NUL
+ write(buf, n);
+}
+
+static const char hexDigits[] = "0123456789abcdef";
+
+inline void RCCResourceLibrary::write2HexDigits(quint8 number)
+{
+ writeChar(hexDigits[number >> 4]);
+ writeChar(hexDigits[number & 0xf]);
}
void RCCResourceLibrary::writeHex(quint8 tmp)
{
- const char digits[] = "0123456789abcdef";
- writeChar('0');
- writeChar('x');
- if (tmp < 16) {
- writeChar(digits[tmp]);
- } else {
- writeChar(digits[tmp >> 4]);
- writeChar(digits[tmp & 0xf]);
+ switch (m_format) {
+ case RCCResourceLibrary::Python3_Code:
+ case RCCResourceLibrary::Python2_Code:
+ if (tmp >= 32 && tmp < 127 && tmp != '"' && tmp != '\\') {
+ writeChar(char(tmp));
+ } else {
+ writeChar('\\');
+ writeChar('x');
+ write2HexDigits(tmp);
+ }
+ break;
+ default:
+ writeChar('0');
+ writeChar('x');
+ if (tmp < 16)
+ writeChar(hexDigits[tmp]);
+ else
+ write2HexDigits(tmp);
+ writeChar(',');
+ break;
}
- writeChar(',');
}
void RCCResourceLibrary::writeNumber2(quint16 number)
@@ -1038,7 +1081,9 @@ void RCCResourceLibrary::writeNumber8(quint64 number)
bool RCCResourceLibrary::writeHeader()
{
- if (m_format == C_Code || m_format == Pass1) {
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("/****************************************************************************\n");
writeString("** Resource object code\n");
writeString("**\n");
@@ -1047,7 +1092,20 @@ bool RCCResourceLibrary::writeHeader()
writeString("\n**\n");
writeString("** WARNING! All changes made in this file will be lost!\n");
writeString( "*****************************************************************************/\n\n");
- } else if (m_format == Binary) {
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("# Resource object code (Python ");
+ writeChar(m_format == Python3_Code ? '3' : '2');
+ writeString(")\n");
+ writeString("# Created by: object code\n");
+ writeString("# Created by: The Resource Compiler for Qt version ");
+ writeByteArray(QT_VERSION_STR);
+ writeString("\n");
+ writeString("# WARNING! All changes made in this file will be lost!\n\n");
+ writeString("from PySide2 import QtCore\n\n");
+ break;
+ case Binary:
writeString("qres");
writeNumber4(0);
writeNumber4(0);
@@ -1055,6 +1113,9 @@ bool RCCResourceLibrary::writeHeader()
writeNumber4(0);
if (m_formatVersion >= 3)
writeNumber4(m_overallFlags);
+ break;
+ default:
+ break;
}
return true;
}
@@ -1062,10 +1123,21 @@ bool RCCResourceLibrary::writeHeader()
bool RCCResourceLibrary::writeDataBlobs()
{
Q_ASSERT(m_errorDevice);
- if (m_format == C_Code) {
+ switch (m_format) {
+ case C_Code:
writeString("static const unsigned char qt_resource_data[] = {\n");
- } else if (m_format == Binary) {
+ break;
+ case Python3_Code:
+ writeString("qt_resource_data = b\"\\\n");
+ break;
+ case Python2_Code:
+ writeString("qt_resource_data = \"\\\n");
+ break;
+ case Binary:
m_dataOffset = m_out.size();
+ break;
+ default:
+ break;
}
if (!m_root)
@@ -1091,24 +1163,46 @@ bool RCCResourceLibrary::writeDataBlobs()
}
}
}
- if (m_format == C_Code)
+ switch (m_format) {
+ case C_Code:
writeString("\n};\n\n");
- else if (m_format == Pass1) {
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("\"\n\n");
+ break;
+ case Pass1:
if (offset < 8)
offset = 8;
writeString("\nstatic const unsigned char qt_resource_data[");
writeByteArray(QByteArray::number(offset));
writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
+ break;
+ default:
+ break;
}
return true;
}
bool RCCResourceLibrary::writeDataNames()
{
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("static const unsigned char qt_resource_name[] = {\n");
- else if (m_format == Binary)
+ break;
+ case Python3_Code:
+ writeString("qt_resource_name = b\"\\\n");
+ break;
+ case Python2_Code:
+ writeString("qt_resource_name = \"\\\n");
+ break;
+ case Binary:
m_namesOffset = m_out.size();
+ break;
+ default:
+ break;
+ }
QHash<QString, int> names;
QStack<RCCFileInfo*> pending;
@@ -1133,8 +1227,18 @@ bool RCCResourceLibrary::writeDataNames()
}
}
}
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("\n};\n\n");
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("\"\n\n");
+ break;
+ default:
+ break;
+ }
return true;
}
@@ -1149,10 +1253,24 @@ struct qt_rcc_compare_hash
bool RCCResourceLibrary::writeDataStructure()
{
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("static const unsigned char qt_resource_struct[] = {\n");
- else if (m_format == Binary)
+ break;
+ case Python3_Code:
+ writeString("qt_resource_struct = b\"\\\n");
+ break;
+ case Python2_Code:
+ writeString("qt_resource_struct = \"\\\n");
+ break;
+ case Binary:
m_treeOffset = m_out.size();
+ break;
+ default:
+ break;
+ }
+
QStack<RCCFileInfo*> pending;
if (!m_root)
@@ -1196,8 +1314,18 @@ bool RCCResourceLibrary::writeDataStructure()
pending.push(child);
}
}
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("\n};\n\n");
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("\"\n\n");
+ break;
+ default:
+ break;
+ }
return true;
}
@@ -1387,6 +1515,16 @@ bool RCCResourceLibrary::writeInitializer()
p[i++] = (m_overallFlags >> 8) & 0xff;
p[i++] = (m_overallFlags >> 0) & 0xff;
}
+ } else if (m_format == Python3_Code || m_format == Python2_Code) {
+ writeString("def qInitResources():\n");
+ writeString(" QtCore.qRegisterResourceData(0x");
+ write2HexDigits(m_formatVersion);
+ writeString(", qt_resource_struct, qt_resource_name, qt_resource_data)\n\n");
+ writeString("def qCleanupResources():\n");
+ writeString(" QtCore.qUnregisterResourceData(0x");
+ write2HexDigits(m_formatVersion);
+ writeString(", qt_resource_struct, qt_resource_name, qt_resource_data)\n\n");
+ writeString("qInitResources()\n");
}
return true;
}
diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h
index ad1c5cd166..190c37a1f6 100644
--- a/src/tools/rcc/rcc.h
+++ b/src/tools/rcc/rcc.h
@@ -58,7 +58,7 @@ public:
bool readFiles(bool listMode, QIODevice &errorDevice);
- enum Format { Binary, C_Code, Pass1, Pass2 };
+ enum Format { Binary, C_Code, Pass1, Pass2, Python3_Code, Python2_Code };
void setFormat(Format f) { m_format = f; }
Format format() const { return m_format; }
@@ -136,12 +136,14 @@ private:
void writeAddNamespaceFunction(const QByteArray &name);
void writeDecimal(int value);
void writeHex(quint8 number);
+ void write2HexDigits(quint8 number);
void writeNumber2(quint16 number);
void writeNumber4(quint32 number);
void writeNumber8(quint64 number);
void writeChar(char c) { m_out.append(c); }
void writeByteArray(const QByteArray &);
void write(const char *, int len);
+ void writeString(const char *s) { write(s, static_cast<int>(strlen(s))); }
#if QT_CONFIG(zstd)
ZSTD_CCtx *m_zstdCCtx;
diff --git a/src/tools/tracegen/etw.cpp b/src/tools/tracegen/etw.cpp
index e839137915..acd81bd5c1 100644
--- a/src/tools/tracegen/etw.cpp
+++ b/src/tools/tracegen/etw.cpp
@@ -45,7 +45,6 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qtextstream.h>
-#include <qregexp.h>
#include <quuid.h>
static inline QString providerVar(const QString &providerName)
diff --git a/src/tools/tracegen/lttng.cpp b/src/tools/tracegen/lttng.cpp
index f0fbca9e16..1aef1b3d17 100644
--- a/src/tools/tracegen/lttng.cpp
+++ b/src/tools/tracegen/lttng.cpp
@@ -46,7 +46,6 @@
#include <qfile.h>
#include <qfileinfo.h>
#include <qtextstream.h>
-#include <qregexp.h>
#include <qdebug.h>
static void writeCtfMacro(QTextStream &stream, const Tracepoint::Field &field)
diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp
index 0ba49627c0..71e02ae9c9 100644
--- a/src/tools/uic/cpp/cppwriteincludes.cpp
+++ b/src/tools/uic/cpp/cppwriteincludes.cpp
@@ -69,7 +69,7 @@ static inline QString moduleHeader(const QString &module, const QString &header)
namespace CPP {
WriteIncludes::WriteIncludes(Uic *uic)
- : m_uic(uic), m_output(uic->output()), m_laidOut(false)
+ : m_uic(uic), m_output(uic->output())
{
// When possible (no namespace) use the "QtModule/QClass" convention
// and create a re-mapping of the old header "qclass.h" to it. Do not do this
diff --git a/src/tools/uic/cpp/cppwriteincludes.h b/src/tools/uic/cpp/cppwriteincludes.h
index e9247f4cc4..9b9ac283fe 100644
--- a/src/tools/uic/cpp/cppwriteincludes.h
+++ b/src/tools/uic/cpp/cppwriteincludes.h
@@ -40,6 +40,7 @@
QT_BEGIN_NAMESPACE
class QTextStream;
+class CustomWidgetsInfo;
class Driver;
class Uic;
@@ -74,11 +75,14 @@ struct WriteIncludes : public TreeWalker
void acceptIncludes(DomIncludes *node) override;
void acceptInclude(DomInclude *node) override;
+protected:
+ QTextStream &output() const { return m_output; }
+
private:
void add(const QString &className, bool determineHeader = true, const QString &header = QString(), bool global = false);
private:
- typedef std::set<QString> OrderedSet;
+ using OrderedSet = std::set<QString>;
void insertIncludeForClass(const QString &className, QString header = QString(), bool global = false);
void insertInclude(const QString &header, bool global);
void writeHeaders(const OrderedSet &headers, bool global);
@@ -93,11 +97,11 @@ private:
QSet<QString> m_knownClasses;
- typedef QMap<QString, QString> StringMap;
+ using StringMap = QMap<QString, QString>;
StringMap m_classToHeader;
StringMap m_oldHeaderToNewHeader;
- bool m_laidOut;
+ bool m_laidOut = false;
};
} // namespace CPP
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index 2fb3e502c5..fd5f8c9017 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -71,7 +71,7 @@ namespace {
// Write a statement to create a spacer item.
void writeSpacerItem(const DomSpacer *node, QTextStream &output) {
const QHash<QString, DomProperty *> properties = propertyMap(node->elementProperty());
- output << "new QSpacerItem(";
+ output << language::operatorNew << "QSpacerItem(";
int w = 0;
int h = 0;
@@ -102,11 +102,9 @@ namespace {
if (orientation == QLatin1String("Qt::Vertical") || orientation == QLatin1String("Vertical"))
isVspacer = true;
}
-
- if (isVspacer)
- output << "QSizePolicy::Minimum, " << sizeType << ')';
- else
- output << sizeType << ", QSizePolicy::Minimum)";
+ const QString horizType = isVspacer ? QLatin1String("QSizePolicy::Minimum") : sizeType;
+ const QString vertType = isVspacer ? sizeType : QLatin1String("QSizePolicy::Minimum");
+ output << language::enumValue(horizType) << ", " << language::enumValue(vertType) << ')';
}
@@ -120,7 +118,8 @@ namespace {
// Write object->setFoo(x);
template <class Value>
void writeSetter(const QString &indent, const QString &varName,const QString &setter, Value v, QTextStream &str) {
- str << indent << varName << "->" << setter << '(' << v << ");\n";
+ str << indent << varName << language::derefPointer
+ << setter << '(' << v << ')' << language::eol;
}
static inline bool iconHasStatePixmaps(const DomResourceIcon *i) {
@@ -456,22 +455,20 @@ WriteInitialization::WriteInitialization(Uic *uic) :
m_driver(uic->driver()), m_output(uic->output()), m_option(uic->option()),
m_indent(m_option.indent + m_option.indent),
m_dindent(m_indent + m_option.indent),
- m_stdsetdef(true),
- m_layoutMarginType(TopLevelMargin),
- m_mainFormUsedInRetranslateUi(false),
m_delayedOut(&m_delayedInitialization, QIODevice::WriteOnly),
m_refreshOut(&m_refreshInitialization, QIODevice::WriteOnly),
- m_actionOut(&m_delayedActionInitialization, QIODevice::WriteOnly),
- m_layoutWidget(false),
- m_firstThemeIcon(true)
+ m_actionOut(&m_delayedActionInitialization, QIODevice::WriteOnly)
{
}
void WriteInitialization::acceptUI(DomUI *node)
{
- m_actionGroupChain.push(0);
- m_widgetChain.push(0);
- m_layoutChain.push(0);
+ m_actionGroupChain.push(nullptr);
+ m_widgetChain.push(nullptr);
+ m_layoutChain.push(nullptr);
+
+ if (node->hasAttributeConnectslotsbyname())
+ m_connectSlotsByName = node->attributeConnectslotsbyname();
acceptLayoutDefault(node->elementLayoutDefault());
acceptLayoutFunction(node->elementLayoutFunction());
@@ -491,22 +488,21 @@ void WriteInitialization::acceptUI(DomUI *node)
const QString varName = m_driver->findOrInsertWidget(node->elementWidget());
m_mainFormVarName = varName;
- m_registeredWidgets.insert(varName, node->elementWidget()); // register the main widget
const QString widgetClassName = node->elementWidget()->attributeClass();
- m_output << m_option.indent << "void " << "setupUi(" << widgetClassName << " *" << varName << ")\n"
- << m_option.indent << "{\n";
+ const QString parameterType = widgetClassName + QLatin1String(" *");
+ m_output << m_option.indent
+ << language::startFunctionDefinition1("setupUi", parameterType, varName, m_option.indent);
const QStringList connections = m_uic->databaseInfo()->connections();
- for (int i=0; i<connections.size(); ++i) {
- QString connection = connections.at(i);
-
+ for (const auto &connection : connections) {
if (connection == QLatin1String("(default)"))
continue;
const QString varConn = connection + QLatin1String("Connection");
- m_output << m_indent << varConn << " = QSqlDatabase::database(" << fixString(connection, m_dindent) << ");\n";
+ m_output << m_indent << varConn << " = QSqlDatabase::database("
+ << language::charliteral(connection, m_dindent) << ");\n";
}
acceptWidget(node->elementWidget());
@@ -514,20 +510,16 @@ void WriteInitialization::acceptUI(DomUI *node)
if (!m_buddies.empty())
m_output << language::openQtConfig(shortcutConfigKey());
for (const Buddy &b : qAsConst(m_buddies)) {
- if (!m_registeredWidgets.contains(b.objName)) {
+ const QString buddyVarName = m_driver->widgetVariableName(b.buddyAttributeName);
+ if (buddyVarName.isEmpty()) {
fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
qPrintable(m_option.messagePrefix()),
- b.objName.toLatin1().data());
- continue;
- }
- if (!m_registeredWidgets.contains(b.buddy)) {
- fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
- qPrintable(m_option.messagePrefix()),
- b.buddy.toLatin1().data());
+ qPrintable(b.buddyAttributeName));
continue;
}
- m_output << m_indent << b.objName << "->setBuddy(" << b.buddy << ");\n";
+ m_output << m_indent << b.labelVarName << language::derefPointer
+ << "setBuddy(" << buddyVarName << ')' << language::eol;
}
if (!m_buddies.empty())
m_output << language::closeQtConfig(shortcutConfigKey());
@@ -538,7 +530,8 @@ void WriteInitialization::acceptUI(DomUI *node)
if (!m_delayedActionInitialization.isEmpty())
m_output << "\n" << m_delayedActionInitialization;
- m_output << "\n" << m_indent << "retranslateUi(" << varName << ");\n";
+ m_output << "\n" << m_indent << language::self
+ << "retranslateUi(" << varName << ')' << language::eol;
if (node->elementConnections())
acceptConnections(node->elementConnections());
@@ -546,22 +539,25 @@ void WriteInitialization::acceptUI(DomUI *node)
if (!m_delayedInitialization.isEmpty())
m_output << "\n" << m_delayedInitialization << "\n";
- if (m_option.autoConnection)
- m_output << "\n" << m_indent << "QMetaObject::connectSlotsByName(" << varName << ");\n";
+ if (m_option.autoConnection && m_connectSlotsByName) {
+ m_output << "\n" << m_indent << "QMetaObject" << language::qualifier
+ << "connectSlotsByName(" << varName << ')' << language::eol;
+ }
- m_output << m_option.indent << "} // setupUi\n\n";
+ m_output << m_option.indent << language::endFunctionDefinition("setupUi");
- if (!m_mainFormUsedInRetranslateUi) {
+ if (!m_mainFormUsedInRetranslateUi && language::language() == Language::Cpp) {
+ // Mark varName as unused to avoid compiler warnings.
m_refreshInitialization += m_indent;
- m_refreshInitialization += QLatin1String("Q_UNUSED(");
+ m_refreshInitialization += QLatin1String("(void)");
m_refreshInitialization += varName ;
- m_refreshInitialization += QLatin1String(");\n");
+ m_refreshInitialization += QLatin1String(";\n");
}
- m_output << m_option.indent << "void " << "retranslateUi(" << widgetClassName << " *" << varName << ")\n"
- << m_option.indent << "{\n"
+ m_output << m_option.indent
+ << language::startFunctionDefinition1("retranslateUi", parameterType, varName, m_option.indent)
<< m_refreshInitialization
- << m_option.indent << "} // retranslateUi\n\n";
+ << m_option.indent << language::endFunctionDefinition("retranslateUi");
m_layoutChain.pop();
m_widgetChain.pop();
@@ -584,9 +580,11 @@ void WriteInitialization::addWizardPage(const QString &pageVarName, const DomWid
}
}
if (id.isEmpty()) {
- m_output << m_indent << parentWidget << "->addPage(" << pageVarName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << "addPage(" << pageVarName << ')' << language::eol;
} else {
- m_output << m_indent << parentWidget << "->setPage(" << id << ", " << pageVarName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << "setPage(" << id << ", " << pageVarName << ')' << language::eol;
}
}
@@ -595,7 +593,6 @@ void WriteInitialization::acceptWidget(DomWidget *node)
m_layoutMarginType = m_widgetChain.count() == 1 ? TopLevelMargin : ChildMargin;
const QString className = node->attributeClass();
const QString varName = m_driver->findOrInsertWidget(node);
- m_registeredWidgets.insert(varName, node); // register the current widget
QString parentWidget, parentClass;
if (m_widgetChain.top()) {
@@ -611,8 +608,9 @@ void WriteInitialization::acceptWidget(DomWidget *node)
const auto *cwi = m_uic->customWidgetsInfo();
if (m_widgetChain.size() != 1) {
- m_output << m_indent << varName << " = new " << cwi->realClassName(className)
- << '(' << parentWidget << ");\n";
+ m_output << m_indent << varName << " = " << language::operatorNew
+ << language::fixClassName(cwi->realClassName(className))
+ << '(' << parentWidget << ')' << language::eol;
}
parentWidget = savedParentWidget;
@@ -664,26 +662,33 @@ void WriteInitialization::acceptWidget(DomWidget *node)
if (cwi->extends(parentClass, QLatin1String("QMainWindow"))) {
if (cwi->extends(className, QLatin1String("QMenuBar"))) {
- m_output << m_indent << parentWidget << "->setMenuBar(" << varName <<");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << "setMenuBar(" << varName << ')' << language::eol;
} else if (cwi->extends(className, QLatin1String("QToolBar"))) {
- m_output << m_indent << parentWidget << "->addToolBar("
- << toolBarAreaStringFromDOMAttributes(attributes) << varName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer << "addToolBar("
+ << language::enumValue(toolBarAreaStringFromDOMAttributes(attributes)) << varName
+ << ')' << language::eol;
if (const DomProperty *pbreak = attributes.value(QLatin1String("toolBarBreak"))) {
if (pbreak->elementBool() == QLatin1String("true")) {
- m_output << m_indent << parentWidget << "->insertToolBarBreak(" << varName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << "insertToolBarBreak(" << varName << ')' << language::eol;
}
}
} else if (cwi->extends(className, QLatin1String("QDockWidget"))) {
- m_output << m_indent << parentWidget << "->addDockWidget(";
- if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea")))
- m_output << "Qt::" << language::dockWidgetArea(pstyle->elementNumber()) << ", ";
+ m_output << m_indent << parentWidget << language::derefPointer << "addDockWidget(";
+ if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) {
+ m_output << "Qt" << language::qualifier
+ << language::dockWidgetArea(pstyle->elementNumber()) << ", ";
+ }
m_output << varName << ");\n";
} else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) {
- m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << "setStatusBar(" << varName << ')' << language::eol;
} else {
- m_output << m_indent << parentWidget << "->setCentralWidget(" << varName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << "setCentralWidget(" << varName << ')' << language::eol;
}
}
@@ -692,56 +697,61 @@ void WriteInitialization::acceptWidget(DomWidget *node)
if (addPageMethod.isEmpty())
addPageMethod = cwi->simpleContainerAddPageMethod(parentClass);
if (!addPageMethod.isEmpty()) {
- m_output << m_indent << parentWidget << "->" << addPageMethod << '(' << varName << ");\n";
+ m_output << m_indent << parentWidget << language::derefPointer
+ << addPageMethod << '(' << varName << ')' << language::eol;
} else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWizard"))) {
addWizardPage(varName, node, parentWidget);
} else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBox"))) {
const DomProperty *plabel = attributes.value(QLatin1String("label"));
- DomString *plabelString = plabel ? plabel->elementString() : 0;
+ DomString *plabelString = plabel ? plabel->elementString() : nullptr;
QString icon;
if (const DomProperty *picon = attributes.value(QLatin1String("icon")))
icon = QLatin1String(", ") + iconCall(picon); // Side effect: Writes icon definition
+ m_output << m_indent << parentWidget << language::derefPointer << "addItem("
+ << varName << icon << ", " << noTrCall(plabelString, pageDefaultString)
+ << ')' << language::eol;
- m_output << m_indent << parentWidget << "->addItem(" << varName << icon
- << ", " << noTrCall(plabelString, pageDefaultString) << ");\n";
-
- autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget << "->setItemText("
- << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(plabelString, pageDefaultString) << ");\n";
+ autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget
+ << language::derefPointer << "setItemText(" << parentWidget
+ << language::derefPointer << "indexOf(" << varName << "), "
+ << autoTrCall(plabelString, pageDefaultString) << ')' << language::eol;
if (DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
autoTrOutput(ptoolTip->elementString())
<< language::openQtConfig(toolTipConfigKey())
- << m_indent << parentWidget << "->setItemToolTip(" << parentWidget
- << "->indexOf(" << varName << "), "
- << autoTrCall(ptoolTip->elementString()) << ");\n"
+ << m_indent << parentWidget << language::derefPointer << "setItemToolTip(" << parentWidget
+ << language::derefPointer << "indexOf(" << varName << "), "
+ << autoTrCall(ptoolTip->elementString()) << ')' << language::eol
<< language::closeQtConfig(toolTipConfigKey());
}
} else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QTabWidget"))) {
const DomProperty *ptitle = attributes.value(QLatin1String("title"));
- DomString *ptitleString = ptitle ? ptitle->elementString() : 0;
+ DomString *ptitleString = ptitle ? ptitle->elementString() : nullptr;
QString icon;
if (const DomProperty *picon = attributes.value(QLatin1String("icon")))
icon = QLatin1String(", ") + iconCall(picon); // Side effect: Writes icon definition
- m_output << m_indent << parentWidget << "->addTab(" << varName << icon
- << ", " << "QString());\n";
+ m_output << m_indent << parentWidget << language::derefPointer << "addTab("
+ << varName << icon << ", " << "QString())" << language::eol;
- autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTabText("
- << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptitleString, pageDefaultString) << ");\n";
+ autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget
+ << language::derefPointer << "setTabText(" << parentWidget
+ << language::derefPointer << "indexOf(" << varName << "), "
+ << autoTrCall(ptitleString, pageDefaultString) << ')' << language::eol;
if (const DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
autoTrOutput(ptoolTip->elementString())
<< language::openQtConfig(toolTipConfigKey())
- << m_indent << parentWidget << "->setTabToolTip(" << parentWidget
- << "->indexOf(" << varName << "), "
- << autoTrCall(ptoolTip->elementString()) << ");\n"
+ << m_indent << parentWidget << language::derefPointer << "setTabToolTip("
+ << parentWidget << language::derefPointer << "indexOf(" << varName
+ << "), " << autoTrCall(ptoolTip->elementString()) << ')' << language::eol
<< language::closeQtConfig(toolTipConfigKey());
}
if (const DomProperty *pwhatsThis = attributes.value(QLatin1String("whatsThis"))) {
autoTrOutput(pwhatsThis->elementString())
<< language::openQtConfig(whatsThisConfigKey())
- << m_indent << parentWidget << "->setTabWhatsThis(" << parentWidget
- << "->indexOf(" << varName << "), "
- << autoTrCall(pwhatsThis->elementString()) << ");\n"
+ << m_indent << parentWidget << language::derefPointer << "setTabWhatsThis("
+ << parentWidget << language::derefPointer << "indexOf(" << varName
+ << "), " << autoTrCall(pwhatsThis->elementString()) << ')' << language::eol
<< language::closeQtConfig(whatsThisConfigKey());
}
}
@@ -776,8 +786,9 @@ void WriteInitialization::acceptWidget(DomWidget *node)
headerProperties << fakeProperty;
}
}
- writeProperties(varName + QLatin1String("->header()"), QLatin1String("QHeaderView"),
- headerProperties, WritePropertyIgnoreObjectName);
+ writeProperties(varName + language::derefPointer + QLatin1String("header()"),
+ QLatin1String("QHeaderView"), headerProperties,
+ WritePropertyIgnoreObjectName);
} else if (cwi->extendsOneOf(className, tables)) {
static const QLatin1String headerPrefixes[] = {
@@ -795,8 +806,9 @@ void WriteInitialization::acceptWidget(DomWidget *node)
headerProperties << fakeProperty;
}
}
- writeProperties(varName + QLatin1String("->") + headerPrefix + QLatin1String("()"),
- QLatin1String("QHeaderView"),
+ const QString headerVar = varName + language::derefPointer
+ + headerPrefix + QLatin1String("()");
+ writeProperties(headerVar, QLatin1String("QHeaderView"),
headerProperties, WritePropertyIgnoreObjectName);
}
}
@@ -806,15 +818,15 @@ void WriteInitialization::acceptWidget(DomWidget *node)
const QStringList zOrder = node->elementZOrder();
for (const QString &name : zOrder) {
- if (!m_registeredWidgets.contains(name)) {
+ const QString varName = m_driver->widgetVariableName(name);
+ if (varName.isEmpty()) {
fprintf(stderr, "%s: Warning: Z-order assignment: '%s' is not a valid widget.\n",
qPrintable(m_option.messagePrefix()),
name.toLatin1().data());
- continue;
+ } else {
+ m_output << m_indent << varName << language::derefPointer << "raise()"
+ << language::eol;
}
-
- if (!name.isEmpty())
- m_output << m_indent << name << "->raise();\n";
}
}
@@ -829,7 +841,7 @@ void WriteInitialization::addButtonGroup(const DomWidget *buttonNode, const QStr
const DomButtonGroup *group = m_driver->findButtonGroup(attributeName);
// Legacy feature: Create missing groups on the fly as the UIC button group feature
// was present before the actual Designer support (4.5)
- const bool createGroupOnTheFly = group == 0;
+ const bool createGroupOnTheFly = group == nullptr;
if (createGroupOnTheFly) {
DomButtonGroup *newGroup = new DomButtonGroup;
newGroup->setAttributeName(attributeName);
@@ -845,11 +857,13 @@ void WriteInitialization::addButtonGroup(const DomWidget *buttonNode, const QStr
m_output << m_indent;
if (createGroupOnTheFly)
m_output << className << " *";
- m_output << groupName << " = new " << className << '(' << m_mainFormVarName << ");\n";
+ m_output << groupName << " = " << language::operatorNew
+ << className << '(' << m_mainFormVarName << ')' << language::eol;
m_buttonGroups.insert(groupName);
writeProperties(groupName, className, group->elementProperty());
}
- m_output << m_indent << groupName << "->addButton(" << varName << ");\n";
+ m_output << m_indent << groupName << language::derefPointer << "addButton("
+ << varName << ')' << language::eol;
}
void WriteInitialization::acceptLayout(DomLayout *node)
@@ -862,7 +876,7 @@ void WriteInitialization::acceptLayout(DomLayout *node)
bool isGroupBox = false;
- m_output << m_indent << varName << " = new " << className << '(';
+ m_output << m_indent << varName << " = " << language::operatorNew << className << '(';
if (!m_layoutChain.top() && !isGroupBox)
m_output << m_driver->findOrInsertWidget(m_widgetChain.top());
@@ -883,8 +897,7 @@ void WriteInitialization::acceptLayout(DomLayout *node)
if (m_layoutWidget) {
bool left, top, right, bottom;
left = top = right = bottom = false;
- for (int i = 0; i < propList.size(); ++i) {
- const DomProperty *p = propList.at(i);
+ for (const DomProperty *p : propList) {
const QString propertyName = p->attributeName();
if (propertyName == QLatin1String("leftMargin") && p->kind() == DomProperty::Number)
left = true;
@@ -954,9 +967,12 @@ void WriteInitialization::writePropertyList(const QString &varName,
return;
const QStringList list = value.split(QLatin1Char(','));
const int count = list.count();
- for (int i = 0; i < count; i++)
- if (list.at(i) != defaultValue)
- m_output << m_indent << varName << "->" << setFunction << '(' << i << ", " << list.at(i) << ");\n";
+ for (int i = 0; i < count; i++) {
+ if (list.at(i) != defaultValue) {
+ m_output << m_indent << varName << language::derefPointer << setFunction
+ << '(' << i << ", " << list.at(i) << ')' << language::eol;
+ }
+ }
}
void WriteInitialization::acceptSpacer(DomSpacer *node)
@@ -1003,7 +1019,7 @@ void WriteInitialization::acceptLayoutItem(DomLayoutItem *node)
const QString layoutName = m_driver->findOrInsertLayout(layout);
const QString itemName = m_driver->findOrInsertLayoutItem(node);
- m_output << "\n" << m_indent << layoutName << "->"
+ m_output << "\n" << m_indent << layoutName << language::derefPointer << ""
<< layoutAddMethod(node->kind(), layout->attributeClass()) << '(';
if (layout->attributeClass() == QLatin1String("QGridLayout")) {
@@ -1014,16 +1030,16 @@ void WriteInitialization::acceptLayoutItem(DomLayoutItem *node)
const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
m_output << itemName << ", " << row << ", " << col << ", " << rowSpan << ", " << colSpan;
if (!node->attributeAlignment().isEmpty())
- m_output << ", " << node->attributeAlignment();
+ m_output << ", " << language::enumValue(node->attributeAlignment());
} else if (layout->attributeClass() == QLatin1String("QFormLayout")) {
const int row = node->attributeRow();
const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
const QString role = formLayoutRole(node->attributeColumn(), colSpan);
- m_output << row << ", " << role << ", " << itemName;
+ m_output << row << ", " << language::enumValue(role) << ", " << itemName;
} else {
m_output << itemName;
if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty())
- m_output << ", 0, " << node->attributeAlignment();
+ m_output << ", 0, " << language::enumValue(node->attributeAlignment());
}
m_output << ");\n\n";
}
@@ -1036,7 +1052,8 @@ void WriteInitialization::acceptActionGroup(DomActionGroup *node)
if (m_actionGroupChain.top())
varName = m_driver->findOrInsertActionGroup(m_actionGroupChain.top());
- m_output << m_indent << actionName << " = new QActionGroup(" << varName << ");\n";
+ m_output << m_indent << actionName << " = " << language::operatorNew
+ << "QActionGroup(" << varName << ");\n";
writeProperties(actionName, QLatin1String("QActionGroup"), node->elementProperty());
m_actionGroupChain.push(node);
@@ -1050,13 +1067,13 @@ void WriteInitialization::acceptAction(DomAction *node)
return;
const QString actionName = m_driver->findOrInsertAction(node);
- m_registeredActions.insert(actionName, node);
QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
if (m_actionGroupChain.top())
varName = m_driver->findOrInsertActionGroup(m_actionGroupChain.top());
- m_output << m_indent << actionName << " = new QAction(" << varName << ");\n";
+ m_output << m_indent << actionName << " = " << language::operatorNew
+ << "QAction(" << varName << ')' << language::eol;
writeProperties(actionName, QLatin1String("QAction"), node->elementProperty());
}
@@ -1069,28 +1086,32 @@ void WriteInitialization::acceptActionRef(DomActionRef *node)
}
const QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
- const bool isSeparator = actionName == QLatin1String("separator");
- bool isMenu = false;
- if (const DomWidget *w = m_driver->widgetByName(actionName)) {
- isMenu = m_uic->isMenu(w->attributeClass());
- } else if (!(m_driver->actionByName(actionName) || isSeparator)) {
- fprintf(stderr, "%s: Warning: action `%s' not declared\n",
- qPrintable(m_option.messagePrefix()),
- actionName.toLatin1().data());
+ if (m_widgetChain.top() && actionName == QLatin1String("separator")) {
+ // separator is always reserved!
+ m_actionOut << m_indent << varName << language::derefPointer
+ << "addSeparator()" << language::eol;
return;
}
- if (m_widgetChain.top() && isSeparator) {
- // separator is always reserved!
- m_actionOut << m_indent << varName << "->addSeparator();\n";
+ const DomWidget *domWidget = m_driver->widgetByName(actionName);
+ if (domWidget && m_uic->isMenu(domWidget->attributeClass())) {
+ m_actionOut << m_indent << varName << language::derefPointer
+ << "addAction(" << m_driver->findOrInsertWidget(domWidget)
+ << language::derefPointer << "menuAction())" << language::eol;
return;
}
- if (isMenu)
- actionName += QLatin1String("->menuAction()");
+ const DomAction *domAction = m_driver->actionByName(actionName);
+ if (!domAction) {
+ fprintf(stderr, "%s: Warning: action `%s' not declared\n",
+ qPrintable(m_option.messagePrefix()), qPrintable(actionName));
+ return;
+ }
- m_actionOut << m_indent << varName << "->addAction(" << actionName << ");\n";
+ m_actionOut << m_indent << varName << language::derefPointer
+ << "addAction(" << m_driver->findOrInsertAction(domAction)
+ << ')' << language::eol;
}
QString WriteInitialization::writeStringListProperty(const DomStringList *list) const
@@ -1107,7 +1128,7 @@ QString WriteInitialization::writeStringListProperty(const DomStringList *list)
str << '\n' << m_indent << " << " << trCall(values.at(i), comment);
} else {
for (int i = 0; i < values.size(); ++i)
- str << " << QString::fromUtf8(" << fixString(values.at(i), m_dindent) << ')';
+ str << " << " << language::qstring(values.at(i), m_dindent);
}
return propertyValue;
}
@@ -1139,19 +1160,32 @@ void WriteInitialization::writeProperties(const QString &varName,
if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
DomPropertyMap properties = propertyMap(lst);
if (DomProperty *p = properties.value(QLatin1String("control"))) {
- m_output << m_indent << varName << "->setControl(QString::fromUtf8("
- << fixString(toString(p->elementString()), m_dindent) << "));\n";
+ m_output << m_indent << varName << language::derefPointer << "setControl("
+ << language::qstring(toString(p->elementString()), m_dindent)
+ << ')' << language::eol;
}
}
QString indent;
if (!m_widgetChain.top()) {
indent = m_option.indent;
- m_output << m_indent << "if (" << varName << "->objectName().isEmpty())\n";
+ switch (language::language()) {
+ case Language::Cpp:
+ m_output << m_indent << "if (" << varName << "->objectName().isEmpty())\n";
+ break;
+ case Language::Python:
+ m_output << m_indent << "if " << varName << ".objectName():\n";
+ break;
+ }
+ }
+ if (!(flags & WritePropertyIgnoreObjectName)) {
+ QString objectName = varName;
+ if (!language::self.isEmpty() && objectName.startsWith(language::self))
+ objectName.remove(0, language::self.size());
+ m_output << m_indent << indent
+ << varName << language::derefPointer << "setObjectName("
+ << language::qstring(objectName, m_dindent) << ')' << language::eol;
}
- if (!(flags & WritePropertyIgnoreObjectName))
- m_output << m_indent << indent << varName
- << "->setObjectName(QString::fromUtf8(" << fixString(varName, m_dindent) << "));\n";
int leftMargin, topMargin, rightMargin, bottomMargin;
leftMargin = topMargin = rightMargin = bottomMargin = -1;
@@ -1167,13 +1201,14 @@ void WriteInitialization::writeProperties(const QString &varName,
// special case for the property `geometry': Do not use position
if (isTopLevel && propertyName == QLatin1String("geometry") && p->elementRect()) {
const DomRect *r = p->elementRect();
- m_output << m_indent << varName << "->resize(" << r->elementWidth() << ", " << r->elementHeight() << ");\n";
+ m_output << m_indent << varName << language::derefPointer << "resize("
+ << r->elementWidth() << ", " << r->elementHeight() << ')' << language::eol;
continue;
}
if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
&& m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
- m_delayedOut << m_indent << varName << "->setCurrentRow("
- << p->elementNumber() << ");\n";
+ m_delayedOut << m_indent << varName << language::derefPointer
+ << "setCurrentRow(" << p->elementNumber() << ')' << language::eol;
continue;
}
static const QStringList currentIndexWidgets = {
@@ -1182,14 +1217,15 @@ void WriteInitialization::writeProperties(const QString &varName,
};
if (propertyName == QLatin1String("currentIndex") // set currentIndex later
&& (m_uic->customWidgetsInfo()->extendsOneOf(className, currentIndexWidgets))) {
- m_delayedOut << m_indent << varName << "->setCurrentIndex("
- << p->elementNumber() << ");\n";
+ m_delayedOut << m_indent << varName << language::derefPointer
+ << "setCurrentIndex(" << p->elementNumber() << ')' << language::eol;
continue;
}
if (propertyName == QLatin1String("tabSpacing")
&& m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))) {
- m_delayedOut << m_indent << varName << "->layout()->setSpacing("
- << p->elementNumber() << ");\n";
+ m_delayedOut << m_indent << varName << language::derefPointer
+ << "layout()" << language::derefPointer << "setSpacing("
+ << p->elementNumber() << ')' << language::eol;
continue;
}
if (propertyName == QLatin1String("control") // ActiveQt support
@@ -1216,10 +1252,15 @@ void WriteInitialization::writeProperties(const QString &varName,
if (p->elementEnum() == QLatin1String("Qt::Vertical"))
shape = QLatin1String("QFrame::VLine");
- m_output << m_indent << varName << "->setFrameShape(" << shape << ");\n";
+ m_output << m_indent << varName << language::derefPointer << "setFrameShape("
+ << language::enumValue(shape) << ')' << language::eol;
// QFrame Default is 'Plain'. Make the line 'Sunken' unless otherwise specified
- if (!frameShadowEncountered)
- m_output << m_indent << varName << "->setFrameShadow(QFrame::Sunken);\n";
+ if (!frameShadowEncountered) {
+ m_output << m_indent << varName << language::derefPointer
+ << "setFrameShadow("
+ << language::enumValue(QLatin1String("QFrame::Sunken"))
+ << ')' << language::eol;
+ }
continue;
} else if ((flags & WritePropertyIgnoreMargin) && propertyName == QLatin1String("margin")) {
continue;
@@ -1251,25 +1292,28 @@ void WriteInitialization::writeProperties(const QString &varName,
QString setFunction;
- if (stdset) {
- setFunction = QLatin1String("->set")
- + propertyName.at(0).toUpper()
- + propertyName.midRef(1)
- + QLatin1Char('(');
- } else {
- setFunction += QLatin1String("->setProperty(\"")
- + propertyName
- + QLatin1String("\", QVariant");
- if (p->kind() == DomProperty::Enum)
- setFunction += QLatin1String("::fromValue");
- setFunction += QLatin1Char('(');
- }
+ {
+ QTextStream str(&setFunction);
+ if (stdset) {
+ str << language::derefPointer <<"set" << propertyName.at(0).toUpper()
+ << propertyName.midRef(1) << '(';
+ } else {
+ str << language::derefPointer << QLatin1String("setProperty(\"")
+ << propertyName << "\", ";
+ if (language::language() == Language::Cpp) {
+ str << "QVariant";
+ if (p->kind() == DomProperty::Enum)
+ str << "::fromValue";
+ str << '(';
+ }
+ }
+ } // QTextStream
QString varNewName = varName;
switch (p->kind()) {
case DomProperty::Bool: {
- propertyValue = p->elementBool();
+ propertyValue = language::boolValue(p->elementBool() == language::cppTrue);
break;
}
case DomProperty::Color:
@@ -1280,13 +1324,12 @@ void WriteInitialization::writeProperties(const QString &varName,
Buddy buddy = { varName, p->elementCstring() };
m_buddies.append(std::move(buddy));
} else {
- if (stdset)
- propertyValue = fixString(p->elementCstring(), m_dindent);
- else {
- propertyValue = QLatin1String("QByteArray(")
- + fixString(p->elementCstring(), m_dindent)
- + QLatin1Char(')');
- }
+ QTextStream str(&propertyValue);
+ if (!stdset)
+ str << "QByteArray(";
+ str << language::charliteral(p->elementCstring(), m_dindent);
+ if (!stdset)
+ str << ')';
}
break;
case DomProperty::Cursor:
@@ -1295,17 +1338,19 @@ void WriteInitialization::writeProperties(const QString &varName,
break;
case DomProperty::CursorShape:
if (p->hasAttributeStdset() && !p->attributeStdset())
- varNewName += QLatin1String("->viewport()");
- propertyValue = QString::fromLatin1("QCursor(Qt::%1)")
- .arg(p->elementCursorShape());
+ varNewName += language::derefPointer + QLatin1String("viewport()");
+ propertyValue = QLatin1String("QCursor(Qt") + language::qualifier
+ + p->elementCursorShape() + QLatin1Char(')');
break;
case DomProperty::Enum:
propertyValue = p->elementEnum();
- if (!propertyValue.contains(QLatin1String("::")))
- propertyValue = className + QLatin1String("::") + propertyValue;
+ if (propertyValue.contains(language::cppQualifier))
+ propertyValue = language::enumValue(propertyValue);
+ else
+ propertyValue.prepend(className + language::qualifier);
break;
case DomProperty::Set:
- propertyValue = p->elementSet();
+ propertyValue = language::enumValue(p->elementSet());
break;
case DomProperty::Font:
propertyValue = writeFontProperties(p->elementFont());
@@ -1319,8 +1364,8 @@ void WriteInitialization::writeProperties(const QString &varName,
case DomProperty::Palette: {
const DomPalette *pal = p->elementPalette();
const QString paletteName = m_driver->unique(QLatin1String("palette"));
- m_output << m_indent << "QPalette " << paletteName << ";\n";
-
+ m_output << m_indent << language::stackVariable("QPalette", paletteName)
+ << language::eol;
writeColorGroup(pal->elementActive(), QLatin1String("QPalette::Active"), paletteName);
writeColorGroup(pal->elementInactive(), QLatin1String("QPalette::Inactive"), paletteName);
writeColorGroup(pal->elementDisabled(), QLatin1String("QPalette::Disabled"), paletteName);
@@ -1356,15 +1401,16 @@ void WriteInitialization::writeProperties(const QString &varName,
}
case DomProperty::Locale: {
const DomLocale *locale = p->elementLocale();
- propertyValue = QString::fromLatin1("QLocale(QLocale::%1, QLocale::%2)")
- .arg(locale->attributeLanguage(), locale->attributeCountry());
+ QTextStream(&propertyValue) << "QLocale(QLocale" << language::qualifier
+ << locale->attributeLanguage() << ", QLocale" << language::qualifier
+ << locale->attributeCountry() << ')';
break;
}
case DomProperty::SizePolicy: {
const QString spName = writeSizePolicy( p->elementSizePolicy());
- m_output << m_indent << spName << QString::fromLatin1(
- ".setHeightForWidth(%1->sizePolicy().hasHeightForWidth());\n")
- .arg(varName);
+ m_output << m_indent << spName << ".setHeightForWidth("
+ << varName << language::derefPointer << "sizePolicy().hasHeightForWidth())"
+ << language::eol;
propertyValue = spName;
break;
@@ -1455,8 +1501,8 @@ void WriteInitialization::writeProperties(const QString &varName,
case DomProperty::Url: {
const DomUrl* u = p->elementUrl();
- propertyValue = QString::fromLatin1("QUrl(QString::fromUtf8(%1))")
- .arg(fixString(u->elementString()->text(), m_dindent));
+ QTextStream(&propertyValue) << "QUrl("
+ << language::qstring(u->elementString()->text(), m_dindent) << ")";
break;
}
case DomProperty::Brush:
@@ -1474,9 +1520,9 @@ void WriteInitialization::writeProperties(const QString &varName,
if (!configKey.isEmpty())
o << language::openQtConfig(configKey);
o << m_indent << varNewName << setFunction << propertyValue;
- if (!stdset)
+ if (!stdset && language::language() == Language::Cpp)
o << ')';
- o << ");\n";
+ o << ')' << language::eol;
if (!configKey.isEmpty())
o << language::closeQtConfig(configKey);
@@ -1488,7 +1534,7 @@ void WriteInitialization::writeProperties(const QString &varName,
}
}
if (leftMargin != -1 || topMargin != -1 || rightMargin != -1 || bottomMargin != -1) {
- m_output << m_indent << varName << "->setContentsMargins("
+ m_output << m_indent << varName << language::derefPointer << "setContentsMargins("
<< leftMargin << ", " << topMargin << ", "
<< rightMargin << ", " << bottomMargin << ");\n";
}
@@ -1509,20 +1555,15 @@ QString WriteInitialization::writeSizePolicy(const DomSizePolicy *sp)
const QString spName = m_driver->unique(QLatin1String("sizePolicy"));
m_sizePolicyNameMap.insert(sizePolicyHandle, spName);
- m_output << m_indent << "QSizePolicy " << spName;
- do {
- if (sp->hasElementHSizeType() && sp->hasElementVSizeType()) {
- m_output << "(QSizePolicy::" << language::sizePolicy(sp->elementHSizeType())
- << ", QSizePolicy::" << language::sizePolicy(sp->elementVSizeType()) << ");\n";
- break;
- }
- if (sp->hasAttributeHSizeType() && sp->hasAttributeVSizeType()) {
- m_output << "(QSizePolicy::" << sp->attributeHSizeType() << ", QSizePolicy::"
- << sp->attributeVSizeType() << ");\n";
- break;
- }
- m_output << ";\n";
- } while (false);
+ m_output << m_indent << language::stackVariableWithInitParameters("QSizePolicy", spName);
+ if (sp->hasElementHSizeType() && sp->hasElementVSizeType()) {
+ m_output << "QSizePolicy" << language::qualifier << language::sizePolicy(sp->elementHSizeType())
+ << ", QSizePolicy" << language::qualifier << language::sizePolicy(sp->elementVSizeType());
+ } else if (sp->hasAttributeHSizeType() && sp->hasAttributeVSizeType()) {
+ m_output << "QSizePolicy" << language::qualifier << sp->attributeHSizeType()
+ << ", QSizePolicy" << language::qualifier << sp->attributeVSizeType();
+ }
+ m_output << ')' << language::eol;
m_output << m_indent << spName << ".setHorizontalStretch("
<< sp->elementHorStretch() << ");\n";
@@ -1546,10 +1587,11 @@ QString WriteInitialization::writeFontProperties(const DomFont *f)
const QString fontName = m_driver->unique(QLatin1String("font"));
m_fontPropertiesNameMap.insert(FontHandle(f), fontName);
- m_output << m_indent << "QFont " << fontName << ";\n";
+ m_output << m_indent << language::stackVariable("QFont", fontName)
+ << language::eol;
if (f->hasElementFamily() && !f->elementFamily().isEmpty()) {
- m_output << m_indent << fontName << ".setFamily(QString::fromUtf8("
- << fixString(f->elementFamily(), m_dindent) << "));\n";
+ m_output << m_indent << fontName << ".setFamily("
+ << language::qstring(f->elementFamily(), m_dindent) << ");\n";
}
if (f->hasElementPointSize() && f->elementPointSize() > 0) {
m_output << m_indent << fontName << ".setPointSize(" << f->elementPointSize()
@@ -1558,39 +1600,51 @@ QString WriteInitialization::writeFontProperties(const DomFont *f)
if (f->hasElementBold()) {
m_output << m_indent << fontName << ".setBold("
- << (f->elementBold() ? "true" : "false") << ");\n";
+ << language::boolValue(f->elementBold()) << ')' << language::eol;
}
if (f->hasElementItalic()) {
m_output << m_indent << fontName << ".setItalic("
- << (f->elementItalic() ? "true" : "false") << ");\n";
+ << language::boolValue(f->elementItalic()) << ')' << language::eol;
}
if (f->hasElementUnderline()) {
m_output << m_indent << fontName << ".setUnderline("
- << (f->elementUnderline() ? "true" : "false") << ");\n";
+ << language::boolValue(f->elementUnderline()) << ')' << language::eol;
}
if (f->hasElementWeight() && f->elementWeight() > 0) {
m_output << m_indent << fontName << ".setWeight("
- << f->elementWeight() << ");" << endl;
+ << f->elementWeight() << ");" << Qt::endl;
}
if (f->hasElementStrikeOut()) {
m_output << m_indent << fontName << ".setStrikeOut("
- << (f->elementStrikeOut() ? "true" : "false") << ");\n";
+ << language::boolValue(f->elementStrikeOut()) << ')' << language::eol;
}
if (f->hasElementKerning()) {
m_output << m_indent << fontName << ".setKerning("
- << (f->elementKerning() ? "true" : "false") << ");\n";
+ << language::boolValue(f->elementKerning()) << ')' << language::eol;
}
if (f->hasElementAntialiasing()) {
- m_output << m_indent << fontName << ".setStyleStrategy("
- << (f->elementAntialiasing() ? "QFont::PreferDefault" : "QFont::NoAntialias") << ");\n";
+ m_output << m_indent << fontName << ".setStyleStrategy(QFont"
+ << language::qualifier
+ << (f->elementAntialiasing() ? "PreferDefault" : "NoAntialias")
+ << ')' << language::eol;
}
if (f->hasElementStyleStrategy()) {
- m_output << m_indent << fontName << ".setStyleStrategy(QFont::"
- << f->elementStyleStrategy() << ");\n";
+ m_output << m_indent << fontName << ".setStyleStrategy(QFont"
+ << language::qualifier << f->elementStyleStrategy() << ')' << language::eol;
}
return fontName;
}
+static void writeIconAddFile(QTextStream &output, const QString &indent,
+ const QString &iconName, const QString &fileName,
+ const char *mode, const char *state)
+{
+ output << indent << iconName << ".addFile("
+ << language::qstring(fileName, indent) << ", QSize(), QIcon"
+ << language::qualifier << mode << ", QIcon" << language::qualifier
+ << state << ')' << language::eol;
+}
+
// Post 4.4 write resource icon
static void writeResourceIcon(QTextStream &output,
const QString &iconName,
@@ -1598,91 +1652,92 @@ static void writeResourceIcon(QTextStream &output,
const DomResourceIcon *i)
{
if (i->hasElementNormalOff()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementNormalOff()->text(), indent)
- << "), QSize(), QIcon::Normal, QIcon::Off);\n";
+ writeIconAddFile(output, indent, iconName, i->elementNormalOff()->text(),
+ "Normal", "Off");
}
if (i->hasElementNormalOn()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementNormalOn()->text(), indent)
- << "), QSize(), QIcon::Normal, QIcon::On);\n";
+ writeIconAddFile(output, indent, iconName, i->elementNormalOn()->text(),
+ "Normal", "On");
}
if (i->hasElementDisabledOff()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementDisabledOff()->text(), indent)
- << "), QSize(), QIcon::Disabled, QIcon::Off);\n";
+ writeIconAddFile(output, indent, iconName, i->elementDisabledOff()->text(),
+ "Disabled", "Off");
}
if (i->hasElementDisabledOn()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementDisabledOn()->text(), indent)
- << "), QSize(), QIcon::Disabled, QIcon::On);\n";
+ writeIconAddFile(output, indent, iconName, i->elementDisabledOn()->text(),
+ "Disabled", "On");
}
if (i->hasElementActiveOff()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementActiveOff()->text(), indent)
- << "), QSize(), QIcon::Active, QIcon::Off);\n";
+ writeIconAddFile(output, indent, iconName, i->elementActiveOff()->text(),
+ "Active", "Off");
}
if (i->hasElementActiveOn()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementActiveOn()->text(), indent)
- << "), QSize(), QIcon::Active, QIcon::On);\n";
+ writeIconAddFile(output, indent, iconName, i->elementActiveOn()->text(),
+ "Active", "On");
}
if (i->hasElementSelectedOff()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementSelectedOff()->text(), indent)
- << "), QSize(), QIcon::Selected, QIcon::Off);\n";
+ writeIconAddFile(output, indent, iconName, i->elementSelectedOff()->text(),
+ "Selected", "Off");
}
if (i->hasElementSelectedOn()) {
- output << indent << iconName << ".addFile(QString::fromUtf8("
- << fixString(i->elementSelectedOn()->text(), indent)
- << "), QSize(), QIcon::Selected, QIcon::On);\n";
+ writeIconAddFile(output, indent, iconName, i->elementSelectedOff()->text(),
+ "Selected", "On");
}
}
+static void writeIconAddPixmap(QTextStream &output, const QString &indent,
+ const QString &iconName, const QString &call,
+ const char *mode, const char *state)
+{
+ output << indent << iconName << ".addPixmap(" << call << ", QIcon"
+ << language::qualifier << mode << ", QIcon" << language::qualifier
+ << state << ')' << language::eol;
+}
+
void WriteInitialization::writePixmapFunctionIcon(QTextStream &output,
const QString &iconName,
const QString &indent,
const DomResourceIcon *i) const
{
if (i->hasElementNormalOff()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementNormalOff()->text())
- << ", QIcon::Normal, QIcon::Off);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementNormalOff()->text()),
+ "Normal", "Off");
}
if (i->hasElementNormalOn()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementNormalOn()->text())
- << ", QIcon::Normal, QIcon::On);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementNormalOn()->text()),
+ "Normal", "On");
}
if (i->hasElementDisabledOff()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementDisabledOff()->text())
- << ", QIcon::Disabled, QIcon::Off);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementDisabledOff()->text()),
+ "Disabled", "Off");
}
if (i->hasElementDisabledOn()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementDisabledOn()->text())
- << ", QIcon::Disabled, QIcon::On);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementDisabledOn()->text()),
+ "Disabled", "On");
}
if (i->hasElementActiveOff()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementActiveOff()->text())
- << ", QIcon::Active, QIcon::Off);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementActiveOff()->text()),
+ "Active", "Off");
}
if (i->hasElementActiveOn()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementActiveOn()->text())
- << ", QIcon::Active, QIcon::On);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementActiveOn()->text()),
+ "Active", "On");
}
if (i->hasElementSelectedOff()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementSelectedOff()->text())
- << ", QIcon::Selected, QIcon::Off);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementSelectedOff()->text()),
+ "Selected", "Off");
}
if (i->hasElementSelectedOn()) {
- output << indent << iconName << ".addPixmap("
- << pixCall(QLatin1String("QPixmap"), i->elementSelectedOn()->text())
- << ", QIcon::Selected, QIcon::On);\n";
+ writeIconAddPixmap(output, indent, iconName,
+ pixCall(QLatin1String("QPixmap"), i->elementSelectedOn()->text()),
+ "Selected", "On");
}
}
@@ -1691,57 +1746,76 @@ QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
// check cache
const IconHandle iconHandle(i);
const IconPropertiesNameMap::const_iterator it = m_iconPropertiesNameMap.constFind(iconHandle);
- if (it != m_iconPropertiesNameMap.constEnd()) {
+ if (it != m_iconPropertiesNameMap.constEnd())
return it.value();
- }
// insert with new name
const QString iconName = m_driver->unique(QLatin1String("icon"));
m_iconPropertiesNameMap.insert(IconHandle(i), iconName);
- if (isIconFormat44(i)) {
- if (i->attributeTheme().isEmpty()) {
- // No theme: Write resource icon as is
- m_output << m_indent << "QIcon " << iconName << ";\n";
- if (m_uic->pixmapFunction().isEmpty())
- writeResourceIcon(m_output, iconName, m_indent, i);
- else
- writePixmapFunctionIcon(m_output, iconName, m_indent, i);
- } else {
- // Theme: Generate code to check the theme and default to resource
- const QString themeIconName = fixString(i->attributeTheme(), QString());
- if (iconHasStatePixmaps(i)) {
- // Theme + default state pixmaps:
- // Generate code to check the theme and default to state pixmaps
- m_output << m_indent << "QIcon " << iconName << ";\n";
- const char themeNameStringVariableC[] = "iconThemeName";
- // Store theme name in a variable
- m_output << m_indent;
- if (m_firstThemeIcon) { // Declare variable string
- m_output << "QString ";
- m_firstThemeIcon = false;
- }
- m_output << themeNameStringVariableC << " = QString::fromUtf8("
- << themeIconName << ");\n";
- m_output << m_indent << "if (QIcon::hasThemeIcon("
- << themeNameStringVariableC
- << ")) {\n"
- << m_dindent << iconName << " = QIcon::fromTheme(" << themeNameStringVariableC << ");\n"
- << m_indent << "} else {\n";
- if (m_uic->pixmapFunction().isEmpty())
- writeResourceIcon(m_output, iconName, m_dindent, i);
- else
- writePixmapFunctionIcon(m_output, iconName, m_dindent, i);
- m_output << m_indent << "}\n";
- } else {
- // Theme, but no state pixmaps: Construct from theme directly.
- m_output << m_indent << "QIcon " << iconName
- << "(QIcon::fromTheme(QString::fromUtf8("
- << themeIconName << ")));\n";
- } // Theme, but not state
- } // >= 4.4
- } else { // pre-4.4 legacy
- m_output << m_indent << "const QIcon " << iconName << " = " << pixCall(QLatin1String("QIcon"), i->text())<< ";\n";
+
+ const bool isCpp = language::language() == Language::Cpp;
+
+ if (Q_UNLIKELY(!isIconFormat44(i))) { // pre-4.4 legacy
+ m_output << m_indent;
+ if (isCpp)
+ m_output << "const QIcon ";
+ m_output << iconName << " = " << pixCall(QLatin1String("QIcon"), i->text())
+ << language::eol;
+ return iconName;
+ }
+
+ // 4.4 onwards
+ if (i->attributeTheme().isEmpty()) {
+ // No theme: Write resource icon as is
+ m_output << m_indent << language::stackVariable("QIcon", iconName)
+ << language::eol;
+ if (m_uic->pixmapFunction().isEmpty())
+ writeResourceIcon(m_output, iconName, m_indent, i);
+ else
+ writePixmapFunctionIcon(m_output, iconName, m_indent, i);
+ return iconName;
}
+
+ // Theme: Generate code to check the theme and default to resource
+ if (iconHasStatePixmaps(i)) {
+ // Theme + default state pixmaps:
+ // Generate code to check the theme and default to state pixmaps
+ m_output << m_indent << language::stackVariable("QIcon", iconName) << ";\n";
+ const char themeNameStringVariableC[] = "iconThemeName";
+ // Store theme name in a variable
+ m_output << m_indent;
+ if (m_firstThemeIcon) { // Declare variable string
+ if (isCpp)
+ m_output << "QString ";
+ m_firstThemeIcon = false;
+ }
+ m_output << themeNameStringVariableC << " = "
+ << language::qstring(i->attributeTheme()) << language::eol;
+ m_output << m_indent << "if ";
+ if (isCpp)
+ m_output << '(';
+ m_output << "QIcon" << language::qualifier << "hasThemeIcon("
+ << themeNameStringVariableC << ')' << (isCpp ? ") {" : ":") << '\n'
+ << m_dindent << iconName << " = QIcon" << language::qualifier << "fromTheme("
+ << themeNameStringVariableC << ')' << language::eol
+ << m_indent << (isCpp ? "} else {" : "else:") << '\n';
+ if (m_uic->pixmapFunction().isEmpty())
+ writeResourceIcon(m_output, iconName, m_dindent, i);
+ else
+ writePixmapFunctionIcon(m_output, iconName, m_dindent, i);
+ m_output << m_indent;
+ if (isCpp)
+ m_output << '}';
+ m_output << '\n';
+ return iconName;
+ }
+
+ // Theme, but no state pixmaps: Construct from theme directly.
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QIcon", iconName)
+ << "QIcon" << language::qualifier << "fromTheme("
+ << language::qstring(i->attributeTheme()) << "))"
+ << language::eol;
return iconName;
}
@@ -1777,7 +1851,7 @@ void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QStri
const DomColor *color = colors.at(i);
m_output << m_indent << paletteName << ".setColor(" << group
- << ", QPalette::" << language::paletteColorRole(i)
+ << ", QPalette" << language::qualifier << language::paletteColorRole(i)
<< ", " << domColor2QString(color)
<< ");\n";
}
@@ -1794,8 +1868,9 @@ void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QStri
<< versionAdded.majorVersion() << ", " << versionAdded.minorVersion()
<< ", " << versionAdded.microVersion() << ")\n";
}
- m_output << m_indent << paletteName << ".setBrush(" << group
- << ", " << "QPalette::" << roleName
+ m_output << m_indent << paletteName << ".setBrush("
+ << language::enumValue(group) << ", "
+ << "QPalette" << language::qualifier << roleName
<< ", " << brushName << ");\n";
if (!versionAdded.isNull())
m_output << "#endif\n";
@@ -1842,31 +1917,36 @@ void WriteInitialization::writeBrush(const DomBrush *brush, const QString &brush
const QString gradientType = gradient->attributeType();
const QString gradientName = m_driver->unique(QLatin1String("gradient"));
if (gradientType == QLatin1String("LinearGradient")) {
- m_output << m_indent << "QLinearGradient " << gradientName
- << '(' << gradient->attributeStartX()
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QLinearGradient", gradientName)
+ << gradient->attributeStartX()
<< ", " << gradient->attributeStartY()
<< ", " << gradient->attributeEndX()
- << ", " << gradient->attributeEndY() << ");\n";
+ << ", " << gradient->attributeEndY() << ')' << language::eol;
} else if (gradientType == QLatin1String("RadialGradient")) {
- m_output << m_indent << "QRadialGradient " << gradientName
- << '(' << gradient->attributeCentralX()
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QRadialGradient", gradientName)
+ << gradient->attributeCentralX()
<< ", " << gradient->attributeCentralY()
<< ", " << gradient->attributeRadius()
<< ", " << gradient->attributeFocalX()
- << ", " << gradient->attributeFocalY() << ");\n";
+ << ", " << gradient->attributeFocalY() << ')' << language::eol;
} else if (gradientType == QLatin1String("ConicalGradient")) {
- m_output << m_indent << "QConicalGradient " << gradientName
- << '(' << gradient->attributeCentralX()
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QConicalGradient", gradientName)
+ << gradient->attributeCentralX()
<< ", " << gradient->attributeCentralY()
- << ", " << gradient->attributeAngle() << ");\n";
+ << ", " << gradient->attributeAngle() << ')' << language::eol;
}
- m_output << m_indent << gradientName << ".setSpread(QGradient::"
- << gradient->attributeSpread() << ");\n";
+ m_output << m_indent << gradientName << ".setSpread(QGradient"
+ << language::qualifier << gradient->attributeSpread()
+ << ')' << language::eol;
if (gradient->hasAttributeCoordinateMode()) {
- m_output << m_indent << gradientName << ".setCoordinateMode(QGradient::"
- << gradient->attributeCoordinateMode() << ");\n";
+ m_output << m_indent << gradientName << ".setCoordinateMode(QGradient"
+ << language::qualifier << gradient->attributeCoordinateMode()
+ << ')' << language::eol;
}
const auto &stops = gradient->elementGradientStop();
@@ -1874,23 +1954,26 @@ void WriteInitialization::writeBrush(const DomBrush *brush, const QString &brush
const DomColor *color = stop->elementColor();
m_output << m_indent << gradientName << ".setColorAt("
<< stop->attributePosition() << ", "
- << domColor2QString(color) << ");\n";
+ << domColor2QString(color) << ')' << language::eol;
}
- m_output << m_indent << "QBrush " << brushName << '('
- << gradientName << ");\n";
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QBrush", brushName)
+ << gradientName << ')' << language::eol;
} else if (style == QLatin1String("TexturePattern")) {
const DomProperty *property = brush->elementTexture();
const QString iconValue = iconCall(property);
- m_output << m_indent << "QBrush " << brushName << " = QBrush("
- << iconValue << ");\n";
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QBrush", brushName)
+ << iconValue << ')' << language::eol;
} else {
const DomColor *color = brush->elementColor();
- m_output << m_indent << "QBrush " << brushName << '('
- << domColor2QString(color) << ");\n";
+ m_output << m_indent
+ << language::stackVariableWithInitParameters("QBrush", brushName)
+ << domColor2QString(color) << ')' << language::eol;
m_output << m_indent << brushName << ".setStyle("
- << "Qt::" << style << ");\n";
+ << language::qtQualifier << style << ')' << language::eol;
}
}
@@ -1910,12 +1993,11 @@ void WriteInitialization::acceptTabStops(DomTabStops *tabStops)
const QStringList l = tabStops->elementTabStop();
for (int i=0; i<l.size(); ++i) {
- const QString &name = l.at(i);
+ const QString name = m_driver->widgetVariableName(l.at(i));
- if (!m_registeredWidgets.contains(name)) {
+ if (name.isEmpty()) {
fprintf(stderr, "%s: Warning: Tab-stop assignment: '%s' is not a valid widget.\n",
- qPrintable(m_option.messagePrefix()),
- name.toLatin1().data());
+ qPrintable(m_option.messagePrefix()), qPrintable(l.at(i)));
continue;
}
@@ -1926,7 +2008,8 @@ void WriteInitialization::acceptTabStops(DomTabStops *tabStops)
if (name.isEmpty() || lastName.isEmpty())
continue;
- m_output << m_indent << "QWidget::setTabOrder(" << lastName << ", " << name << ");\n";
+ m_output << m_indent << "QWidget" << language::qualifier << "setTabOrder("
+ << lastName << ", " << name << ')' << language::eol;
lastName = name;
}
@@ -1968,15 +2051,14 @@ QString WriteInitialization::pixCall(const QString &t, const QString &text) cons
return type;
}
+ QTextStream str(&type);
+ str << '(';
QString pixFunc = m_uic->pixmapFunction();
if (pixFunc.isEmpty())
- pixFunc = QLatin1String("QString::fromUtf8");
-
- type += QLatin1Char('(')
- + pixFunc
- + QLatin1Char('(')
- + fixString(text, m_dindent)
- + QLatin1String("))");
+ str << language::qstring(text, m_dindent);
+ else
+ str << pixFunc << '(' << language::charliteral(text, m_dindent) << ')';
+ str << ')';
return type;
}
@@ -1999,13 +2081,15 @@ void WriteInitialization::initializeComboBox(DomWidget *w)
if (icon)
iconValue = iconCall(icon);
- m_output << m_indent << varName << "->addItem(";
+ m_output << m_indent << varName << language::derefPointer << "addItem(";
if (icon)
m_output << iconValue << ", ";
if (needsTranslation(text->elementString())) {
m_output << "QString());\n";
- m_refreshOut << m_indent << varName << "->setItemText(" << i << ", " << trCall(text->elementString()) << ");\n";
+ m_refreshOut << m_indent << varName << language::derefPointer
+ << "setItemText(" << i << ", " << trCall(text->elementString())
+ << ')' << language::eol;
} else {
m_output << noTrCall(text->elementString()) << ");\n";
}
@@ -2020,9 +2104,13 @@ QString WriteInitialization::disableSorting(DomWidget *w, const QString &varName
if (!w->elementItem().isEmpty()) {
tempName = m_driver->unique(QLatin1String("__sortingEnabled"));
m_refreshOut << "\n";
- m_refreshOut << m_indent << "const bool " << tempName
- << " = " << varName << "->isSortingEnabled();\n";
- m_refreshOut << m_indent << varName << "->setSortingEnabled(false);\n";
+ m_refreshOut << m_indent;
+ if (language::language() == Language::Cpp)
+ m_refreshOut << "const bool ";
+ m_refreshOut << tempName << " = " << varName << language::derefPointer
+ << "isSortingEnabled()" << language::eol
+ << m_indent << varName << language::derefPointer
+ << "setSortingEnabled(" << language::boolValue(false) << ')' << language::eol;
}
return tempName;
}
@@ -2030,7 +2118,8 @@ QString WriteInitialization::disableSorting(DomWidget *w, const QString &varName
void WriteInitialization::enableSorting(DomWidget *w, const QString &varName, const QString &tempName)
{
if (!w->elementItem().isEmpty()) {
- m_refreshOut << m_indent << varName << "->setSortingEnabled(" << tempName << ");\n\n";
+ m_refreshOut << m_indent << varName << language::derefPointer
+ << "setSortingEnabled(" << tempName << ')' << language::eol << '\n';
}
}
@@ -2055,7 +2144,7 @@ void WriteInitialization::addInitializer(Item *item,
if (!value.isEmpty()) {
QString setter;
QTextStream str(&setter);
- str << "->set" << name.at(0).toUpper() << name.midRef(1) << '(';
+ str << language::derefPointer << "set" << name.at(0).toUpper() << name.midRef(1) << '(';
if (column >= 0)
str << column << ", ";
str << value << ");";
@@ -2105,10 +2194,11 @@ void WriteInitialization::addQtFlagsInitializer(Item *item,
const DomPropertyMap &properties, const QString &name, int column) const
{
if (const DomProperty *p = properties.value(name)) {
+ const QString orOperator = QLatin1Char('|') + language::qtQualifier;
QString v = p->elementSet();
if (!v.isEmpty()) {
- v.replace(QLatin1Char('|'), QLatin1String("|Qt::"));
- addInitializer(item, name, column, QLatin1String("Qt::") + v);
+ v.replace(QLatin1Char('|'), orOperator);
+ addInitializer(item, name, column, language::qtQualifier + v);
}
}
}
@@ -2123,7 +2213,7 @@ void WriteInitialization::addQtEnumInitializer(Item *item,
if (const DomProperty *p = properties.value(name)) {
QString v = p->elementEnum();
if (!v.isEmpty())
- addInitializer(item, name, column, QLatin1String("Qt::") + v);
+ addInitializer(item, name, column, language::qtQualifier + v);
}
}
@@ -2172,7 +2262,9 @@ void WriteInitialization::initializeListWidget(DomWidget *w)
addCommonInitializers(&item, properties);
item.writeSetupUi(varName);
- item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(i) + QLatin1Char(')'));
+ QString parentPath;
+ QTextStream(&parentPath) << varName << language::derefPointer << "item(" << i << ')';
+ item.writeRetranslateUi(parentPath);
}
enableSorting(w, varName, tempName);
}
@@ -2193,14 +2285,19 @@ void WriteInitialization::initializeTreeWidget(DomWidget *w)
if (const DomProperty *p = properties.value(QLatin1String("text"))) {
DomString *str = p->elementString();
- if (str && str->text().isEmpty())
- m_output << m_indent << varName << "->headerItem()->setText(" << i << ", QString());\n";
+ if (str && str->text().isEmpty()) {
+ m_output << m_indent << varName << language::derefPointer
+ << "headerItem()" << language::derefPointer << "setText("
+ << i << ", QString())" << language::eol;
+ }
}
}
const QString itemName = item.writeSetupUi(QString(), Item::DontConstruct);
- item.writeRetranslateUi(varName + QLatin1String("->headerItem()"));
- if (!itemName.isNull())
- m_output << m_indent << varName << "->setHeaderItem(" << itemName << ");\n";
+ item.writeRetranslateUi(varName + language::derefPointer + QLatin1String("headerItem()"));
+ if (!itemName.isNull()) {
+ m_output << m_indent << varName << language::derefPointer
+ << "setHeaderItem(" << itemName << ')' << language::eol;
+ }
if (w->elementItem().empty())
return;
@@ -2211,7 +2308,9 @@ void WriteInitialization::initializeTreeWidget(DomWidget *w)
for (int i = 0; i < items.count(); i++) {
Item *itm = items[i];
itm->writeSetupUi(varName);
- itm->writeRetranslateUi(varName + QLatin1String("->topLevelItem(") + QString::number(i) + QLatin1Char(')'));
+ QString parentPath;
+ QTextStream(&parentPath) << varName << language::derefPointer << "topLevelItem(" << i << ')';
+ itm->writeRetranslateUi(parentPath);
delete itm;
}
@@ -2273,8 +2372,10 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
const auto &columns = w->elementColumn();
if (!columns.empty()) {
- m_output << m_indent << "if (" << varName << "->columnCount() < " << columns.size() << ")\n"
- << m_dindent << varName << "->setColumnCount(" << columns.size() << ");\n";
+ m_output << m_indent << "if (" << varName << language::derefPointer << "columnCount() < "
+ << columns.size() << ")\n"
+ << m_dindent << varName << language::derefPointer << "setColumnCount("
+ << columns.size() << ')' << language::eol;
}
for (int i = 0; i < columns.size(); ++i) {
@@ -2286,8 +2387,12 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
addCommonInitializers(&item, properties);
QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
- item.writeRetranslateUi(varName + QLatin1String("->horizontalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
- m_output << m_indent << varName << "->setHorizontalHeaderItem(" << i << ", " << itemName << ");\n";
+ QString parentPath;
+ QTextStream(&parentPath) << varName << language::derefPointer
+ << "horizontalHeaderItem(" << i << ')';
+ item.writeRetranslateUi(parentPath);
+ m_output << m_indent << varName << language::derefPointer << "setHorizontalHeaderItem("
+ << i << ", " << itemName << ')' << language::eol;
}
}
@@ -2295,8 +2400,9 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
const auto &rows = w->elementRow();
if (!rows.isEmpty()) {
- m_output << m_indent << "if (" << varName << "->rowCount() < " << rows.size() << ")\n"
- << m_dindent << varName << "->setRowCount(" << rows.size() << ");\n";
+ m_output << m_indent << "if (" << varName << language::derefPointer << "rowCount() < " << rows.size() << ")\n"
+ << m_dindent << varName << language::derefPointer << "setRowCount("
+ << rows.size() << ')' << language::eol;
}
for (int i = 0; i < rows.size(); ++i) {
@@ -2308,8 +2414,11 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
addCommonInitializers(&item, properties);
QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
- item.writeRetranslateUi(varName + QLatin1String("->verticalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
- m_output << m_indent << varName << "->setVerticalHeaderItem(" << i << ", " << itemName << ");\n";
+ QString parentPath;
+ QTextStream(&parentPath) << varName << language::derefPointer << "verticalHeaderItem(" << i << ')';
+ item.writeRetranslateUi(parentPath);
+ m_output << m_indent << varName << language::derefPointer << "setVerticalHeaderItem("
+ << i << ", " << itemName << ')' << language::eol;
}
}
@@ -2329,8 +2438,12 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
addCommonInitializers(&item, properties);
QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
- item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(r) + QLatin1String(", ") + QString::number(c) + QLatin1Char(')'));
- m_output << m_indent << varName << "->setItem(" << r << ", " << c << ", " << itemName << ");\n";
+ QString parentPath;
+ QTextStream(&parentPath) << varName << language::derefPointer << "item(" << r
+ << ", " << c << ')';
+ item.writeRetranslateUi(parentPath);
+ m_output << m_indent << varName << language::derefPointer << "setItem("
+ << r << ", " << c << ", " << itemName << ')' << language::eol;
}
}
enableSorting(w, varName, tempName);
@@ -2338,32 +2451,37 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
QString WriteInitialization::trCall(const QString &str, const QString &commentHint, const QString &id) const
{
- if (str.isEmpty())
- return QLatin1String("QString()");
+ if (str.isEmpty()) {
+ return language::language() == Language::Cpp
+ ? QLatin1String("QString()") : QLatin1String("\"\"");
+ }
QString result;
- const QString comment = commentHint.isEmpty() ? QString(QLatin1String("nullptr")) : fixString(commentHint, m_dindent);
+ QTextStream ts(&result);
const bool idBasedTranslations = m_driver->useIdBasedTranslations();
if (m_option.translateFunction.isEmpty()) {
if (idBasedTranslations || m_option.idBased) {
- result += QLatin1String("qtTrId(");
+ ts << "qtTrId(";
} else {
- result += QLatin1String("QCoreApplication::translate(\"")
- + m_generatedClass
- + QLatin1String("\", ");
+ ts << "QCoreApplication" << language::qualifier << "translate("
+ << '"' << m_generatedClass << "\", ";
}
} else {
- result += m_option.translateFunction + QLatin1Char('(');
+ ts << m_option.translateFunction << '(';
}
- result += fixString(idBasedTranslations ? id : str, m_dindent);
+ ts << language::charliteral(idBasedTranslations ? id : str, m_dindent);
if (!idBasedTranslations && !m_option.idBased) {
- result += QLatin1String(", ") + comment;
+ ts << ", ";
+ if (commentHint.isEmpty())
+ ts << language::nullPtr;
+ else
+ ts << language::charliteral(commentHint, m_dindent);
}
- result += QLatin1Char(')');
+ ts << ')';
return result;
}
@@ -2374,7 +2492,8 @@ void WriteInitialization::initializeMenu(DomWidget *w, const QString &/*parentWi
const DomAction *action = m_driver->actionByName(menuAction);
if (action && action->hasAttributeMenu()) {
- m_output << m_indent << menuAction << " = " << menuName << "->menuAction();\n";
+ m_output << m_indent << menuAction << " = " << menuName
+ << language::derefPointer << "menuAction()" << language::eol;
}
}
@@ -2398,9 +2517,9 @@ QString WriteInitialization::noTrCall(DomString *str, const QString &defaultStri
return QString();
if (str)
value = str->text();
- QString ret = QLatin1String("QString::fromUtf8(");
- ret += fixString(value, m_dindent);
- ret += QLatin1Char(')');
+ QString ret;
+ QTextStream ts(&ret);
+ ts << language::qstring(value, m_dindent);
return ret;
}
@@ -2428,36 +2547,42 @@ QTextStream &WriteInitialization::autoTrOutput(const DomString *str, const QStri
return m_output;
}
-QString WriteInitialization::findDeclaration(const QString &name)
+WriteInitialization::Declaration WriteInitialization::findDeclaration(const QString &name)
{
- const QString normalized = Driver::normalizedName(name);
-
- if (const DomWidget *widget = m_driver->widgetByName(normalized))
- return m_driver->findOrInsertWidget(widget);
- if (const DomAction *action = m_driver->actionByName(normalized))
- return m_driver->findOrInsertAction(action);
- if (const DomButtonGroup *group = m_driver->findButtonGroup(normalized))
- return m_driver->findOrInsertButtonGroup(group);
- return QString();
+ if (const DomWidget *widget = m_driver->widgetByName(name))
+ return {m_driver->findOrInsertWidget(widget), widget->attributeClass()};
+ if (const DomAction *action = m_driver->actionByName(name))
+ return {m_driver->findOrInsertAction(action), QStringLiteral("QAction")};
+ if (const DomButtonGroup *group = m_driver->findButtonGroup(name))
+ return {m_driver->findOrInsertButtonGroup(group), QStringLiteral("QButtonGroup")};
+ return {};
}
void WriteInitialization::acceptConnection(DomConnection *connection)
{
- const QString sender = findDeclaration(connection->elementSender());
- const QString receiver = findDeclaration(connection->elementReceiver());
+ const QString senderName = connection->elementSender();
+ const QString receiverName = connection->elementReceiver();
+
+ const auto senderDecl = findDeclaration(senderName);
+ const auto receiverDecl = findDeclaration(receiverName);
- if (sender.isEmpty() || receiver.isEmpty())
+ if (senderDecl.name.isEmpty() || receiverDecl.name.isEmpty()) {
+ QString message;
+ QTextStream(&message) << m_option.messagePrefix()
+ << ": Warning: Invalid signal/slot connection: \""
+ << senderName << "\" -> \"" << receiverName << "\".";
+ fprintf(stderr, "%s\n", qPrintable(message));
return;
+ }
+
+ language::SignalSlot theSignal{senderDecl.name, connection->elementSignal(),
+ senderDecl.className};
+ language::SignalSlot theSlot{receiverDecl.name, connection->elementSlot(),
+ receiverDecl.className};
- m_output << m_indent << "QObject::connect("
- << sender
- << ", "
- << "SIGNAL("<<connection->elementSignal()<<')'
- << ", "
- << receiver
- << ", "
- << "SLOT("<<connection->elementSlot()<<')'
- << ");\n";
+ m_output << m_indent;
+ language::formatConnection(m_output, theSignal, theSlot);
+ m_output << ";\n";
}
static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QString> &directives)
@@ -2470,14 +2595,14 @@ static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QS
return;
}
- auto list = directives.toList();
+ auto list = directives.values();
// sort (always generate in the same order):
std::sort(list.begin(), list.end());
outputStream << "#if " << language::qtConfig(list.constFirst());
for (int i = 1, size = list.size(); i < size; ++i)
outputStream << " || " << language::qtConfig(list.at(i));
- outputStream << endl;
+ outputStream << Qt::endl;
}
static void generateMultiDirectiveEnd(QTextStream &outputStream, const QSet<QString> &directives)
@@ -2485,12 +2610,11 @@ static void generateMultiDirectiveEnd(QTextStream &outputStream, const QSet<QStr
if (directives.isEmpty())
return;
- outputStream << "#endif" << endl;
+ outputStream << "#endif" << Qt::endl;
}
WriteInitialization::Item::Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver)
:
- m_parent(0),
m_itemClassName(itemClassName),
m_indent(indent),
m_setupUiStream(setupUiStream),
@@ -2513,7 +2637,8 @@ QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::Emp
bool generateMultiDirective = false;
if (emptyItemPolicy == Item::ConstructItemOnly && m_children.isEmpty()) {
if (m_setupUiData.policy == ItemData::DontGenerate) {
- m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
+ m_setupUiStream << m_indent << language::operatorNew << m_itemClassName
+ << '(' << parent << ')' << language::eol;
return QString();
}
if (m_setupUiData.policy == ItemData::GenerateWithMultiDirective)
@@ -2524,11 +2649,17 @@ QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::Emp
generateMultiDirectiveBegin(m_setupUiStream, m_setupUiData.directives);
const QString uniqueName = m_driver->unique(QLatin1String("__") + m_itemClassName.toLower());
- m_setupUiStream << m_indent << m_itemClassName << " *" << uniqueName << " = new " << m_itemClassName << '(' << parent << ");\n";
+ m_setupUiStream << m_indent;
+ if (language::language() == Language::Cpp)
+ m_setupUiStream << m_itemClassName << " *";
+ m_setupUiStream << uniqueName
+ << " = " << language::operatorNew << m_itemClassName << '(' << parent
+ << ')' << language::eol;
if (generateMultiDirective) {
m_setupUiStream << "#else\n";
- m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
+ m_setupUiStream << m_indent << language::operatorNew << m_itemClassName
+ << '(' << parent << ')' << language::eol;
generateMultiDirectiveEnd(m_setupUiStream, m_setupUiData.directives);
}
@@ -2536,7 +2667,7 @@ QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::Emp
while (it != m_setupUiData.setters.constEnd()) {
if (!it.key().isEmpty())
m_setupUiStream << language::openQtConfig(it.key());
- m_setupUiStream << m_indent << uniqueName << it.value() << endl;
+ m_setupUiStream << m_indent << uniqueName << it.value() << Qt::endl;
if (!it.key().isEmpty())
m_setupUiStream << language::closeQtConfig(it.key());
++it;
@@ -2555,7 +2686,10 @@ void WriteInitialization::Item::writeRetranslateUi(const QString &parentPath)
generateMultiDirectiveBegin(m_retranslateUiStream, m_retranslateUiData.directives);
const QString uniqueName = m_driver->unique(QLatin1String("___") + m_itemClassName.toLower());
- m_retranslateUiStream << m_indent << m_itemClassName << " *" << uniqueName << " = " << parentPath << ";\n";
+ m_retranslateUiStream << m_indent;
+ if (language::language() == Language::Cpp)
+ m_retranslateUiStream << m_itemClassName << " *";
+ m_retranslateUiStream << uniqueName << " = " << parentPath << language::eol;
if (m_retranslateUiData.policy == ItemData::GenerateWithMultiDirective)
generateMultiDirectiveEnd(m_retranslateUiStream, m_retranslateUiData.directives);
@@ -2571,14 +2705,17 @@ void WriteInitialization::Item::writeRetranslateUi(const QString &parentPath)
m_retranslateUiStream << language::openQtConfig(newDirective);
oldDirective = newDirective;
}
- m_retranslateUiStream << m_indent << uniqueName << it.value() << endl;
+ m_retranslateUiStream << m_indent << uniqueName << it.value() << Qt::endl;
++it;
}
if (!oldDirective.isEmpty())
m_retranslateUiStream << language::closeQtConfig(oldDirective);
- for (int i = 0; i < m_children.size(); i++)
- m_children[i]->writeRetranslateUi(uniqueName + QLatin1String("->child(") + QString::number(i) + QLatin1Char(')'));
+ for (int i = 0; i < m_children.size(); i++) {
+ QString method;
+ QTextStream(&method) << uniqueName << language::derefPointer << "child(" << i << ')';
+ m_children[i]->writeRetranslateUi(method);
+ }
}
void WriteInitialization::Item::addSetter(const QString &setter, const QString &directive, bool translatable)
diff --git a/src/tools/uic/cpp/cppwriteinitialization.h b/src/tools/uic/cpp/cppwriteinitialization.h
index c408c44b40..6f8e352f6a 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.h
+++ b/src/tools/uic/cpp/cppwriteinitialization.h
@@ -85,8 +85,8 @@ namespace CPP {
struct WriteInitialization : public TreeWalker
{
- typedef QList<DomProperty*> DomPropertyList;
- typedef QHash<QString, DomProperty*> DomPropertyMap;
+ using DomPropertyList = QList<DomProperty*>;
+ using DomPropertyMap = QHash<QString, DomProperty*>;
WriteInitialization(Uic *uic);
@@ -161,7 +161,7 @@ private:
// special initialization
//
class Item {
- Q_DISABLE_COPY(Item)
+ Q_DISABLE_COPY_MOVE(Item)
public:
Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver);
~Item();
@@ -188,7 +188,7 @@ private:
ItemData m_setupUiData;
ItemData m_retranslateUiData;
QList<Item *> m_children;
- Item *m_parent;
+ Item *m_parent = nullptr;
const QString m_itemClassName;
const QString m_indent;
@@ -220,7 +220,13 @@ private:
QString disableSorting(DomWidget *w, const QString &varName);
void enableSorting(DomWidget *w, const QString &varName, const QString &tempName);
- QString findDeclaration(const QString &name);
+ struct Declaration
+ {
+ QString name;
+ QString className;
+ };
+
+ Declaration findDeclaration(const QString &name);
private:
QString writeFontProperties(const DomFont *f);
@@ -238,12 +244,12 @@ private:
const Option &m_option;
QString m_indent;
QString m_dindent;
- bool m_stdsetdef;
+ bool m_stdsetdef = true;
struct Buddy
{
- QString objName;
- QString buddy;
+ QString labelVarName;
+ QString buddyAttributeName;
};
friend class QTypeInfo<Buddy>;
@@ -253,15 +259,13 @@ private:
QVector<Buddy> m_buddies;
QSet<QString> m_buttonGroups;
- QHash<QString, DomWidget*> m_registeredWidgets;
- QHash<QString, DomAction*> m_registeredActions;
- typedef QHash<uint, QString> ColorBrushHash;
+ using ColorBrushHash = QHash<uint, QString>;
ColorBrushHash m_colorBrushHash;
// Map from font properties to font variable name for reuse
// Map from size policy to variable for reuse
- typedef QMap<FontHandle, QString> FontPropertiesNameMap;
- typedef QMap<IconHandle, QString> IconPropertiesNameMap;
- typedef QMap<SizePolicyHandle, QString> SizePolicyNameMap;
+ using FontPropertiesNameMap = QMap<FontHandle, QString>;
+ using IconPropertiesNameMap = QMap<IconHandle, QString>;
+ using SizePolicyNameMap = QMap<SizePolicyHandle, QString>;
FontPropertiesNameMap m_fontPropertiesNameMap;
IconPropertiesNameMap m_iconPropertiesNameMap;
SizePolicyNameMap m_sizePolicyNameMap;
@@ -290,11 +294,11 @@ private:
// layout defaults
LayoutDefaultHandler m_LayoutDefaultHandler;
- int m_layoutMarginType;
+ int m_layoutMarginType = TopLevelMargin;
QString m_generatedClass;
QString m_mainFormVarName;
- bool m_mainFormUsedInRetranslateUi;
+ bool m_mainFormUsedInRetranslateUi = false;
QString m_delayedInitialization;
QTextStream m_delayedOut;
@@ -305,8 +309,9 @@ private:
QString m_delayedActionInitialization;
QTextStream m_actionOut;
- bool m_layoutWidget;
- bool m_firstThemeIcon;
+ bool m_layoutWidget = false;
+ bool m_firstThemeIcon = true;
+ bool m_connectSlotsByName = true;
};
} // namespace CPP
diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp
index d6a409152b..c838feaf73 100644
--- a/src/tools/uic/customwidgetsinfo.cpp
+++ b/src/tools/uic/customwidgetsinfo.cpp
@@ -95,7 +95,7 @@ bool CustomWidgetsInfo::extendsOneOf(const QString &classNameIn,
bool CustomWidgetsInfo::isCustomWidgetContainer(const QString &className) const
{
- if (const DomCustomWidget *dcw = m_customWidgets.value(className, 0))
+ if (const DomCustomWidget *dcw = m_customWidgets.value(className, nullptr))
if (dcw->hasElementContainer())
return dcw->elementContainer() != 0;
return false;
@@ -111,7 +111,7 @@ QString CustomWidgetsInfo::realClassName(const QString &className) const
QString CustomWidgetsInfo::customWidgetAddPageMethod(const QString &name) const
{
- if (DomCustomWidget *dcw = m_customWidgets.value(name, 0))
+ if (DomCustomWidget *dcw = m_customWidgets.value(name, nullptr))
return dcw->elementAddPageMethod();
return QString();
}
diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h
index 8a10999027..a1b24ab042 100644
--- a/src/tools/uic/customwidgetsinfo.h
+++ b/src/tools/uic/customwidgetsinfo.h
@@ -62,7 +62,7 @@ public:
bool isCustomWidgetContainer(const QString &className) const;
private:
- typedef QMap<QString, DomCustomWidget*> NameCustomWidgetMap;
+ using NameCustomWidgetMap = QMap<QString, DomCustomWidget*>;
NameCustomWidgetMap m_customWidgets;
};
diff --git a/src/tools/uic/databaseinfo.cpp b/src/tools/uic/databaseinfo.cpp
index fa5d5f5df0..9b0d1614ab 100644
--- a/src/tools/uic/databaseinfo.cpp
+++ b/src/tools/uic/databaseinfo.cpp
@@ -33,9 +33,7 @@
QT_BEGIN_NAMESPACE
-DatabaseInfo::DatabaseInfo()
-{
-}
+DatabaseInfo::DatabaseInfo() = default;
void DatabaseInfo::acceptUI(DomUI *node)
{
@@ -59,10 +57,9 @@ void DatabaseInfo::acceptWidget(DomWidget *node)
DomProperty *db = properties.value(QLatin1String("database"));
if (db && db->elementStringList()) {
QStringList info = db->elementStringList()->elementString();
-
- QString connection = info.size() > 0 ? info.at(0) : QString();
- if (connection.isEmpty())
+ if (info.isEmpty() || info.constFirst().isEmpty())
return;
+ const QString &connection = info.constFirst();
m_connections.append(connection);
QString table = info.size() > 1 ? info.at(1) : QString();
diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp
index 03fa1e17cf..8b9b4806e6 100644
--- a/src/tools/uic/driver.cpp
+++ b/src/tools/uic/driver.cpp
@@ -30,6 +30,8 @@
#include "uic.h"
#include "ui4.h"
+#include <language.h>
+
#include <qfileinfo.h>
#include <qdebug.h>
@@ -51,18 +53,43 @@ static inline QString actionClass() { return QStringLiteral("QAction"); }
static inline QString buttonGroupClass() { return QStringLiteral("QButtonGroup"); }
template <class DomClass>
+Driver::DomObjectHashConstIt<DomClass>
+ Driver::findByAttributeNameIt(const DomObjectHash<DomClass> &domHash,
+ const QString &name) const
+{
+ const auto end = domHash.cend();
+ for (auto it = domHash.cbegin(); it != end; ++it) {
+ if (it.key()->attributeName() == name)
+ return it;
+ }
+ return end;
+}
+
+template <class DomClass>
+const DomClass *Driver::findByAttributeName(const DomObjectHash<DomClass> &domHash,
+ const QString &name) const
+{
+ auto it = findByAttributeNameIt(domHash, name);
+ return it != domHash.cend() ? it.key() : nullptr;
+}
+
+template <class DomClass>
QString Driver::findOrInsert(DomObjectHash<DomClass> *domHash, const DomClass *dom,
- const QString &className)
+ const QString &className, bool isMember)
{
auto it = domHash->find(dom);
- if (it == domHash->end())
- it = domHash->insert(dom, this->unique(dom->attributeName(), className));
+ if (it == domHash->end()) {
+ const QString name = this->unique(dom->attributeName(), className);
+ it = domHash->insert(dom, isMember ? language::self + name : name);
+ }
return it.value();
}
QString Driver::findOrInsertWidget(const DomWidget *ui_widget)
{
- return findOrInsert(&m_widgets, ui_widget, ui_widget->attributeClass());
+ // Top level is passed into setupUI(), everything else is a member variable
+ const bool isMember = !m_widgets.isEmpty();
+ return findOrInsert(&m_widgets, ui_widget, ui_widget->attributeClass(), isMember);
}
QString Driver::findOrInsertSpacer(const DomSpacer *ui_spacer)
@@ -111,11 +138,7 @@ QString Driver::findOrInsertButtonGroup(const DomButtonGroup *ui_group)
// Find a group by its non-uniqified name
const DomButtonGroup *Driver::findButtonGroup(const QString &attributeName) const
{
- for (auto it = m_buttonGroups.cbegin(), end = m_buttonGroups.cend(); it != end; ++it) {
- if (it.key()->attributeName() == attributeName)
- return it.key();
- }
- return nullptr;
+ return findByAttributeName(m_buttonGroups, attributeName);
}
@@ -233,7 +256,7 @@ bool Driver::uic(const QString &fileName, DomUI *ui, QTextStream *out)
QTextStream *oldOutput = m_output;
- m_output = out != 0 ? out : &m_stdout;
+ m_output = out != nullptr ? out : &m_stdout;
Uic tool(this);
const bool result = tool.write(ui);
@@ -286,19 +309,25 @@ bool Driver::uic(const QString &fileName, QTextStream *out)
return rtn;
}
-const DomWidget *Driver::widgetByName(const QString &name) const
+const DomWidget *Driver::widgetByName(const QString &attributeName) const
+{
+ return findByAttributeName(m_widgets, attributeName);
+}
+
+QString Driver::widgetVariableName(const QString &attributeName) const
{
- return m_widgets.key(name);
+ auto it = findByAttributeNameIt(m_widgets, attributeName);
+ return it != m_widgets.cend() ? it.value() : QString();
}
-const DomActionGroup *Driver::actionGroupByName(const QString &name) const
+const DomActionGroup *Driver::actionGroupByName(const QString &attributeName) const
{
- return m_actionGroups.key(name);
+ return findByAttributeName(m_actionGroups, attributeName);
}
-const DomAction *Driver::actionByName(const QString &name) const
+const DomAction *Driver::actionByName(const QString &attributeName) const
{
- return m_actions.key(name);
+ return findByAttributeName(m_actions, attributeName);
}
QT_END_NAMESPACE
diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h
index 1303d0bf8a..45ec23b4aa 100644
--- a/src/tools/uic/driver.h
+++ b/src/tools/uic/driver.h
@@ -56,8 +56,8 @@ public:
// tools
bool printDependencies(const QString &fileName);
- bool uic(const QString &fileName, QTextStream *output = 0);
- bool uic(const QString &fileName, DomUI *ui, QTextStream *output = 0);
+ bool uic(const QString &fileName, QTextStream *output = nullptr);
+ bool uic(const QString &fileName, DomUI *ui, QTextStream *output = nullptr);
// configuration
inline QTextStream &output() const { return *m_output; }
@@ -84,18 +84,28 @@ public:
// Find a group by its non-uniqified name
const DomButtonGroup *findButtonGroup(const QString &attributeName) const;
- const DomWidget *widgetByName(const QString &name) const;
- const DomActionGroup *actionGroupByName(const QString &name) const;
- const DomAction *actionByName(const QString &name) const;
+ const DomWidget *widgetByName(const QString &attributeName) const;
+ QString widgetVariableName(const QString &attributeName) const;
+ const DomActionGroup *actionGroupByName(const QString &attributeName) const;
+ const DomAction *actionByName(const QString &attributeName) const;
bool useIdBasedTranslations() const { return m_idBasedTranslations; }
void setUseIdBasedTranslations(bool u) { m_idBasedTranslations = u; }
private:
template <class DomClass> using DomObjectHash = QHash<const DomClass *, QString>;
+ template <class DomClass> using DomObjectHashConstIt =
+ typename DomObjectHash<DomClass>::ConstIterator;
template <class DomClass>
- QString findOrInsert(DomObjectHash<DomClass> *domHash, const DomClass *dom, const QString &className);
+ DomObjectHashConstIt<DomClass> findByAttributeNameIt(const DomObjectHash<DomClass> &domHash,
+ const QString &name) const;
+ template <class DomClass>
+ const DomClass *findByAttributeName(const DomObjectHash<DomClass> &domHash,
+ const QString &name) const;
+ template <class DomClass>
+ QString findOrInsert(DomObjectHash<DomClass> *domHash, const DomClass *dom, const QString &className,
+ bool isMember = true);
Option m_option;
QTextStream m_stdout;
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
index 0516b854ff..9cf22d502d 100644
--- a/src/tools/uic/main.cpp
+++ b/src/tools/uic/main.cpp
@@ -29,6 +29,7 @@
#include "uic.h"
#include "option.h"
#include "driver.h"
+#include <language.h>
#include <qfile.h>
#include <qdir.h>
@@ -67,6 +68,10 @@ int runUic(int argc, char *argv[])
outputOption.setValueName(QStringLiteral("file"));
parser.addOption(outputOption);
+ QCommandLineOption noAutoConnectionOption(QStringList() << QStringLiteral("a") << QStringLiteral("no-autoconnection"));
+ noAutoConnectionOption.setDescription(QStringLiteral("Do not generate a call to QObject::connectSlotsByName()."));
+ parser.addOption(noAutoConnectionOption);
+
QCommandLineOption noProtOption(QStringList() << QStringLiteral("p") << QStringLiteral("no-protection"));
noProtOption.setDescription(QStringLiteral("Disable header protection."));
parser.addOption(noProtOption);
@@ -96,7 +101,7 @@ int runUic(int argc, char *argv[])
QCommandLineOption generatorOption(QStringList() << QStringLiteral("g") << QStringLiteral("generator"));
generatorOption.setDescription(QStringLiteral("Select generator."));
- generatorOption.setValueName(QStringLiteral("java|cpp"));
+ generatorOption.setValueName(QStringLiteral("python|cpp"));
parser.addOption(generatorOption);
QCommandLineOption idBasedOption(QStringLiteral("idbased"));
@@ -109,6 +114,7 @@ int runUic(int argc, char *argv[])
driver.option().dependencies = parser.isSet(dependenciesOption);
driver.option().outputFile = parser.value(outputOption);
+ driver.option().autoConnection = !parser.isSet(noAutoConnectionOption);
driver.option().headerProtection = !parser.isSet(noProtOption);
driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption);
driver.option().idBased = parser.isSet(idBasedOption);
@@ -116,6 +122,13 @@ int runUic(int argc, char *argv[])
driver.option().translateFunction = parser.value(translateOption);
driver.option().includeFile = parser.value(includeOption);
+ Language language = Language::Cpp;
+ if (parser.isSet(generatorOption)) {
+ if (parser.value(generatorOption).compare(QLatin1String("python")) == 0)
+ language = Language::Python;
+ }
+ language::setLanguage(language);
+
if (parser.isSet(noStringLiteralOption))
fprintf(stderr, "The -s, --no-stringliteral option is deprecated and it won't take any effect.\n");
@@ -129,7 +142,7 @@ int runUic(int argc, char *argv[])
return !driver.printDependencies(inputFile);
}
- QTextStream *out = 0;
+ QTextStream *out = nullptr;
QFile f;
if (!driver.option().outputFile.isEmpty()) {
f.setFileName(driver.option().outputFile);
diff --git a/src/tools/uic/python/python.pri b/src/tools/uic/python/python.pri
new file mode 100644
index 0000000000..4dd31160a1
--- /dev/null
+++ b/src/tools/uic/python/python.pri
@@ -0,0 +1,8 @@
+INCLUDEPATH += $$PWD
+
+# Input
+HEADERS += $$PWD/pythonwritedeclaration.h \
+ $$PWD/pythonwriteimports.h
+
+SOURCES += $$PWD/pythonwritedeclaration.cpp \
+ $$PWD/pythonwriteimports.cpp
diff --git a/src/tools/uic/python/pythonwritedeclaration.cpp b/src/tools/uic/python/pythonwritedeclaration.cpp
new file mode 100644
index 0000000000..5122b18e23
--- /dev/null
+++ b/src/tools/uic/python/pythonwritedeclaration.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pythonwritedeclaration.h"
+#include <cppwriteinitialization.h>
+#include <language.h>
+#include <driver.h>
+#include <ui4.h>
+#include <uic.h>
+
+#include <QtCore/qtextstream.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Python {
+
+WriteDeclaration::WriteDeclaration(Uic *uic) :
+ m_uic(uic),
+ m_driver(uic->driver()),
+ m_output(uic->output()),
+ m_option(uic->option())
+{
+}
+
+void WriteDeclaration::acceptUI(DomUI *node)
+{
+ // remove any left-over C++ namespaces
+ const QString qualifiedClassName = QLatin1String("Ui_") + node->elementClass()
+ + m_option.postfix;
+ m_output << "class " << language::fixClassName(qualifiedClassName) << "(object):\n";
+
+ TreeWalker::acceptWidget(node->elementWidget());
+ if (const DomButtonGroups *domButtonGroups = node->elementButtonGroups())
+ acceptButtonGroups(domButtonGroups);
+ CPP::WriteInitialization(m_uic).acceptUI(node);
+}
+
+// Register button groups to prevent the on-the-fly creation legacy
+// feature from triggering
+void WriteDeclaration::acceptButtonGroup(const DomButtonGroup *buttonGroup)
+{
+ m_driver->findOrInsertButtonGroup(buttonGroup);
+}
+
+} // namespace Python
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/python/pythonwritedeclaration.h b/src/tools/uic/python/pythonwritedeclaration.h
new file mode 100644
index 0000000000..a8d50b6fbf
--- /dev/null
+++ b/src/tools/uic/python/pythonwritedeclaration.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PYTHONWRITEDECLARATION_H
+#define PYTHONWRITEDECLARATION_H
+
+#include <treewalker.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class Driver;
+class Uic;
+
+struct Option;
+
+namespace Python {
+
+struct WriteDeclaration : public TreeWalker
+{
+ WriteDeclaration(Uic *uic);
+
+ void acceptUI(DomUI *node) override;
+ void acceptButtonGroup(const DomButtonGroup *buttonGroup) override;
+
+private:
+ Uic *m_uic;
+ Driver *m_driver;
+ QTextStream &m_output;
+ const Option &m_option;
+};
+
+} // namespace Python
+
+QT_END_NAMESPACE
+
+#endif // PYTHONWRITEDECLARATION_H
diff --git a/src/tools/uic/python/pythonwriteimports.cpp b/src/tools/uic/python/pythonwriteimports.cpp
new file mode 100644
index 0000000000..303615f77b
--- /dev/null
+++ b/src/tools/uic/python/pythonwriteimports.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pythonwriteimports.h"
+
+#include <customwidgetsinfo.h>
+#include <uic.h>
+
+#include <ui4.h>
+
+#include <QtCore/qtextstream.h>
+
+QT_BEGIN_NAMESPACE
+
+static const char *standardImports =
+R"I(from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
+ QRect, QSize, QUrl, Qt)
+from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QFont,
+ QFontDatabase, QIcon, QLinearGradient, QPalette, QPainter, QPixmap,
+ QRadialGradient)
+from PySide2.QtWidgets import *
+)I";
+
+namespace Python {
+
+WriteImports::WriteImports(Uic *uic) : m_uic(uic)
+{
+}
+
+void WriteImports::acceptUI(DomUI *node)
+{
+ auto &output = m_uic->output();
+ output << standardImports << '\n';
+ if (auto customWidgets = node->elementCustomWidgets()) {
+ TreeWalker::acceptCustomWidgets(customWidgets);
+ output << '\n';
+ }
+}
+
+QString WriteImports::qtModuleOf(const DomCustomWidget *node) const
+{
+ if (m_uic->customWidgetsInfo()->extends(node->elementClass(), QLatin1String("QAxWidget")))
+ return QStringLiteral("QtAxContainer");
+ if (const auto headerElement = node->elementHeader()) {
+ const auto &header = headerElement->text();
+ if (header.startsWith(QLatin1String("Qt"))) {
+ const int slash = header.indexOf(QLatin1Char('/'));
+ if (slash != -1)
+ return header.left(slash);
+ }
+ }
+ return QString();
+}
+
+void WriteImports::acceptCustomWidget(DomCustomWidget *node)
+{
+ const auto &className = node->elementClass();
+ if (className.contains(QLatin1String("::")))
+ return; // Exclude namespaced names (just to make tests pass).
+ const QString &qtModule = qtModuleOf(node);
+ auto &output = m_uic->output();
+ if (!qtModule.isEmpty())
+ output << "from PySide2." << qtModule << ' ';
+ output << "import " << className << '\n';
+}
+
+} // namespace Python
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/python/pythonwriteimports.h b/src/tools/uic/python/pythonwriteimports.h
new file mode 100644
index 0000000000..427cbb48b1
--- /dev/null
+++ b/src/tools/uic/python/pythonwriteimports.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PYTHONWRITEIMPORTS_H
+#define PYTHONWRITEIMPORTS_H
+
+#include <treewalker.h>
+
+QT_BEGIN_NAMESPACE
+
+class Uic;
+
+namespace Python {
+
+struct WriteImports : public TreeWalker
+{
+public:
+ explicit WriteImports(Uic *uic);
+
+ void acceptUI(DomUI *node) override;
+ void acceptCustomWidget(DomCustomWidget *node) override;
+
+private:
+ QString qtModuleOf(const DomCustomWidget *node) const;
+
+ Uic *const m_uic;
+};
+
+} // namespace Python
+
+QT_END_NAMESPACE
+
+#endif // PYTHONWRITEIMPORTS_H
diff --git a/src/tools/uic/qclass_lib_map.h b/src/tools/uic/qclass_lib_map.h
index 8e1afa0878..8cebe65a00 100644
--- a/src/tools/uic/qclass_lib_map.h
+++ b/src/tools/uic/qclass_lib_map.h
@@ -249,7 +249,7 @@ QT_CLASS_LIB(QLatin1String, QtCore, qstring.h)
QT_CLASS_LIB(QCharRef, QtCore, qstring.h)
QT_CLASS_LIB(QConstString, QtCore, qstring.h)
QT_CLASS_LIB(QStringRef, QtCore, qstring.h)
-QT_CLASS_LIB(QLatin1Literal, QtCore, qstringbuilder.h)
+QT_CLASS_LIB(QLatin1Literal, QtCore, qstring.h)
QT_CLASS_LIB(QAbstractConcatenable, QtCore, qstringbuilder.h)
QT_CLASS_LIB(QConcatenable, QtCore, qstringbuilder.h)
QT_CLASS_LIB(QStringBuilder, QtCore, qstringbuilder.h)
diff --git a/src/tools/uic/shared/language.cpp b/src/tools/uic/shared/language.cpp
index 730e1562bc..235a8ed2fc 100644
--- a/src/tools/uic/shared/language.cpp
+++ b/src/tools/uic/shared/language.cpp
@@ -32,6 +32,50 @@
namespace language {
+static Encoding encoding = Encoding::Utf8;
+static Language _language = Language::Cpp;
+
+Language language() { return _language; }
+
+void setLanguage(Language l)
+{
+ _language = l;
+ switch (_language) {
+ case Language::Cpp:
+ derefPointer = QLatin1String("->");
+ nullPtr = QLatin1String("nullptr");
+ operatorNew = QLatin1String("new ");
+ qtQualifier = QLatin1String("Qt::");
+ qualifier = QLatin1String("::");
+ self = QLatin1String(""); // for testing: change to "this->";
+ eol = QLatin1String(";\n");
+ encoding = Encoding::Utf8;
+ break;
+ case Language::Python:
+ derefPointer = QLatin1String(".");
+ nullPtr = QLatin1String("None");
+ operatorNew = QLatin1String("");
+ qtQualifier = QLatin1String("Qt.");
+ qualifier = QLatin1String(".");
+ self = QLatin1String("self.");
+ eol = QLatin1String("\n");
+ encoding = Encoding::Unicode;
+ break;
+ }
+}
+
+QString derefPointer;
+QString nullPtr;
+QString operatorNew;
+QString qtQualifier;
+QString qualifier;
+QString self;
+QString eol;
+
+QString cppQualifier = QLatin1String("::");
+QString cppTrue = QLatin1String("true");
+QString cppFalse = QLatin1String("false");
+
QTextStream &operator<<(QTextStream &str, const qtConfig &c)
{
str << "QT_CONFIG(" << c.parameter() << ')';
@@ -69,6 +113,13 @@ const char *lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex
return defaultValue;
}
+QString fixClassName(QString className)
+{
+ if (language() == Language::Python)
+ className.replace(cppQualifier, QLatin1String("_"));
+ return className;
+}
+
const char *toolbarArea(int v)
{
static const EnumLookup toolBarAreas[] =
@@ -141,4 +192,235 @@ const char *paletteColorRole(int v)
return lookupEnum(colorRoles, v);
}
+// Helpers for formatting a character sequences
+
+// Format a special character like '\x0a'
+static int formatEscapedNumber(QTextStream &str, ushort value, int base, int width,
+ char prefix = 0)
+{
+ int length = 1 + width;
+ str << '\\';
+ if (prefix) {
+ str << prefix;
+ ++length;
+ }
+ const auto oldPadChar = str.padChar();
+ const auto oldFieldWidth = str.fieldWidth();
+ const auto oldFieldAlignment = str.fieldAlignment();
+ const auto oldIntegerBase = str.integerBase();
+ str.setPadChar(QLatin1Char('0'));
+ str.setFieldWidth(width);
+ str.setFieldAlignment(QTextStream::AlignRight);
+ str.setIntegerBase(base);
+ str << value;
+ str.setIntegerBase(oldIntegerBase);
+ str.setFieldAlignment(oldFieldAlignment);
+ str.setFieldWidth(oldFieldWidth);
+ str.setPadChar(oldPadChar);
+ return length;
+}
+
+static int formatSpecialCharacter(QTextStream &str, ushort value)
+{
+ int length = 0;
+ switch (value) {
+ case '\\':
+ str << "\\\\";
+ length += 2;
+ break;
+ case '\"':
+ str << "\\\"";
+ length += 2;
+ break;
+ case '\n':
+ str << "\\n\"\n\"";
+ length += 5;
+ break;
+ default:
+ break;
+ }
+ return length;
+}
+
+// Format a sequence of characters for C++ with special characters numerically
+// escaped (non-raw string literals), wrappped at maxSegmentSize. FormattingTraits
+// are used to transform characters into (unsigned) codes, which can be used
+// for either normal escapes or Unicode code points as used in Unicode literals.
+
+enum : int { maxSegmentSize = 1024 };
+
+template <Encoding e>
+struct FormattingTraits
+{
+};
+
+template <>
+struct FormattingTraits<Encoding::Utf8>
+{
+ static ushort code(char c) { return uchar(c); }
+};
+
+template <>
+struct FormattingTraits<Encoding::Unicode>
+{
+ static ushort code(QChar c) { return c.unicode(); }
+};
+
+template <Encoding e, class Iterator>
+static void formatStringSequence(QTextStream &str, Iterator it, Iterator end,
+ const QString &indent,
+ int escapeIntegerBase, int escapeWidth,
+ char escapePrefix = 0)
+{
+ str << '"';
+ int length = 0;
+ while (it != end) {
+ const auto code = FormattingTraits<e>::code(*it);
+ if (code >= 0x80) {
+ length += formatEscapedNumber(str, code, escapeIntegerBase, escapeWidth, escapePrefix);
+ } else if (const int l = formatSpecialCharacter(str, code)) {
+ length += l;
+ } else if (code != '\r') {
+ str << *it;
+ ++length;
+ }
+ ++it;
+ if (it != end && length > maxSegmentSize) {
+ str << "\"\n" << indent << indent << '"';
+ length = 0;
+ }
+ }
+ str << '"';
+}
+
+void _formatString(QTextStream &str, const QString &value, const QString &indent,
+ bool qString)
+{
+ switch (encoding) {
+ // Special characters as 3 digit octal escapes (u8"\303\234mlaut")
+ case Encoding::Utf8: {
+ if (qString && _language == Language::Cpp)
+ str << "QString::fromUtf8(";
+ const QByteArray utf8 = value.toUtf8();
+ formatStringSequence<Encoding::Utf8>(str, utf8.cbegin(), utf8.cend(), indent,
+ 8, 3);
+ if (qString && _language == Language::Cpp)
+ str << ')';
+ }
+ break;
+ // Special characters as 4 digit hex Unicode points (u8"\u00dcmlaut")
+ case Encoding::Unicode:
+ str << 'u'; // Python Unicode literal (would be UTF-16 in C++)
+ formatStringSequence<Encoding::Unicode>(str, value.cbegin(), value.cend(), indent,
+ 16, 4, 'u');
+ break;
+ }
+}
+
+QTextStream &operator<<(QTextStream &str, const repeat &r)
+{
+ for (int i = 0; i < r.m_count; ++i)
+ str << r.m_char;
+ return str;
+}
+
+startFunctionDefinition1::startFunctionDefinition1(const char *name, const QString &parameterType,
+ const QString &parameterName,
+ const QString &indent,
+ const char *returnType) :
+ m_name(name), m_parameterType(parameterType), m_parameterName(parameterName),
+ m_indent(indent), m_return(returnType)
+{
+}
+
+QTextStream &operator<<(QTextStream &str, const startFunctionDefinition1 &f)
+{
+ switch (language()) {
+ case Language::Cpp:
+ str << (f.m_return ? f.m_return : "void") << ' ' << f.m_name << '('
+ << f.m_parameterType;
+ if (f.m_parameterType.cend()->isLetter())
+ str << ' ';
+ str << f.m_parameterName << ')' << '\n' << f.m_indent << "{\n";
+ break;
+ case Language::Python:
+ str << "def " << f.m_name << "(self, " << f.m_parameterName << "):\n";
+ break;
+ }
+ return str;
+}
+
+endFunctionDefinition::endFunctionDefinition(const char *name) : m_name(name)
+{
+}
+
+QTextStream &operator<<(QTextStream &str, const endFunctionDefinition &f)
+{
+ switch (language()) {
+ case Language::Cpp:
+ str << "} // " << f.m_name << "\n\n";
+ break;
+ case Language::Python:
+ str << "# " << f.m_name << "\n\n";
+ break;
+ }
+ return str;
+}
+
+void _formatStackVariable(QTextStream &str, const char *className, QStringView varName,
+ bool withInitParameters)
+{
+ switch (language()) {
+ case Language::Cpp:
+ str << className << ' ' << varName;
+ if (withInitParameters)
+ str << '(';
+ break;
+ case Language::Python:
+ str << varName << " = " << className << '(';
+ if (!withInitParameters)
+ str << ')';
+ break;
+ }
+}
+
+void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver)
+{
+ switch (language()) {
+ case Language::Cpp:
+ str << "QObject::connect(" << sender.name << ", SIGNAL("<< sender.signature
+ << "), " << receiver.name << ", SLOT("<< receiver.signature << "))";
+ break;
+ case Language::Python:
+ str << sender.name << '.'
+ << sender.signature.leftRef(sender.signature.indexOf(QLatin1Char('(')))
+ << ".connect(" << receiver.name << '.'
+ << receiver.signature.leftRef(receiver.signature.indexOf(QLatin1Char('(')))
+ << ')';
+ break;
+ }
+}
+
+QString boolValue(bool v)
+{
+ switch (language()) {
+ case Language::Cpp:
+ return v ? cppTrue : cppFalse;
+ case Language::Python:
+ return v ? QStringLiteral("True") : QStringLiteral("False");
+ }
+ Q_UNREACHABLE();
+}
+
+static inline QString dot() { return QStringLiteral("."); }
+
+QString enumValue(const QString &value)
+{
+ if (language() == Language::Cpp || !value.contains(cppQualifier))
+ return value;
+ QString fixed = value;
+ fixed.replace(cppQualifier, dot());
+ return fixed;
+}
+
} // namespace language
diff --git a/src/tools/uic/shared/language.h b/src/tools/uic/shared/language.h
index e7201b6529..fc8af9715b 100644
--- a/src/tools/uic/shared/language.h
+++ b/src/tools/uic/shared/language.h
@@ -29,12 +29,31 @@
#ifndef LANGUAGE_H
#define LANGUAGE_H
+#include <QtCore/qstring.h>
#include <QtCore/qstringview.h>
+#include <QtCore/qstring.h>
QT_FORWARD_DECLARE_CLASS(QTextStream)
+enum class Language { Cpp, Python };
+
namespace language {
+Language language();
+void setLanguage(Language);
+
+extern QString derefPointer;
+extern QString nullPtr;
+extern QString operatorNew;
+extern QString qtQualifier;
+extern QString qualifier;
+extern QString self;
+extern QString eol;
+
+extern QString cppQualifier;
+extern QString cppTrue;
+extern QString cppFalse;
+
// Base class for streamable objects with one QStringView parameter
class StringViewStreamable
{
@@ -71,11 +90,119 @@ public:
QTextStream &operator<<(QTextStream &, const closeQtConfig &c);
+QString fixClassName(QString className);
+
const char *toolbarArea(int v);
const char *sizePolicy(int v);
const char *dockWidgetArea(int v);
const char *paletteColorRole(int v);
+enum class Encoding { Utf8, Unicode };
+
+void _formatString(QTextStream &str, const QString &value, const QString &indent,
+ bool qString);
+
+template <bool AsQString>
+class _string
+{
+public:
+ explicit _string(const QString &value, const QString &indent = QString())
+ : m_value(value), m_indent(indent) {}
+
+ void format(QTextStream &str) const
+ { _formatString(str, m_value, m_indent, AsQString); }
+
+private:
+ const QString &m_value;
+ const QString &m_indent;
+};
+
+template <bool AsQString>
+inline QTextStream &operator<<(QTextStream &str, const language::_string<AsQString> &s)
+{
+ s.format(str);
+ return str;
+}
+
+using charliteral = _string<false>;
+using qstring = _string<true>;
+
+class repeat {
+public:
+ explicit repeat(int count, char c) : m_count(count), m_char(c) {}
+
+ friend QTextStream &operator<<(QTextStream &str, const repeat &r);
+
+private:
+ const int m_count;
+ const char m_char;
+};
+
+class startFunctionDefinition1 {
+public:
+ explicit startFunctionDefinition1(const char *name, const QString &parameterType,
+ const QString &parameterName,
+ const QString &indent,
+ const char *returnType = nullptr);
+
+ friend QTextStream &operator<<(QTextStream &str, const startFunctionDefinition1 &f);
+private:
+ const char *m_name;
+ const QString &m_parameterType;
+ const QString &m_parameterName;
+ const QString &m_indent;
+ const char *m_return;
+};
+
+class endFunctionDefinition {
+public:
+ explicit endFunctionDefinition(const char *name);
+
+ friend QTextStream &operator<<(QTextStream &str, const endFunctionDefinition &f);
+private:
+ const char *m_name;
+};
+
+void _formatStackVariable(QTextStream &str, const char *className, QStringView varName, bool withInitParameters);
+
+template <bool withInitParameters>
+class _stackVariable {
+public:
+ explicit _stackVariable(const char *className, QStringView varName) :
+ m_className(className), m_varName(varName) {}
+
+ void format(QTextStream &str) const
+ { _formatStackVariable(str, m_className, m_varName, withInitParameters); }
+
+private:
+ const char *m_className;
+ QStringView m_varName;
+ QStringView m_parameters;
+};
+
+template <bool withInitParameters>
+inline QTextStream &operator<<(QTextStream &str, const _stackVariable<withInitParameters> &s)
+{
+ s.format(str);
+ return str;
+}
+
+using stackVariable = _stackVariable<false>;
+using stackVariableWithInitParameters = _stackVariable<true>;
+
+struct SignalSlot
+{
+ QString name;
+ QString signature;
+ QString className;
+};
+
+void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver);
+
+QString boolValue(bool v);
+
+QString enumValue(const QString &value);
+
} // namespace language
#endif // LANGUAGE_H
diff --git a/src/tools/uic/treewalker.h b/src/tools/uic/treewalker.h
index 7e8eda57d9..3777229517 100644
--- a/src/tools/uic/treewalker.h
+++ b/src/tools/uic/treewalker.h
@@ -77,6 +77,9 @@ class DomButtonGroup;
struct TreeWalker
{
+ Q_DISABLE_COPY_MOVE(TreeWalker)
+
+ TreeWalker() = default;
inline virtual ~TreeWalker() = default;
virtual void acceptUI(DomUI *ui);
@@ -101,7 +104,7 @@ struct TreeWalker
virtual void acceptTime(DomTime *time);
virtual void acceptDateTime(DomDateTime *dateTime);
virtual void acceptProperty(DomProperty *property);
- typedef QVector<DomWidget *> DomWidgets;
+ using DomWidgets = QVector<DomWidget *>;
virtual void acceptIncludes(DomIncludes *includes);
virtual void acceptInclude(DomInclude *incl);
virtual void acceptAction(DomAction *action);
diff --git a/src/tools/uic/ui4.cpp b/src/tools/uic/ui4.cpp
index 984ef36274..334ced276d 100644
--- a/src/tools/uic/ui4.cpp
+++ b/src/tools/uic/ui4.cpp
@@ -76,6 +76,10 @@ void DomUI::read(QXmlStreamReader &reader)
setAttributeIdbasedtr(attribute.value() == QLatin1String("true"));
continue;
}
+ if (name == QLatin1String("connectslotsbyname")) {
+ setAttributeConnectslotsbyname(attribute.value() == QLatin1String("true"));
+ continue;
+ }
if (name == QLatin1String("stdsetdef")) {
setAttributeStdsetdef(attribute.value().toInt());
continue;
@@ -209,6 +213,9 @@ void DomUI::write(QXmlStreamWriter &writer, const QString &tagName) const
if (hasAttributeIdbasedtr())
writer.writeAttribute(QStringLiteral("idbasedtr"), (attributeIdbasedtr() ? QLatin1String("true") : QLatin1String("false")));
+ if (hasAttributeConnectslotsbyname())
+ writer.writeAttribute(QStringLiteral("connectslotsbyname"), (attributeConnectslotsbyname() ? QLatin1String("true") : QLatin1String("false")));
+
if (hasAttributeStdsetdef())
writer.writeAttribute(QStringLiteral("stdsetdef"), QString::number(attributeStdsetdef()));
diff --git a/src/tools/uic/ui4.h b/src/tools/uic/ui4.h
index 1710147342..08a3abf490 100644
--- a/src/tools/uic/ui4.h
+++ b/src/tools/uic/ui4.h
@@ -169,6 +169,11 @@ public:
inline void setAttributeIdbasedtr(bool a) { m_attr_idbasedtr = a; m_has_attr_idbasedtr = true; }
inline void clearAttributeIdbasedtr() { m_has_attr_idbasedtr = false; }
+ inline bool hasAttributeConnectslotsbyname() const { return m_has_attr_connectslotsbyname; }
+ inline bool attributeConnectslotsbyname() const { return m_attr_connectslotsbyname; }
+ inline void setAttributeConnectslotsbyname(bool a) { m_attr_connectslotsbyname = a; m_has_attr_connectslotsbyname = true; }
+ inline void clearAttributeConnectslotsbyname() { m_has_attr_connectslotsbyname = false; }
+
inline bool hasAttributeStdsetdef() const { return m_has_attr_stdsetdef; }
inline int attributeStdsetdef() const { return m_attr_stdsetdef; }
inline void setAttributeStdsetdef(int a) { m_attr_stdsetdef = a; m_has_attr_stdsetdef = true; }
@@ -285,6 +290,9 @@ private:
bool m_attr_idbasedtr = false;
bool m_has_attr_idbasedtr = false;
+ bool m_attr_connectslotsbyname = false;
+ bool m_has_attr_connectslotsbyname = false;
+
int m_attr_stdsetdef = 0;
bool m_has_attr_stdsetdef = false;
diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp
index 225dc6aeb2..207356f28d 100644
--- a/src/tools/uic/uic.cpp
+++ b/src/tools/uic/uic.cpp
@@ -35,6 +35,10 @@
#include "cppwriteincludes.h"
#include "cppwritedeclaration.h"
+#include <pythonwritedeclaration.h>
+#include <pythonwriteimports.h>
+
+#include <language.h>
#include <qxmlstream.h>
#include <qfileinfo.h>
@@ -65,7 +69,7 @@ bool Uic::printDependencies()
return false;
}
- DomUI *ui = 0;
+ DomUI *ui = nullptr;
{
QXmlStreamReader reader;
reader.setDevice(&f);
@@ -103,7 +107,7 @@ bool Uic::printDependencies()
return true;
}
-void Uic::writeCopyrightHeader(DomUI *ui)
+void Uic::writeCopyrightHeaderCpp(const DomUI *ui) const
{
QString comment = ui->elementComment();
if (!comment.isEmpty())
@@ -118,6 +122,48 @@ void Uic::writeCopyrightHeader(DomUI *ui)
out << "********************************************************************************/\n\n";
}
+// Format existing UI file comments for Python with some smartness : Replace all
+// leading C++ comment characters by '#' or prepend '#' if needed.
+
+static inline bool isCppCommentChar(QChar c)
+{
+ return c == QLatin1Char('/') || c == QLatin1Char('*');
+}
+
+static int leadingCppCommentCharCount(const QStringRef &s)
+{
+ int i = 0;
+ for (const int size = s.size(); i < size && isCppCommentChar(s.at(i)); ++i) {
+ }
+ return i;
+}
+
+void Uic::writeCopyrightHeaderPython(const DomUI *ui) const
+{
+ QString comment = ui->elementComment();
+ if (!comment.isEmpty()) {
+ const auto lines = comment.splitRef(QLatin1Char('\n'));
+ for (const auto &line : lines) {
+ if (const int leadingCommentChars = leadingCppCommentCharCount(line)) {
+ out << language::repeat(leadingCommentChars, '#')
+ << line.right(line.size() - leadingCommentChars);
+ } else {
+ if (!line.startsWith(QLatin1Char('#')))
+ out << "# ";
+ out << line;
+ }
+ out << '\n';
+ }
+ out << '\n';
+ }
+
+ out << language::repeat(80, '#') << "\n## Form generated from reading UI file '"
+ << QFileInfo(opt.inputFile).fileName()
+ << "'\n##\n## Created by: Qt User Interface Compiler version " << QT_VERSION_STR
+ << "\n##\n## WARNING! All changes made in this file will be lost when recompiling UI file!\n"
+ << language::repeat(80, '#') << "\n\n";
+}
+
// Check the version with a stream reader at the <ui> element.
static double versionFromUiAttribute(QXmlStreamReader &reader)
@@ -132,7 +178,7 @@ static double versionFromUiAttribute(QXmlStreamReader &reader)
DomUI *Uic::parseUiFile(QXmlStreamReader &reader)
{
- DomUI *ui = 0;
+ DomUI *ui = nullptr;
const QString uiElement = QLatin1String("ui");
while (!reader.atEnd()) {
@@ -143,7 +189,7 @@ DomUI *Uic::parseUiFile(QXmlStreamReader &reader)
if (version < 4.0) {
const QString msg = QString::fromLatin1("uic: File generated with too old version of Qt Designer (%1)").arg(version);
fprintf(stderr, "%s\n", qPrintable(msg));
- return 0;
+ return nullptr;
}
ui = new DomUI();
@@ -155,7 +201,7 @@ DomUI *Uic::parseUiFile(QXmlStreamReader &reader)
}
if (reader.hasError()) {
delete ui;
- ui = 0;
+ ui = nullptr;
fprintf(stderr, "%s\n", qPrintable(QString::fromLatin1("uic: Error in line %1, column %2 : %3")
.arg(reader.lineNumber()).arg(reader.columnNumber())
.arg(reader.errorString())));
@@ -195,15 +241,26 @@ bool Uic::write(QIODevice *in)
bool Uic::write(DomUI *ui)
{
- using namespace CPP;
-
if (!ui || !ui->elementWidget())
return false;
- if (opt.copyrightHeader)
- writeCopyrightHeader(ui);
+ const auto lang = language::language();
+
+ if (lang == Language::Python)
+ out << "# -*- coding: utf-8 -*-\n\n";
- if (opt.headerProtection) {
+ if (opt.copyrightHeader) {
+ switch (language::language()) {
+ case Language::Cpp:
+ writeCopyrightHeaderCpp(ui);
+ break;
+ case Language::Python:
+ writeCopyrightHeaderPython(ui);
+ break;
+ }
+ }
+
+ if (opt.headerProtection && lang == Language::Cpp) {
writeHeaderProtectionStart();
out << "\n";
}
@@ -218,13 +275,25 @@ bool Uic::write(DomUI *ui)
info.acceptUI(ui);
cWidgetsInfo.acceptUI(ui);
- WriteIncludes writeIncludes(this);
- writeIncludes.acceptUI(ui);
- Validator(this).acceptUI(ui);
- WriteDeclaration(this).acceptUI(ui);
+ switch (language::language()) {
+ case Language::Cpp: {
+ CPP::WriteIncludes writeIncludes(this);
+ writeIncludes.acceptUI(ui);
+ Validator(this).acceptUI(ui);
+ CPP::WriteDeclaration(this).acceptUI(ui);
+ }
+ break;
+ case Language::Python: {
+ Python::WriteImports writeImports(this);
+ writeImports.acceptUI(ui);
+ Validator(this).acceptUI(ui);
+ Python::WriteDeclaration(this).acceptUI(ui);
+ }
+ break;
+ }
- if (opt.headerProtection)
+ if (opt.headerProtection && lang == Language::Cpp)
writeHeaderProtectionEnd();
return true;
diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h
index af5f42c6db..f3dfd49149 100644
--- a/src/tools/uic/uic.h
+++ b/src/tools/uic/uic.h
@@ -91,7 +91,8 @@ public:
private:
// copyright header
- void writeCopyrightHeader(DomUI *ui);
+ void writeCopyrightHeaderCpp(const DomUI *ui) const;
+ void writeCopyrightHeaderPython(const DomUI *ui) const;
DomUI *parseUiFile(QXmlStreamReader &reader);
// header protection
diff --git a/src/tools/uic/uic.pro b/src/tools/uic/uic.pro
index 4469ce50e5..1bf8ef8ad3 100644
--- a/src/tools/uic/uic.pro
+++ b/src/tools/uic/uic.pro
@@ -7,6 +7,7 @@ DEFINES += QT_UIC QT_NO_CAST_FROM_ASCII QT_NO_FOREACH
include(uic.pri)
include(shared/shared.pri)
include(cpp/cpp.pri)
+include(python/python.pri)
HEADERS += uic.h
diff --git a/src/tools/uic/utils.h b/src/tools/uic/utils.h
index 3f32a532ca..34c4ab23d4 100644
--- a/src/tools/uic/utils.h
+++ b/src/tools/uic/utils.h
@@ -42,55 +42,6 @@ inline bool toBool(const QString &str)
inline QString toString(const DomString *str)
{ return str ? str->text() : QString(); }
-inline QString fixString(const QString &str, const QString &indent)
-{
- QString cursegment;
- QStringList result;
- const QByteArray utf8 = str.toUtf8();
- const int utf8Length = utf8.length();
-
- for (int i = 0; i < utf8Length; ++i) {
- const uchar cbyte = utf8.at(i);
- if (cbyte >= 0x80) {
- cursegment += QLatin1Char('\\');
- cursegment += QString::number(cbyte, 8);
- } else {
- switch(cbyte) {
- case '\\':
- cursegment += QLatin1String("\\\\"); break;
- case '\"':
- cursegment += QLatin1String("\\\""); break;
- case '\r':
- break;
- case '\n':
- cursegment += QLatin1String("\\n\"\n\""); break;
- default:
- cursegment += QLatin1Char(cbyte);
- }
- }
-
- if (cursegment.length() > 1024) {
- result << cursegment;
- cursegment.clear();
- }
- }
-
- if (!cursegment.isEmpty())
- result << cursegment;
-
-
- QString joinstr = QLatin1String("\"\n");
- joinstr += indent;
- joinstr += indent;
- joinstr += QLatin1Char('"');
-
- QString rc(QLatin1Char('"'));
- rc += result.join(joinstr);
- rc += QLatin1Char('"');
-
- return rc;
-}
-
inline QHash<QString, DomProperty *> propertyMap(const QList<DomProperty *> &properties)
{
QHash<QString, DomProperty *> map;