aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2009-08-25 19:43:06 -0300
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-08-25 19:43:06 -0300
commitfd52957d375eb990a0fabbfab35d36480ee057ae (patch)
tree3ef09ee06c63dc953dfa25829cc8f4a71bb81dde
parent8f941405798b67204945d7ec94ef8e63e1535877 (diff)
parentf8fba84d7b0230b1f48109c339197c407757bea1 (diff)
Merge commit 'mainline/master' into metaclassname
Conflicts: boostpythongenerator.cpp
-rw-r--r--CMakeLists.txt46
-rw-r--r--generator.cpp439
-rw-r--r--generator.h330
-rw-r--r--generators/CMakeLists.txt2
-rw-r--r--generators/boostpython/CMakeLists.txt14
-rw-r--r--generators/boostpython/boostpython.cpp29
-rw-r--r--generators/boostpython/boostpythongenerator.cpp (renamed from boostpythongenerator.cpp)187
-rw-r--r--generators/boostpython/boostpythongenerator.h (renamed from boostpythongenerator.h)22
-rw-r--r--generators/boostpython/convertergenerator.cpp (renamed from convertergenerator.cpp)0
-rw-r--r--generators/boostpython/convertergenerator.h (renamed from convertergenerator.h)0
-rw-r--r--generators/boostpython/cppgenerator.cpp (renamed from cppgenerator.cpp)52
-rw-r--r--generators/boostpython/cppgenerator.h (renamed from cppgenerator.h)8
-rw-r--r--generators/boostpython/hppgenerator.cpp (renamed from hppgenerator.cpp)37
-rw-r--r--generators/boostpython/hppgenerator.h (renamed from hppgenerator.h)0
-rw-r--r--generators/qtdoc/CMakeLists.txt10
-rw-r--r--generators/qtdoc/qtdocgenerator.cpp (renamed from docgenerator.cpp)74
-rw-r--r--generators/qtdoc/qtdocgenerator.h (renamed from docgenerator.h)33
-rw-r--r--main.cpp194
-rw-r--r--tests/CMakeLists.txt4
-rw-r--r--tests/sphinxtabletest.cpp4
-rw-r--r--tests/sphinxtabletest.h4
21 files changed, 1131 insertions, 358 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5e385494f..cf93f1078 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,24 +1,25 @@
-project(boostpythongenerator)
+project(generatorrunner)
cmake_minimum_required(VERSION 2.6)
find_package(Qt4 4.5.0 REQUIRED)
find_package(ApiExtractor REQUIRED)
+set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
+set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
+
+
+# lib generator version
+set(generator_MAJOR_VERSION "0")
+set(generator_MINOR_VERSION "1")
+set(generator_VERSION "${generator_MAJOR_VERSION}.${generator_MINOR_VERSION}")
+
add_definitions(${QT_DEFINITIONS})
set(boostpythongenerator_VERSION 0.2)
configure_file(boostpythongeneratorversion.h.in ${CMAKE_CURRENT_BINARY_DIR}/boostpythongeneratorversion.h @ONLY)
set(CMAKE_BUILD_TYPE Debug)
-set(boostpythongenerator_SRC
-boostpythongenerator.cpp
-convertergenerator.cpp
-docgenerator.cpp
-hppgenerator.cpp
-cppgenerator.cpp
-)
-
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${APIEXTRACTOR_INCLUDE_DIR}
@@ -26,13 +27,15 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${QT_INCLUDE_DIR}
${QT_QTCORE_INCLUDE_DIR})
-add_library(libboostpythongenerator STATIC ${boostpythongenerator_SRC})
-target_link_libraries(libboostpythongenerator
+add_library(genrunner SHARED generator.cpp)
+set_target_properties(genrunner PROPERTIES SOVERSION ${generator_VERSION} VERSION ${generator_MAJOR_VERSION})
+target_link_libraries(genrunner ${QT_QTCORE_LIBRARY} ${APIEXTRACTOR_LIBRARY})
+
+add_executable(generatorrunner main.cpp)
+target_link_libraries(generatorrunner
+ genrunner
${APIEXTRACTOR_LIBRARY}
- ${QT_QTCORE_LIBRARY}
- ${QT_QTXML_LIBRARY})
-add_executable(boostpythongenerator main.cpp)
-target_link_libraries(boostpythongenerator libboostpythongenerator)
+ ${QT_QTCORE_LIBRARY})
# uninstall target
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake"
@@ -42,11 +45,6 @@ add_custom_target(uninstall "${CMAKE_COMMAND}"
-P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
-# "make dist", in fact "make package_source"
-#set(CPACK_SOURCE_PACKAGE_FILE_NAME "boostpythongenerator-${boostpythongenerator_VERSION}")
-#set(CPACK_SOURCE_GENERATOR TGZ)
-#set(CPACK_SOURCE_IGNORE_FILES "~$" ".svn" "debian/" "build/" ".swp$" "*.kdev4")
-#include(CPack)
set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${boostpythongenerator_VERSION})
add_custom_target(dist
@@ -54,9 +52,11 @@ add_custom_target(dist
| bzip2 > ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-install(TARGETS boostpythongenerator DESTINATION bin)
+install(TARGETS genrunner DESTINATION ${LIB_INSTALL_DIR})
+install(TARGETS generatorrunner DESTINATION bin)
+install(FILES generator.h DESTINATION include)
enable_testing()
-#add_subdirectory(libbindgen)
-add_subdirectory(tests)
+add_subdirectory(generators)
+add_subdirectory(tests)
diff --git a/generator.cpp b/generator.cpp
new file mode 100644
index 000000000..80610c401
--- /dev/null
+++ b/generator.cpp
@@ -0,0 +1,439 @@
+/*
+ * This file is part of the API Extractor project.
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "generator.h"
+#include "reporthandler.h"
+#include "fileout.h"
+#include "apiextractor.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QDebug>
+
+Generator::Generator() : m_numGenerated(0), m_numGeneratedWritten(0)
+{}
+
+Generator::~Generator()
+{
+}
+
+bool Generator::setup(const ApiExtractor& extractor, const QMap< QString, QString > args)
+{
+ m_globalEnums = extractor.globalEnums();
+ m_globalFunctions = extractor.globalFunctions();
+ m_classes = extractor.classes();
+ m_primitiveTypes = extractor.primitiveTypes();
+ m_containerTypes = extractor.containerTypes();
+
+ // FIXME: Avoid this ugly hack to get the package name.. and... why the name "package"!?
+ foreach (const AbstractMetaClass* cppClass, m_classes) {
+ if (m_packageName.isEmpty()
+ && cppClass->typeEntry()->generateCode()
+ && !cppClass->package().isEmpty()) {
+ m_packageName = cppClass->package();
+ break;
+ }
+ }
+ // does anyone use this?
+ m_qmetatypeDeclaredTypenames = extractor.qtMetaTypeDeclaredTypeNames();
+ return doSetup(args);
+}
+
+QMap< QString, QString > Generator::options() const
+{
+ return QMap<QString, QString>();
+}
+
+AbstractMetaClassList Generator::classes() const
+{
+ return m_classes;
+}
+
+AbstractMetaFunctionList Generator::globalFunctions() const
+{
+ return m_globalFunctions;
+}
+
+AbstractMetaEnumList Generator::globalEnums() const
+{
+ return m_globalEnums;
+}
+
+QList<const PrimitiveTypeEntry*> Generator::primitiveTypes() const
+{
+ return m_primitiveTypes;
+}
+
+QList<const ContainerTypeEntry*> Generator::containerTypes() const
+{
+ return m_containerTypes;
+}
+
+/// Returns the output directory
+QString Generator::outputDirectory() const
+{
+ return m_outDir;
+}
+
+/// Set the output directory
+void Generator::setOutputDirectory(const QString &outDir)
+{
+ m_outDir = outDir;
+}
+
+void Generator::generate()
+{
+ foreach (AbstractMetaClass *cls, m_classes) {
+ if (!shouldGenerate(cls))
+ continue;
+
+ QString fileName = fileNameForClass(cls);
+ if (fileName.isNull())
+ continue;
+ ReportHandler::debugSparse(QString("generating: %1").arg(fileName));
+
+ FileOut fileOut(outputDirectory() + '/' + subDirectoryForClass(cls) + '/' + fileName);
+ generateClass(fileOut.stream, cls);
+
+ if (fileOut.done())
+ ++m_numGeneratedWritten;
+ ++m_numGenerated;
+ }
+ finishGeneration();
+}
+
+bool Generator::shouldGenerate(const AbstractMetaClass* metaClass) const
+{
+ return metaClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang;
+}
+
+void Generator::verifyDirectoryFor(const QFile &file)
+{
+ QDir dir = QFileInfo(file).dir();
+ if (!dir.exists()) {
+ if (!dir.mkpath(dir.absolutePath()))
+ ReportHandler::warning(QString("unable to create directory '%1'")
+ .arg(dir.absolutePath()));
+ }
+}
+
+bool Generator::hasDefaultConstructor(const AbstractMetaType *type)
+{
+ QString full_name = type->typeEntry()->qualifiedTargetLangName();
+ QString class_name = type->typeEntry()->targetLangName();
+
+ foreach (const AbstractMetaClass *cls, m_classes) {
+ if (cls->typeEntry()->qualifiedTargetLangName() == full_name) {
+ AbstractMetaFunctionList functions = cls->functions();
+ foreach (const AbstractMetaFunction *function, functions) {
+ if (function->arguments().isEmpty() && function->name() == class_name)
+ return true;
+ }
+ return false;
+ }
+ }
+ return false;
+}
+
+void Generator::replaceTemplateVariables(QString &code, const AbstractMetaFunction *func)
+{
+ const AbstractMetaClass *cpp_class = func->ownerClass();
+ code.replace("%TYPE", cpp_class->name());
+
+ foreach (AbstractMetaArgument *arg, func->arguments())
+ code.replace("%" + QString::number(arg->argumentIndex() + 1), arg->argumentName());
+
+ //template values
+ code.replace("%RETURN_TYPE", translateType(func->type(), cpp_class));
+ code.replace("%FUNCTION_NAME", func->originalName());
+
+ if (code.contains("%ARGUMENT_NAMES")) {
+ QString str;
+ QTextStream aux_stream(&str);
+ writeArgumentNames(aux_stream, func, Generator::SkipRemovedArguments);
+ code.replace("%ARGUMENT_NAMES", str);
+ }
+
+ if (code.contains("%ARGUMENTS")) {
+ QString str;
+ QTextStream aux_stream(&str);
+ writeFunctionArguments(aux_stream, func, Generator::SkipDefaultValues | Generator::SkipRemovedArguments);
+ code.replace("%ARGUMENTS", str);
+ }
+}
+
+AbstractMetaFunctionList Generator::queryFunctions(const AbstractMetaClass *cppClass, bool allFunctions)
+{
+ AbstractMetaFunctionList result;
+
+ if (allFunctions) {
+ int default_flags = AbstractMetaClass::NormalFunctions | AbstractMetaClass::Visible;
+ default_flags |= cppClass->isInterface() ? 0 : AbstractMetaClass::ClassImplements;
+
+ // Constructors
+ result = cppClass->queryFunctions(AbstractMetaClass::Constructors |
+ default_flags);
+
+ // put enum constructor first to avoid conflict with int contructor
+ result = sortContructor(result);
+
+ // Final functions
+ result += cppClass->queryFunctions(AbstractMetaClass::FinalInTargetLangFunctions |
+ AbstractMetaClass::NonStaticFunctions |
+ default_flags);
+
+ //virtual
+ result += cppClass->queryFunctions(AbstractMetaClass::VirtualInTargetLangFunctions |
+ AbstractMetaClass::NonStaticFunctions |
+ default_flags);
+
+ // Static functions
+ result += cppClass->queryFunctions(AbstractMetaClass::StaticFunctions | default_flags);
+
+ // Empty, private functions, since they aren't caught by the other ones
+ result += cppClass->queryFunctions(AbstractMetaClass::Empty |
+ AbstractMetaClass::Invisible | default_flags);
+ // Signals
+ result += cppClass->queryFunctions(AbstractMetaClass::Signals | default_flags);
+ } else {
+ result = cppClass->functionsInTargetLang();
+ }
+
+ return result;
+}
+
+AbstractMetaFunctionList Generator::filterFunctions(const AbstractMetaClass *cppClass)
+{
+ AbstractMetaFunctionList lst = queryFunctions(cppClass, true);
+ foreach (AbstractMetaFunction *func, lst) {
+ //skip signals
+ if (func->isSignal() ||
+ func->isDestructor() ||
+ (func->isModifiedRemoved() && !func->isAbstract())) {
+ lst.removeOne(func);
+ }
+ }
+
+ //virtual not implemented in current class
+ AbstractMetaFunctionList virtual_lst = cppClass->queryFunctions(AbstractMetaClass::VirtualFunctions);
+ foreach (AbstractMetaFunction *func, virtual_lst) {
+ if ((func->implementingClass() != cppClass) &&
+ !lst.contains(func)) {
+ lst.append(func);
+ }
+ }
+
+ //append global operators
+ foreach (AbstractMetaFunction *func , queryGlobalOperators(cppClass)) {
+ if (!lst.contains(func))
+ lst.append(func);
+ }
+
+ return lst;
+ //return cpp_class->functions();
+}
+
+AbstractMetaFunctionList Generator::queryGlobalOperators(const AbstractMetaClass *cppClass)
+{
+ AbstractMetaFunctionList result;
+
+ foreach (AbstractMetaFunction *func, cppClass->functions()) {
+ if (func->isInGlobalScope() && func->isOperatorOverload())
+ result.append(func);
+ }
+ return result;
+}
+
+AbstractMetaFunctionList Generator::sortContructor(AbstractMetaFunctionList list)
+{
+ AbstractMetaFunctionList result;
+
+ foreach (AbstractMetaFunction *func, list) {
+ bool inserted = false;
+ foreach (AbstractMetaArgument *arg, func->arguments()) {
+ if (arg->type()->isFlags() || arg->type()->isEnum()) {
+ result.push_back(func);
+ inserted = true;
+ break;
+ }
+ }
+ if (!inserted)
+ result.push_front(func);
+ }
+
+ return result;
+}
+
+FunctionModificationList Generator::functionModifications(const AbstractMetaFunction *metaFunction)
+{
+ FunctionModificationList mods;
+ const AbstractMetaClass *cls = metaFunction->implementingClass();
+ while (cls) {
+ mods += metaFunction->modifications(cls);
+
+ if (cls == cls->baseClass())
+ break;
+ cls = cls->baseClass();
+ }
+ return mods;
+}
+
+static QString formattedCodeHelper(QTextStream &s, Indentor &indentor, QStringList &lines)
+{
+ bool multilineComment = false;
+ bool lastEmpty = true;
+ QString lastLine;
+ while (!lines.isEmpty()) {
+ const QString line = lines.takeFirst().trimmed();
+ if (line.isEmpty()) {
+ if (!lastEmpty)
+ s << endl;
+ lastEmpty = true;
+ continue;
+ } else
+ lastEmpty = false;
+
+ if (line.startsWith("/*"))
+ multilineComment = true;
+
+ if (multilineComment) {
+ s << indentor;
+ if (line.startsWith("*"))
+ s << " ";
+ s << line << endl;
+ if (line.endsWith("*/"))
+ multilineComment = false;
+ } else if (line.startsWith("}"))
+ return line;
+ else if (line.endsWith("")) {
+ s << indentor << line << endl;
+ return 0;
+ } else if (line.endsWith("{")) {
+ s << indentor << line << endl;
+ QString tmp;
+ {
+ Indentation indent(indentor);
+ tmp = formattedCodeHelper(s, indentor, lines);
+ }
+ if (!tmp.isNull())
+ s << indentor << tmp << endl;
+
+ lastLine = tmp;
+ continue;
+ } else {
+ s << indentor;
+ if (!lastLine.isEmpty() &&
+ !lastLine.endsWith(";") &&
+ !line.startsWith("@") &&
+ !line.startsWith("//") &&
+ !lastLine.startsWith("//") &&
+ !lastLine.endsWith("}") &&
+ !line.startsWith("{"))
+ s << " ";
+ s << line << endl;
+ }
+ lastLine = line;
+ }
+ return 0;
+}
+
+QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor)
+{
+ QStringList lst(code.split("\n"));
+ while (!lst.isEmpty()) {
+ QString tmp = formattedCodeHelper(s, indentor, lst);
+ if (!tmp.isNull())
+ s << indentor << tmp << endl;
+
+ }
+ s.flush();
+ return s;
+}
+
+CodeSnipList Generator::getCodeSnips(const AbstractMetaFunction *func)
+{
+ CodeSnipList result;
+ const AbstractMetaClass *cppClass = func->implementingClass();
+ while (cppClass) {
+ foreach (FunctionModification mod, func->modifications(cppClass)) {
+ if (mod.isCodeInjection())
+ result << mod.snips;
+ }
+
+ if (cppClass == cppClass->baseClass())
+ break;
+ cppClass = cppClass->baseClass();
+ }
+
+ return result;
+}
+
+QString Generator::translateType(const AbstractMetaType *cType,
+ const AbstractMetaClass *context,
+ int option) const
+{
+ QString s;
+
+ if (context && cType &&
+ context->typeEntry()->isGenericClass() &&
+ cType->originalTemplateType()) {
+ qDebug() << "set original templateType" << cType->name();
+ cType = cType->originalTemplateType();
+ }
+
+ if (!cType) {
+ s = "void";
+ } else if (cType->isArray()) {
+ s = translateType(cType->arrayElementType(), context) + "[]";
+ } else if (cType->isEnum() || cType->isFlags()) {
+ if (option & Generator::EnumAsInts)
+ s = "int";
+ else
+ s = cType->cppSignature();
+#if 0
+ } else if (c_type->isContainer()) {
+ qDebug() << "is container" << c_type->cppSignature();
+ s = c_type->name();
+ if (!(option & SkipTemplateParameters)) {
+ s += " < ";
+ QList<AbstractMetaType *> args = c_type->instantiations();
+ for (int i = 0; i < args.size(); ++i) {
+ if (i)
+ s += ", ";
+ qDebug() << "container type: " << args.at(i)->cppSignature() << " / " << args.at(i)->instantiations().count();
+ s += translateType(args.at(i), context, option);
+ }
+ s += " > ";
+ }
+#endif
+ } else {
+ s = cType->cppSignature();
+ if (cType->isConstant() && (option & Generator::ExcludeConst))
+ s.replace("const", "");
+ if (cType->isReference() && (option & Generator::ExcludeReference))
+ s.replace("&", "");
+ }
+
+ return s;
+}
diff --git a/generator.h b/generator.h
new file mode 100644
index 000000000..8040072aa
--- /dev/null
+++ b/generator.h
@@ -0,0 +1,330 @@
+/*
+ * This file is part of the API Extractor project.
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: PySide team <contact@pyside.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <QtCore/QObject>
+#include <QtCore/QDir>
+#include <QtCore/QLinkedList>
+#include <apiextractor/abstractmetalang.h>
+
+class ApiExtractor;
+class AbstractMetaBuilder;
+class QFile;
+
+#define EXPORT_GENERATOR_PLUGIN(X)\
+extern "C" Q_DECL_EXPORT GeneratorList getGenerators()\
+{\
+ return GeneratorList() << X;\
+}\
+
+QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor);
+
+/**
+ * Base class for all generators. The default implementations does nothing,
+ * you must subclass this to create your own generators.
+ */
+class Generator
+{
+public:
+ /// Optiosn used around the generator code
+ enum Option {
+ NoOption = 0x00000000,
+ BoxedPrimitive = 0x00000001,
+ ExcludeConst = 0x00000002,
+ ExcludeReference = 0x00000004,
+ UseNativeIds = 0x00000008,
+
+ EnumAsInts = 0x00000010,
+ SkipName = 0x00000020,
+ NoCasts = 0x00000040,
+ SkipReturnType = 0x00000080,
+ OriginalName = 0x00000100,
+ ShowStatic = 0x00000200,
+ UnderscoreSpaces = 0x00000400,
+ ForceEnumCast = 0x00000800,
+ ArrayAsPointer = 0x00001000,
+ VirtualCall = 0x00002000,
+ SkipTemplateParameters = 0x00004000,
+ SkipAttributes = 0x00008000,
+ OriginalTypeDescription = 0x00010000,
+ SkipRemovedArguments = 0x00020000,
+ IncludeDefaultExpression = 0x00040000,
+ NoReturnStatement = 0x00080000,
+ NoBlockedSlot = 0x00100000,
+
+ SuperCall = 0x00200000,
+
+ GlobalRefJObject = 0x00100000,
+
+ SkipDefaultValues = 0x00400000,
+
+ WriteSelf = 0x00800000,
+ ExcludeMethodConst = 0x01000000,
+
+ ForceValueType = ExcludeReference | ExcludeConst
+ };
+
+ Generator();
+ virtual ~Generator();
+
+ bool setup(const ApiExtractor& extractor, const QMap<QString, QString> args);
+
+ virtual QMap<QString, QString> options() const;
+
+ /// Returns the classes used to generate the binding code.
+ AbstractMetaClassList classes() const;
+
+ AbstractMetaFunctionList globalFunctions() const;
+
+ AbstractMetaEnumList globalEnums() const;
+
+ QList<const PrimitiveTypeEntry*> primitiveTypes() const;
+
+ QList<const ContainerTypeEntry*> containerTypes() const;
+
+ /// Returns the output directory
+ QString outputDirectory() const;
+
+ /// Set the output directory
+ void setOutputDirectory(const QString &outDir);
+
+ /**
+ * Start the code generation, be sure to call setClasses before callign this method.
+ * For each class it creates a QTextStream, call the write method with the current
+ * class and the associated text stream, then write the text stream contents if needed.
+ * \see #write
+ */
+ void generate();
+
+ /// Returns the number of generated items
+ int numGenerated()
+ {
+ return m_numGenerated;
+ }
+
+ /// Returns the number of generated items written
+ int numGeneratedAndWritten()
+ {
+ return m_numGeneratedWritten;
+ }
+
+ virtual const char* name() const = 0;
+
+ /// Returns true if the generator should generate any code for the AbstractMetaClass
+ virtual bool shouldGenerate(const AbstractMetaClass *) const;
+
+ /// Returns the subdirectory used to write the binding code of an AbstractMetaClass.
+ virtual QString subDirectoryForClass(const AbstractMetaClass* clazz) const = 0;
+
+ /**
+ * Translate metatypes to binding source format.
+ * \param metatype a pointer to metatype
+ * \param context the current meta class
+ * \param option some extra options
+ * \return the metatype translated to binding source format
+ */
+ QString translateType(const AbstractMetaType *metatype,
+ const AbstractMetaClass *context,
+ int option = NoOption) const;
+
+ /**
+ * Function used to write the fucntion arguments on the class buffer.
+ * \param s the class output buffer
+ * \param metafunction the pointer to metafunction information
+ * \param count the number of function arguments
+ * \param options some extra options used during the parser
+ */
+ virtual void writeFunctionArguments(QTextStream &s,
+ const AbstractMetaFunction *metafunction,
+ uint options = 0) const = 0;
+
+ virtual void writeArgumentNames(QTextStream &s,
+ const AbstractMetaFunction *metafunction,
+ uint options = 0) const = 0;
+
+ void replaceTemplateVariables(QString &code, const AbstractMetaFunction *func);
+
+ bool hasDefaultConstructor(const AbstractMetaType *type);
+
+ // QtScript
+ QSet<QString> qtMetaTypeDeclaredTypeNames() const
+ {
+ return m_qmetatypeDeclaredTypenames;
+ }
+
+ /**
+ * Returns the license comment to be prepended to each source file generated.
+ */
+ QString licenseComment()
+ {
+ return m_licenseComment;
+ }
+
+ /**
+ * Sets the license comment to be prepended to each source file generated.
+ */
+ void setLicenseComment(const QString &licenseComment)
+ {
+ m_licenseComment = licenseComment;
+ }
+
+ /**
+ * Returns the package name.
+ */
+ QString packageName()
+ {
+ return m_packageName;
+ }
+
+ /**
+ * Sets the package name.
+ */
+ void setPackageName(const QString &packageName)
+ {
+ m_packageName = packageName;
+ }
+
+ /**
+ * Retrieves the name of the currently processed module. While package name
+ * is a complete package idetification, e.g. 'PySide.QtCore', a module name
+ * represents the last part of the package, e.g. 'QtCore'.
+ * If the target language separates the modules with characters other than
+ * dots ('.') the generator subclass must overload this method.
+ * /return a string representing the last part of a package name
+ */
+ virtual QString moduleName()
+ {
+ return QString(m_packageName).remove(0, m_packageName.lastIndexOf('.') + 1);
+ }
+
+ /// returns the code snips of a function
+ CodeSnipList getCodeSnips(const AbstractMetaFunction *func);
+
+protected:
+ QString m_packageName;
+
+ /**
+ * Returns the file name used to write the binding code of an AbstractMetaClass.
+ * /param metaClass the AbstractMetaClass for which the file name must be
+ * returned
+ * /return the file name used to write the binding code for the class
+ */
+ virtual QString fileNameForClass(const AbstractMetaClass* metaClass) const = 0;
+
+ static FunctionModificationList functionModifications(const AbstractMetaFunction *meta_function);
+ AbstractMetaFunctionList filterFunctions(const AbstractMetaClass *cppClass);
+ AbstractMetaFunctionList queryFunctions(const AbstractMetaClass *cpp_class, bool all_function = false);
+ AbstractMetaFunctionList queryGlobalOperators(const AbstractMetaClass *cpp_class);
+ AbstractMetaFunctionList sortContructor(AbstractMetaFunctionList list);
+
+ virtual bool doSetup(const QMap<QString, QString>& args) = 0;
+
+ /**
+ * Returns the subdirectory path for a given package
+ * (aka module, aka library) name.
+ * If the target language separates the package modules with characters other
+ * than dots ('.') the generator subclass must overload this method.
+ * /param packageName complete package name for which to return the subdirectory path
+ * or nothing the use the name of the currently processed package
+ * /return a string representing the subdirectory path for the given package
+ */
+ virtual QString subDirectoryForPackage(QString packageName = QString()) const
+ {
+ if (packageName.isEmpty())
+ packageName = m_packageName;
+ return QString(packageName).replace(".", QDir::separator());
+ }
+
+ /**
+ * Write the bindding code for an AbstractMetaClass.
+ * This is called by the default implementation of generate method.
+ * \param s text stream to write the generated output
+ * \param metaClass the class that should be generated
+ */
+ virtual void generateClass(QTextStream& s, const AbstractMetaClass* metaClass) = 0;
+ virtual void finishGeneration() = 0;
+
+ void verifyDirectoryFor(const QFile &file);
+
+ int m_numGenerated;
+ int m_numGeneratedWritten;
+
+private:
+ AbstractMetaClassList m_classes;
+ AbstractMetaFunctionList m_globalFunctions;
+ AbstractMetaEnumList m_globalEnums;
+ QString m_outDir;
+
+ QList<const PrimitiveTypeEntry*> m_primitiveTypes;
+ QList<const ContainerTypeEntry*> m_containerTypes;
+
+ // QtScript
+ QSet<QString> m_qmetatypeDeclaredTypenames;
+
+ // License comment
+ QString m_licenseComment;
+};
+
+typedef QLinkedList<Generator*> GeneratorList;
+
+/**
+* Utility class to store the identation level, use it in a QTextStream.
+*/
+class Indentor
+{
+public:
+ Indentor():
+ indent(0) {}
+ int indent;
+};
+
+/**
+* Class that use the RAII idiom to set and unset the identation level.
+*/
+class Indentation
+{
+public:
+ Indentation(Indentor &indentor) : indentor(indentor)
+ {
+ indentor.indent++;
+ }
+ ~Indentation()
+ {
+ indentor.indent--;
+ }
+
+private:
+ Indentor &indentor;
+};
+
+inline QTextStream &operator <<(QTextStream &s, const Indentor &indentor)
+{
+ for (int i = 0; i < indentor.indent; ++i)
+ s << " ";
+ return s;
+}
+
+#endif // GENERATOR_H
+
diff --git a/generators/CMakeLists.txt b/generators/CMakeLists.txt
new file mode 100644
index 000000000..73b5eea22
--- /dev/null
+++ b/generators/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(boostpython)
+add_subdirectory(qtdoc)
diff --git a/generators/boostpython/CMakeLists.txt b/generators/boostpython/CMakeLists.txt
new file mode 100644
index 000000000..b29b8cf89
--- /dev/null
+++ b/generators/boostpython/CMakeLists.txt
@@ -0,0 +1,14 @@
+project(boostpython)
+
+set(boostpython_generator_SRC
+boostpythongenerator.cpp
+convertergenerator.cpp
+cppgenerator.cpp
+hppgenerator.cpp
+boostpython.cpp
+)
+
+add_library(boostpython_generator SHARED ${boostpython_generator_SRC})
+target_link_libraries(boostpython_generator ${APIEXTRACTOR_LIBRARY} ${QT_QTCORE_LIBRARY} genrunner)
+
+install(TARGETS boostpython_generator DESTINATION ${LIB_INSTALL_DIR})
diff --git a/generators/boostpython/boostpython.cpp b/generators/boostpython/boostpython.cpp
new file mode 100644
index 000000000..e165f93b9
--- /dev/null
+++ b/generators/boostpython/boostpython.cpp
@@ -0,0 +1,29 @@
+/*
+* This file is part of the API Extractor project.
+*
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+*
+* Contact: PySide team <contact@pyside.org>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA
+*
+*/
+
+#include "generator.h"
+#include "hppgenerator.h"
+#include "cppgenerator.h"
+#include "convertergenerator.h"
+
+EXPORT_GENERATOR_PLUGIN(new HppGenerator << new CppGenerator << new ConverterGenerator)
diff --git a/boostpythongenerator.cpp b/generators/boostpython/boostpythongenerator.cpp
index 732ef3b65..8930c40cf 100644
--- a/boostpythongenerator.cpp
+++ b/generators/boostpython/boostpythongenerator.cpp
@@ -36,69 +36,6 @@
static Indentor INDENT;
static void dump_function(AbstractMetaFunctionList lst);
-FunctionModificationList BoostPythonGenerator::functionModifications(const AbstractMetaFunction *metaFunction)
-{
- FunctionModificationList mods;
- const AbstractMetaClass *cls = metaFunction->implementingClass();
- while (cls) {
- mods += metaFunction->modifications(cls);
-
- if (cls == cls->baseClass())
- break;
- cls = cls->baseClass();
- }
- return mods;
-}
-
-QString BoostPythonGenerator::translateType(const AbstractMetaType *cType,
- const AbstractMetaClass *context,
- int option) const
-{
- QString s;
-
- if (context && cType &&
- context->typeEntry()->isGenericClass() &&
- cType->originalTemplateType()) {
- qDebug() << "set original templateType" << cType->name();
- cType = cType->originalTemplateType();
- }
-
- if (!cType) {
- s = "void";
- } else if (cType->isArray()) {
- s = translateType(cType->arrayElementType(), context) + "[]";
- } else if (cType->isEnum() || cType->isFlags()) {
- if (option & Generator::EnumAsInts)
- s = "int";
- else
- s = cType->cppSignature();
-#if 0
- } else if (c_type->isContainer()) {
- qDebug() << "is container" << c_type->cppSignature();
- s = c_type->name();
- if (!(option & SkipTemplateParameters)) {
- s += " < ";
- QList<AbstractMetaType *> args = c_type->instantiations();
- for (int i = 0; i < args.size(); ++i) {
- if (i)
- s += ", ";
- qDebug() << "container type: " << args.at(i)->cppSignature() << " / " << args.at(i)->instantiations().count();
- s += translateType(args.at(i), context, option);
- }
- s += " > ";
- }
-#endif
- } else {
- s = cType->cppSignature();
- if (cType->isConstant() && (option & Generator::ExcludeConst))
- s.replace("const", "");
- if (cType->isReference() && (option & Generator::ExcludeReference))
- s.replace("&", "");
- }
-
- return s;
-}
-
QString BoostPythonGenerator::getWrapperName(const AbstractMetaClass* metaClass)
{
QString result = metaClass->typeEntry()->qualifiedCppName().toLower();
@@ -271,77 +208,6 @@ void BoostPythonGenerator::writeArgumentNames(QTextStream &s,
}
}
-AbstractMetaFunctionList BoostPythonGenerator::queryGlobalOperators(const AbstractMetaClass *cppClass)
-{
- AbstractMetaFunctionList result;
-
- foreach (AbstractMetaFunction *func, cppClass->functions()) {
- if (func->isInGlobalScope() && func->isOperatorOverload())
- result.append(func);
- }
- return result;
-}
-
-AbstractMetaFunctionList BoostPythonGenerator::sortContructor(AbstractMetaFunctionList list)
-{
- AbstractMetaFunctionList result;
-
- foreach (AbstractMetaFunction *func, list) {
- bool inserted = false;
- foreach (AbstractMetaArgument *arg, func->arguments()) {
- if (arg->type()->isFlags() || arg->type()->isEnum()) {
- result.push_back(func);
- inserted = true;
- break;
- }
- }
- if (!inserted)
- result.push_front(func);
- }
-
- return result;
-}
-
-AbstractMetaFunctionList BoostPythonGenerator::queryFunctions(const AbstractMetaClass *cppClass, bool allFunctions)
-{
- AbstractMetaFunctionList result;
-
- if (allFunctions) {
- int default_flags = AbstractMetaClass::NormalFunctions | AbstractMetaClass::Visible;
- default_flags |= cppClass->isInterface() ? 0 : AbstractMetaClass::ClassImplements;
-
- // Constructors
- result = cppClass->queryFunctions(AbstractMetaClass::Constructors |
- default_flags);
-
- // put enum constructor first to avoid conflict with int contructor
- result = sortContructor(result);
-
- // Final functions
- result += cppClass->queryFunctions(AbstractMetaClass::FinalInTargetLangFunctions |
- AbstractMetaClass::NonStaticFunctions |
- default_flags);
-
- //virtual
- result += cppClass->queryFunctions(AbstractMetaClass::VirtualInTargetLangFunctions |
- AbstractMetaClass::NonStaticFunctions |
- default_flags);
-
- // Static functions
- result += cppClass->queryFunctions(AbstractMetaClass::StaticFunctions | default_flags);
-
- // Empty, private functions, since they aren't caught by the other ones
- result += cppClass->queryFunctions(AbstractMetaClass::Empty |
- AbstractMetaClass::Invisible | default_flags);
- // Signals
- result += cppClass->queryFunctions(AbstractMetaClass::Signals | default_flags);
- } else {
- result = cppClass->functionsInTargetLang();
- }
-
- return result;
-}
-
void BoostPythonGenerator::writeFunctionCall(QTextStream &s,
const AbstractMetaFunction* func,
uint options)
@@ -355,55 +221,6 @@ void BoostPythonGenerator::writeFunctionCall(QTextStream &s,
s << ')';
}
-AbstractMetaFunctionList BoostPythonGenerator::filterFunctions(const AbstractMetaClass *cppClass)
-{
- AbstractMetaFunctionList lst = queryFunctions(cppClass, true);
- foreach (AbstractMetaFunction *func, lst) {
- //skip signals
- if (func->isSignal() ||
- func->isDestructor() ||
- (func->isModifiedRemoved() && !func->isAbstract())) {
- lst.removeOne(func);
- }
- }
-
- //virtual not implemented in current class
- AbstractMetaFunctionList virtual_lst = cppClass->queryFunctions(AbstractMetaClass::VirtualFunctions);
- foreach (AbstractMetaFunction *func, virtual_lst) {
- if ((func->implementingClass() != cppClass) &&
- !lst.contains(func)) {
- lst.append(func);
- }
- }
-
- //append global operators
- foreach (AbstractMetaFunction *func , queryGlobalOperators(cppClass)) {
- if (!lst.contains(func))
- lst.append(func);
- }
-
- return lst;
- //return cpp_class->functions();
-}
-
-CodeSnipList BoostPythonGenerator::getCodeSnips(const AbstractMetaFunction *func)
-{
- CodeSnipList result;
- const AbstractMetaClass *cppClass = func->implementingClass();
- while (cppClass) {
- foreach (FunctionModification mod, func->modifications(cppClass)) {
- if (mod.isCodeInjection())
- result << mod.snips;
- }
-
- if (cppClass == cppClass->baseClass())
- break;
- cppClass = cppClass->baseClass();
- }
-
- return result;
-}
-
void BoostPythonGenerator::writeCodeSnips(QTextStream &s,
const CodeSnipList &codeSnips,
CodeSnip::Position position,
@@ -419,7 +236,7 @@ void BoostPythonGenerator::writeCodeSnips(QTextStream &s,
QString code;
QTextStream tmpStream(&code);
- snip.formattedCode(tmpStream, INDENT);
+ formatCode(tmpStream, snip.code(), INDENT);
if (func)
replaceTemplateVariables(code, func);
@@ -488,7 +305,7 @@ static void dump_function(AbstractMetaFunctionList lst)
}
-bool BoostPythonGenerator::prepareGeneration(const QMap<QString, QString>&)
+bool BoostPythonGenerator::doSetup(const QMap<QString, QString>&)
{
return true;
}
diff --git a/boostpythongenerator.h b/generators/boostpython/boostpythongenerator.h
index 4ad191b50..14311b2e0 100644
--- a/boostpythongenerator.h
+++ b/generators/boostpython/boostpythongenerator.h
@@ -24,8 +24,8 @@
#ifndef BOOSTPYTHONGENERATOR_H
#define BOOSTPYTHONGENERATOR_H
-#include <apiextractor/generator.h>
#include <QtCore/QTextStream>
+#include "generator.h"
class DocParser;
@@ -36,16 +36,6 @@ class BoostPythonGenerator : public Generator
{
public:
/**
- * Translate metatypes to boost::python format.
- * \param boost_type a pointer to metatype
- * \param context the current meta class
- * \param option some extra options
- * \return the metatype translated to boost::python format
- */
- virtual QString translateType(const AbstractMetaType *boost_type,
- const AbstractMetaClass *context,
- int option = NoOption) const;
- /**
* Write a function argument in the boost::python format in the text stream \p s.
* This function just call \code s << argumentString(); \endcode
* \param s text stream used to write the output.
@@ -96,8 +86,6 @@ public:
CodeSnip::Position position,
TypeSystem::Language language,
const AbstractMetaFunction *cpp_function = 0);
- /// returns the code snips of a function
- CodeSnipList getCodeSnips(const AbstractMetaFunction *func);
static bool canCreateWrapperFor(const AbstractMetaClass* cppClass);
/**
* Function witch parse the metafunction information
@@ -127,19 +115,13 @@ public:
static QString getWrapperName(const AbstractMetaClass* clazz);
- virtual bool prepareGeneration(const QMap<QString, QString>& args);
+ virtual bool doSetup(const QMap<QString, QString>& args);
protected:
// verify if the class is copyalbe
bool isCopyable(const AbstractMetaClass *cpp_class);
- static FunctionModificationList functionModifications(const AbstractMetaFunction *meta_function);
- AbstractMetaFunctionList queryFunctions(const AbstractMetaClass *cpp_class, bool all_function = false);
void writeFunctionCall(QTextStream &s, const AbstractMetaFunction *cpp_func, uint options = 0);
-
- AbstractMetaFunctionList filterFunctions(const AbstractMetaClass *cpp_class);
- AbstractMetaFunctionList queryGlobalOperators(const AbstractMetaClass *cpp_class);
- AbstractMetaFunctionList sortContructor(AbstractMetaFunctionList list);
};
diff --git a/convertergenerator.cpp b/generators/boostpython/convertergenerator.cpp
index ea52b9193..ea52b9193 100644
--- a/convertergenerator.cpp
+++ b/generators/boostpython/convertergenerator.cpp
diff --git a/convertergenerator.h b/generators/boostpython/convertergenerator.h
index 8f91377c0..8f91377c0 100644
--- a/convertergenerator.h
+++ b/generators/boostpython/convertergenerator.h
diff --git a/cppgenerator.cpp b/generators/boostpython/cppgenerator.cpp
index d99815776..ca4b704ff 100644
--- a/cppgenerator.cpp
+++ b/generators/boostpython/cppgenerator.cpp
@@ -244,18 +244,27 @@ QString CppGenerator::writeFunctionCast(QTextStream &s,
QString CppGenerator::verifyDefaultReturnPolicy(const AbstractMetaFunction *cppFunction, const QString& callPolicy)
{
AbstractMetaType *type = cppFunction->type();
+
+ //If return type replaced, the return policy need be set manually.
+ if (!type || !cppFunction->typeReplaced(0).isEmpty())
+ return QString();
+
+ //avoid natives types
+ if (!type->name().startsWith("Q"))
+ return QString();
+
QString returnPolicy;
- if (type && type->isReference() && type->isConstant()) {
+ if (type->isConstant() && type->isReference()) {
returnPolicy = "python::return_value_policy<python::copy_const_reference";
if (!callPolicy.isEmpty())
returnPolicy += ", " + callPolicy;
returnPolicy += " >()";
- } else if (type && (type->isReference() || type->isQObject() || type->isObject())) {
+ } else if (type->isReference() || type->isQObject() || type->isObject() || type->isNativePointer()) {
bool cppOwnership = type->isConstant();
if (cppFunction->isStatic() || cppOwnership) {
- returnPolicy = "python::return_value_policy<PySide::return_ptr_object< "
- + (cppOwnership ? QString("true") : QString("false")) + "> >()";
+ returnPolicy = QString("python::return_value_policy<PySide::return_ptr_object<")
+ + (cppOwnership ? "true" : "false") + QString("> >()");
} else if (type->isQObject() || type->isObject()) {
returnPolicy = QString("PySide::return_object<1, 0, %1, %2 %3 %4 >()")
.arg(getArgumentType(cppFunction->ownerClass(), cppFunction, -1))
@@ -624,11 +633,13 @@ void CppGenerator::writeModifiedConstructorImpl ( QTextStream& s, const Abstract
void CppGenerator::writeConstructorImpl(QTextStream& s, const AbstractMetaFunction* func)
{
- s << functionSignature(func, getWrapperName(func->ownerClass()) + "::", "",
- (Option)(OriginalTypeDescription | SkipDefaultValues));
- s << " : ";
+ QString wrapperName = getWrapperName(func->ownerClass());
+ s << wrapperName << "::" << wrapperName << "(PyObject *py_self" << (func->arguments().size() ? ", " : "");
+ writeFunctionArguments(s, func, OriginalTypeDescription | SkipDefaultValues);
+ s << ")" << endl;
+ s << INDENT << " : ";
writeFunctionCall(s, func);
- s << " {" << endl;
+ s << ", wrapper(py_self)" << endl << "{" << endl;
writeCodeSnips(s, getCodeSnips(func), CodeSnip::Beginning, TypeSystem::All, func);
writeCodeSnips(s, getCodeSnips(func), CodeSnip::End, TypeSystem::All, func);
s << '}' << endl << endl;
@@ -644,7 +655,7 @@ void CppGenerator::writeVirtualMethodImplHead(QTextStream& s, const AbstractMeta
CodeSnip::Beginning, TypeSystem::NativeCode, func);
}
- s << INDENT << "python::object method = PySide::detail::get_override(this, \"" << func->implementingClass()->name();
+ s << INDENT << "python::object method = get_override(\"" << func->implementingClass()->name();
if (func->implementingClass()->typeEntry()->isObject() || func->implementingClass()->typeEntry()->isQObject())
s << '*';
@@ -682,9 +693,7 @@ void CppGenerator::writeVirtualMethodImplHead(QTextStream& s, const AbstractMeta
(func->type()->isObject() || func->type()->isQObject())) {
s << INDENT << "PySide::qptr<" << QString(typeName).replace("*", "") << " > __ptr(__result.ptr());" << endl
- << INDENT << "if (__ptr.is_wrapper()) {" << endl
- << INDENT << INDENT << "python::incref(__result.ptr());" << endl
- << INDENT << "}" << endl
+ << INDENT << "python::incref(__result.ptr());" << endl
<< INDENT << "__ptr.release_ownership();" << endl;
}
@@ -902,11 +911,8 @@ void CppGenerator::writeBoostDeclaration(QTextStream& s, const AbstractMetaClass
s << INDENT << "python::scope " << wrapperName << "_scope(python_cls);" << endl;
if (cppClass->templateBaseClass() && cppClass->templateBaseClass()->typeEntry()->isContainer()) {
- //const ContainerTypeEntry *type = static_cast<const ContainerTypeEntry*>(cppClass->templateBaseClass()->typeEntry());
- //if (type->type() == ContainerTypeEntry::ListContainer) {
s << endl << INDENT << "//Index suite for QContainer" << endl
<< INDENT << "python_cls.def(qcontainer_indexing_suite< " << cppClass->qualifiedCppName() << " >());" << endl << endl;
- //}
}
if (isCopyable(cppClass) && !cppClass->isNamespace()) {
@@ -1399,9 +1405,9 @@ void CppGenerator::writeGlobalFunctions()
if (moduleEntry && moduleEntry->codeSnips().size() > 0) {
foreach (CodeSnip snip, moduleEntry->codeSnips()) {
if (snip.position == CodeSnip().Beginning)
- snip.formattedCode(s, INDENT);
+ formatCode(s, snip.code(), INDENT);
else
- snip.formattedCode(snipEnd, INDENT);
+ formatCode(snipEnd, snip.code(), INDENT);
}
}
@@ -1419,3 +1425,15 @@ void CppGenerator::writeGlobalFunctions()
s << "}\n";
}
+QMap<QString, QString> CppGenerator::options() const
+{
+ QMap<QString, QString> res;
+ res.insert("disable-named-arg", "Disable Python names arguments.");
+ return res;
+}
+
+bool CppGenerator::doSetup(const QMap<QString, QString>& args )
+{
+ m_disableNamedArgs = args.contains("disable-named-arg");
+ return BoostPythonGenerator::doSetup(args);
+}
diff --git a/cppgenerator.h b/generators/boostpython/cppgenerator.h
index 03d37438a..5fcc6f38f 100644
--- a/cppgenerator.h
+++ b/generators/boostpython/cppgenerator.h
@@ -32,16 +32,14 @@
class CppGenerator : public BoostPythonGenerator
{
public:
- void setDisableNamedArgs(bool disable)
- {
- m_disableNamedArgs = disable;
- }
-
const char* name() const
{
return "CppGenerator";
}
+ QMap<QString, QString> options() const;
+ bool doSetup(const QMap<QString, QString>& args);
+
protected:
QString fileNameForClass(const AbstractMetaClass *cppClass) const;
void generateClass(QTextStream &s, const AbstractMetaClass *cppClass);
diff --git a/hppgenerator.cpp b/generators/boostpython/hppgenerator.cpp
index 4e7da1120..f6d576d08 100644
--- a/hppgenerator.cpp
+++ b/generators/boostpython/hppgenerator.cpp
@@ -38,8 +38,8 @@ QString HppGenerator::fileNameForClass(const AbstractMetaClass *cppClass) const
void HppGenerator::writeCopyCtor(QTextStream &s, const AbstractMetaClass *cppClass)
{
- s << INDENT << getWrapperName(cppClass) << "(const " << cppClass->qualifiedCppName() << "& self)"
- << " : " << cppClass->qualifiedCppName() << "(self)" << endl
+ s << INDENT << getWrapperName(cppClass) << "(PyObject *py_self, const " << cppClass->qualifiedCppName() << "& self)"
+ << " : " << cppClass->qualifiedCppName() << "(self), wrapper(py_self)" << endl
<< INDENT << "{" << endl
<< INDENT << "}" << endl;
}
@@ -67,11 +67,13 @@ void HppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
if (!cppClass->isPolymorphic() || cppClass->hasPrivateDestructor() || cppClass->isNamespace())
s << "namespace " << wrapperName << " {" << endl << endl;
+ bool needWriteBackReference = false;
if (cppClass->isNamespace()) {
s << INDENT << "struct Namespace {};" << endl;
} else {
QString className;
bool create_wrapper = canCreateWrapperFor(cppClass);
+ bool is_wrapper = false;
// detect the held type
QString held_type = cppClass->typeEntry()->heldTypeValue();
if (held_type.isEmpty() && create_wrapper)
@@ -81,16 +83,10 @@ void HppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
CodeSnip::Declaration, TypeSystem::NativeCode);
if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) {
- if (!held_type.isEmpty()) {
- s << "// held type forward decalration" << endl;
- s << "template<typename T> class " << held_type << ';' << endl;
- }
-
// Class
s << "class PYSIDE_LOCAL " << wrapperName;
if (create_wrapper) {
- s << " : public " << cppClass->qualifiedCppName() << ", public boost::python::wrapper<";
- s << cppClass->qualifiedCppName() << '>';
+ s << " : public " << cppClass->qualifiedCppName() << ", public PySide::wrapper";
}
s << endl;
s << "{" << endl;
@@ -101,22 +97,20 @@ void HppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) {
s << endl << "private:" << endl;
-
- if (cppClass->hasPrivateDestructor())
- className = cppClass->qualifiedCppName();
- else
- className = wrapperName;
+ className = wrapperName;
+ is_wrapper = true;
} else {
className = cppClass->qualifiedCppName();
}
// print the huge boost::python::class_ typedef
- s << INDENT << "typedef boost::python::class_< " << className;
+ s << INDENT << "typedef boost::python::class_< " << cppClass->qualifiedCppName();
writeBaseClass(s, cppClass);
if (!held_type.isEmpty())
- s << ", PySide::" << held_type << " < " << className << ", PySide::qptr_base::avoid_cache > ";
+ s << ", PySide::" << held_type << " < " << className << ", qptr_base::no_check_cache | qptr_base::"
+ << ( is_wrapper ? "wrapper_pointer" : "no_wrapper_pointer") << "> ";
if (!isCopyable(cppClass))
s << ", boost::noncopyable";
@@ -143,7 +137,6 @@ void HppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
writeCodeSnips(s, cppClass->typeEntry()->codeSnips(),
CodeSnip::End, TypeSystem::ShellDeclaration);
-
}
QString staticKeyword = cppClass->isNamespace() ? QLatin1String("") : QLatin1String("static ");
@@ -159,6 +152,7 @@ void HppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
s << "};" << endl << endl;
+
s << "#endif // __" << wrapperName.toUpper() << "__" << endl << endl;
}
@@ -179,7 +173,14 @@ void HppGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction* fun
s << INDENT << "static " << signatureForDefaultVirtualMethod(func, "", "_default", Generator::SkipName) << ';' << endl;
}
- s << INDENT << functionSignature(func, "", "", Generator::OriginalTypeDescription | Generator::SkipName);
+ if (func->isConstructor()) {
+ s << INDENT << getWrapperName(func->ownerClass()) << "(PyObject *py_self" << (func->arguments().size() ? "," : "");
+ writeFunctionArguments(s, func, Generator::OriginalTypeDescription | Generator::SkipName);
+ s << ")";
+ } else {
+ s << INDENT << functionSignature(func, "", "", Generator::OriginalTypeDescription | Generator::SkipName);
+ }
+
if (func->isModifiedRemoved() && func->isAbstract())
writeDefaultImplementation(s, func);
else
diff --git a/hppgenerator.h b/generators/boostpython/hppgenerator.h
index 8e0f5f03b..8e0f5f03b 100644
--- a/hppgenerator.h
+++ b/generators/boostpython/hppgenerator.h
diff --git a/generators/qtdoc/CMakeLists.txt b/generators/qtdoc/CMakeLists.txt
new file mode 100644
index 000000000..fb71784ab
--- /dev/null
+++ b/generators/qtdoc/CMakeLists.txt
@@ -0,0 +1,10 @@
+project(qtdoc_generator)
+
+set(qtdoc_generator_SRC
+qtdocgenerator.cpp
+)
+
+add_library(qtdoc_generator SHARED ${qtdoc_generator_SRC})
+target_link_libraries(qtdoc_generator ${APIEXTRACTOR_LIBRARY} ${QT_QTCORE_LIBRARY} genrunner)
+
+install(TARGETS qtdoc_generator DESTINATION ${LIB_INSTALL_DIR})
diff --git a/docgenerator.cpp b/generators/qtdoc/qtdocgenerator.cpp
index 455615e00..762c8a9b6 100644
--- a/docgenerator.cpp
+++ b/generators/qtdoc/qtdocgenerator.cpp
@@ -21,7 +21,7 @@
*
*/
-#include "docgenerator.h"
+#include "qtdocgenerator.h"
#include <reporthandler.h>
#include <qtdocparser.h>
#include <algorithm>
@@ -65,7 +65,7 @@ QString escape(const QStringRef& strref)
}
-QtXmlToSphinx::QtXmlToSphinx(DocGenerator* generator, const QString& doc, const QString& context)
+QtXmlToSphinx::QtXmlToSphinx(QtDocGenerator* generator, const QString& doc, const QString& context)
: m_context(context), m_generator(generator), m_insideBold(false), m_insideItalic(false)
{
m_handlerMap.insert("heading", &QtXmlToSphinx::handleHeadingTag);
@@ -843,12 +843,12 @@ static QString getFuncName(const AbstractMetaFunction *cppFunc) {
return result.replace("::", ".");
}
-QString DocGenerator::fileNameForClass(const AbstractMetaClass *cppClass) const
+QString QtDocGenerator::fileNameForClass(const AbstractMetaClass *cppClass) const
{
return QString("%1.rst").arg(getClassName(cppClass));
}
-void DocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc, const AbstractMetaClass* metaClass)
+void QtDocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc, const AbstractMetaClass* metaClass)
{
QString metaClassName;
@@ -865,7 +865,7 @@ void DocGenerator::writeFormatedText(QTextStream& s, const Documentation& doc, c
s << endl;
}
-void DocGenerator::writeFunctionBrief(QTextStream &s,
+void QtDocGenerator::writeFunctionBrief(QTextStream &s,
const AbstractMetaClass *cppClass,
const AbstractMetaFunction *cppFunction)
{
@@ -878,7 +878,7 @@ void DocGenerator::writeFunctionBrief(QTextStream &s,
<< " (" << parseArgDocStyle(cppClass, cppFunction) << "):";
}
-void DocGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppClass)
+void QtDocGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppClass)
{
QString doc;
QTextStream doc_s(&doc);
@@ -898,35 +898,6 @@ void DocGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
AbstractMetaFunctionList functionList = filterFunctions(cppClass);
qSort(functionList.begin(), functionList.end(), functionSort);
-#if 0
- if (functionList.size() > 0)
- {
- QtXmlToSphinx::Table functionTable;
- QtXmlToSphinx::TableRow row;
-
- s << "Functions\n"
- "---------\n\n";
-
-
- foreach (AbstractMetaFunction *func, functionList) {
- if ((func->isConstructor() || func->isModifiedRemoved()) ||
- (func->declaringClass() != cppClass))
- continue;
-
- QString rowString;
- QTextStream rowStream(&rowString);
-
- writeFunctionBrief(rowStream, cppClass, func);
- row << rowString;
- functionTable << row;
- row.clear();
- }
- functionTable.normalize();
- s << functionTable;
- }
-
-#endif
-
doc_s << "Detailed Description\n"
"--------------------\n\n";
@@ -961,7 +932,7 @@ void DocGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppCla
s << doc;
}
-QString DocGenerator::parseFunctionDeclaration(const QString &doc, const AbstractMetaClass *cppClass)
+QString QtDocGenerator::parseFunctionDeclaration(const QString &doc, const AbstractMetaClass *cppClass)
{
//.. method:: QObject.childEvent(arg__1)
//def :meth:`removeEventFilter<QObject.removeEventFilter>` (arg__1):
@@ -1001,7 +972,7 @@ QString DocGenerator::parseFunctionDeclaration(const QString &doc, const Abstrac
}
-void DocGenerator::writeFunctionList(QTextStream &s, const QString &content, const AbstractMetaClass *cppClass)
+void QtDocGenerator::writeFunctionList(QTextStream &s, const QString &content, const AbstractMetaClass *cppClass)
{
QStringList functionList;
QStringList staticFunctionList;
@@ -1058,7 +1029,7 @@ void DocGenerator::writeFunctionList(QTextStream &s, const QString &content, con
}
}
-void DocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClass)
+void QtDocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClass)
{
static const QString section_title(".. attribute:: ");
@@ -1068,7 +1039,7 @@ void DocGenerator::writeEnums(QTextStream& s, const AbstractMetaClass* cppClass)
}
}
-void DocGenerator::writeFields(QTextStream &s, const AbstractMetaClass *cppClass)
+void QtDocGenerator::writeFields(QTextStream &s, const AbstractMetaClass *cppClass)
{
static const QString section_title(".. attribute:: ");
@@ -1079,7 +1050,7 @@ void DocGenerator::writeFields(QTextStream &s, const AbstractMetaClass *cppClass
}
}
-void DocGenerator::writeConstructors(QTextStream &s, const AbstractMetaClass *cppClass)
+void QtDocGenerator::writeConstructors(QTextStream &s, const AbstractMetaClass *cppClass)
{
static const QString sectionTitle = ".. class:: ";
static const QString sectionTitleSpace = QString(sectionTitle.size(), ' ');
@@ -1122,7 +1093,7 @@ void DocGenerator::writeConstructors(QTextStream &s, const AbstractMetaClass *cp
}
}
-QString DocGenerator::parseArgDocStyle(const AbstractMetaClass *cppClass, const AbstractMetaFunction *func)
+QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass *cppClass, const AbstractMetaFunction *func)
{
QString ret;
bool optional = false;
@@ -1152,7 +1123,7 @@ QString DocGenerator::parseArgDocStyle(const AbstractMetaClass *cppClass, const
return ret;
}
-void DocGenerator::writeDocSnips(QTextStream &s,
+void QtDocGenerator::writeDocSnips(QTextStream &s,
const CodeSnipList &codeSnips,
CodeSnip::Position position,
TypeSystem::Language language)
@@ -1215,7 +1186,7 @@ void DocGenerator::writeDocSnips(QTextStream &s,
}
}
-void DocGenerator::writeInjectDocumentation(QTextStream &s,
+void QtDocGenerator::writeInjectDocumentation(QTextStream &s,
DocModification::Mode mode,
const AbstractMetaClass *cppClass,
const AbstractMetaFunction *func)
@@ -1257,7 +1228,7 @@ void DocGenerator::writeInjectDocumentation(QTextStream &s,
}
}
-void DocGenerator::writeFunctionSignature(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
+void QtDocGenerator::writeFunctionSignature(QTextStream& s, const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
{
if (!func->isConstructor())
s << getClassName(cppClass) << '.';
@@ -1266,7 +1237,7 @@ void DocGenerator::writeFunctionSignature(QTextStream& s, const AbstractMetaClas
s << getFuncName(func) << "(" << parseArgDocStyle(cppClass, func) << ")";
}
-QString DocGenerator::translateToPythonType(const AbstractMetaType *type, const AbstractMetaClass *cppClass)
+QString QtDocGenerator::translateToPythonType(const AbstractMetaType *type, const AbstractMetaClass *cppClass)
{
QString originalType = translateType(type, cppClass, Generator::ExcludeConst | Generator::ExcludeReference);
QString strType = originalType;
@@ -1299,13 +1270,13 @@ QString DocGenerator::translateToPythonType(const AbstractMetaType *type, const
}
}
-void DocGenerator::writeParamerteType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaArgument *arg)
+void QtDocGenerator::writeParamerteType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaArgument *arg)
{
s << INDENT << ":param " << arg->argumentName() << ": "
<< translateToPythonType(arg->type(), cppClass) << endl;
}
-void DocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaFunction* func)
+void QtDocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaFunction* func)
{
Indentation indentation(INDENT);
@@ -1324,7 +1295,7 @@ void DocGenerator::writeFunctionParametersType(QTextStream &s, const AbstractMet
s << endl;
}
-void DocGenerator::writeFunction(QTextStream &s, bool writeDoc, const AbstractMetaClass *cppClass, const AbstractMetaFunction* func)
+void QtDocGenerator::writeFunction(QTextStream &s, bool writeDoc, const AbstractMetaClass *cppClass, const AbstractMetaFunction* func)
{
writeFunctionSignature(s, cppClass, func);
s << endl;
@@ -1339,7 +1310,7 @@ void DocGenerator::writeFunction(QTextStream &s, bool writeDoc, const AbstractMe
}
}
-void DocGenerator::finishGeneration()
+void QtDocGenerator::finishGeneration()
{
if (classes().isEmpty())
return;
@@ -1383,9 +1354,8 @@ void DocGenerator::finishGeneration()
}
}
-bool DocGenerator::prepareGeneration(const QMap<QString, QString>& args)
+bool QtDocGenerator::doSetup(const QMap<QString, QString>& args)
{
- BoostPythonGenerator::prepareGeneration(args);
m_libSourceDir = args.value("library-source-dir");
setOutputDirectory(args.value("documentation-out-dir"));
m_docDataDir = args.value("documentation-data-dir");
@@ -1409,7 +1379,7 @@ bool DocGenerator::prepareGeneration(const QMap<QString, QString>& args)
}
-QMap<QString, QString> DocGenerator::options() const
+QMap<QString, QString> QtDocGenerator::options() const
{
QMap<QString, QString> options;
options.insert("library-source-dir", "Directory where library source code is located");
diff --git a/docgenerator.h b/generators/qtdoc/qtdocgenerator.h
index 225b429b4..b312d4455 100644
--- a/docgenerator.h
+++ b/generators/qtdoc/qtdocgenerator.h
@@ -23,11 +23,16 @@
#ifndef DOCGENERATOR_H
#define DOCGENERATOR_H
-#include "boostpythongenerator.h"
#include <QtCore/QStack>
+#include <QtCore/QHash>
+#include <QtCore/QTextStream>
+#include <apiextractor/abstractmetalang.h>
+#include "generator.h"
+class AbstractMetaFunction;
+class AbstractMetaClass;
class QXmlStreamReader;
-class DocGenerator;
+class QtDocGenerator;
class QtXmlToSphinx
{
@@ -77,7 +82,7 @@ public:
bool m_normalized;
};
- QtXmlToSphinx(DocGenerator* generator, const QString& doc, const QString& context = QString());
+ QtXmlToSphinx(QtDocGenerator* generator, const QString& doc, const QString& context = QString());
QString result() const
{
@@ -128,7 +133,7 @@ private:
Table m_currentTable;
bool m_tableHasHeader;
QString m_context;
- DocGenerator* m_generator;
+ QtDocGenerator* m_generator;
bool m_insideBold;
bool m_insideItalic;
QString m_lastTagName;
@@ -150,24 +155,19 @@ QTextStream& operator<<(QTextStream& s, const QtXmlToSphinx::Table &table);
/**
* The DocGenerator generates documentation from library being binded.
*/
-class DocGenerator : public BoostPythonGenerator
+class QtDocGenerator : public Generator
{
public:
- virtual GeneratorType type() const
- {
- return DocumentationType;
- }
-
QString libSourceDir() const
{
return m_libSourceDir;
}
- virtual bool prepareGeneration(const QMap<QString, QString>& args);
+ bool doSetup(const QMap<QString, QString>& args);
const char* name() const
{
- return "DocGenerator";
+ return "QtDocGenerator";
}
QMap<QString, QString> options() const;
@@ -181,6 +181,15 @@ protected:
QString fileNameForClass(const AbstractMetaClass* cppClass) const;
void generateClass(QTextStream& s, const AbstractMetaClass* cppClass);
void finishGeneration();
+
+ void writeFunctionArguments(QTextStream&, const AbstractMetaFunction*, uint) const {}
+ void writeArgumentNames(QTextStream&, const AbstractMetaFunction*, uint) const {}
+ QString subDirectoryForClass(const AbstractMetaClass* clazz) const
+ {
+ Q_ASSERT(false);
+ return QString();
+ }
+
private:
void writeEnums(QTextStream& s, const AbstractMetaClass* cppClass);
diff --git a/main.cpp b/main.cpp
index 9560effc6..f419bab4f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -21,32 +21,186 @@
*
*/
-#include <QtCore/QCoreApplication>
+#include <QCoreApplication>
+#include <QLinkedList>
+#include <QLibrary>
+#include <iostream>
#include <apiextractor/apiextractor.h>
-#include "hppgenerator.h"
-#include "cppgenerator.h"
-#include "hppgenerator.h"
-#include "convertergenerator.h"
-#include "docgenerator.h"
#include "boostpythongeneratorversion.h"
-#include <iostream>
+#include "generator.h"
-void showVersion(const char* apiextractor_version) {
- using namespace std;
+#if defined(Q_OS_WIN32)
+ #define PATH_SPLITTER ";"
+#else
+ #define PATH_SPLITTER ":"
+#endif
- cout << "BoostPythonGenerator v" BOOSTPYTHONGENERATOR_VERSION << " using " << apiextractor_version << endl;
- cout << "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)" << endl;
+
+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;
+ }
+}
+
+typedef QLinkedList<Generator*> (*getGeneratorsFunc)();
+
+QMap<QString, QString> getCommandLineArgs(int argc, char** argv)
+{
+ QMap<QString, QString> args;
+ 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)
+ args[arg.mid(2).left(split-2)] = arg.mid(split + 1).trimmed();
+ else
+ args[arg.mid(2)] = QString();
+ } else if (arg.startsWith("-")) {
+ args[arg.mid(1)] = QString();
+ } else {
+ argNum++;
+ args[QString("arg-%1").arg(argNum)] = arg;
+ }
+ }
+ return args;
+}
+
+void printUsage(const GeneratorList& generators)
+{
+ QTextStream s(stdout);
+ s << "Usage:\n "
+ << "generator [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>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]", "Include paths used by the C++ parser");
+ generalOptions.insert("typesystem-paths=<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]", "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");
+ generalOptions.insert("generatorSet", "generatorSet to be used. e.g. boostpython");
+ printOptions(s, generalOptions);
+
+ foreach (Generator* generator, generators) {
+ QMap<QString, QString> options = generator->options();
+ if (!options.isEmpty()) {
+ s << endl << generator->name() << " options:\n";
+ printOptions(s, generator->options());
+ }
+ }
}
int main(int argc, char *argv[])
{
- QCoreApplication app(argc, argv); // needed by qxmlpatterns
-
- ApiExtractor extractor(argc, argv);
- extractor.addGenerator(new HppGenerator);
- extractor.addGenerator(new CppGenerator);
- extractor.addGenerator(new ConverterGenerator);
- extractor.addGenerator(new DocGenerator);
- extractor.setVersionHandler(&showVersion);
- return extractor.exec();
+ // needed by qxmlpatterns
+ QCoreApplication app(argc, argv);
+
+ // Store command arguments in a map
+ QMap<QString, QString> args = getCommandLineArgs(argc, argv);
+ GeneratorList generators;
+
+ if (args.contains("version")) {
+ std::cout << "generator v" BOOSTPYTHONGENERATOR_VERSION << std::endl;
+ std::cout << "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)" << std::endl;
+ return EXIT_SUCCESS;
+ }
+
+ // Try to load a generator
+ QString generatorSet = args.value("generatorSet");
+ if (!generatorSet.isEmpty()) {
+ QLibrary plugin(generatorSet+"_generator");
+ getGeneratorsFunc getGenerators = reinterpret_cast<getGeneratorsFunc>(plugin.resolve("getGenerators"));
+ if (getGenerators)
+ generators = getGenerators();
+ else {
+ std::cerr << argv[0] << ": Error loading generatorset plugin: " << qPrintable(plugin.errorString()) << std::endl;
+ return EXIT_FAILURE;
+ }
+ } else if (!args.contains("help")) {
+ std::cerr << argv[0] << ": You need to specify a generator with --generatorSet=GENERATOR_NAME" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (args.contains("help")) {
+ printUsage(generators);
+ return EXIT_SUCCESS;
+ }
+
+
+ QString licenseComment;
+ if (args.contains("license-file") && !args.value("license-file").isEmpty()) {
+ QString licenseFileName = args.value("license-file");
+ if (QFile::exists(licenseFileName)) {
+ QFile licenseFile(licenseFileName);
+ if (licenseFile.open(QIODevice::ReadOnly))
+ licenseComment = licenseFile.readAll();
+ } else {
+ std::cerr << "Couldn't find the file containing the license heading: ";
+ std::cerr << qPrintable(licenseFileName) << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ // Create and set-up API Extractor
+ ApiExtractor extractor;
+
+ if (args.contains("silent")) {
+ extractor.setSilent(true);
+ } else if (args.contains("debug-level")) {
+ QString level = args.value("debug-level");
+ if (level == "sparse")
+ extractor.setDebugLevel(ReportHandler::SparseDebug);
+ else if (level == "medium")
+ extractor.setDebugLevel(ReportHandler::MediumDebug);
+ else if (level == "full")
+ extractor.setDebugLevel(ReportHandler::FullDebug);
+ }
+ if (args.contains("no-suppress-warnings"))
+ extractor.setSuppressWarnings(false);
+
+ if (args.contains("typesystem-paths"))
+ extractor.addTypesystemSearchPath(args.value("typesystem-paths").split(PATH_SPLITTER));
+ if (!args.value("include-paths").isEmpty())
+ extractor.addIncludePath(args.value("include-paths").split(PATH_SPLITTER));
+
+
+ QString cppFileName = args.value("arg-1");
+ QString typeSystemFileName = args.value("arg-2");
+ if (args.contains("arg-3")) {
+ std::cerr << "Too many arguments!" << std::endl;
+ return EXIT_FAILURE;
+ }
+ extractor.setCppFileName(cppFileName);
+ extractor.setTypeSystem(typeSystemFileName);
+ extractor.run();
+
+ if (!extractor.classCount()) {
+ std::cerr << "No C++ classes found!" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+
+ QString outputDirectory = args.contains("output-directory") ? args["output-directory"] : "out";
+ foreach (Generator* g, generators) {
+ g->setOutputDirectory(outputDirectory);
+ g->setLicenseComment(licenseComment);
+ if (g->setup(extractor, args))
+ g->generate();
+ }
+
+ std::cout << "Done, " << ReportHandler::warningCount();
+ std::cout << " warnings (" << ReportHandler::suppressedCount() << " known issues)";
+ std::cout << std::endl;
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 9099adff8..b4fba105d 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -3,7 +3,7 @@ project(sphinxtabletest)
# TODO
set(sphinxtabletest_SRC sphinxtabletest.cpp)
qt4_automoc(${sphinxtabletest_SRC})
-include_directories(${QT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${boostpythongenerator_SOURCE_DIR})
+include_directories(${QT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${qtdoc_generator_SOURCE_DIR})
add_executable(sphinxtabletest ${sphinxtabletest_SRC})
-target_link_libraries(sphinxtabletest ${QT_QTTEST_LIBRARY} ${APIEXTRACTOR_LIBRARY} libboostpythongenerator)
+target_link_libraries(sphinxtabletest ${QT_QTTEST_LIBRARY} ${APIEXTRACTOR_LIBRARY} qtdoc_generator genrunner)
add_test("sphinxtable" sphinxtabletest)
diff --git a/tests/sphinxtabletest.cpp b/tests/sphinxtabletest.cpp
index 058a3b522..a35d11926 100644
--- a/tests/sphinxtabletest.cpp
+++ b/tests/sphinxtabletest.cpp
@@ -22,7 +22,7 @@
*/
#include "sphinxtabletest.h"
-#include "docgenerator.h"
+#include "qtdocgenerator.h"
#include <QtTest/QTest>
#include <QDebug>
@@ -33,7 +33,7 @@ QString SphinxTableTest::transformXml(const char* xml)
void SphinxTableTest::setUp()
{
- m_generator = new DocGenerator;
+ m_generator = new QtDocGenerator;
}
void SphinxTableTest::tearDown()
diff --git a/tests/sphinxtabletest.h b/tests/sphinxtabletest.h
index 163cc5337..57d8937d0 100644
--- a/tests/sphinxtabletest.h
+++ b/tests/sphinxtabletest.h
@@ -26,7 +26,7 @@
#include <QObject>
-class DocGenerator;
+class QtDocGenerator;
class SphinxTableTest : public QObject {
Q_OBJECT
@@ -40,7 +40,7 @@ private slots:
void testComplexTable();
void testRowSpan2();
private:
- DocGenerator* m_generator;
+ QtDocGenerator* m_generator;
QString transformXml(const char* xml);
};