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.cpp214
1 files changed, 147 insertions, 67 deletions
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 874540e54..b22919981 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -46,6 +46,12 @@
#define PATH_SPLITTER ":"
#endif
+static inline QString includePathOption() { return QStringLiteral("include-paths"); }
+static inline QString frameworkIncludePathOption() { return QStringLiteral("framework-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
@@ -134,14 +140,17 @@ QString ArgsHandler::errorMessage() const
}
}
-static void printOptions(QTextStream& s, const QMap<QString, QString>& options)
+typedef Generator::OptionDescriptions OptionDescriptions;
+
+static void printOptions(QTextStream& s, const OptionDescriptions& options)
{
- QMap<QString, QString>::const_iterator it = options.constBegin();
s.setFieldAlignment(QTextStream::AlignLeft);
- for (; it != options.constEnd(); ++it) {
- s << " --";
+ for (const auto &od : options) {
+ s << ' ';
+ if (!od.first.startsWith(QLatin1Char('-')))
+ s << "--";
s.setFieldWidth(38);
- s << it.key() << it.value();
+ s << od.first << od.second;
s.setFieldWidth(0);
s << endl;
}
@@ -156,6 +165,7 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
return false;
QStringList includePaths;
+ QStringList frameworkIncludePaths;
QStringList typesystemPaths;
QStringList apiVersions;
@@ -176,6 +186,8 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
if (key == "include-path")
includePaths << QDir::toNativeSeparators(value);
+ else if (key == "framework-include-path")
+ frameworkIncludePaths << QDir::toNativeSeparators(value);
else if (key == "typesystem-path")
typesystemPaths << QDir::toNativeSeparators(value);
else if (key == "api-version")
@@ -189,10 +201,14 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
}
if (!includePaths.isEmpty())
- args.insert(QLatin1String("include-paths"), includePaths.join(QLatin1String(PATH_SPLITTER)));
+ args.insert(includePathOption(), includePaths.join(QLatin1String(PATH_SPLITTER)));
+
+ if (!frameworkIncludePaths.isEmpty())
+ args.insert(frameworkIncludePathOption(),
+ frameworkIncludePaths.join(QLatin1String(PATH_SPLITTER)));
if (!typesystemPaths.isEmpty())
- args.insert(QLatin1String("typesystem-paths"), typesystemPaths.join(QLatin1String(PATH_SPLITTER)));
+ args.insert(typesystemPathOption(), typesystemPaths.join(QLatin1String(PATH_SPLITTER)));
if (!apiVersions.isEmpty())
args.insert(QLatin1String("api-version"), apiVersions.join(QLatin1Char('|')));
return true;
@@ -206,7 +222,7 @@ static QMap<QString, QString> getInitializedArguments()
arguments.removeFirst();
QString projectFileName;
- foreach (const QString& arg, arguments) {
+ for (const QString &arg : qAsConst(arguments)) {
if (arg.startsWith(QLatin1String("--project-file"))) {
int split = arg.indexOf(QLatin1Char('='));
if (split > 0)
@@ -239,6 +255,55 @@ static QMap<QString, QString> getInitializedArguments()
return args;
}
+// 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)
+{
+ const QMap<QString, QString>::iterator it = args.find(option);
+ if (it != args.end())
+ it.value().append(QLatin1String(PATH_SPLITTER) + value);
+ else
+ args.insert(option, value);
+}
+
+static void getCommandLineArg(QString arg, int &argNum, QMap<QString, QString> &args)
+{
+ if (arg.startsWith(QLatin1String("--"))) {
+ arg.remove(0, 2);
+ const int split = arg.indexOf(QLatin1Char('='));
+ if (split < 0) {
+ args.insert(arg, QString());
+ return;
+ }
+ const QString option = arg.left(split);
+ const QString value = arg.mid(split + 1).trimmed();
+ if (option == includePathOption() || option == frameworkIncludePathOption()
+ || option == typesystemPathOption()) {
+ addPathOptionValue(option, value, args);
+ } else {
+ args.insert(option, value);
+ }
+ return;
+ }
+ if (arg.startsWith(QLatin1Char('-'))) {
+ arg.remove(0, 1);
+ if (arg.startsWith(QLatin1Char('I'))) // Shorthand path arguments -I/usr/include...
+ addPathOptionValue(includePathOption(), arg.mid(1), args);
+ else if (arg.startsWith(QLatin1Char('F')))
+ addPathOptionValue(frameworkIncludePathOption(), arg.mid(1), args);
+ else if (arg.startsWith(QLatin1Char('T')))
+ addPathOptionValue(typesystemPathOption(), arg.mid(1), args);
+ else if (arg == QLatin1String("h"))
+ args.insert(helpOption(), QString());
+ else
+ args.insert(arg, QString());
+ return;
+ }
+ argNum++;
+ args.insert(QStringLiteral("arg-") + QString::number(argNum), arg);
+}
+
static QMap<QString, QString> getCommandLineArgs()
{
QMap<QString, QString> args = getInitializedArguments();
@@ -246,21 +311,9 @@ static QMap<QString, QString> getCommandLineArgs()
arguments.removeFirst();
int argNum = 0;
- foreach (const QString &carg, arguments) {
- const QString &arg = carg.trimmed();
- if (arg.startsWith(QLatin1String("--"))) {
- int split = arg.indexOf(QLatin1Char('='));
- if (split > 0)
- args[arg.mid(2).left(split-2)] = arg.mid(split + 1).trimmed();
- else
- args[arg.mid(2)] = QString();
- } else if (arg.startsWith(QLatin1Char('-'))) {
- args[arg.mid(1)] = QString();
- } else {
- argNum++;
- args[QString::fromLatin1("arg-%1").arg(argNum)] = arg;
- }
- }
+ for (const QString &carg : qAsConst(arguments))
+ getCommandLineArg(carg.trimmed(), argNum, args);
+
return args;
}
@@ -286,40 +339,47 @@ void printUsage()
s << "Usage:\n "
<< "shiboken [options] header-file typesystem-file\n\n"
<< "General options:\n";
- QMap<QString, QString> generalOptions;
- generalOptions.insert(QLatin1String("project-file=<file>"),
- QLatin1String("text file containing a description of the binding project. Replaces and overrides command line arguments"));
- generalOptions.insert(QLatin1String("debug-level=[sparse|medium|full]"),
- QLatin1String("Set the debug level"));
- generalOptions.insert(QLatin1String("silent"),
- QLatin1String("Avoid printing any message"));
- generalOptions.insert(QLatin1String("help"),
- QLatin1String("Display this help and exit"));
- generalOptions.insert(QLatin1String("no-suppress-warnings"),
- QLatin1String("Show all warnings"));
- generalOptions.insert(QLatin1String("output-directory=<path>"),
- QLatin1String("The directory where the generated files will be written"));
- generalOptions.insert(QLatin1String("include-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"),
- QLatin1String("Include paths used by the C++ parser"));
- generalOptions.insert(QLatin1String("typesystem-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]"),
- QLatin1String("Paths used when searching for typesystems"));
- generalOptions.insert(QLatin1String("documentation-only"),
- QLatin1String("Do not generates any code, just the documentation"));
- generalOptions.insert(QLatin1String("license-file=<license-file>"),
- QLatin1String("File used for copyright headers of generated files"));
- generalOptions.insert(QLatin1String("version"),
- QLatin1String("Output version information and exit"));
- generalOptions.insert(QLatin1String("generator-set=<\"generator module\">"),
- QLatin1String("generator-set to be used. e.g. qtdoc"));
- generalOptions.insert(QLatin1String("api-version=<\"package mask\">,<\"version\">"),
- QLatin1String("Specify the supported api version used to generate the bindings"));
- generalOptions.insert(QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
- QLatin1String("Semicolon separated list of type system entries (classes, namespaces, global functions and enums) to be dropped from generation."));
+ const QString pathSyntax = QLatin1String("<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]");
+ OptionDescriptions generalOptions = OptionDescriptions()
+ << qMakePair(QLatin1String("api-version=<\"package mask\">,<\"version\">"),
+ QLatin1String("Specify the supported api version used to generate the bindings"))
+ << qMakePair(QLatin1String("debug-level=[sparse|medium|full]"),
+ QLatin1String("Set the debug level"))
+ << qMakePair(QLatin1String("documentation-only"),
+ QLatin1String("Do not generates any code, just the documentation"))
+ << qMakePair(QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
+ QLatin1String("Semicolon separated list of type system entries (classes, namespaces, global functions and enums) to be dropped from generation."))
+ << qMakePair(QLatin1String("-F") + pathSyntax, QString())
+ << qMakePair(QLatin1String("framework-include-paths=") + pathSyntax,
+ QLatin1String("Framework include paths used by the C++ parser"))
+ << qMakePair(QLatin1String("generator-set=<\"generator module\">"),
+ QLatin1String("generator-set to be used. e.g. qtdoc"))
+ << qMakePair(QLatin1String("-h"), QString())
+ << qMakePair(helpOption(),
+ QLatin1String("Display this help and exit"))
+ << qMakePair(QLatin1String("-I") + pathSyntax, QString())
+ << qMakePair(QLatin1String("include-paths=") + pathSyntax,
+ QLatin1String("Include paths used by the C++ parser"))
+ << qMakePair(QLatin1String("license-file=<license-file>"),
+ QLatin1String("File used for copyright headers of generated files"))
+ << qMakePair(QLatin1String("no-suppress-warnings"),
+ QLatin1String("Show all warnings"))
+ << qMakePair(QLatin1String("output-directory=<path>"),
+ QLatin1String("The directory where the generated files will be written"))
+ << qMakePair(QLatin1String("project-file=<file>"),
+ QLatin1String("text file containing a description of the binding project. Replaces and overrides command line arguments"))
+ << qMakePair(QLatin1String("silent"),
+ QLatin1String("Avoid printing any message"))
+ << qMakePair(QLatin1String("-T") + pathSyntax, QString())
+ << qMakePair(QLatin1String("typesystem-paths=") + pathSyntax,
+ QLatin1String("Paths used when searching for typesystems"))
+ << qMakePair(QLatin1String("version"),
+ QLatin1String("Output version information and exit"));
printOptions(s, generalOptions);
const Generators generators = shibokenGenerators() + docGenerators();
- foreach (const GeneratorPtr &generator, generators) {
- QMap<QString, QString> options = generator->options();
+ for (const GeneratorPtr &generator : generators) {
+ const OptionDescriptions options = generator->options();
if (!options.isEmpty()) {
s << endl << generator->name() << " options:\n";
printOptions(s, generator->options());
@@ -437,8 +497,8 @@ int main(int argc, char *argv[])
extractor.setSuppressWarnings(false);
if (argsHandler.argExists(QLatin1String("api-version"))) {
- QStringList versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|'));
- foreach (const QString &fullVersion, versions) {
+ const QStringList &versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|'));
+ for (const QString &fullVersion : versions) {
QStringList parts = fullVersion.split(QLatin1Char(','));
QString package;
QString version;
@@ -460,11 +520,29 @@ int main(int argc, char *argv[])
extractor.addTypesystemSearchPath(path.split(QLatin1String(PATH_SPLITTER)));
path = argsHandler.removeArg(QLatin1String("include-paths"));
- if (!path.isEmpty())
- extractor.addIncludePath(path.split(QLatin1String(PATH_SPLITTER)));
+ if (!path.isEmpty()) {
+ const QStringList includePathListList = path.split(QLatin1String(PATH_SPLITTER));
+ for (const QString &s : qAsConst(includePathListList)) {
+ const bool isFramework = false;
+ extractor.addIncludePath(HeaderPath(s, isFramework));
+ }
+ }
+
+ path = argsHandler.removeArg(QLatin1String("framework-include-paths"));
+ if (!path.isEmpty()) {
+ const QStringList frameworkPathList = path.split(QLatin1String(PATH_SPLITTER));
+ const bool isFramework = true;
+ for (const QString &s : qAsConst(frameworkPathList)) {
+ extractor.addIncludePath(HeaderPath(s, isFramework));
+ }
+ }
QString cppFileName = argsHandler.removeArg(QLatin1String("arg-1"));
QString typeSystemFileName = argsHandler.removeArg(QLatin1String("arg-2"));
+ 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
@@ -478,18 +556,20 @@ int main(int argc, char *argv[])
for ( ; it != projectFileArgs.constEnd(); ++it)
argsHandler.removeArg(it.key());
}
- foreach (const GeneratorPtr &generator, generators) {
- QMap<QString, QString> options = generator->options();
- if (!options.isEmpty()) {
- QMap<QString, QString>::const_iterator it = options.constBegin();
- for ( ; it != options.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);
}
if (!argsHandler.noArgs()) {
errorPrint(argsHandler.errorMessage());
- std::cout << "Note: use --help option for more information." << std::endl;
+ std::cout << helpHint;
+ return EXIT_FAILURE;
+ }
+
+ if (typeSystemFileName.isEmpty()) {
+ std::cout << "You must specify a Type System file." << std::endl << helpHint;
return EXIT_FAILURE;
}
@@ -505,7 +585,7 @@ int main(int argc, char *argv[])
qCDebug(lcShiboken) << extractor;
- foreach (const GeneratorPtr &g, generators) {
+ for (const GeneratorPtr &g : qAsConst(generators)) {
g->setOutputDirectory(outputDirectory);
g->setLicenseComment(licenseComment);
if (g->setup(extractor, args)) {