aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/generator/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/generator/main.cpp')
-rw-r--r--sources/shiboken2/generator/main.cpp290
1 files changed, 138 insertions, 152 deletions
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 7ee43710e..c996c7cc3 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -34,6 +34,7 @@
#include <QtCore/QDir>
#include <iostream>
#include <apiextractor.h>
+#include <fileout.h>
#include "generator.h"
#include "shibokenconfig.h"
#include "cppgenerator.h"
@@ -52,87 +53,19 @@ static inline QString frameworkIncludePathOption() { return QStringLiteral("fram
static inline QString systemIncludePathOption() { return QStringLiteral("system-include-paths"); }
static inline QString typesystemPathOption() { return QStringLiteral("typesystem-paths"); }
static inline QString helpOption() { return QStringLiteral("help"); }
-static const char helpHint[] = "Note: use --help or -h for more information.\n";
-
-namespace {
-
-class ArgsHandler
-{
-public:
- explicit ArgsHandler(const QMap<QString, QString>& other);
- virtual ~ArgsHandler();
-
- inline QMap<QString, QString>& args() const
- {
- return *m_args;
- }
-
- inline bool argExists(const QString& s) const
- {
- return m_args->contains(s);
- }
-
- QString removeArg(const QString& s);
- bool argExistsRemove(const QString& s);
-
- inline QString argValue(const QString& s) const
- {
- return m_args->value(s);
- }
-
- inline bool noArgs() const
- {
- return m_args->isEmpty();
- }
-
- QString errorMessage() const;
-
-private:
- QMap<QString, QString>* m_args;
-};
+static inline QString diffOption() { return QStringLiteral("diff"); }
+static inline QString dryrunOption() { return QStringLiteral("dry-run"); }
-ArgsHandler::ArgsHandler(const QMap<QString, QString>& other)
- : m_args(new QMap<QString, QString>(other))
-{
-}
-
-ArgsHandler::~ArgsHandler()
-{
- delete m_args;
-}
-
-QString ArgsHandler::removeArg(const QString& s)
-{
- QString retval;
-
- if (argExists(s)) {
- retval = argValue(s);
- m_args->remove(s);
- }
-
- return retval;
-}
-
-bool ArgsHandler::argExistsRemove(const QString& s)
-{
- bool retval = false;
-
- if (argExists(s)) {
- retval = true;
- m_args->remove(s);
- }
+static const char helpHint[] = "Note: use --help or -h for more information.\n";
- return retval;
-}
+typedef QMap<QString, QString> CommandArgumentMap;
-QString ArgsHandler::errorMessage() const
+static QString msgLeftOverArguments(const CommandArgumentMap &remainingArgs)
{
- typedef QMap<QString, QString>::ConstIterator StringMapConstIt;
-
QString message;
QTextStream str(&message);
str << "shiboken: Called with wrong arguments:";
- for (StringMapConstIt it = m_args->cbegin(), end = m_args->cend(); it != end; ++it) {
+ for (auto it = remainingArgs.cbegin(), end = remainingArgs.cend(); it != end; ++it) {
str << ' ' << it.key();
if (!it.value().isEmpty())
str << ' ' << it.value();
@@ -140,7 +73,6 @@ QString ArgsHandler::errorMessage() const
str << "\nCommand line: " << QCoreApplication::arguments().join(QLatin1Char(' '));
return message;
}
-}
typedef Generator::OptionDescriptions OptionDescriptions;
@@ -233,9 +165,9 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
return true;
}
-static QMap<QString, QString> getInitializedArguments()
+static CommandArgumentMap getInitializedArguments()
{
- QMap<QString, QString> args;
+ CommandArgumentMap args;
QStringList arguments = QCoreApplication::arguments();
QString appName = arguments.constFirst();
arguments.removeFirst();
@@ -277,9 +209,9 @@ static QMap<QString, QString> getInitializedArguments()
// Concatenate values of path arguments that can occur multiple times on the
// command line.
static void addPathOptionValue(const QString &option, const QString &value,
- QMap<QString, QString> &args)
+ CommandArgumentMap &args)
{
- const QMap<QString, QString>::iterator it = args.find(option);
+ const CommandArgumentMap::iterator it = args.find(option);
if (it != args.end())
it.value().append(QLatin1String(PATH_SPLITTER) + value);
else
@@ -380,18 +312,22 @@ void printUsage()
<< qMakePair(QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
QLatin1String("Semicolon separated list of type system entries (classes, namespaces,\n"
"global functions and enums) to be dropped from generation."))
- << qMakePair(QLatin1String("-F") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-F<path>"), QString())
<< qMakePair(QLatin1String("framework-include-paths=") + pathSyntax,
QLatin1String("Framework include paths used by the C++ parser"))
- << qMakePair(QLatin1String("-isystem") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-isystem<path>"), QString())
<< qMakePair(QLatin1String("system-include-paths=") + pathSyntax,
QLatin1String("System include paths used by the C++ parser"))
<< qMakePair(QLatin1String("generator-set=<\"generator module\">"),
QLatin1String("generator-set to be used. e.g. qtdoc"))
+ << qMakePair(diffOption(),
+ QLatin1String("Print a diff of wrapper files"))
+ << qMakePair(dryrunOption(),
+ QLatin1String("Dry run, do not generate wrapper files"))
<< qMakePair(QLatin1String("-h"), QString())
<< qMakePair(helpOption(),
QLatin1String("Display this help and exit"))
- << qMakePair(QLatin1String("-I") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-I<path>"), QString())
<< qMakePair(QLatin1String("include-paths=") + pathSyntax,
QLatin1String("Include paths used by the C++ parser"))
<< qMakePair(languageLevelOption() + QLatin1String("=, -std=<level>"),
@@ -407,7 +343,7 @@ void printUsage()
"Replaces and overrides command line arguments"))
<< qMakePair(QLatin1String("silent"),
QLatin1String("Avoid printing any message"))
- << qMakePair(QLatin1String("-T") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-T<path>"), QString())
<< qMakePair(QLatin1String("typesystem-paths=") + pathSyntax,
QLatin1String("Paths used when searching for typesystems"))
<< qMakePair(QLatin1String("version"),
@@ -445,12 +381,14 @@ static QString msgInvalidVersion(const QString &package, const QString &version)
}
static void parseIncludePathOption(const QString &option, HeaderType headerType,
- ArgsHandler &args,
+ CommandArgumentMap &args,
ApiExtractor &extractor)
{
- const QString path = args.removeArg(option);
- if (!path.isEmpty()) {
- const QStringList includePathListList = path.split(QLatin1String(PATH_SPLITTER));
+ const CommandArgumentMap::iterator it = args.find(option);
+ if (it != args.end()) {
+ const QStringList includePathListList =
+ it.value().split(QLatin1String(PATH_SPLITTER), QString::SkipEmptyParts);
+ args.erase(it);
for (const QString &s : includePathListList)
extractor.addIncludePath(HeaderPath{QFile::encodeName(s), headerType});
}
@@ -466,19 +404,24 @@ int main(int argc, char *argv[])
qCDebug(lcShiboken()).noquote().nospace() << QCoreApplication::arguments().join(QLatin1Char(' '));
// Store command arguments in a map
- QMap<QString, QString> args = getCommandLineArgs();
- ArgsHandler argsHandler(args);
+ CommandArgumentMap args = getCommandLineArgs();
Generators generators;
- if (argsHandler.argExistsRemove(QLatin1String("version"))) {
+ CommandArgumentMap::iterator ait = args.find(QLatin1String("version"));
+ if (ait != args.end()) {
+ args.erase(ait);
printVerAndBanner();
return EXIT_SUCCESS;
}
- QString generatorSet = argsHandler.removeArg(QLatin1String("generator-set"));
- // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
- if (generatorSet.isEmpty())
- generatorSet = argsHandler.removeArg(QLatin1String("generatorSet"));
+ QString generatorSet;
+ ait = args.find(QLatin1String("generator-set"));
+ if (ait == args.end()) // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
+ ait = args.find(QLatin1String("generatorSet"));
+ if (ait != args.end()) {
+ generatorSet = ait.value();
+ args.erase(ait);
+ }
// Pre-defined generator sets.
if (generatorSet == QLatin1String("qtdoc")) {
@@ -494,28 +437,45 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- if (argsHandler.argExistsRemove(QLatin1String("help"))) {
+ ait = args.find(QLatin1String("help"));
+ if (ait != args.end()) {
+ args.erase(ait);
printUsage();
return EXIT_SUCCESS;
}
+ ait = args.find(diffOption());
+ if (ait != args.end()) {
+ args.erase(ait);
+ FileOut::diff = true;
+ }
+
+ ait = args.find(dryrunOption());
+ if (ait != args.end()) {
+ args.erase(ait);
+ FileOut::dummy = true;
+ }
+
QString licenseComment;
- QString licenseFileName = argsHandler.removeArg(QLatin1String("license-file"));
- if (!licenseFileName.isEmpty()) {
- if (QFile::exists(licenseFileName)) {
- QFile licenseFile(licenseFileName);
- if (licenseFile.open(QIODevice::ReadOnly))
- licenseComment = QString::fromUtf8(licenseFile.readAll());
+ ait = args.find(QLatin1String("license-file"));
+ if (ait != args.end()) {
+ QFile licenseFile(ait.value());
+ args.erase(ait);
+ if (licenseFile.open(QIODevice::ReadOnly)) {
+ licenseComment = QString::fromUtf8(licenseFile.readAll());
} else {
- errorPrint(QStringLiteral("Couldn't find the file containing the license heading: %1").
- arg(licenseFileName));
+ errorPrint(QStringLiteral("Could not open the file \"%1\" containing the license heading: %2").
+ arg(QDir::toNativeSeparators(licenseFile.fileName()), licenseFile.errorString()));
return EXIT_FAILURE;
}
}
- QString outputDirectory = argsHandler.removeArg(QLatin1String("output-directory"));
- if (outputDirectory.isEmpty())
- outputDirectory = QLatin1String("out");
+ QString outputDirectory = QLatin1String("out");
+ ait = args.find(QLatin1String("output-directory"));
+ if (ait != args.end()) {
+ outputDirectory = ait.value();
+ args.erase(ait);
+ }
if (!QDir(outputDirectory).exists()) {
if (!QDir().mkpath(outputDirectory)) {
@@ -529,11 +489,15 @@ int main(int argc, char *argv[])
ApiExtractor extractor;
extractor.setLogDirectory(outputDirectory);
- if (argsHandler.argExistsRemove(QLatin1String("silent"))) {
+ ait = args.find(QLatin1String("silent"));
+ if (ait != args.end()) {
extractor.setSilent(true);
+ args.erase(ait);
} else {
- QString level = argsHandler.removeArg(QLatin1String("debug-level"));
- if (!level.isEmpty()) {
+ ait = args.find(QLatin1String("debug-level"));
+ if (ait != args.end()) {
+ const QString level = ait.value();
+ args.erase(ait);
if (level == QLatin1String("sparse"))
extractor.setDebugLevel(ReportHandler::SparseDebug);
else if (level == QLatin1String("medium"))
@@ -542,11 +506,15 @@ int main(int argc, char *argv[])
extractor.setDebugLevel(ReportHandler::FullDebug);
}
}
- if (argsHandler.argExistsRemove(QLatin1String("no-suppress-warnings")))
+ ait = args.find(QLatin1String("no-suppress-warnings"));
+ if (ait != args.end()) {
+ args.erase(ait);
extractor.setSuppressWarnings(false);
-
- if (argsHandler.argExists(QLatin1String("api-version"))) {
- const QStringList &versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|'));
+ }
+ ait = args.find(QLatin1String("api-version"));
+ if (ait != args.end()) {
+ const QStringList &versions = ait.value().split(QLatin1Char('|'));
+ args.erase(ait);
for (const QString &fullVersion : versions) {
QStringList parts = fullVersion.split(QLatin1Char(','));
QString package;
@@ -560,54 +528,65 @@ int main(int argc, char *argv[])
}
}
- if (argsHandler.argExists(QLatin1String("drop-type-entries")))
- extractor.setDropTypeEntries(argsHandler.removeArg(QLatin1String("drop-type-entries")));
+ ait = args.find(QLatin1String("drop-type-entries"));
+ if (ait != args.end()) {
+ extractor.setDropTypeEntries(ait.value());
+ args.erase(ait);
+ }
- QString path = argsHandler.removeArg(QLatin1String("typesystem-paths"));
- if (!path.isEmpty())
- extractor.addTypesystemSearchPath(path.split(QLatin1String(PATH_SPLITTER)));
+ ait = args.find(QLatin1String("typesystem-paths"));
+ if (ait != args.end()) {
+ extractor.addTypesystemSearchPath(ait.value().split(QLatin1String(PATH_SPLITTER)));
+ args.erase(ait);
+ }
parseIncludePathOption(includePathOption(), HeaderType::Standard,
- argsHandler, extractor);
+ args, extractor);
parseIncludePathOption(frameworkIncludePathOption(), HeaderType::Framework,
- argsHandler, extractor);
+ args, extractor);
parseIncludePathOption(systemIncludePathOption(), HeaderType::System,
- argsHandler, extractor);
+ args, extractor);
- QString cppFileName = argsHandler.removeArg(QLatin1String("arg-1"));
+ ait = args.find(QLatin1String("arg-1"));
+ if (ait == args.end()) {
+ errorPrint(QLatin1String("Required argument header-file is missing."));
+ return EXIT_FAILURE;
+ }
+ const QString cppFileName = ait.value();
+ args.erase(ait);
const QFileInfo cppFileNameFi(cppFileName);
if (!cppFileNameFi.isFile() && !cppFileNameFi.isSymLink()) {
errorPrint(QLatin1Char('"') + cppFileName + QLatin1String("\" does not exist."));
return EXIT_FAILURE;
}
- QString typeSystemFileName = argsHandler.removeArg(QLatin1String("arg-2"));
+ ait = args.find(QLatin1String("arg-2"));
+ if (ait == args.end()) {
+ errorPrint(QLatin1String("Required argument typesystem-file is missing."));
+ return EXIT_FAILURE;
+ }
+ const QString typeSystemFileName = ait.value();
+ args.erase(ait);
QString messagePrefix = QFileInfo(typeSystemFileName).baseName();
if (messagePrefix.startsWith(QLatin1String("typesystem_")))
messagePrefix.remove(0, 11);
ReportHandler::setPrefix(QLatin1Char('(') + messagePrefix + QLatin1Char(')'));
- /* Make sure to remove the project file's arguments (if any) and
- * --project-file, also the arguments of each generator before
- * checking if there isn't any existing arguments in argsHandler.
- */
- argsHandler.removeArg(QLatin1String("project-file"));
- QMap<QString, QString> projectFileArgs = getInitializedArguments();
- if (!projectFileArgs.isEmpty()) {
- QMap<QString, QString>::const_iterator it =
- projectFileArgs.constBegin();
- for ( ; it != projectFileArgs.constEnd(); ++it)
- argsHandler.removeArg(it.key());
- }
- for (const GeneratorPtr &generator : qAsConst(generators)) {
- const OptionDescriptions &options = generator->options();
- for (const auto &od : options)
- argsHandler.removeArg(od.first);
- }
-
- const QString languageLevel = argsHandler.removeArg(languageLevelOption());
- if (!languageLevel.isEmpty()) {
- const QByteArray languageLevelBA = languageLevel.toLatin1();
+ // Pass option to all generators (Cpp/Header generator have the same options)
+ for (ait = args.begin(); ait != args.end(); ) {
+ bool found = false;
+ for (const GeneratorPtr &generator : qAsConst(generators))
+ found |= generator->handleOption(ait.key(), ait.value());
+ if (found)
+ ait = args.erase(ait);
+ else
+ ++ait;
+ }
+
+ ait = args.find(languageLevelOption());
+ if (ait != args.end()) {
+ const QByteArray languageLevelBA = ait.value().toLatin1();
+ args.erase(ait);
const LanguageLevel level = clang::languageLevelFromOption(languageLevelBA.constData());
if (level == LanguageLevel::Default) {
std::cout << "Invalid argument for language level: \""
@@ -617,8 +596,17 @@ int main(int argc, char *argv[])
extractor.setLanguageLevel(level);
}
- if (!argsHandler.noArgs()) {
- errorPrint(argsHandler.errorMessage());
+ /* Make sure to remove the project file's arguments (if any) and
+ * --project-file, also the arguments of each generator before
+ * checking if there isn't any existing arguments in argsHandler.
+ */
+ args.remove(QLatin1String("project-file"));
+ CommandArgumentMap projectFileArgs = getInitializedArguments();
+ for (auto it = projectFileArgs.cbegin(), end = projectFileArgs.cend(); it != end; ++it)
+ args.remove(it.key());
+
+ if (!args.isEmpty()) {
+ errorPrint(msgLeftOverArguments(args));
std::cout << helpHint;
return EXIT_FAILURE;
}
@@ -644,12 +632,10 @@ int main(int argc, char *argv[])
for (const GeneratorPtr &g : qAsConst(generators)) {
g->setOutputDirectory(outputDirectory);
g->setLicenseComment(licenseComment);
- if (g->setup(extractor, args)) {
- if (!g->generate()) {
- errorPrint(QLatin1String("Error running generator: ")
- + QLatin1String(g->name()) + QLatin1Char('.'));
- return EXIT_FAILURE;
- }
+ if (!g->setup(extractor) || !g->generate()) {
+ errorPrint(QLatin1String("Error running generator: ")
+ + QLatin1String(g->name()) + QLatin1Char('.'));
+ return EXIT_FAILURE;
}
}