diff options
Diffstat (limited to 'apiextractor.cpp')
-rw-r--r-- | apiextractor.cpp | 243 |
1 files changed, 48 insertions, 195 deletions
diff --git a/apiextractor.cpp b/apiextractor.cpp index d2ef9ee23..8c7ea145e 100644 --- a/apiextractor.cpp +++ b/apiextractor.cpp @@ -22,8 +22,9 @@ */ #include "apiextractor.h" -#include <QtCore/QDir> -#include <QtCore/QDebug> +#include <QDir> +#include <QDebug> +#include <QTemporaryFile> #include <iostream> #include "reporthandler.h" @@ -31,207 +32,79 @@ #include "fileout.h" #include "parser/rpp/pp.h" #include "abstractmetabuilder.h" -#include "generator.h" #include "apiextractorversion.h" static bool preprocess(const QString& sourceFile, - const QString& targetFile, - const QString& commandLineIncludes); + QFile& targetFile, + const QStringList& includes); -ApiExtractor::ApiExtractor(int argc, char** argv) : m_versionHandler(0) +ApiExtractor::ApiExtractor() { - m_programName = argv[0]; - // store args in m_args map - int argNum = 0; - for (int i = 1; i < argc; ++i) { - QString arg(argv[i]); - arg = arg.trimmed(); - if (arg.startsWith("--")) { - int split = arg.indexOf("="); - if (split > 0) - m_args[arg.mid(2).left(split-2)] = arg.mid(split + 1).trimmed(); - else - m_args[arg.mid(2)] = QString(); - } else if (arg.startsWith("-")) { - m_args[arg.mid(1)] = QString(); - } else { - argNum++; - m_args[QString("arg-%1").arg(argNum)] = arg; - } - } - // Environment TYPESYSTEMPATH QString envTypesystemPaths = getenv("TYPESYSTEMPATH"); - TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths); + if (!envTypesystemPaths.isEmpty()) + TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths); ReportHandler::setContext("ApiExtractor"); } ApiExtractor::~ApiExtractor() { - qDeleteAll(m_generators); } -void ApiExtractor::addGenerator(Generator* generator) +void ApiExtractor::addTypesystemSearchPath ( const QString& path ) { - m_generators << generator; + TypeDatabase::instance()->addTypesystemPath(path); } -bool ApiExtractor::parseGeneralArgs() +void ApiExtractor::addIncludePath ( const QString& path ) { - // set debug level - if (m_args.contains("silent")) { - ReportHandler::setSilent(true); - } else if (m_args.contains("debug-level")) { - QString level = m_args.value("debug-level"); - if (level == "sparse") - ReportHandler::setDebugLevel(ReportHandler::SparseDebug); - else if (level == "medium") - ReportHandler::setDebugLevel(ReportHandler::MediumDebug); - else if (level == "full") - ReportHandler::setDebugLevel(ReportHandler::FullDebug); - } - - if (m_args.contains("no-suppress-warnings")) { - TypeDatabase *db = TypeDatabase::instance(); - db->setSuppressWarnings(false); - } - - if (m_args.contains("dummy")) - FileOut::dummy = true; - - if (m_args.contains("diff")) - FileOut::diff = true; - - if (m_args.count() == 1) - return false; - - if (m_args.contains("typesystem-paths")) - TypeDatabase::instance()->addTypesystemPath(m_args.value("typesystem-paths")); - - m_globalHeaderFileName = m_args.value("arg-1"); - m_typeSystemFileName = m_args.value("arg-2"); - if (m_args.contains("arg-3")) - return false; - - if (m_globalHeaderFileName.isEmpty() || m_typeSystemFileName.isEmpty()) - return false; - return true; + m_includePaths << path; } -int ApiExtractor::exec() +void ApiExtractor::setCppFileName(const QString& cppFileName) { - if (m_args.contains("version")) { - if (m_versionHandler) - m_versionHandler("ApiExtractor v" APIEXTRACTOR_VERSION); - else - std::cout << m_programName << " using ApiExtractor v" APIEXTRACTOR_VERSION << std::endl; - return 0; - } else if (!parseGeneralArgs()) { - printUsage(); - return 1; - } - - QLatin1String ppFileName(".preprocessed.tmp"); - - if (!TypeDatabase::instance()->parseFile(m_typeSystemFileName)) - std::cerr << "Cannot parse file: " << qPrintable(m_typeSystemFileName); - - if (!preprocess(m_globalHeaderFileName, ppFileName, m_args.value("include-paths"))) { - std::cerr << "Preprocessor failed on file: " << qPrintable(m_globalHeaderFileName); - return 1; - } - - QString licenseComment; - if (m_args.contains("license-file") && !m_args.value("license-file").isEmpty()) { - QString license_filename = m_args.value("license-file"); - if (QFile::exists(license_filename)) { - QFile license_file(license_filename); - if (license_file.open(QIODevice::ReadOnly)) - licenseComment = license_file.readAll(); - } else { - std::cerr << "Couldn't find the file containing the license heading: "; - std::cerr << qPrintable(license_filename); - return 1; - } - } - - AbstractMetaBuilder builder; - QFile ppFile(ppFileName); - builder.build(&ppFile); + m_cppFileName = cppFileName; +} - QString outputDirectory = m_args.contains("output-directory") ? m_args["output-directory"] : "out"; - bool docOnly = m_args.contains("documentation-only"); - foreach (Generator* g, m_generators) { - bool docGen = g->type() == Generator::DocumentationType; - bool missingDocInfo = m_args["library-source-dir"].isEmpty() - || m_args["documentation-data-dir"].isEmpty(); - if ((!docGen && docOnly) || (docGen && missingDocInfo)) { - std::cout << "Skipping " << g->name() << std::endl; - continue; - } - g->setOutputDirectory(outputDirectory); - g->setLicenseComment(licenseComment); - g->setBuilder(&builder); - std::cout << "Running " << g->name() << std::endl; - if (g->prepareGeneration(m_args)) - g->generate(); - } +void ApiExtractor::setTypeSystem(const QString& typeSystemFileName) +{ + m_typeSystemFileName = typeSystemFileName; +} - std::cout << "Done, " << ReportHandler::warningCount(); - std::cout << " warnings (" << ReportHandler::suppressedCount() << " known issues)"; - std::cout << std::endl; - return 0; +void ApiExtractor::setDebugLevel(ReportHandler::DebugLevel debugLevel) +{ + ReportHandler::setDebugLevel(debugLevel); } -static void printOptions(QTextStream& s, const QMap<QString, QString>& options) { - QMap<QString, QString>::const_iterator it = options.constBegin(); - s.setFieldAlignment(QTextStream::AlignLeft); - for (; it != options.constEnd(); ++it) { - s << " --"; - s.setFieldWidth(38); - s << it.key() << it.value(); - s.setFieldWidth(0); - s << endl; - } +void ApiExtractor::setSupressWarnings ( bool value ) +{ + TypeDatabase::instance()->setSuppressWarnings(value); } -void ApiExtractor::printUsage() +bool ApiExtractor::run() { - #if defined(Q_OS_WIN32) - #define PATHSPLITTER ";" - #else - #define PATHSPLITTER ":" - #endif - QTextStream s(stdout); - s << "Usage:\n " - << m_programName << " [options] header-file typesystem-file\n\n" - "General options:\n"; - QMap<QString, QString> generalOptions; - generalOptions.insert("debug-level=[sparse|medium|full]", "Set the debug level"); - generalOptions.insert("silent", "Avoid printing any message"); - generalOptions.insert("help", "Display this help and exit"); - generalOptions.insert("no-suppress-warnings", "Show all warnings"); - generalOptions.insert("output-directory=[dir]", "The directory where the generated files will be written"); - generalOptions.insert("include-paths=<path>[" PATHSPLITTER "<path>" PATHSPLITTER "...]", "Include paths used by the C++ parser"); - generalOptions.insert("typesystem-paths=<path>[" PATHSPLITTER "<path>" PATHSPLITTER "...]", "Paths used when searching for typesystems"); - generalOptions.insert("documentation-only", "Do not generates any code, just the documentation"); - generalOptions.insert("license-file=[licensefile]", "File used for copyright headers of generated files"); - generalOptions.insert("version", "Output version information and exit"); - printOptions(s, generalOptions); + if (m_builder) + return false; + // read typesystem + if (!TypeDatabase::instance()->parseFile(m_typeSystemFileName)) { + std::cerr << "Cannot parse file: " << qPrintable(m_typeSystemFileName); + return false; + } - foreach (Generator* generator, m_generators) { - QMap<QString, QString> options = generator->options(); - if (!options.isEmpty()) { - s << endl << generator->name() << " options:\n"; - printOptions(s, generator->options()); - } + QTemporaryFile ppFile; + // run rpp pre-processor + if (!preprocess(m_cppFileName, ppFile, m_includePaths)) { + std::cerr << "Preprocessor failed on file: " << qPrintable(m_cppFileName); + return 1; } + m_builder = new AbstractMetaBuilder; + m_builder->build(&ppFile); + return true; } - static bool preprocess(const QString& sourceFile, - const QString& targetFile, - const QString& commandLineIncludes) + QFile& targetFile, + const QStringList& includes) { rpp::pp_environment env; rpp::pp preprocess(env); @@ -250,26 +123,8 @@ static bool preprocess(const QString& sourceFile, file.close(); preprocess.operator()(ba.constData(), ba.constData() + ba.size(), null_out); - QStringList includes; - -#if defined(Q_OS_WIN32) - char *pathSplitter = const_cast<char *>(";"); -#else - char *pathSplitter = const_cast<char *>(":"); -#endif - - // Environment INCLUDE - QString includePath = getenv("INCLUDE"); - if (!includePath.isEmpty()) - includes += includePath.split(pathSplitter); - - // Includes from the command line - if (!commandLineIncludes.isEmpty()) - includes += commandLineIncludes.split(pathSplitter); - - includes << QLatin1String("."); - includes << QLatin1String("/usr/include"); - + preprocess.push_include_path("."); + preprocess.push_include_path("/usr/include"); foreach (QString include, includes) preprocess.push_include_path(QDir::convertSeparators(include).toStdString()); @@ -294,14 +149,12 @@ static bool preprocess(const QString& sourceFile, QDir::setCurrent(currentDir); - QFile f(targetFile); - if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { - std::cerr << "Failed to write preprocessed file: " << qPrintable(targetFile) << std::endl; + if (!targetFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + std::cerr << "Failed to write preprocessed file: " << qPrintable(targetFile.fileName()) << std::endl; return false; } - f.write(result.c_str(), result.length()); - + targetFile.write(result.c_str(), result.length()); return true; } |