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.cpp642
1 files changed, 0 insertions, 642 deletions
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
deleted file mode 100644
index 25daea99e..000000000
--- a/sources/shiboken2/generator/main.cpp
+++ /dev/null
@@ -1,642 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $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 <QLibrary>
-#include <QtCore/QFile>
-#include <QtCore/QDir>
-#include <iostream>
-#include <apiextractor.h>
-#include <fileout.h>
-#include <typedatabase.h>
-#include <messages.h>
-#include "generator.h"
-#include "shibokenconfig.h"
-#include "cppgenerator.h"
-#include "headergenerator.h"
-#include "qtdocgenerator.h"
-
-#ifdef _WINDOWS
-static const QChar pathSplitter = QLatin1Char(';');
-#else
-static const QChar pathSplitter = QLatin1Char(':');
-#endif
-
-static inline QString languageLevelOption() { return QStringLiteral("language-level"); }
-static inline QString includePathOption() { return QStringLiteral("include-paths"); }
-static inline QString frameworkIncludePathOption() { return QStringLiteral("framework-include-paths"); }
-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 inline QString diffOption() { return QStringLiteral("diff"); }
-static inline QString dryrunOption() { return QStringLiteral("dry-run"); }
-static inline QString skipDeprecatedOption() { return QStringLiteral("skip-deprecated"); }
-
-static const char helpHint[] = "Note: use --help or -h for more information.\n";
-
-using CommandArgumentMap = QMap<QString, QString>;
-
-using OptionDescriptions = Generator::OptionDescriptions;
-
-static void printOptions(QTextStream &s, const OptionDescriptions &options)
-{
- s.setFieldAlignment(QTextStream::AlignLeft);
- for (const auto &od : options) {
- if (!od.first.startsWith(QLatin1Char('-')))
- s << "--";
- s << od.first;
- if (od.second.isEmpty()) {
- s << ", ";
- } else {
- s << endl;
- const auto lines = od.second.splitRef(QLatin1Char('\n'));
- for (const auto &line : lines)
- s << " " << line << endl;
- s << endl;
- }
- }
-}
-
-static bool processProjectFile(QFile &projectFile, QMap<QString, QString> &args)
-{
- QByteArray line = projectFile.readLine().trimmed();
- if (line.isEmpty() || line != "[generator-project]")
- return false;
-
- QStringList includePaths;
- QStringList frameworkIncludePaths;
- QStringList systemIncludePaths;
- QStringList typesystemPaths;
- QStringList apiVersions;
- QString languageLevel;
-
- while (!projectFile.atEnd()) {
- line = projectFile.readLine().trimmed();
- if (line.isEmpty())
- continue;
-
- int split = line.indexOf('=');
- QByteArray key;
- QString value;
- if (split > 0) {
- key = line.left(split - 1).trimmed();
- value = QString::fromUtf8(line.mid(split + 1).trimmed());
- } else {
- key = line;
- }
-
- if (key == "include-path")
- includePaths << QDir::toNativeSeparators(value);
- else if (key == "framework-include-path")
- frameworkIncludePaths << QDir::toNativeSeparators(value);
- else if (key == "system-include-paths")
- systemIncludePaths << QDir::toNativeSeparators(value);
- else if (key == "typesystem-path")
- typesystemPaths << QDir::toNativeSeparators(value);
- else if (key == "language-level")
- languageLevel = value;
- else if (key == "api-version")
- apiVersions << value;
- else if (key == "header-file")
- args.insert(QLatin1String("arg-1"), value);
- else if (key == "typesystem-file")
- args.insert(QLatin1String("arg-2"), value);
- else
- args.insert(QString::fromUtf8(key), value);
- }
-
- if (!includePaths.isEmpty())
- args.insert(includePathOption(), includePaths.join(pathSplitter));
-
- if (!frameworkIncludePaths.isEmpty())
- args.insert(frameworkIncludePathOption(),
- frameworkIncludePaths.join(pathSplitter));
- if (!systemIncludePaths.isEmpty()) {
- args.insert(systemIncludePathOption(),
- systemIncludePaths.join(pathSplitter));
- }
-
- if (!typesystemPaths.isEmpty())
- args.insert(typesystemPathOption(), typesystemPaths.join(pathSplitter));
- if (!apiVersions.isEmpty())
- args.insert(QLatin1String("api-version"), apiVersions.join(QLatin1Char('|')));
- if (!languageLevel.isEmpty())
- args.insert(languageLevelOption(), languageLevel);
- return true;
-}
-
-static CommandArgumentMap getInitializedArguments()
-{
- CommandArgumentMap args;
- QStringList arguments = QCoreApplication::arguments();
- QString appName = arguments.constFirst();
- arguments.removeFirst();
-
- QString projectFileName;
- for (const QString &arg : qAsConst(arguments)) {
- if (arg.startsWith(QLatin1String("--project-file"))) {
- int split = arg.indexOf(QLatin1Char('='));
- if (split > 0)
- projectFileName = arg.mid(split + 1).trimmed();
- break;
- }
- }
-
- if (projectFileName.isEmpty())
- return args;
-
- if (!QFile::exists(projectFileName)) {
- std::cerr << qPrintable(appName) << ": Project file \"";
- std::cerr << qPrintable(projectFileName) << "\" not found.";
- std::cerr << std::endl;
- return args;
- }
-
- QFile projectFile(projectFileName);
- if (!projectFile.open(QIODevice::ReadOnly))
- return args;
-
- if (!processProjectFile(projectFile, args)) {
- std::cerr << qPrintable(appName) << ": first line of project file \"";
- std::cerr << qPrintable(projectFileName) << "\" must be the string \"[generator-project]\"";
- std::cerr << std::endl;
- return args;
- }
-
- 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,
- CommandArgumentMap &args)
-{
- const CommandArgumentMap::iterator it = args.find(option);
- if (it != args.end())
- it.value().append(pathSplitter + 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 == systemIncludePathOption() || 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(QLatin1String("isystem")))
- addPathOptionValue(systemIncludePathOption(), arg.mid(7), args);
- else if (arg.startsWith(QLatin1Char('T')))
- addPathOptionValue(typesystemPathOption(), arg.mid(1), args);
- else if (arg == QLatin1String("h"))
- args.insert(helpOption(), QString());
- else if (arg.startsWith(QLatin1String("std=")))
- args.insert(languageLevelOption(), arg.mid(4));
- 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();
- QStringList arguments = QCoreApplication::arguments();
- arguments.removeFirst();
-
- int argNum = 0;
- for (const QString &carg : qAsConst(arguments))
- getCommandLineArg(carg.trimmed(), argNum, args);
-
- return args;
-}
-
-static inline Generators docGenerators()
-{
- Generators result;
-#ifdef DOCSTRINGS_ENABLED
- result.append(GeneratorPtr(new QtDocGenerator));
-#endif
- return result;
-}
-
-static inline Generators shibokenGenerators()
-{
- Generators result;
- result << GeneratorPtr(new CppGenerator) << GeneratorPtr(new HeaderGenerator);
- return result;
-}
-
-static inline QString languageLevelDescription()
-{
- return QLatin1String("C++ Language level (c++11..c++17, default=")
- + QLatin1String(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
- + QLatin1Char(')');
-}
-
-void printUsage()
-{
- QTextStream s(stdout);
- s << "Usage:\n "
- << "shiboken [options] header-file typesystem-file\n\n"
- << "General options:\n";
- QString pathSyntax;
- QTextStream(&pathSyntax) << "<path>[" << pathSplitter << "<path>"
- << pathSplitter << "...]";
- 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,\n"
- "global functions and enums) to be dropped from generation."))
- << qMakePair(QLatin1String("-F<path>"), QString())
- << qMakePair(QLatin1String("framework-include-paths=") + pathSyntax,
- QLatin1String("Framework include paths used by the C++ parser"))
- << 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(skipDeprecatedOption(),
- QLatin1String("Skip deprecated functions"))
- << 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<path>"), QString())
- << qMakePair(QLatin1String("include-paths=") + pathSyntax,
- QLatin1String("Include paths used by the C++ parser"))
- << qMakePair(languageLevelOption() + QLatin1String("=, -std=<level>"),
- languageLevelDescription())
- << 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.\n"
- "Replaces and overrides command line arguments"))
- << qMakePair(QLatin1String("silent"),
- QLatin1String("Avoid printing any message"))
- << qMakePair(QLatin1String("-T<path>"), 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();
- for (const GeneratorPtr &generator : generators) {
- const OptionDescriptions options = generator->options();
- if (!options.isEmpty()) {
- s << endl << generator->name() << " options:\n\n";
- printOptions(s, generator->options());
- }
- }
-}
-
-static inline void printVerAndBanner()
-{
- std::cout << "shiboken v" SHIBOKEN_VERSION << std::endl;
- std::cout << "Copyright (C) 2016 The Qt Company Ltd." << std::endl;
-}
-
-static inline void errorPrint(const QString &s)
-{
- QStringList arguments = QCoreApplication::arguments();
- arguments.pop_front();
- std::cerr << "shiboken: " << qPrintable(s)
- << "\nCommand line: " << qPrintable(arguments.join(QLatin1Char(' '))) << '\n';
-}
-
-static void parseIncludePathOption(const QString &option, HeaderType headerType,
- CommandArgumentMap &args,
- ApiExtractor &extractor)
-{
- const CommandArgumentMap::iterator it = args.find(option);
- if (it != args.end()) {
- const QStringList includePathListList =
- it.value().split(pathSplitter, QString::SkipEmptyParts);
- args.erase(it);
- for (const QString &s : includePathListList) {
- auto path = QFile::encodeName(QDir::cleanPath(s));
- extractor.addIncludePath(HeaderPath{path, headerType});
- }
- }
-}
-
-int main(int argc, char *argv[])
-{
- // PYSIDE-757: Request a deterministic ordering of QHash in the code model
- // and type system.
- qSetGlobalQHashSeed(0);
- // needed by qxmlpatterns
- QCoreApplication app(argc, argv);
- ReportHandler::install();
- qCDebug(lcShiboken()).noquote().nospace() << QCoreApplication::arguments().join(QLatin1Char(' '));
-
- // Store command arguments in a map
- CommandArgumentMap args = getCommandLineArgs();
- Generators generators;
-
- CommandArgumentMap::iterator ait = args.find(QLatin1String("version"));
- if (ait != args.end()) {
- args.erase(ait);
- printVerAndBanner();
- return EXIT_SUCCESS;
- }
-
- 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")) {
- generators = docGenerators();
- if (generators.isEmpty()) {
- errorPrint(QLatin1String("Doc strings extractions was not enabled in this shiboken build."));
- return EXIT_FAILURE;
- }
- } else if (generatorSet.isEmpty() || generatorSet == QLatin1String("shiboken")) {
- generators = shibokenGenerators();
- } else {
- errorPrint(QLatin1String("Unknown generator set, try \"shiboken\" or \"qtdoc\"."));
- return EXIT_FAILURE;
- }
-
- 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;
- 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("Could not open the file \"%1\" containing the license heading: %2").
- arg(QDir::toNativeSeparators(licenseFile.fileName()), licenseFile.errorString()));
- return EXIT_FAILURE;
- }
- }
-
- 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)) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Can't create output directory: " << QDir::toNativeSeparators(outputDirectory);
- return EXIT_FAILURE;
- }
- }
-
- // Create and set-up API Extractor
- ApiExtractor extractor;
- extractor.setLogDirectory(outputDirectory);
- ait = args.find(skipDeprecatedOption());
- if (ait != args.end()) {
- extractor.setSkipDeprecated(true);
- args.erase(ait);
- }
-
- ait = args.find(QLatin1String("silent"));
- if (ait != args.end()) {
- extractor.setSilent(true);
- args.erase(ait);
- } else {
- 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"))
- extractor.setDebugLevel(ReportHandler::MediumDebug);
- else if (level == QLatin1String("full"))
- extractor.setDebugLevel(ReportHandler::FullDebug);
- }
- }
- ait = args.find(QLatin1String("no-suppress-warnings"));
- if (ait != args.end()) {
- args.erase(ait);
- extractor.setSuppressWarnings(false);
- }
- 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;
- QString version;
- package = parts.count() == 1 ? QLatin1String("*") : parts.constFirst();
- version = parts.constLast();
- if (!extractor.setApiVersion(package, version)) {
- errorPrint(msgInvalidVersion(package, version));
- return EXIT_FAILURE;
- }
- }
- }
-
- ait = args.find(QLatin1String("drop-type-entries"));
- if (ait != args.end()) {
- extractor.setDropTypeEntries(ait.value());
- args.erase(ait);
- }
-
- ait = args.find(QLatin1String("typesystem-paths"));
- if (ait != args.end()) {
- extractor.addTypesystemSearchPath(ait.value().split(pathSplitter));
- args.erase(ait);
- }
-
- parseIncludePathOption(includePathOption(), HeaderType::Standard,
- args, extractor);
- parseIncludePathOption(frameworkIncludePathOption(), HeaderType::Framework,
- args, extractor);
- parseIncludePathOption(systemIncludePathOption(), HeaderType::System,
- args, extractor);
-
- 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;
- }
-
- 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(')'));
-
- // 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: \""
- << languageLevelBA.constData() << "\"\n" << helpHint;
- return EXIT_FAILURE;
- }
- extractor.setLanguageLevel(level);
- }
-
- /* 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;
- }
-
- if (typeSystemFileName.isEmpty()) {
- std::cout << "You must specify a Type System file." << std::endl << helpHint;
- return EXIT_FAILURE;
- }
-
- extractor.setCppFileName(cppFileNameFi.absoluteFilePath());
- extractor.setTypeSystem(typeSystemFileName);
-
- if (!extractor.run()) {
- errorPrint(QLatin1String("Error running ApiExtractor."));
- return EXIT_FAILURE;
- }
-
- if (!extractor.classCount())
- qCWarning(lcShiboken) << "No C++ classes found!";
-
- qCDebug(lcShiboken) << extractor << '\n'
- << *TypeDatabase::instance();
-
- for (const GeneratorPtr &g : qAsConst(generators)) {
- g->setOutputDirectory(outputDirectory);
- g->setLicenseComment(licenseComment);
- ReportHandler::startProgress(QByteArray("Running ") + g->name() + "...");
- const bool ok = g->setup(extractor) && g->generate();
- ReportHandler::endProgress();
- if (!ok) {
- errorPrint(QLatin1String("Error running generator: ")
- + QLatin1String(g->name()) + QLatin1Char('.'));
- return EXIT_FAILURE;
- }
- }
-
- const QByteArray doneMessage = ReportHandler::doneMessage();
- qCDebug(lcShiboken, "%s", doneMessage.constData());
- std::cout << doneMessage.constData() << std::endl;
-
- return EXIT_SUCCESS;
-}