aboutsummaryrefslogtreecommitdiffstats
path: root/apiextractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apiextractor.cpp')
-rw-r--r--apiextractor.cpp243
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;
}