From ae3abca2b15794bdde313eed3f7f9391cd68f72d Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Mon, 26 Oct 2009 09:31:08 -0300 Subject: forked boostpythongenerator project to separate the generatorrunner so that it could be used independently; the qtdoc generator module remained part of generatorrunner --- CMakeLists.txt | 2 +- ChangeLog | 7 +- Doxyfile | 10 +- boostpythongenerator.1 | 1 - doc/Makefile | 4 +- doc/_templates/index.html | 16 +- doc/compiling/cmake-primer.rst | 2 +- doc/compiling/setup-generator.rst | 17 +- doc/conf.py | 6 +- doc/overview.rst | 2 +- doc/tutorial/bindinglibfoo.rst | 77 -- doc/tutorial/buildingthebinding.rst | 132 -- doc/tutorial/globalheader.rst | 36 - doc/tutorial/images/generatorworkings.png | Bin 37257 -> 0 bytes doc/tutorial/images/generatorworkings.svg | 392 ------ doc/tutorial/introduction.rst | 32 - doc/tutorial/libfoo.rst | 68 - doc/tutorial/typesystemcreation.rst | 135 -- generatorrunner.1 | 22 +- generatorrunner.pc.in | 4 +- generators/CMakeLists.txt | 1 - generators/boostpython/CMakeLists.txt | 19 - generators/boostpython/boostpython.cpp | 29 - generators/boostpython/boostpythongenerator.cpp | 321 ----- generators/boostpython/boostpythongenerator.h | 124 -- generators/boostpython/convertergenerator.cpp | 178 --- generators/boostpython/convertergenerator.h | 77 -- generators/boostpython/cppgenerator.cpp | 1560 ----------------------- generators/boostpython/cppgenerator.h | 107 -- generators/boostpython/hppgenerator.cpp | 220 ---- generators/boostpython/hppgenerator.h | 51 - generators/boostpython/main.cpp | 34 - generators/qtdoc/main.cpp | 2 +- generators/qtdoc/qtdocgenerator.cpp | 2 +- generators/qtdoc/qtdocgenerator.h | 2 +- main.cpp | 4 +- tests/CMakeLists.txt | 9 - tests/Makefile | 12 - tests/foo_test.py | 105 -- tests/foobinding/Makefile | 13 - tests/foobinding/foo/Makefile | 21 - tests/foobinding/global.h | 2 - tests/foobinding/typesystem_foo.xml | 6 - tests/libfoo/Makefile | 15 - tests/libfoo/bar.cpp | 15 - tests/libfoo/bar.h | 15 - tests/libfoo/foo.cpp | 17 - tests/libfoo/foo.h | 14 - tests/libfoo/main.cpp | 15 - tests/sphinxtabletest.cpp | 269 ---- tests/sphinxtabletest.h | 48 - 51 files changed, 47 insertions(+), 4225 deletions(-) delete mode 120000 boostpythongenerator.1 delete mode 100644 doc/tutorial/bindinglibfoo.rst delete mode 100644 doc/tutorial/buildingthebinding.rst delete mode 100644 doc/tutorial/globalheader.rst delete mode 100644 doc/tutorial/images/generatorworkings.png delete mode 100644 doc/tutorial/images/generatorworkings.svg delete mode 100644 doc/tutorial/introduction.rst delete mode 100644 doc/tutorial/libfoo.rst delete mode 100644 doc/tutorial/typesystemcreation.rst delete mode 100644 generators/boostpython/CMakeLists.txt delete mode 100644 generators/boostpython/boostpython.cpp delete mode 100644 generators/boostpython/boostpythongenerator.cpp delete mode 100644 generators/boostpython/boostpythongenerator.h delete mode 100644 generators/boostpython/convertergenerator.cpp delete mode 100644 generators/boostpython/convertergenerator.h delete mode 100644 generators/boostpython/cppgenerator.cpp delete mode 100644 generators/boostpython/cppgenerator.h delete mode 100644 generators/boostpython/hppgenerator.cpp delete mode 100644 generators/boostpython/hppgenerator.h delete mode 100644 generators/boostpython/main.cpp delete mode 100644 tests/CMakeLists.txt delete mode 100644 tests/Makefile delete mode 100644 tests/foo_test.py delete mode 100644 tests/foobinding/Makefile delete mode 100644 tests/foobinding/foo/Makefile delete mode 100644 tests/foobinding/global.h delete mode 100644 tests/foobinding/typesystem_foo.xml delete mode 100644 tests/libfoo/Makefile delete mode 100644 tests/libfoo/bar.cpp delete mode 100644 tests/libfoo/bar.h delete mode 100644 tests/libfoo/foo.cpp delete mode 100644 tests/libfoo/foo.h delete mode 100644 tests/libfoo/main.cpp delete mode 100644 tests/sphinxtabletest.cpp delete mode 100644 tests/sphinxtabletest.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a9a72b53..58e376f7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,4 +76,4 @@ install(FILES ${manpages} DESTINATION share/man/man1) enable_testing() add_subdirectory(generators) -add_subdirectory(tests) + diff --git a/ChangeLog b/ChangeLog index 270aadd78..e9b5feaac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,14 @@ +2009-10-26 Marcelo Lira + + * moved BoostPythonGenerator out of GeneratorRunner and created + a separated project for the latter. + 2009-09-28 Hugo Lima * main.cpp: reinterpert_cast replaced by a C-style cast, to avoid compiler errors on some plataforms. Cast an object pointer to a function pointer is an undefinied behaviour in some exotic platforms, so some compiler raise a - flag against it. However if we use a C-style cast the compiler ignores it. + flag against it. However if we use a C-style cast the compiler ignores it. This problem is related to the QLibrary API returning a void* instead of a generic function pointer. diff --git a/Doxyfile b/Doxyfile index f5e8d73fe..9be56a0e4 100644 --- a/Doxyfile +++ b/Doxyfile @@ -4,7 +4,7 @@ # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "Boost Python Generator Backend" +PROJECT_NAME = "Generator Runner" PROJECT_NUMBER = 0.1 OUTPUT_DIRECTORY = doc CREATE_SUBDIRS = NO @@ -25,7 +25,7 @@ ABBREVIATE_BRIEF = "The $name class" \ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES -STRIP_FROM_PATH = /tmp/src/boostbackend/ +STRIP_FROM_PATH = /tmp/src/generatorrunner/ STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES @@ -94,7 +94,7 @@ WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = /tmp/src/boostbackend +INPUT = /tmp/src/generatorrunner INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.cc \ @@ -270,8 +270,8 @@ SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- -TAGFILES = ../libgenerator/libgenerator.tag=../libgenerator -GENERATE_TAGFILE = boostbackend.tag +TAGFILES = ../libgenrunner/libgenrunner.tag=../libgenrunner +GENERATE_TAGFILE = generatorrunner.tag ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl diff --git a/boostpythongenerator.1 b/boostpythongenerator.1 deleted file mode 120000 index c65282f98..000000000 --- a/boostpythongenerator.1 +++ /dev/null @@ -1 +0,0 @@ -generatorrunner.1 \ No newline at end of file diff --git a/doc/Makefile b/doc/Makefile index f9fe2f01c..ec5c4d5b9 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -60,9 +60,9 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in _build/qthelp, like this:" - @echo "# qcollectiongenerator _build/qthelp/BoostPythonGenerator.qhcp" + @echo "# qcollectiongenerator _build/qthelp/GeneratorRunner.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile _build/qthelp/BoostPythonGenerator.qhc" + @echo "# assistant -collectionFile _build/qthelp/GeneratorRunner.qhc" latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex diff --git a/doc/_templates/index.html b/doc/_templates/index.html index 7bb17efdd..c24fce100 100644 --- a/doc/_templates/index.html +++ b/doc/_templates/index.html @@ -2,16 +2,14 @@ {% set title = 'Overview' %} {% block body %}
-

BoostPythonGenerator {{ version }}

+

GeneratorRunner {{ version }}

-

BoostPythonGenerator is a tool that eases the development of Python bindings for Qt-based - libraries by automating most of the process. It relies heavily on the ApiExtractor library - to parse the header files and manipulate the classes information while generating the code. - This generated code uses the - Boost::Python library - in order to bridge the C++ library and Python.

+

GeneratorRunner is a tool that eases the development of binding generators for C++ and Qt-based + libraries by providing a framework to help automating most of the process. It uses the + ApiExtractor library to parse the header files and manipulate the classes information while + generating the binding code using front-end modules provided by the user. -

BoostPythonGenerator is based on the +

GeneratorRunner is based on the QtScriptGenerator project.

Documentation

@@ -24,7 +22,7 @@ + how to compile and install GeneratorRunner

diff --git a/doc/compiling/cmake-primer.rst b/doc/compiling/cmake-primer.rst index 7769005be..499b8433a 100644 --- a/doc/compiling/cmake-primer.rst +++ b/doc/compiling/cmake-primer.rst @@ -6,7 +6,7 @@ CMake primer ************ This chapter is a basic introduction to CMake, the build system used by PySide -and the boost binding generator. +and the binding generator runner. The practical steps will focus on how to use cmake on a Unix-like (GNU/Linux) environment. diff --git a/doc/compiling/setup-generator.rst b/doc/compiling/setup-generator.rst index d58f98368..2118a352c 100644 --- a/doc/compiling/setup-generator.rst +++ b/doc/compiling/setup-generator.rst @@ -1,17 +1,18 @@ -.. _boost-python-generator: +.. _generatorrunner: -*********************** -Boost::Python Generator -*********************** +**************** +Generator Runner +**************** Overview ========================================= -The **Boost::Python Generator** (A.K.A. :program:`boostpythongenerator`) is -the program that creates the bindings source files from Qt headers and -auxiliary files (typesystems, ``global.h`` and glue files). It makes -heavy use of the :ref:`api-extractor` library. +The **GeneratorRunner** (A.K.A. :program:`generatorrunner`) is +the program that collects relevant data from C++ headers (paying +special attention to Qt provided information, like signals and +properties) and auxiliary files (typesystems, ``global.h`` and +glue files). For this it relies on the :ref:`api-extractor` library. Getting the sources diff --git a/doc/conf.py b/doc/conf.py index 4d4df5d7c..12cbcd5f1 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# BoostPythonGenerator documentation build configuration file, created by +# GeneratorRunner documentation build configuration file, created by # sphinx-quickstart on Wed Apr 22 15:04:20 2009. # # This file is execfile()d with the current directory set to its containing dir. @@ -25,7 +25,7 @@ import sys, os extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig', 'sphinx.ext.refcounting', 'sphinx.ext.coverage'] rst_epilog = """ -.. |project| replace:: BoostPythonGenerator +.. |project| replace:: GeneratorRunner """ # Add any paths that contain templates here, relative to this directory. @@ -41,7 +41,7 @@ source_encoding = 'utf-8' #master_doc = 'contents' # General information about the project. -project = u'BoostPythonGenerator' +project = u'GeneratorRunner' copyright = u'2009, Nokia Corporation' # The version info for the project you're documenting, acts as replacement for diff --git a/doc/overview.rst b/doc/overview.rst index 122019760..6191c0edb 100644 --- a/doc/overview.rst +++ b/doc/overview.rst @@ -20,7 +20,7 @@ Each module of the generator system has an specific role. 1. Provide enough data about the classes and functions. 2. Generate valid code, with modifications from typesystems and injected codes. -3. Modify the API to expose the objects in a Python-friendly way. +3. Modify the API to expose the objects in a way that fits you target language best. 4. Insert customizations where handwritten code is needed. .. figure:: images/boostqtarch.png diff --git a/doc/tutorial/bindinglibfoo.rst b/doc/tutorial/bindinglibfoo.rst deleted file mode 100644 index 87b7e482a..000000000 --- a/doc/tutorial/bindinglibfoo.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. highlight:: xml - -.. _gentut-bindinglibfoo: - -Binding libfoo with the Generator -================================= - -In order to create bindings for a library based on Qt4 a number of components -must be available on the system. - - + Qt4 library (with headers and pkg-config .pc files for development -- the - ``-dev`` packages in a Debian distribution). - + Qt4 Python bindings made with :program:`boostpythongenerator`. - + Typesystems for the Qt4 Python bindings. - + Headers for the library to be bound. - -With the items listed above the developer must write the components from -where the generator will gather information to create the binding source code. - - + Typesystem file describing the way the binding must be done. - + **global.h** including all the **libfoo** headers and defining required macros. - + A build system to direct the process of generating, compiling and linking the - binding. - -The directory structure for the binding project could be something like the tree -shown below: - -:: - - foobinding/ - |-- data/ - `-- module_dir/ - `-- glue/ - - -The **data** directory should contain the **global.h** and the typesystem -file. This typesystem need to refer to the ones used to create the Qt4 bindings, -commonly located on **/usr/share/PySide/typesystem**, the exact location -can be checked with pkg-config: - -:: - - $ pkg-config pyside --variable=typesystemdir - - -The **module_dir** directory is the place where the sources generated should -be placed. It starts empty except for the build instructions file (Makefile, -Makefile.am, CMakeLists.txt, etc). The realname of this directory must be the -same written in the typesystem file: - -:: - - - - -If there is any need for handwritten source code longer than a couple of lines, -making them unconfortable to be put on the typesystem xml file, the sources -could be orderly placed in a **glue** directory, also referred in the -new binding typesystem. - -When writing the typesystem file (more on this later) there is no need to refer -to the other required typesystem files with absolute paths, the locations where -they can be found could be passed to the generator through a command line -option (``--typesystem-paths=PATH1:PATH2:[...]``) or the environment variable -**TYPESYSTEMPATH**. - -For **libfoo** no glue code will be needed so this directory is not used, -the other directories are created with proper names. - -:: - - foobinding/ - |-- data/global.h - | `-- typesystem_foo.xml - `-- foo/ - `-- Makefile - diff --git a/doc/tutorial/buildingthebinding.rst b/doc/tutorial/buildingthebinding.rst deleted file mode 100644 index b5bec28e3..000000000 --- a/doc/tutorial/buildingthebinding.rst +++ /dev/null @@ -1,132 +0,0 @@ -.. _gentut-buildingthebinding: - -Building The Binding -==================== - -As mentioned before the build system used must perform the following tasks -in the correct order: - - + Gather data about locations of headers and external needed typesystems. - + Run the generator with the correct parameters. - + Compile and link the binding. - -The first and last are the usual, being the second the only novelty in the -process. - -Running the Generator ---------------------- - -The generator is called with the following parameters and options: - -:: - - $ boostpythongenerator global_headers.h \ - --include-paths=$(PATHS_TO_HEADERS)) \ - --typesystem-paths=$(PATHS_TO_TYPESYSTEMS) \ - --output-directory=. \ - typesystem.xml - -Notice that the variables for include and typesystem paths could be determined -at build time with the pkg-config tool. - -Collecting information with pkg-config -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Qt4 bindings include compile and build information through the pkg-config -mechanism. The pkg-config name for Qt4 Python bindings is **pyside** and a -simple ``pkg-config pyside --cflags --libs`` will retrieve the information -needed to build the new binding. - -The Qt4 bindings file ``pyside.pc`` for the use of pkg-config requires -the ``.pc`` files from Qt4 to be installed. If the library is in an unusual -location, e.g. ``/opt/qt45``, remember to export it to the ``PKG_CONFIG_PATH`` -environment variable. -For example: ``export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/qt45/lib/pkgconfig`` - -There is a vital information also available through pkg-config: -the **typesystemdir** variable. It is used like this: -``pkg-config pyside --variable=typesystemdir`` This provides information -where to find the typesystem files used to create the Qt4 bindings, and as said -before the binding being created needs this to complement its own binding -information for the generation proccess. - -Makefile --------- - -Below is a plain Makefile for the binding project. - -**foobinding/foo/Makefile** -:: - - LIBFOO_DIR = ../../libfoo - LIBS = -lboost_python `python-config --libs` \ - `pkg-config pyside --libs` \ - -lfoo -L$(LIBFOO_DIR) \ - -lpthread -ldl -lutil - CXXFLAGS = -I/usr/share/qt4/mkspecs/linux-g++ -I. \ - -I$(LIBFOO_DIR) \ - `pkg-config pyside --cflags` \ - -I`python-config --includes` \ - -I/usr/include/boost/python - QT4TYPESYSTEM_DIR = `pkg-config --variable=typesystemdir pyside` - QT4HEADER_DIRS = `pkg-config --variable=includedir QtCore`:`pkg-config --variable=includedir QtCore`/.. - - SOURCES = foo_globals_wrapper.cpp foo_module_wrapper.cpp math_wrapper.cpp - OBJECTS = foo_globals_wrapper.o foo_module_wrapper.o math_wrapper.o - - all: generate compile link - - generate: - boostpythongenerator ../data/global.h \ - --include-paths=$(LIBFOO_DIR):$(QT4HEADER_DIRS):/usr/include \ - --typesystem-paths=../data:$(QT4TYPESYSTEM_DIR) \ - --output-directory=.. \ - ../data/typesystem_foo.xml - - compile: $(SOURCES) - g++ -Wall -fPIC -DPIC $(CXXFLAGS) -c foo_globals_wrapper.cpp - g++ -Wall -fPIC -DPIC $(CXXFLAGS) -c foo_module_wrapper.cpp - g++ -Wall -fPIC -DPIC $(CXXFLAGS) -c math_wrapper.cpp - - link: - g++ -shared -Wl,-soname,foo.so -o foo.so $(LIBS) $(OBJECTS) - - test: - LD_LIBRARY_PATH=$(LIBFOO_DIR):$LD_LIBRARY_PATH python -c \ - "import PySide.QtCore; import foo; print dir(foo); m = foo.Math(); print \"5 squared is %d\" % m.squared(5)" - - clean: - rm -rf *.o *.so *.?pp *.log - - -Keep in mind that the Makefile above expects the ``libfoo`` and -``foobinding`` directories to be in the same level in the directory -hierarchy, remember to change any path references accordingly if -you choose to change things. - -**Warning:** - The order in which the link flags are passed matters. - **libboost_python** must come first, otherwise weeping - and gnashing of teeth will follow. - -Testing the Binding -------------------- -Now compile the binding with ``make``: - -:: - - $ cd foobinding/foo - $ make - -To test if the new binding is working (it can pass the build phase but still -blow up at runtime) start up a Python terminal and import it by the name. - -:: - - $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libfoo/shared/object/dir - $ export PYTHONPATH=$PYTHONPATH:/path/to/foo/python/module/file/dir - $ python - >> import foo - >> print dir(foo) - >> m = foo.Math() - >> print m.squared(5) diff --git a/doc/tutorial/globalheader.rst b/doc/tutorial/globalheader.rst deleted file mode 100644 index d1ac2392e..000000000 --- a/doc/tutorial/globalheader.rst +++ /dev/null @@ -1,36 +0,0 @@ -.. highlight:: cpp - -.. _gentut-globalheader: - -The Global Header -================= - -Besides the information provided by the typesystem, the generator needs to -gather more data from the library headers containing the classes to be exposed -in Python. If there is a header that include all the others (or just one, as is -the case of **libfoo**) this could be passed directly to the generator. - -If such a file is not available, or only a subset of the library is desired, or -if some flags must be defined before parsing the library headers, then a -``global.h`` file must be provided. - -The use of a ``global.h`` file is preferred if some macros must be defined -before the parser gather data from the headers. For example, if ``NULL`` is not -defined and it is used as a default paramater for some constructor or method, -the parser will not recognize it. - -The solve this create a ``global.h`` including all the desired headers and the -defined (and undefined) flags as follows: - -**foobinding/data/global.h** -:: - - #undef QT_NO_STL - #undef QT_NO_STL_WCHAR - - #ifndef NULL - #define NULL 0 - #endif - - #include - diff --git a/doc/tutorial/images/generatorworkings.png b/doc/tutorial/images/generatorworkings.png deleted file mode 100644 index d35a565ff..000000000 Binary files a/doc/tutorial/images/generatorworkings.png and /dev/null differ diff --git a/doc/tutorial/images/generatorworkings.svg b/doc/tutorial/images/generatorworkings.svg deleted file mode 100644 index 85a7782af..000000000 --- a/doc/tutorial/images/generatorworkings.svg +++ /dev/null @@ -1,392 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - bindingsource code - - - - - - - typesystemdescriptions - - - - customsourcecode - - - - - - libraryheaders - - - - - - Parser - - - - GeneratorBackend - - - - TypeDatabase - - - - - diff --git a/doc/tutorial/introduction.rst b/doc/tutorial/introduction.rst deleted file mode 100644 index 62372af1b..000000000 --- a/doc/tutorial/introduction.rst +++ /dev/null @@ -1,32 +0,0 @@ -Binding Generation Tutorial -*************************** - -This tutorial intends to describe the process of binding creation with -BoostPythonGenerator and using a very simple Qt4 based library will be used as an -example. - -The image below shows the inputs needed to generate the binding source code. - -.. image:: images/generatorworkings.png - -Putting in words, the user provides the headers for the library along with a -typesystem file describing how the classes will be exposed in the target -language, as well as any needed custom source code to be merged with -the generated source code. - -This tutorial will go through the steps needed to have the binding -being able to be imported and used from a Python program. The tutorial -source code is available as a tar ball `here <../_static/bindingexample.tar.bz2>`_. - -**NOTE:** the binding generator is intended to be used with Qt4 based libraries -only, at least for the time being. - -.. toctree:: - :maxdepth: 3 - - libfoo - bindinglibfoo - typesystemcreation - globalheader - buildingthebinding - diff --git a/doc/tutorial/libfoo.rst b/doc/tutorial/libfoo.rst deleted file mode 100644 index 76246570d..000000000 --- a/doc/tutorial/libfoo.rst +++ /dev/null @@ -1,68 +0,0 @@ -.. highlight:: cpp - -.. _gentut-libfoo: - -Creating the foo library -========================= - -In this section it will be presented the code and the build instructions for a -very simple Qt4 based library. It will be used as the subject for this tutorial. - -The Source Code ---------------- - -There is only one class on this foo library plus a ``.pro`` file which means -that the build system used will be Trolltech's **qmake**. - -Put the files below in a directory called **libfoo**. Be aware that this -directory will be refered by the binding Makefile presented in a next section -of this tutorial. If you want to use other names or paths change the binding -Makefile accordingly. Blind copy'n'paste shortens your life. - -**libfoo/foo.h** -:: - - #ifndef FOO_H - #define FOO_H - - #include - - class Math : public QObject - { - Q_OBJECT - public: - Math() {} - virtual ~Math() {} - int squared(int x); - }; - #endif // FOO_H - - -**libfoo/foo.cpp** -:: - - #include "foo.h" - - int Math::squared(int x) - { - return x * x; - } - - -**libfoo/foo.pro** -:: - - TEMPLATE = lib - TARGET = foo - DEPENDPATH += . - INCLUDEPATH += . - HEADERS += foo.h - SOURCES += foo.cpp - -To build the lib: - -:: - - $ cd libfoo - $ qmake - $ make diff --git a/doc/tutorial/typesystemcreation.rst b/doc/tutorial/typesystemcreation.rst deleted file mode 100644 index ae33ccb9e..000000000 --- a/doc/tutorial/typesystemcreation.rst +++ /dev/null @@ -1,135 +0,0 @@ -.. highlight:: xml - -.. _gentut-typesystem: - -Creating the Typesystem Description -=================================== - -The typesystem is an specification used when mapping a C++ based library onto a -corresponding Python module. The specification is a handwritten XML document -listing the types that will be available in the generated binding, alterations -to classes and function signatures to better suit the target language, -and listing the components that should be rejected for the binding. - -**PySide** uses a typesystem format similar to the ones used by **QtJambi** and -**QtScript**, thoroughly described in the page *"The Qt Jambi Type System"*. [#]_ - -The divergences between **PySide** and QtScript/QtJambi typesystems will be -highlighted whenever they appear. Things to be aware of when writing -a typesystem will be also mentioned. - -Describing **libfoo** for Python Audiences ------------------------------------------- - -All typesystem files start with the root ``typesystem`` tag. The -``package`` attribute carries the name of the package as it will be seen -from Python. - -Right after that, all the typesystem files providing information required for -the generation process are included in the same fashion as header files in C. - -**foobinding/data/typesystem_foo.xml** -:: - - - - - - - - -The inclusion of other typesystem files is achieved with the -``load-typesystem`` tag. The ``generate`` attribute must be set to ``"no"`` -otherwise the generator will try to create more source code for the already -existing bindings included for reference. - -The C++ classes derived from **QObject** intended to be exposed in the target -language are described with ``object-type`` tags. - - -For this example binding just specifying the name of the class does the trick, -since the generator system will automatically catch the methods with arguments -and return value of types known. These types can be described in the same -typesystem file or in the ones referenced with the ``load-typesystem`` tag. - -In more complex situations method signatures can be changed or rejected with -other tags that can be checked out in the typesystem reference. - - -Other Common Cases and Differences ----------------------------------- - -What follows now is some common uses of the typesystem capabilities. All of them -can be seen in the Qt4 typesystem files. They are not used for this binding -tutorial example, so if you just want to have things working ASAP, move along. - -Templates -~~~~~~~~~ - -To ease the process of writing custom code for the binding, recurring pieces of -code can be turned generic with the typesystem template mechanism. -They are declared in a way similar to this snippet: - -:: - - - -And is used as in this example: - -:: - - - - - - -The ``typesystem_template.xml`` file from the Qt4 bindings can be used as a -good resource for examples of this. Check also the QtJambi documentation on -typesystem templates. [#]_ - -Non-QObject Derived Classes -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Even in a Qt4 based library it is common to find classes that doesn't -pertain to the QObject hierarchy, these must be declared as ``value-type``: - -:: - - - - -Unused Tags -~~~~~~~~~~~ - -Some tags defined in the QtScript/QtJambi typesystem has no effect in **PySide** -typesystem, they are: - - + conversion-rule - + argument-map - -Changes to ``"inject-code"`` Tag -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can pass a file name to the **inject-code** tag so the file contents will -be injected in the generated code. - -The ``class`` attribute value ``java`` was changed to ``target``, while -``native`` remained the same. - -Global Functions -~~~~~~~~~~~~~~~~ - -The BoostPythonGenerator supports global functions, you can also reject these functions using -the **rejection** tag like is done to reject classes. Just pass an empty string to -the class attribute. - -:: - - - - -.. [#] http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-typesystem.html -.. [#] http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-typesystem.html#using-code-templates diff --git a/generatorrunner.1 b/generatorrunner.1 index b1284c70c..c5ffc2413 100644 --- a/generatorrunner.1 +++ b/generatorrunner.1 @@ -9,27 +9,17 @@ generatorrunner \- plugin-based code generator is a utility that uses the information taken from APIExtractor related to the provided C++ headers and typesystem files and execute generators using this information. Generators are plugins and you need -to specify one using the --generatorSet parameter. At the moment there +to specify one using the --generatorSet parameter. At the moment there are two generators available: -.B boostpython -\- Generates Boost::Python-based wrappers that compound a Python binding -for the library described in the typesystem, making the C++ classes available -for Python developers. Can be called by supplying -.B --generatorSet=boostpython -to -.B generatorrunner -or by calling the convenience executable -.B boostpythongenerator. - .B qtdoc -\- Generates Sphinx-based documentation for C++ libraries documented using -.B qdoc3 -documentation syntax, using the XML files created by the documentation tool +\- Generates Sphinx-based documentation for C++ libraries documented using +.B qdoc3 +documentation syntax, using the XML files created by the documentation tool .B (qdoc3). Can be called supplying .B --generatorSet=qtdoc -to +to .B generatorrunner or by calling the convenience executable .B docgenerator. @@ -66,8 +56,6 @@ The directories where the generator will search for the external typesystems referred by the main one. .IP --version Displays the current version. -.SS "Specific to boostpython plugin" -.IP --disable-named-arg Drops support for named args. .SS "Specific to qtdoc plugin" .IP --documentation-code-snippets-dir diff --git a/generatorrunner.pc.in b/generatorrunner.pc.in index 20b800440..e7ec9841f 100644 --- a/generatorrunner.pc.in +++ b/generatorrunner.pc.in @@ -5,9 +5,9 @@ includedir=@CMAKE_INSTALL_PREFIX@/include Name: generatorrunner -Description: Python binding generator based on Boost.Python +Description: Generator Runner loads and calls binding generator front-ends. Requires: apiextractor -Version: @boostpythongenerator_VERSION@ +Version: @generatorrunner_VERSION@ Libs: -L${libdir} -lgenrunner Cflags: -I${includedir} diff --git a/generators/CMakeLists.txt b/generators/CMakeLists.txt index 73b5eea22..f26def274 100644 --- a/generators/CMakeLists.txt +++ b/generators/CMakeLists.txt @@ -1,2 +1 @@ -add_subdirectory(boostpython) add_subdirectory(qtdoc) diff --git a/generators/boostpython/CMakeLists.txt b/generators/boostpython/CMakeLists.txt deleted file mode 100644 index f94d800be..000000000 --- a/generators/boostpython/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -project(boostpython) - -set(boostpython_generator_SRC -boostpythongenerator.cpp -convertergenerator.cpp -cppgenerator.cpp -hppgenerator.cpp -boostpython.cpp -) - -add_executable(boostpythongenerator main.cpp) -target_link_libraries(boostpythongenerator ${QT_QTCORE_LIBRARY}) - -add_library(boostpython_generator SHARED ${boostpython_generator_SRC}) -target_link_libraries(boostpython_generator ${APIEXTRACTOR_LIBRARY} ${QT_QTCORE_LIBRARY} genrunner) - -install(TARGETS boostpython_generator DESTINATION ${generator_plugin_DIR}) -install(TARGETS boostpythongenerator DESTINATION bin) - diff --git a/generators/boostpython/boostpython.cpp b/generators/boostpython/boostpython.cpp deleted file mode 100644 index e165f93b9..000000000 --- a/generators/boostpython/boostpython.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* -* This file is part of the API Extractor project. -* -* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -* -* Contact: PySide team -* -* 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/generators/boostpython/boostpythongenerator.cpp b/generators/boostpython/boostpythongenerator.cpp deleted file mode 100644 index d266d395a..000000000 --- a/generators/boostpython/boostpythongenerator.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 "boostpythongenerator.h" -#include - -#include -#include -#include -#include -#include - -#define NULL_VALUE "NULL" -#define COMMENT_LINE_WIDTH 77 - -static Indentor INDENT; -static void dump_function(AbstractMetaFunctionList lst); - -QString BoostPythonGenerator::getWrapperName(const AbstractMetaClass* metaClass) -{ - QString result = metaClass->typeEntry()->qualifiedCppName().toLower(); - result.replace("::", "_"); - result += "_wrapper"; - return result; -} - -QString BoostPythonGenerator::argumentString(const AbstractMetaFunction *cppFunction, - const AbstractMetaArgument *cppArgument, - Options options) const -{ - QString modifiedType = cppFunction->typeReplaced(cppArgument->argumentIndex() + 1); - QString arg; - - if ((options & OriginalTypeDescription) || modifiedType.isEmpty()) - arg = translateType(cppArgument->type(), cppFunction->implementingClass(), options); - else - arg = modifiedType.replace('$', '.'); - - if (!(options & Generator::SkipName)) { - arg += " "; - arg += cppArgument->argumentName(); - } - - QList referenceCounts; - referenceCounts = cppFunction->referenceCounts(cppFunction->implementingClass(), cppArgument->argumentIndex() + 1); - if ((options & Generator::SkipDefaultValues) != Generator::SkipDefaultValues && - !cppArgument->defaultValueExpression().isEmpty()) { - QString defaultValue = cppArgument->defaultValueExpression(); - if (defaultValue == "NULL") - defaultValue = NULL_VALUE; - - //WORKAROUND: fix this please - if (defaultValue.startsWith("new ")) - defaultValue.remove(0, 4); - - arg += " = " + defaultValue; - } - - return arg; -} - -void BoostPythonGenerator::writeArgument(QTextStream &s, - const AbstractMetaFunction *func, - const AbstractMetaArgument *cppArgument, - Options options) const -{ - s << argumentString(func, cppArgument, options); -} - -void BoostPythonGenerator::writeFunctionArguments(QTextStream &s, - const AbstractMetaFunction *func, - Options options) const -{ - AbstractMetaArgumentList arguments = func->arguments(); - - if (options & Generator::WriteSelf) { - s << func->implementingClass()->name() << '&'; - if (!(options & SkipName)) - s << " self"; - } - - int argUsed = 0; - for (int i = 0; i < arguments.size(); ++i) { - if ((options & Generator::SkipRemovedArguments) && func->argumentRemoved(i + 1)) - continue; - - if ((options & Generator::WriteSelf) || argUsed) - s << ", "; - - writeArgument(s, func, arguments[i], options); - argUsed++; - } -} - -QString BoostPythonGenerator::functionReturnType(const AbstractMetaFunction* func, Options options) -{ - QString modifiedReturnType = QString(func->typeReplaced(0)); - if (!modifiedReturnType.isNull() && (!(options & OriginalTypeDescription))) - return modifiedReturnType; - else - return translateType(func->type(), func->implementingClass(), options); -} - -QString BoostPythonGenerator::functionSignature(const AbstractMetaFunction *func, - QString prepend, - QString append, - Options options, - int argCount) -{ - AbstractMetaArgumentList arguments = func->arguments(); - int argument_count = argCount < 0 ? arguments.size() : argCount; - - - QString result; - QTextStream s(&result); - // The actual function - if (!(func->isEmptyFunction() || - func->isNormal() || - func->isSignal())) { - options |= Generator::SkipReturnType; - } else { - s << functionReturnType(func, options) << ' '; - } - - // name - QString name(func->originalName()); - if (func->isConstructor()) - name = getWrapperName(func->ownerClass()); - - s << prepend << name << append << "("; - writeFunctionArguments(s, func, options); - s << ")"; - - if (func->isConstant() && (!(options & Generator::ExcludeMethodConst))) - s << " const"; - - return result; -} - -QString BoostPythonGenerator::signatureForDefaultVirtualMethod(const AbstractMetaFunction *cppFunction, - QString prepend, - QString append, - Options options, - int arg_count) -{ - QString defaultMethodSignature = functionSignature(cppFunction, prepend, append, options, arg_count); - QString staticSelf("("); - if (cppFunction->isConstant()) - staticSelf += "const "; - - staticSelf += cppFunction->ownerClass()->qualifiedCppName() + "& "; - if (!(options & SkipName)) - staticSelf += " self"; - - if (cppFunction->arguments().size() > 0) - staticSelf += ", "; - - defaultMethodSignature.replace(defaultMethodSignature.lastIndexOf(") const"), 7, ")"); - defaultMethodSignature.replace(defaultMethodSignature.indexOf('('), 1, staticSelf); - return defaultMethodSignature; -} - -void BoostPythonGenerator::writeArgumentNames(QTextStream &s, - const AbstractMetaFunction *func, - Options options) const -{ - AbstractMetaArgumentList arguments = func->arguments(); - int argCount = 0; - for (int j = 0, max = arguments.size(); j < max; j++) { - - if ((options & Generator::SkipRemovedArguments) && - (func->argumentRemoved(arguments.at(j)->argumentIndex() + 1))) { - continue; - } - - if (argCount > 0) - s << ", "; - - QString argName = arguments.at(j)->argumentName(); - if (((options & Generator::VirtualCall) == 0) && - (!func->conversionRule(TypeSystem::NativeCode, arguments.at(j)->argumentIndex() + 1).isEmpty() || - !func->conversionRule(TypeSystem::TargetLangCode, arguments.at(j)->argumentIndex() + 1).isEmpty()) - ) - argName += "_out"; - - if ((options & Generator::BoxedPrimitive) && - !arguments.at(j)->type()->isReference() && - (arguments.at(j)->type()->isQObject() || - arguments.at(j)->type()->isObject())) { - - s << "PySide::ptr( " << argName << ")"; - } else { - s << argName; - } - argCount++; - } -} - -void BoostPythonGenerator::writeFunctionCall(QTextStream &s, - const AbstractMetaFunction* func, - Options options) - -{ - if (!(options & Generator::SkipName)) - s << (func->isConstructor() ? func->ownerClass()->qualifiedCppName() : func->originalName()); - - s << '('; - writeArgumentNames(s, func, options); - s << ')'; -} - -void BoostPythonGenerator::writeCodeSnips(QTextStream &s, - const CodeSnipList &codeSnips, - CodeSnip::Position position, - TypeSystem::Language language, - const AbstractMetaFunction *func) -{ - Indentation indentation(INDENT); - foreach (CodeSnip snip, codeSnips) { - if ((snip.position != position) || - !(snip.language & language)) { - continue; - } - - QString code; - QTextStream tmpStream(&code); - formatCode(tmpStream, snip.code(), INDENT); - - if (func) - replaceTemplateVariables(code, func); - - s << code << endl; - } -} - -bool BoostPythonGenerator::canCreateWrapperFor(const AbstractMetaClass* cppClass) -{ - return !cppClass->hasPrivateDestructor() && !cppClass->isNamespace(); -} - - - -QStringList BoostPythonGenerator::getBaseClasses(const AbstractMetaClass *cppClass) -{ - QStringList baseClass; - - if (!cppClass->baseClassName().isEmpty() && - (cppClass->name() != cppClass->baseClassName())) { - baseClass.append(cppClass->baseClassName()); - } - - foreach (AbstractMetaClass *interface, cppClass->interfaces()) { - AbstractMetaClass *aux = interface->primaryInterfaceImplementor(); - if (!aux) - continue; - - //skip templates - if (aux->templateArguments().size() > 0) - continue; - - if (!aux->name().isEmpty() && (cppClass->qualifiedCppName() != aux->qualifiedCppName())) - baseClass.append(aux->qualifiedCppName()); - } - - return baseClass; -} - - -bool BoostPythonGenerator::isCopyable(const AbstractMetaClass *cppClass) -{ - if (cppClass->isNamespace()) - return false; - else if (cppClass->typeEntry()->copyable() == ComplexTypeEntry::Unknown) - return cppClass->hasCloneOperator(); - else - return (cppClass->typeEntry()->copyable() == ComplexTypeEntry::CopyableSet); - - return false; -} - -static void dump_function(AbstractMetaFunctionList lst) -{ - qDebug() << "DUMP FUNCTIONS: "; - foreach (AbstractMetaFunction *func, lst) { - qDebug() << "*" << func->ownerClass()->name() - << func->signature() - << "Private: " << func->isPrivate() - << "Empty: " << func->isEmptyFunction() - << "Static:" << func->isStatic() - << "Signal:" << func->isSignal() - << "ClassImplements: " << (func->ownerClass() != func->implementingClass()) - << "is operator:" << func->isOperatorOverload() - << "is global:" << func->isInGlobalScope(); - } -} - - -bool BoostPythonGenerator::doSetup(const QMap&) -{ - return true; -} diff --git a/generators/boostpython/boostpythongenerator.h b/generators/boostpython/boostpythongenerator.h deleted file mode 100644 index e41081f6d..000000000 --- a/generators/boostpython/boostpythongenerator.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 BOOSTPYTHONGENERATOR_H -#define BOOSTPYTHONGENERATOR_H - -#include -#include "generator.h" - -class DocParser; - -/** -* Abstract generator that contains common methods used in CppGenerator and HppGenerator. -*/ -class BoostPythonGenerator : public Generator -{ -public: - /** - * 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. - * \param boost_fuction the current metafunction. - * \param boost_argument metaargument information to be parsed. - * \param options some extra options. - */ - void writeArgument(QTextStream &s, - const AbstractMetaFunction *boost_function, - const AbstractMetaArgument *boost_argument, - Options options = NoOption) const; - /** - * Create a QString in the boost::python format to an function argument. - * \param boost_fuction the current metafunction. - * \param boost_argument metaargument information to be parsed. - * \param options some extra options. - */ - QString argumentString(const AbstractMetaFunction *boost_function, - const AbstractMetaArgument *boost_argument, - Options options = NoOption) const; - - void writeArgumentNames(QTextStream &s, - const AbstractMetaFunction *cpp_function, - Options options = NoOption) const; - - /** - * Function used to write the fucntion arguments on the class buffer. - * \param s the class output buffer - * \param boost_function the pointer to metafunction information - * \param count the number of function arguments - * \param options some extra options used during the parser - */ - void writeFunctionArguments(QTextStream &s, - const AbstractMetaFunction *boost_function, - Options options = NoOption) const; - QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption); - /** - * Write a code snip into the buffer \p s. - * CodeSnip are codes inside inject-code tags. - * \param s the buffer - * \param cpp_function the cpp function - * \param code_snips a list of code snips - * \param position the position to insert the code snip - * \param language the kind of code snip - */ - void writeCodeSnips(QTextStream &s, - const CodeSnipList &code_snips, - CodeSnip::Position position, - TypeSystem::Language language, - const AbstractMetaFunction *cpp_function = 0); - static bool canCreateWrapperFor(const AbstractMetaClass* cppClass); - /** - * Function witch parse the metafunction information - * \param cpp_function the function witch will be parserd - * \param option some extra options - * \param arg_count the number of function arguments - */ - QString functionSignature(const AbstractMetaFunction *boost_function, - QString prepend = "", - QString append = "", - Options options = NoOption, - int arg_count = -1); - - QString signatureForDefaultVirtualMethod(const AbstractMetaFunction *cpp_function, - QString prepend = "", - QString append = "_default", - Options = NoOption, - int arg_count = -1); - - QStringList getBaseClasses(const AbstractMetaClass* cppClass); - - static QString getWrapperName(const AbstractMetaClass* clazz); - - - virtual bool doSetup(const QMap& args); - -protected: - // verify if the class is copyalbe - bool isCopyable(const AbstractMetaClass *cpp_class); - - void writeFunctionCall(QTextStream &s, const AbstractMetaFunction *cpp_func, Options options = NoOption); -}; - - -#endif // BOOSTPYTHONGENERATOR_H - diff --git a/generators/boostpython/convertergenerator.cpp b/generators/boostpython/convertergenerator.cpp deleted file mode 100644 index 23a5d3601..000000000 --- a/generators/boostpython/convertergenerator.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 -#include -#include "convertergenerator.h" - -static Indentor INDENT; - -ConverterGenerator::ConverterGenerator() -{ - // QPair - m_conversions << qMakePair(QString("QPair<"), &m_qpairTypes); - // QList - m_conversions << qMakePair(QString("QList<"), &m_qlistTypes); - // QVector - m_conversions << qMakePair(QString("QVector<"), &m_qvectorTypes); - // QMap - m_conversions << qMakePair(QString("QMap<"), &m_qmapTypes); - // QHash - m_conversions << qMakePair(QString("QHash<"), &m_qhashTypes); - // QMultiMap - m_conversions << qMakePair(QString("QMultiMap<"), &m_qmultiMapTypes); - -} - -void ConverterGenerator::finishGeneration() -{ - if (!classes().size()) - return; - - QString fileOutPath; - - foreach (AbstractMetaClass *cls, classes()) { - if (!shouldGenerate(cls)) - continue; - - if (fileOutPath.isNull()) { - m_packageName = cls->package(); - fileOutPath = outputDirectory() + '/' + subDirectoryForClass(cls) - + "/converter_register_" + moduleName().toLower() + ".hpp"; - } - - foreach (AbstractMetaFunction* func, filterFunctions(cls)) - checkFunctionMetaTypes(func); - } - - FileOut fileOut(fileOutPath); - QTextStream& s = fileOut.stream; - - // write license comment - s << licenseComment() << endl; - - s << "#ifndef CONVERTERREGISTER_" << moduleName().toUpper() << "_HPP\n"; - s << "#define CONVERTERREGISTER_" << moduleName().toUpper() << "_HPP\n\n"; - - //Includes - QStringList includes; - foreach (AbstractMetaClass *cls, classes()) { - if (cls->typeEntry()->include().isValid()) { - QString include_file = cls->typeEntry()->include().toString(); - if (!includes.contains(include_file)) { - s << include_file << endl; - includes << include_file; - } - } - - if (cls->typeEntry()->generateCode()) { - QList extra_includes = cls->typeEntry()->extraIncludes(); - foreach (Include include, extra_includes) { - if (!includes.contains(include.toString())) { - s << include.toString() << endl; - includes << include.toString(); - } - } - } - } - - s << "#include \"type_converter.hpp\"\n\n"; - - s << "void register_type_converters_" << moduleName().toLower() << "()\n{\n"; - Indentation indent(INDENT); - writeConverterRegistration(s, "register_qpair_converter", "QPair", m_qpairTypes); - writeConverterRegistration(s, "register_container_converter", "QList", m_qlistTypes); - writeConverterRegistration(s, "register_container_converter", "QVector", m_qvectorTypes); - writeConverterRegistration(s, "register_dict_converter", "QMap", m_qmapTypes); - writeConverterRegistration(s, "register_dict_converter", "QHash", m_qhashTypes); - writeConverterRegistration(s, "register_multimap_converter", "QMultiMap", m_qmultiMapTypes); - s << "}\n\n"; - s << "#endif\n\n"; - - m_numGeneratedWritten = m_qpairTypes.size() + m_qlistTypes.size() + - m_qvectorTypes.size() + m_qmapTypes.size() + - m_qhashTypes.size(); -} - -void ConverterGenerator::writeConverterRegistration(QTextStream& out, - const QString& funcName, - const QString& type, - const QSet& params) -{ - foreach (QString param, params) { - QString completeType(QMetaObject::normalizedType( - (type + '<' + param + " >").toLatin1().data())); - out << INDENT << "PySide::" << funcName; - out << '<' << completeType << " >(\""; - out << completeType << "\");" << endl; - } -} - -void ConverterGenerator::checkFunctionMetaTypes(AbstractMetaFunction* func) -{ - if (func->type()) - checkMetaType(functionReturnType(func)); - - foreach (AbstractMetaArgument* arg, func->arguments()) { - if (arg->type()) - checkMetaType(argumentString(func, arg, Options(SkipName) | SkipDefaultValues)); - } -} - -// FIXME Use some AbstracyMetaAnything info instead of parse the cpp signature? -void ConverterGenerator::checkMetaType(const QString& cppSignature) -{ - QRegExp typeRegex("Q\\w+"); - - foreach (Conversion conv, m_conversions) { - int index = cppSignature.indexOf(conv.first); - if (index >= 0) { - QString templateArg = extractTemplateArgument(cppSignature.right(cppSignature.length() - index - conv.first.length())); - conv.second->insert(templateArg); - // detect types to generate includes - int offset = 0; - while ((offset = typeRegex.indexIn(templateArg, offset)) != -1) { - const QString cap(typeRegex.cap(0)); - offset += cap.length(); - } - } - } -} - -QString ConverterGenerator::extractTemplateArgument(const QString& templateParams) -{ - int stack = 0; - for (int i = 0; i < templateParams.length(); ++i) { - QChar c = templateParams[i]; - if (c == '<') { - stack++; - } else if (c == '>') { - stack--; - if (stack < 0) - return templateParams.left(i).trimmed(); - } - } - Q_ASSERT(false); - return QString(); -} - diff --git a/generators/boostpython/convertergenerator.h b/generators/boostpython/convertergenerator.h deleted file mode 100644 index 8f91377c0..000000000 --- a/generators/boostpython/convertergenerator.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 CONVERTERGENERATOR_H -#define CONVERTERGENERATOR_H - -// #include -#include -#include "boostpythongenerator.h" - -/** -* Generator for convertions between python collections and Qt collections. -* -* It generates a file called converter_register_MODULENAME.hpp with only one -* function called register_type_converters_MODULENAME, where MODULENAME is the current module name. -* QPair are converted to python tuples, QList, QVector and QLinkedList to python lists, QHash and QMap to python dicts. -*/ -class ConverterGenerator : public BoostPythonGenerator -{ -public: - ConverterGenerator(); - - const char* name() const - { - return "ConverterGenerator"; - } - -protected: - void generateClass(QTextStream& s, const AbstractMetaClass* clazz) - { - } - - void finishGeneration(); - QString fileNameForClass(const AbstractMetaClass* cppClass) const - { - return QString(); - } -private: - void checkFunctionMetaTypes(AbstractMetaFunction* func); - void checkMetaType(const QString& cppSignature); - QString extractTemplateArgument(const QString& templateParams); - - void writeConverterRegistration(QTextStream& out, const QString& func_name, const QString& type, const QSet& params); - - typedef QPair* > Conversion; - typedef QList ConversionList; - ConversionList m_conversions; - QSet m_qpairTypes; - QSet m_qlistTypes; - QSet m_qvectorTypes; - QSet m_qmapTypes; - QSet m_qhashTypes; - QSet m_qmultiMapTypes; -}; - -#endif // CONVERSIONGENERATOR_H - diff --git a/generators/boostpython/cppgenerator.cpp b/generators/boostpython/cppgenerator.cpp deleted file mode 100644 index f144e297a..000000000 --- a/generators/boostpython/cppgenerator.cpp +++ /dev/null @@ -1,1560 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 "cppgenerator.h" -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static Indentor INDENT; - -// utiliy functions -inline void writeConversionRule(QTextStream &s, TypeSystem::Language lang, const AbstractMetaFunction *function, const AbstractMetaArgument *arg) -{ - QString convRule = function->conversionRule(lang, arg->argumentIndex() + 1); - if (!convRule.isEmpty()) { - convRule.replace("%in", arg->argumentName()); - convRule.replace("%out", arg->argumentName() + "_out"); - s << convRule; - } -} - -inline QString getMethodPointerString(const AbstractMetaFunction* func) -{ - QString className; - if (!func->declaringClass()->isAbstract()) - className = func->declaringClass()->qualifiedCppName(); - else - className = func->ownerClass()->qualifiedCppName(); - - return '&' + className + "::" + func->originalName(); -} - -static QString nameForModifiedCtorFunction(const AbstractMetaFunction* func) { - QString res = func->ownerClass()->name().toLower().replace("::", "_"); - res += "_constructor"; - foreach (AbstractMetaArgument* arg, func->arguments()) { - res += '_'; - res += arg->type()->name().toLower(); - } - return res; -} - -static QString createStaticFunctionName(const AbstractMetaFunction* func) -{ - QString funcName; - QString originalName(func->name()); - - - funcName = func->ownerClass()->name().toLower(); - - //remove initial 'Q' - if (funcName.startsWith('q')) - funcName = funcName.remove(0, 1); - - //upercase first letter - funcName += originalName[0].toUpper() + originalName.mid(1); - - return funcName; -} - -QString CppGenerator::fileNameForClass(const AbstractMetaClass* cppClass) const -{ - return getWrapperName(cppClass) + QLatin1String(".cpp"); -} - -QString CppGenerator::getFuncTypedefName(const AbstractMetaFunction* func) const -{ - return func->name() + QLatin1String("_type"); -} - -void CppGenerator::writeConstructorInitialization(QTextStream &s, const AbstractMetaFunction *function) -{ - QStringList nonOpts; - QStringList opts; - - Options options = Options(SkipName) | SkipDefaultValues; - foreach (AbstractMetaArgument *arg, function->arguments()) { - QString argType = argumentString(function, arg, options); - if (arg->defaultValueExpression().isEmpty()) - nonOpts << argType; - else - opts << argType; - } - - bool hasModifications = function->allowThread() || function->hasInjectedCode(); - - if (hasModifications) { - s << "\"__init__\", python::make_constructor(" - << nameForModifiedCtorFunction(function); - } else { - s << "python::init< "; - - if (nonOpts.size() > 0) - s << nonOpts.join(", "); - - if (opts.size() > 0) { - if (nonOpts.size() > 0) - s << ", "; - - s << "python::optional< " << opts.join(",") << " > "; - } - - s << " > ()"; - } - - QString callPolicy = getFunctionCallPolicy(function); - QString parentType; - const AbstractMetaClass *cppClass = function->ownerClass(); - uint closePolicy = 0; - bool hasPolicy = false; - - if ( - !hasModifications && - (!cppClass->isPolymorphic() || cppClass->hasPrivateDestructor() || cppClass->isNamespace()) - ) { - closePolicy++; - hasPolicy = true; - s << "[ PySide::register_wrapper_object< " - << function->ownerClass()->qualifiedCppName(); - } - - if (callPolicy.isEmpty()) { - int parentIndex = -1; - //try find for parent arg to create callPolicy - foreach (AbstractMetaArgument *arg, function->arguments()) { - if (arg->argumentName() == "parent") { - parentIndex = arg->argumentIndex(); - parentType = translateType(arg->type(), function->ownerClass(), - Options(ExcludeConst) | ExcludeReference).replace("*", ""); - break; - } - } - if (parentIndex != -1) { - if (!closePolicy) - s << (hasModifications ? ", " : "[ "); - else - s << ", "; - - s << "parent_policy_add< " << parentIndex + 2 << ", 1, " - << parentType << " , " << function->ownerClass()->qualifiedCppName(); - - hasPolicy = true; - closePolicy++; - } - } else { - if (!closePolicy) - s << (hasModifications ? ", " : "[ "); - else - s << ", "; - - if (callPolicy.endsWith("()")) - callPolicy = callPolicy.remove(callPolicy.size() - 2, 2); - - s << callPolicy; - hasPolicy = true; - } - - while(closePolicy) { - s << " > "; - closePolicy--; - } - - if (hasModifications) - s << ')'; - else if (hasPolicy) - s << "() ]"; -} - -QString CppGenerator::getFunctionReturnType(const AbstractMetaFunction* func) -{ - QString modifiedReturnType = QString(func->typeReplaced(0)); - - return modifiedReturnType.isNull() ? translateType(func->type(), func->implementingClass()) : modifiedReturnType; -} - -QString CppGenerator::writeFunctionCast(QTextStream &s, - const AbstractMetaFunction* func, - const QString& castNameSuffix, - const QString& className) -{ - QString castName = getFuncTypedefName(func) + castNameSuffix; - const AbstractMetaClass* cppClass = func->ownerClass(); - bool isWrapped = !func->isVirtual() && - (func->hasInjectedCode() || func->isThread() || func->allowThread()); - bool isVirtualMethodDefault = castNameSuffix == "_default"; - - s << INDENT << "typedef "; - s << getFunctionReturnType(func); - s << " ("; - if (cppClass && !func->isStatic() && func->ownerClass() && !isVirtualMethodDefault) { - if (!isWrapped) { - // pointer to a class method - if (!className.isEmpty()) - s << className; - else if (func->isVirtual() && !func->declaringClass()->isAbstract()) - s << func->declaringClass()->qualifiedCppName(); - else - s << cppClass->qualifiedCppName(); - - s << "::"; - } - } - - s << '*' << castName << ") ("; - if (isVirtualMethodDefault) { - if (func->isConstant()) - s << "const "; - - s << func->implementingClass()->qualifiedCppName() << "&"; - if (func->arguments().size() > 0) - s << ", "; - } - Options options = Options(SkipName) | SkipDefaultValues | SkipRemovedArguments; - if (isWrapped && !func->isStatic()) - options |= WriteSelf; - - writeFunctionArguments(s, func, options); - s << ')'; - - if (func->isConstant() && !isWrapped && !isVirtualMethodDefault) - s << " const"; - - s << ';' << endl; - - return castName; -} - -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(); - } - - QString returnPolicy; - - if (type->isReference()) { - QString detail; - if (type->isConstant()) { - detail = "copy_const_reference"; - } else { - detail = "copy_non_const_reference"; - } - - returnPolicy = "python::return_value_policyisQObject() || type->isObject() || type->isValuePointer()) { - bool cppOwnership = type->isConstant(); - if (cppFunction->isStatic() || cppOwnership) { - returnPolicy = QString("python::return_value_policy >()"); - } else { - returnPolicy = QString("PySide::return_object<1, 0, %1, %2 %3 %4 >()") - .arg(getArgumentType(cppFunction->ownerClass(), cppFunction, -1)) - .arg(getArgumentType(cppFunction->ownerClass(), cppFunction, 0)) - .arg(callPolicy.isEmpty() ? "" : ",") - .arg(callPolicy); - } - } else if (!callPolicy.isEmpty()) { - returnPolicy = callPolicy + "()"; - } - - return returnPolicy; -} - -static int boost_parent_policy_index(int i, const AbstractMetaFunction* func = 0) -{ - if (func && func->isStatic()) - return i; - - if (i == -1) - return 1; - else if (i > 0) - return i + 1; - else - return i; -} - -QString CppGenerator::getArgumentType(const AbstractMetaClass *cppClass, const AbstractMetaFunction *func, int idx) -{ - QString retval; - if (idx == -1) { - retval = cppClass->qualifiedCppName(); - } else if (idx == 0 && func->type()) { - retval = translateType(func->type(), cppClass, - Options(Generator::ExcludeConst) | Generator::ExcludeReference); - } else if (idx > 0) { - retval = argumentString(func, func->arguments()[idx-1], - Options(SkipDefaultValues) | ExcludeConst | - ExcludeReference | SkipName); - } - - retval = retval.trimmed(); - if (retval.endsWith('*')) - retval.chop(1); - return retval; -} - -QString CppGenerator::getFunctionCallPolicy(const AbstractMetaFunction *func) -{ - QString callPolicy; - QStringList callPolicies; - bool returnChild = false; - const AbstractMetaClass* cppClass = func->implementingClass(); - - const int numArgs = func->arguments().count(); - - if (func->type() && (func->type()->name() == "HANDLE")) { - return "python::return_value_policy()"; - } - - for (int i = -1; i <= numArgs; ++i) { - ArgumentOwner ao = func->argumentOwner(cppClass, i); - //Parent Policy - if ((ao.index != -2) && (ao.index != i)) { - switch (ao.action) { - case ArgumentOwner::Add: - if (!i) { - callPolicy = "return_object<"; - returnChild = true; - } else { - callPolicy = "parent_policy_add<"; - } - break; - case ArgumentOwner::Remove: - callPolicy = "parent_policy_remove<"; - break; - default: - continue; - } - - callPolicy += QString("%1, %2, %3, %4") - .arg(boost_parent_policy_index(ao.index, func)) - .arg(boost_parent_policy_index(i, func)) - .arg(getArgumentType(cppClass, func, ao.index)) - .arg(getArgumentType(cppClass, func, i)); - - callPolicies << callPolicy; - } else if (i) { //only function args ignore return value - //Ownership policy - bool changeOwnership = false; - bool releaseOwnership = false; - TypeSystem::Ownership owner = func->ownership(cppClass, - TypeSystem::TargetLangCode, i); - - switch(owner) - { - case TypeSystem::CppOwnership: - releaseOwnership = true; - case TypeSystem::TargetLangOwnership: - changeOwnership = true; - break; - default: - changeOwnership = false; - } - - if (changeOwnership) - { - QString ownershipPolicy = QString("transfer_ownership<%1, %2, %3") - .arg(boost_parent_policy_index(i, func)) - .arg(releaseOwnership ? "true" : "false") - .arg(getArgumentType(cppClass, func, i)); - callPolicies << ownershipPolicy; - } - } - } - - if (callPolicies.size() > 0) { - callPolicy = callPolicies.join(", "); - for (int i = 0; i < callPolicies.count(); ++i) - callPolicy += " >"; - } - - QString returnPolicy; - - //return value - bool cppOwnership = false; - - if (!returnChild) { - switch (func->ownership(cppClass, TypeSystem::TargetLangCode, 0)) - { - case TypeSystem::CppOwnership: - cppOwnership = true; - case TypeSystem::TargetLangOwnership: - { - QString cppOwnershipFlag = (cppOwnership ? "true" : "false"); - returnPolicy = "python::return_value_policy< PySide::return_ptr_object<" + cppOwnershipFlag + "> "; - if (!callPolicy.isEmpty()) - returnPolicy += ", " + callPolicy; - returnPolicy += " >()"; - break; - } - default: - returnPolicy = verifyDefaultReturnPolicy(func, callPolicy); - break; - } - } - - //return policy - if (func->shouldReturnThisObject()) - return "python::return_self< " + callPolicy + " >()"; - else if (!returnPolicy.isEmpty()) - return returnPolicy; - else if (!callPolicy.isEmpty()) - return callPolicy + "()"; - - return QString(); -} - -/*!\internal - Function used to write the enum boost code on the buffer - \param s the output buffer - \param cpp_enum the pointer to metaenum information to be translated to boost -*/ -void CppGenerator::writeEnum(QTextStream &s, - const AbstractMetaEnum *cppEnum, - const QString &nameSpace) -{ - s << INDENT << "python::enum_<" << nameSpace << cppEnum->name(); - s << ">(\"" << cppEnum->name() << "\")" << endl; - const AbstractMetaEnumValueList &values = cppEnum->values(); - EnumTypeEntry *ete = cppEnum->typeEntry(); - - foreach (const AbstractMetaEnumValue* enumValue, values) { - Indentation indent(INDENT); - if (ete->isEnumValueRejected(enumValue->name())) - continue; - - s << INDENT << ".value(\"" << enumValue->name() << "\", "; - s << nameSpace << enumValue->name() << ")" << endl; - } - - //Export values to current scope - s << INDENT << INDENT << ".export_values()" << endl; - s << INDENT << ";" << endl << endl; - - FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags(); - - if (flagsEntry) { - s << INDENT << "PySide::declare_" << (cppEnum->typeEntry()->forceInteger() ? "int_" : "") << "qflags< " - << flagsEntry->originalName() << " >(\"" << flagsEntry->flagsName() << "\");" << endl; - } - - //register enum in typemanager - s << INDENT - << "type_manager::instance().register_native_type(\"" - << nameSpace << cppEnum->name() << "\");\n\n"; -} - -void CppGenerator::writeEnums(QTextStream &s, const AbstractMetaClass *cppClass, bool useNamespace) -{ - AbstractMetaEnumList enums = cppClass->enums(); - if (!enums.size()) - return; - - s << INDENT << "// Enums" << endl; - QString name_space; - if (useNamespace || !cppClass->isPolymorphic() || cppClass->hasPrivateDestructor()) - name_space = cppClass->qualifiedCppName() + "::"; - - foreach (AbstractMetaEnum *cpp_enum, enums) - writeEnum(s, cpp_enum, name_space); -} - -void CppGenerator::writeImplicitlyConversion(QTextStream &s, const AbstractMetaClass *cppClass) -{ -#if 0 - if (cppClass->isNamespace()) - return; - s << endl << "// Implicitly conversions" << endl; - QStringList interfaces = getBaseClasses(cppClass); - - if (!interfaces.size()) { - s << INDENT << "python::implicitly_convertible< " << endl; - s << INDENT << INDENT << "std::auto_ptr< " << getWrapperName(cppClass->name()) << " >," << endl; - s << INDENT << INDENT << "std::auto_ptr< " << cppClass->name() << " > >();" << endl; - } else { - foreach (QString base_class, interfaces) { - s << INDENT << "python::implicitly_convertible< " << endl; - s << INDENT << INDENT << "std::auto_ptr< " << cppClass->name() << " >," << endl; - s << INDENT << INDENT << "std::auto_ptr< " << base_class << " > >();" << endl; - } - } -#endif -} - - -void CppGenerator::writeDestructor(QTextStream &s, const AbstractMetaClass *cppClass) -{ - Indentation indentation(INDENT); - QString wrapperName = getWrapperName(cppClass); - s << wrapperName << "::~" << wrapperName << "()" << endl << "{" << endl - << INDENT << "PySide::qptr_base::invalidate(this);" << endl << "}" << endl; -} - -/*! - Function used to write the class generated boost code on the buffer - \param s the output buffer - \param cppClass the pointer to metaclass information -*/ -void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppClass) -{ - ReportHandler::debugSparse("Generating wrapper implementation for " + cppClass->fullName()); - - // write license comment - s << licenseComment() << endl; - - QString localStr, globalStr; - QTextStream includesLocal(&localStr); - QTextStream includesGlobal(&globalStr); - - bool canCreateWrapper = canCreateWrapperFor(cppClass); - - QList includes = cppClass->typeEntry()->extraIncludes(); - qSort(includes.begin(), includes.end()); - - foreach (Include inc, includes) { - if (inc.type == Include::IncludePath) - includesGlobal << inc.toString() << endl; - else - includesLocal << inc.toString() << endl; - } - - //workaround to access protected functions - s << "//workaround to access protected functions" << endl; - s << "#define protected public" << endl; - - s << "//Base Class" << endl; - if (cppClass->typeEntry()->include().isValid()) - s << cppClass->typeEntry()->include().toString() << endl << endl; - - s << "//Extra includes [global]" << endl; - s << globalStr << endl; - - s << "#undef protected" << endl; - s << "//Base include" << endl; - s << "#include \"pyside.hpp\"" << endl; - s << "#include \"" << getWrapperName(cppClass) << ".hpp\"" << endl; - foreach (AbstractMetaClass* innerClass, cppClass->innerClasses()) { - if (shouldGenerate(innerClass)) - s << "#include \"" << getWrapperName(innerClass) << ".hpp\"" << endl; - } - s << endl << "//Extra includes [local]" << endl; - s << localStr << endl; - - s << endl << "using namespace boost;" << endl; - s << "using namespace PySide;" << endl; - s << endl; - - if (cppClass->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated) - s << "#Deprecated" << endl; - - if (canCreateWrapper) { - writePrelude(s, cppClass); - if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) - writeDestructor(s, cppClass); - } - - writeFieldsAccessFunctions(s, cppClass); - - //inject code native end - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::End, TypeSystem::NativeCode); - - writeBoostDeclaration(s, cppClass); -} - -void CppGenerator::writeFieldsAccessFunctions(QTextStream& s, const AbstractMetaClass* cppClass) -{ - //Fields - foreach (AbstractMetaField *field, cppClass->fields()) { - if (field->isPublic()) { - writeFieldAccess(s, cppClass, field); - } - } -} - -void CppGenerator::writePrelude(QTextStream& s, const AbstractMetaClass* cppClass) -{ - //inject code native beginner - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::Beginning, TypeSystem::NativeCode); - - foreach (AbstractMetaFunction *func, filterFunctions(cppClass)) { - if ((func->isPrivate() || func->isModifiedRemoved()) && !func->isAbstract()) - continue; - - if (func->isConstructor() && (func->allowThread() || func->hasInjectedCode())) { - writeModifiedConstructorImpl(s, func); - } else if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor() && - func->isConstructor() && !func->isCopyConstructor()) { - writeConstructorImpl(s, func); - } else if (func->isVirtual() || func->isAbstract()) { - writeVirtualMethodImpl(s, func); - } else if (func->hasInjectedCode() || func->isThread() || func->allowThread()) { - writeNonVirtualModifiedFunctionImpl(s, func); - } else if (func->isInGlobalScope() && func->isOperatorOverload()) { - writeGlobalOperatorOverloadImpl(s, func); - } - } -} - - -void CppGenerator::writeModifiedConstructorImpl ( QTextStream& s, const AbstractMetaFunction* func ) -{ - Indentation indentation(INDENT); - const AbstractMetaClass* clazz = func->ownerClass(); - s << "static " << clazz->name() << "* " << nameForModifiedCtorFunction(func) << '('; - writeFunctionArguments(s, func, SkipDefaultValues); - s << ")\n{" << endl; - - s << INDENT << clazz->name() << "* _self = 0;" << endl; - s << INDENT << '{' << endl; - { - Indentation indentation(INDENT); - if (func->allowThread()) - s << INDENT << "py_allow_threads allow_threads;" << endl; - - s << INDENT << "_self = new "; - writeFunctionCall(s, func); - s << ';' << endl; - } - s << INDENT << '}' << endl; - writeCodeSnips(s, getCodeSnips(func), CodeSnip::Beginning, TypeSystem::All, func); - writeCodeSnips(s, getCodeSnips(func), CodeSnip::End, TypeSystem::All, func); - s << INDENT << "python::object _obj(PySide::ptr(_self));" << endl; - s << INDENT << "return _self;" << endl; - s << '}' << endl; -} - -void CppGenerator::writeConstructorImpl(QTextStream& s, const AbstractMetaFunction* func) -{ - QString wrapperName = getWrapperName(func->ownerClass()); - s << wrapperName << "::" << wrapperName << "(PyObject *py_self" << (func->arguments().size() ? ", " : ""); - writeFunctionArguments(s, func, Options(OriginalTypeDescription) | SkipDefaultValues); - s << ")" << endl; - s << INDENT << " : "; - writeFunctionCall(s, func); - 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; -} - -void CppGenerator::writeVirtualMethodImplHead(QTextStream& s, const AbstractMetaFunction* func) -{ - Indentation indentation(INDENT); - s << INDENT << "thread_locker lock;" << endl; - - if (func->hasInjectedCode()) { - writeCodeSnips(s, getCodeSnips(func), - CodeSnip::Beginning, TypeSystem::NativeCode, func); - } - - s << INDENT << "python::object method = get_override(\"" << func->implementingClass()->name(); - if (func->implementingClass()->typeEntry()->isObject() || func->implementingClass()->typeEntry()->isQObject()) - s << '*'; - - s << "\", \"" << func->name() << "\");" << endl - << INDENT << "if (method)" << endl << INDENT << "{" << endl; - - { - Indentation indentation(INDENT); - s << INDENT << "try {" << endl << INDENT << INDENT; - if (func->type()) - s << "python::object __result = "; - - foreach(AbstractMetaArgument *arg, func->arguments()) { - writeConversionRule(s, TypeSystem::TargetLangCode, func, arg); - } - - s << INDENT << "method("; - writeArgumentNames(s, func, Generator::Options(Generator::BoxedPrimitive | Generator::SkipRemovedArguments)); - s << ");" << endl; - - QString typeName = getFunctionReturnType(func); - if (!typeName.isEmpty()) { - - CodeSnipList codeSnips = getCodeSnips(func); - bool hasVirtualBeginningCode = false; - foreach(CodeSnip cs, codeSnips) { - if ((cs.position == CodeSnip::Beginning) && (cs.language == TypeSystem::TargetLangCode)) { - hasVirtualBeginningCode = true; - break; - } - } - - if (hasVirtualBeginningCode) { - writeCodeSnips(s, codeSnips, CodeSnip::Beginning, TypeSystem::TargetLangCode, func); - } else if (func->type()) { - s << INDENT << typeName << " __return_value = " << "python::extract<" << typeName << " >(__result);" << endl; - bool boxedPointer = false; - if (func->type() && !func->type()->isConstant() && - (func->type()->isObject() || func->type()->isQObject())) { - - s << INDENT << "PySide::qptr<" << QString(typeName).replace("*", "") << " > __ptr(__result.ptr());" << endl - << INDENT << "python::incref(__result.ptr());" << endl - << INDENT << "__ptr.release_ownership();" << endl; - } - - s << INDENT << "return __return_value;" << endl; - } - } - - s << INDENT << "} catch (boost::python::error_already_set) {" << endl; - s << INDENT << INDENT << "PyErr_Print();" << endl; - s << INDENT << INDENT << "throw boost::python::error_already_set();" << endl; - s << INDENT << "}" << endl; - - - } - s << INDENT << "}" << endl; -} - -void CppGenerator::writeVirtualMethodImpl(QTextStream& s, const AbstractMetaFunction* func) -{ - if (func->isModifiedRemoved()) - return; - - if (!func->isAbstract() && !func->ownerClass()->hasPrivateDestructor() && - func->implementingClass() == func->ownerClass()) { - writeVirtualDefaultFunction(s, func); - } - - - QString prefix = getWrapperName(func->ownerClass()) + "::"; - s << functionSignature(func, prefix, "", - Options(Generator::OriginalTypeDescription) | Generator::SkipDefaultValues | Generator::VirtualCall) - << endl << "{" << endl; - - writeVirtualMethodImplHead(s, func); - - if (func->isAbstract()) - writePureVirtualMethodImplFoot(s, func); - else - writeVirtualMethodImplFoot(s, func); - - s << '}' << endl << endl; -} - - -void CppGenerator::writePureVirtualMethodImplFoot(QTextStream& s, const AbstractMetaFunction* func) -{ - Indentation indentation(INDENT); - s << INDENT << "else" << endl - << INDENT << "{" << endl; - { - Indentation indentation(INDENT); - s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"" - << func->ownerClass()->name() << "." << func->name() << " : " - << "You need to implement pure virtual functions in python\");" << endl - << INDENT << "throw python::error_already_set();" << endl; - } - s << INDENT << "}" << endl; -} - -void CppGenerator::writeVirtualMethodImplFoot(QTextStream& s, const AbstractMetaFunction* func) -{ - Indentation indentation(INDENT); - s << INDENT << "else" << endl << INDENT << "{" << endl; - { - Indentation indentation(INDENT); - QString returnKeyword = func->type() ? QLatin1String("return ") : QString(); - - if (func->allowThread()) - s << INDENT << "py_allow_threads allow_threads;" << endl; - - s << INDENT << returnKeyword << func->implementingClass()->qualifiedCppName() << "::"; - writeFunctionCall(s, func, Generator::VirtualCall); - s << ';' << endl; - } - s << INDENT << '}' << endl; -} - -void CppGenerator::writeVirtualDefaultFunction(QTextStream &s, const AbstractMetaFunction *func) -{ - Indentation indentation(INDENT); - QString returnKeyword = func->type() ? QLatin1String("return ") : QString(); - Generator::Options opt = Generator::Options(Generator::SkipDefaultValues); - QString defaultMethodSignature = signatureForDefaultVirtualMethod(func, getWrapperName(func->ownerClass()) + "::", "_default", - opt | Generator::SkipRemovedArguments | Generator::VirtualCall); - s << defaultMethodSignature << endl << '{' << endl; - - if (func->allowThread()) - s << INDENT << "py_allow_threads allow_threads;" << endl; - - CodeSnipList codeSnips = getCodeSnips(func); - bool hasVirtualEndCode = false; - foreach(CodeSnip cs, codeSnips) { - if ((cs.position == CodeSnip::End) && (cs.language == TypeSystem::TargetLangCode)) { - hasVirtualEndCode = true; - break; - } - } - - foreach(AbstractMetaArgument *arg, func->arguments()) { - writeConversionRule(s, TypeSystem::NativeCode, func, arg); - } - - if (!hasVirtualEndCode) { - s << INDENT << returnKeyword << "self." << func->implementingClass()->qualifiedCppName() << "::"; - writeFunctionCall(s, func, opt); - s << ";" << endl; - } else { - writeCodeSnips(s, getCodeSnips(func), - CodeSnip::End, TypeSystem::TargetLangCode, func); - } - s << '}' << endl << endl; - -} - - - -void CppGenerator::writeNonVirtualModifiedFunctionImpl(QTextStream& s, const AbstractMetaFunction* func) -{ - Indentation indentation(INDENT); - - s << "static " << getFunctionReturnType(func) << ' '; - s << func->ownerClass()->name() << '_' << func->originalName() << "_modified("; - - Options options = Options(SkipRemovedArguments) | SkipDefaultValues; - if (!func->isStatic()) - options |= WriteSelf; - - writeFunctionArguments(s, func, options); - s << ")" << endl << "{" << endl; - - if (func->isThread()) - s << INDENT << "thread_locker lock;" << endl; - - if (func->allowThread()) - s << INDENT << "py_allow_threads allow_threads;" << endl; - - if (getCodeSnips(func).size() > 0) { - writeCodeSnips(s, getCodeSnips(func), CodeSnip::Beginning, TypeSystem::All, func); - writeCodeSnips(s, getCodeSnips(func), CodeSnip::End, TypeSystem::All, func); - } else { - s << INDENT; - if (func->type()) - s << "return "; - - if (func->isStatic()) - s << func->declaringClass()->name() << "::"; - else - s << "self."; - - writeFunctionCall(s, func); - s << ";" << endl; - } - - s << '}' << endl << endl; -} - -AbstractMetaFunction* CppGenerator::findMainConstructor(const AbstractMetaClass* clazz) -{ - foreach (AbstractMetaFunction* func, filterFunctions(clazz)) { - if (func->isConstructor() && - func->isPublic() && - !func->isModifiedRemoved() && - !func->isPrivate()) { - - //do not use copy constructor here - if (func->isCopyConstructor()) - continue; - return func; - } - } - return 0; -} - -void CppGenerator::writeGetterFieldFunction(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaField *field) -{ - s << "static "; - - bool pointer = false; - if (field->type()->isQObject() || field->type()->isObject()) - pointer = true; - - if (pointer) - s << "python::object"; - else - s << field->type()->cppSignature(); - - s << " getter_" << cppClass->name() << "_" << field->name() << "("; - - if (!field->isStatic()) - s << cppClass->qualifiedCppName() << " &self"; - - s << ")" << endl << "{" << endl - << INDENT << "return "; - - if (pointer) - s << "python::object(PySide::ptr("; - - if (!field->isStatic()) - s << "self."; - else - s << field->enclosingClass()->typeEntry()->qualifiedCppName() << "::"; - - s << field->name(); - - if (pointer) - s << "))"; - - s << ";" << endl << "}" << endl; -} - -void CppGenerator::writeSetterFieldFunction(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaField *field) -{ - s << "static void setter_" << cppClass->name() << "_" << field->name() << "("; - - if (!field->isStatic()) - s << cppClass->qualifiedCppName() << " &self, "; - - s << field->type()->cppSignature() << " _value)" << endl << "{" << endl - << INDENT; - - if (!field->isStatic()) - s << "self."; - else - s << field->enclosingClass()->typeEntry()->qualifiedCppName() << "::"; - - s << field->name() << " = _value;" << endl << "}" << endl; -} - - -void CppGenerator::writeFieldAccess(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaField *field) -{ - Indentation indent(INDENT); - - writeGetterFieldFunction(s, cppClass, field); - if (!field->type()->isConstant()) - writeSetterFieldFunction(s, cppClass, field); -} - - -void CppGenerator::writeHashFunction(QTextStream& s, const AbstractMetaClass* cppClass) -{ - QString argType; - - //WORKAROUND: diferent way to QChar - if (cppClass->name() == "QChar") - argType = "QChar"; - else - argType = "const " + cppClass->name() + "&"; - - s << "// Hash function" << endl - << "{" << endl - << INDENT << INDENT << "typedef uint (*hash_type) ( " << argType << " );" - << INDENT << INDENT << "python_cls.def(\"__hash__\", hash_type(&" - << cppClass->typeEntry()->hashFunction() << "));" << endl - << "}" << endl; -} - -QString CppGenerator::baseClassName(const QString& name) -{ - QStringList lst = name.split("::"); - return lst.last(); -} - -void CppGenerator::writeBoostDeclaration(QTextStream& s, const AbstractMetaClass* cppClass) -{ - Indentation indent(INDENT); - QString wrapperName = getWrapperName(cppClass); - - s << "void " << wrapperName << "::define_python_class() throw() {" << endl; - - const AbstractMetaFunction* mainCtor = 0; - bool mainCtorHasModifications = false; - if (!cppClass->isNamespace()) { - // python_cls declaration - mainCtor = findMainConstructor(cppClass); - if (mainCtor) - mainCtorHasModifications = mainCtor->allowThread() || mainCtor->hasInjectedCode(); - - s << INDENT; - if (!cppClass->isPolymorphic() || cppClass->hasPrivateDestructor()) - s << wrapperName << "::"; - - s << "class_type python_cls(\"" - << baseClassName(cppClass->name()) << "\", "; - - if (!mainCtor || mainCtorHasModifications) - s << "python::no_init"; - else - writeConstructorInitialization(s, mainCtor); - - s << ");" << endl << endl; - } else { - QRegExp reg("(?:\\w+::)*(\\w+)"); - reg.indexIn(cppClass->name()); - s << INDENT << "python::class_ python_cls(\"" << reg.cap(1) << "\");" << endl; - } - // scope declaration - s << INDENT << "python::scope " << wrapperName << "_scope(python_cls);" << endl; - - if (cppClass->templateBaseClass() && cppClass->templateBaseClass()->typeEntry()->isContainer()) { - s << endl << INDENT << "//Index suite for QContainer" << endl - << INDENT << "python_cls.def(qcontainer_indexing_suite< " << cppClass->qualifiedCppName() << " >());" << endl << endl; - } - - - if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor() && canCreateWrapperFor(cppClass)) { - QString heldType = cppClass->typeEntry()->heldTypeValue(); - if (heldType.isEmpty()) - heldType = "PySide::qptr"; - - s << INDENT << "python::implicitly_convertible< " - << heldType << "<" << wrapperName << ">, " - << heldType << "<" << cppClass->qualifiedCppName() << "> >();" << endl; - } - - //Enums - writeEnums(s, cppClass, cppClass->hasPrivateDestructor() || cppClass->isNamespace()); - - if (cppClass->innerClasses().count()) { - s << endl << INDENT << "// Inner classes" << endl; - foreach (AbstractMetaClass* innerClass, cppClass->innerClasses()) { - if (!innerClass->typeEntry()->generateCode()) - continue; - s << INDENT << getWrapperName(innerClass) << "::define_python_class();" << endl; - } - } - - //Fields - foreach (AbstractMetaField *field, cppClass->fields()) { - QString strAccess; - - if (field->isPublic()) { - - s << INDENT << "python_cls.add_property(" - << "\"" << field->name() << "\"" - << ", getter_" << cppClass->name() << "_" << field->name(); - if (!field->type()->isConstant()) - s << ", setter_" << cppClass->name() << "_" << field->name(); - - s << ");" << endl; - - } - } - - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::Beginning, TypeSystem::TargetLangCode); - - QSet staticMethods; - AbstractMetaFunctionList functionList = filterFunctions(cppClass); - - if (!cppClass->isNamespace()) { - //search for all static methods to match with normal functions - //to rename when match with one member function - foreach (AbstractMetaFunction *func, functionList) { - if (func->isStatic() && !func->isOperatorOverload()) - staticMethods << func->name(); - } - } - - foreach (AbstractMetaFunction *func, functionList) { - if (func->isModifiedRemoved() || func->isPrivate() || func->isSignal()) - continue; - - //rename static function when is the same name as member function - if (!cppClass->isNamespace() && func->isStatic()) { - QString staticName(createStaticFunctionName(func)); - QSet::iterator staticFuncInter = staticMethods.find(staticName); - if (staticFuncInter != staticMethods.end()) - func->setName(staticName); - } else { - QSet::iterator staticFuncInter = staticMethods.find(func->name()); - if (staticFuncInter != staticMethods.end()) { - staticMethods.erase(staticFuncInter); - staticMethods << createStaticFunctionName(func); - } - } - - if (func->isOperatorOverload()) { - // Do not join the ifs -- isOperatorOverload must be checked alone - if (func->originalName() == func->name()) - writeOperatorOverload(s, func); - } else if (func->isConstructor()) { - //Use same rule as hpp genenrator for copy constructor - if ((mainCtorHasModifications || func != mainCtor) && !func->isCopyConstructor()) { - writeConstructor(s, func); - } - } else if (!func->isVirtual() && - (func->hasInjectedCode() || - func->isThread() || func->allowThread())) { - writeModifiedMethodDef(s, func); - } else if (func->implementingClass() == func->ownerClass()) { - writeNormalMethodDef(s, func); - } - - //if is namespace all methothds is stattic - if (cppClass->isNamespace()) - s << INDENT << "python_cls.staticmethod(\"" << func->name() << "\");" << endl; - } - - //write copy constructor here - if (isCopyable(cppClass) && !cppClass->isNamespace()) { - s << INDENT << "python_cls.def(python::initqualifiedCppName() << "&>());" << endl; - } - - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::End, TypeSystem::TargetLangCode); - - if (!cppClass->isNamespace()) { - // Static methods - if (!staticMethods.isEmpty()) - s << INDENT << "// Static methods" << endl; - - foreach (QString funcName, staticMethods) - s << INDENT << "python_cls.staticmethod(\"" << funcName << "\");" << endl; - } - - // qHash usage - if (!cppClass->typeEntry()->hashFunction().isEmpty()) - writeHashFunction(s, cppClass); - - // implicity conversions - writeImplicitlyConversion(s, cppClass); - - // register object/value type - if (!cppClass->isNamespace()) { - QString className = cppClass->qualifiedCppName(); - const char* funcName = (cppClass->typeEntry()->isObject() || !isCopyable(cppClass)) ? "object" : "value"; - s << INDENT - << "type_manager::instance().register_" - << funcName - << "_type<" << className << " >(\"" - << cppClass->qualifiedCppName() << (cppClass->typeEntry()->isObject() ? "*" : "") << "\");\n"; - } - s << '}' << endl; -} - -void CppGenerator::writeConstructor(QTextStream& s, const AbstractMetaFunction* func) -{ - s << INDENT << "python_cls.def("; - writeConstructorInitialization(s, func); - s << ");" << endl; -} - -void CppGenerator::writeFunctionArgsDef(QTextStream &sOut, - const AbstractMetaFunction *cppFunction) -{ - bool hasDefaultValue = false; - int argUsed = 0; - QString aux; - QTextStream s(&aux); - - foreach (const AbstractMetaArgument *arg, cppFunction->arguments()) { - if (cppFunction->argumentRemoved(arg->argumentIndex() + 1)) - continue; - - if (argUsed > 0) - s << ", "; - - if (!m_disableNamedArgs) - s << "python::arg(\"" << arg->argumentName() << "\")"; - else - s << "python::arg(0)"; - - if (!arg->defaultValueExpression().isEmpty()) { - QString defaultValue = arg->defaultValueExpression(); - bool isPointer = arg->type()->isObject() || - arg->type()->isQObject() || - arg->type()->isValuePointer() || - arg->type()->isNativePointer(); - - if (isPointer && defaultValue == "0") { - defaultValue = "python::object()"; - } else if (arg->type()->isFlags()) { - defaultValue = " (int) " + defaultValue; - } else if (arg->type()->isEnum()) { - QString enumName = arg->type()->minimalSignature(); - QRegExp reg("(.*::)"); - reg.indexIn(enumName); - if (!defaultValue.startsWith(reg.cap(1))) - defaultValue = reg.cap(1) + defaultValue; - } - - s << "=" << defaultValue; - hasDefaultValue = true; - } - argUsed++; - } - - if (hasDefaultValue || ((argUsed > 0) && !m_disableNamedArgs)) - sOut << "," << endl << INDENT << INDENT << "(" << aux << ")"; -} - -void CppGenerator::writeNormalMethodDef(QTextStream& s, const AbstractMetaFunction* func) -{ - s << INDENT << '{' << endl; - { - Indentation indentation(INDENT); - QString wrapperClassName = getWrapperName(func->ownerClass()); - bool needDefaultFunction = func->isVirtual() && !func->isAbstract() && !func->ownerClass()->hasPrivateDestructor(); - QString castName; - - if (needDefaultFunction) - castName = writeFunctionCast(s, func, "_default", func->implementingClass()->qualifiedCppName()); - else - castName = writeFunctionCast(s, func); - - s << INDENT << "python_cls.def(\"" << func->name() << "\", "; - - if (needDefaultFunction) { // add the default function - s << castName << "(&" << wrapperClassName << "::" << func->originalName() << "_default)"; - } else { - if (func->isAbstract()) - s << "python::pure_virtual"; - s << '(' << castName << '(' << getMethodPointerString(func) << "))"; - } - - QString functionPolicy = getFunctionCallPolicy(func); - if (!functionPolicy.isEmpty()) - s << ", " << functionPolicy; - - writeFunctionArgsDef(s, func); - s << ");" << endl; - } - s << INDENT << '}' << endl; -} - -void CppGenerator::writeModifiedMethodDef(QTextStream& s, const AbstractMetaFunction* func) -{ - s << INDENT << '{' << endl; - { - Indentation indentation(INDENT); - QString castName = writeFunctionCast(s, func); - s << INDENT - << "python_cls.def(\"" - << func->name() << "\", " - << castName - << "(&" << func->implementingClass()->name() - << "_" << func->originalName() - << "_modified)"; - QString functionPolicy = getFunctionCallPolicy(func); - if (!functionPolicy.isEmpty()) - s << ", " << functionPolicy; - - writeFunctionArgsDef(s, func); - s << ");" << endl; - } - s << INDENT << '}' << endl; -} - -QString CppGenerator::operatorFunctionName(const AbstractMetaFunction *cppFunction) -{ - QString funcName = QString("%1_operator_%2_") - .arg(cppFunction->arguments()[0]->type()->name()) - .arg(cppFunction->arguments()[1]->type()->name()); - - if (cppFunction->name().contains(">>")) { - funcName += "rshift"; - } else if (cppFunction->name().contains("<<")) { - funcName += "lshift"; - } else { - //TODO: implemente support to others operators - return QString(); - } - - return funcName; -} - -void CppGenerator::writeGlobalOperatorOverloadImpl(QTextStream& s, const AbstractMetaFunction* cppFunction) -{ - Indentation indent(INDENT); - QString operatorStr; - - if (cppFunction->name().contains(">>")) { - operatorStr = " >> "; - } else if (cppFunction->name().contains("<<")) { - operatorStr = " << "; - } else { - //TODO: implemente support to others operators - return; - } - - QString funcName = operatorFunctionName(cppFunction); - bool reverse = cppFunction->isReverseOperator(); - - const AbstractMetaClass *klass = cppFunction->ownerClass(); - s << "python::object " << funcName << "("; - writeFunctionArguments(s, cppFunction, Options(SkipDefaultValues) | SkipRemovedArguments); - s << ")" << endl << "{" << endl - << INDENT << cppFunction->arguments()[reverse]->argumentName() - << operatorStr << cppFunction->arguments()[!reverse]->argumentName() << ";" << endl - << INDENT << "return python::object(PySide::ptr(&" - << cppFunction->arguments()[reverse]->argumentName() << "));" << endl - << "}" << endl; -} - -void CppGenerator::writeGlobalOperatorOverload(QTextStream &s, const AbstractMetaFunction *cppFunction) -{ - QString funcName = operatorFunctionName(cppFunction); - if (funcName.isEmpty()) - return; - - bool reverse = cppFunction->isReverseOperator(); - QString operatorStr; - if (cppFunction->name().contains(">>")) { - operatorStr = QString("__%1rshift__").arg(reverse ? "r" : ""); - } else if (cppFunction->name().contains("<<")) { - operatorStr = QString("__%1lshift__").arg(reverse ? "r" : ""); - } else { - //TODO: implemente support to others operators - return; - } - - s << INDENT << "python_cls.def(\"" << operatorStr << "\", " << funcName << ");\n"; -} - -QString CppGenerator::getOperatorArgumentTypeName(const AbstractMetaFunction *cppFunction, int argumentIndex) -{ - AbstractMetaType* type = cppFunction->arguments()[argumentIndex]->type(); - if (type->name() == cppFunction->implementingClass()->name()) - return QLatin1String("python::self"); - - QString typeName = translateType(type, cppFunction->implementingClass(), - (Option)(ExcludeReference)); - return type->isPrimitive() ? "(" + typeName + ")(0)" : "python::other<" + typeName + " >()"; -} - -void CppGenerator::writeOperatorOverload(QTextStream& s, const AbstractMetaFunction* cppFunction) -{ - static QRegExp operatorRegex("operator(.+)"); - - if (!operatorRegex.exactMatch(cppFunction->originalName())) { - qWarning("What kind of operator is that!? %s", - cppFunction->originalName().toLocal8Bit().data()); - return; - } - - QString op(operatorRegex.cap(1)); - if (op == "=" || op == "[]") { - // = is handled by type boost and type conversions, [] by someone... - return; - } - - // no args == member unary operator - if (!cppFunction->arguments().count()) { - // check if it is a name instead of an operator symbol - // this means it is a conversion operator that will be ignored for now - static QRegExp ConversionOperatorRegex("[A-Za-z]+"); - if (ConversionOperatorRegex.indexIn(op) < 0) - s << INDENT << "python_cls.def(" << op << "python::self);" << endl; - return; - } - - //this because global operators use first arg with current class - if (cppFunction->isInGlobalScope()) { - writeGlobalOperatorOverload(s, cppFunction); - return; - } - - QString operand1, operand2; - if (cppFunction->arguments().count() == 1) { - operand1 = "python::self"; - operand2 = getOperatorArgumentTypeName(cppFunction, 0); - } else { - operand1 = getOperatorArgumentTypeName(cppFunction, 0); - operand2 = getOperatorArgumentTypeName(cppFunction, 1); - } - s << INDENT << "python_cls.def(" << operand1 << ' ' << op << ' ' << operand2 << ");\n"; -} - -void CppGenerator::finishGeneration() -{ - //Generate boost wrapper file - QString classFiles; - QTextStream sClassFiles(&classFiles); - QString classPythonDefines; - QTextStream sClassPythonDefines(&classPythonDefines); - - Indentation indent(INDENT); - - foreach (AbstractMetaClass *cls, classes()) { - if (!shouldGenerate(cls) || cls->enclosingClass()) - continue; - - if (m_packageName.isEmpty()) - m_packageName = cls->package(); - - QString wrapperName = getWrapperName(cls); - QString boostFilename; - boostFilename += wrapperName + ".hpp"; - sClassFiles << "#include \"" << boostFilename << "\"" << endl; - - QString define_str = wrapperName + "::"; - define_str += "define_python_class();"; - - sClassPythonDefines << INDENT << define_str << endl; - } - - QString moduleFileName(outputDirectory() + "/" + subDirectoryForPackage(m_packageName)); - moduleFileName += "/" + moduleName().toLower() + "_module_wrapper.cpp"; - - QFile file(moduleFileName); - if (file.open(QFile::WriteOnly)) { - QTextStream s(&file); - - // write license comment - s << licenseComment() << endl; - - s << "#include \"converter_register_" << moduleName().toLower(); - s << ".hpp\"" << endl << endl; - - s << classFiles << endl; - - s << "using namespace boost;" << endl << endl; - s << "using namespace PySide;" << endl << endl; - - s << "// forward decl. for global func. register\n"; - s << "void register_global_functions_" << moduleName().toLower() << "();\n\n"; - - s << "BOOST_PYTHON_MODULE(" << moduleName() << ")" << endl; - s << "{" << endl; - - foreach (QString requiredModule, TypeDatabase::instance()->requiredTargetImports()) { - s << INDENT << "if ("; - s << "PyImport_ImportModule(\"" << requiredModule << "\") == NULL) {" << endl; - s << INDENT << INDENT << "PyErr_SetString(PyExc_ImportError,"; - s << "\"could not import " << requiredModule << "\");" << endl; - s << INDENT << INDENT << "return;" << endl; - s << INDENT << "}" << endl; - } - s << endl; - - - - s << INDENT << "register_type_converters_" << moduleName().toLower() << "();" << endl << endl - << classPythonDefines << endl - << INDENT << "register_global_functions_" << moduleName().toLower() << "();" << endl - << INDENT << "//Namespaces" << endl; - - s << "}" << endl << endl; - } - - writeGlobalFunctions(); -} - -void CppGenerator::writeGlobalFunctions() -{ - QString fileName = moduleName().toLower() + "_globals_wrapper.cpp"; - - FileOut fileOut(outputDirectory() + "/" + subDirectoryForPackage(m_packageName) + "/" + fileName); - - QSet includes; - QString defsStr; - QTextStream defsStream(&defsStr); - - foreach (AbstractMetaFunction* func, globalFunctions()) { - QString incFile = func->includeFile(); - QRegExp regex("\\b" + moduleName() + "\\b"); - //FIXME: this regex doesn't work with all cases, e.g.: - // moduleName() = local - // incFile = /usr/local/include/local - if (regex.indexIn(incFile) == -1) - continue; - - int idx = incFile.indexOf(moduleName()); - QString cleanPath = QDir::cleanPath(incFile.mid(idx)); - if (!cleanPath.startsWith(moduleName())) - continue; - - includes << cleanPath; - defsStream << INDENT << "{\n" << INDENT; - QString castName = writeFunctionCast(defsStream, func); - defsStream << INDENT << INDENT << "python::def(\"" << func->name(); - defsStream << "\", " << castName << '(' << func->name() << ')'; - if (func->type() && func->type()->isReference()) - defsStream << ", python::return_internal_reference<>()"; - defsStream << ");\n"; - defsStream << INDENT << "}\n"; - } - - QTextStream& s = fileOut.stream; - - // write license comment - s << licenseComment() << endl; - - s << "#include \"pyside.hpp\"" << endl; - - foreach (QString include, includes) - s << "#include <" << include << ">\n"; - - s << "using namespace boost;\n\n"; - s << "using namespace PySide;\n\n"; - - // Add module level code snippets to 'Global' class - TypeSystemTypeEntry *moduleEntry = dynamic_cast( - TypeDatabase::instance()->findType(m_packageName)); - QString sEnd; - QTextStream snipEnd(&sEnd); - if (moduleEntry && moduleEntry->codeSnips().size() > 0) { - foreach (CodeSnip snip, moduleEntry->codeSnips()) { - if (snip.position == CodeSnip().Beginning) - formatCode(s, snip.code(), INDENT); - else - formatCode(snipEnd, snip.code(), INDENT); - } - } - - s << "\nvoid register_global_functions_" << moduleName().toLower() << "() {\n"; - { //global enums - QString name_space; - - foreach (AbstractMetaEnum *cppEnum, globalEnums()) { - if (cppEnum) - writeEnum(s, cppEnum, name_space); - } - } - s << sEnd; - s << defsStr; - s << "}\n"; -} - -QMap CppGenerator::options() const -{ - QMap res; - res.insert("disable-named-arg", "Disable Python names arguments."); - return res; -} - -bool CppGenerator::doSetup(const QMap& args ) -{ - m_disableNamedArgs = args.contains("disable-named-arg"); - return BoostPythonGenerator::doSetup(args); -} diff --git a/generators/boostpython/cppgenerator.h b/generators/boostpython/cppgenerator.h deleted file mode 100644 index d2d65a4e5..000000000 --- a/generators/boostpython/cppgenerator.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 CPPGENERATOR_H -#define CPPGENERATOR_H - -#include "boostpythongenerator.h" - -/** -* The CppGenerator generate the implementation of boost::python bindings classes. -*/ -class CppGenerator : public BoostPythonGenerator -{ -public: - const char* name() const - { - return "CppGenerator"; - } - - QMap options() const; - bool doSetup(const QMap& args); - -protected: - QString fileNameForClass(const AbstractMetaClass *cppClass) const; - void generateClass(QTextStream &s, const AbstractMetaClass *cppClass); - void finishGeneration(); - -private: - void writePrelude(QTextStream &s, const AbstractMetaClass *cppClass); - void writeBoostDeclaration(QTextStream &s, const AbstractMetaClass *cppClass); - - // method declaration writers - void writeConstructor(QTextStream &s, const AbstractMetaFunction *func); - void writeConstructorInitialization(QTextStream &s, const AbstractMetaFunction *func); - void writeNormalMethodDef(QTextStream &s, const AbstractMetaFunction *func); - void writeModifiedMethodDef(QTextStream &s, const AbstractMetaFunction *func); - void writeOperatorOverload(QTextStream &s, const AbstractMetaFunction *func); - void writeGlobalOperatorOverload(QTextStream &s, const AbstractMetaFunction *func); - void writeFunctionArgsDef(QTextStream &s_out, const AbstractMetaFunction *func); - void writeGlobalFunctions(); - void writeDestructor(QTextStream &s, const AbstractMetaClass *cppClass); - - // method implementation writers - void writeModifiedConstructorImpl(QTextStream &s, const AbstractMetaFunction *func); - void writeConstructorImpl(QTextStream &s, const AbstractMetaFunction *func); - void writeVirtualMethodImpl(QTextStream &s, const AbstractMetaFunction *func); - void writeVirtualMethodImplHead(QTextStream &s, const AbstractMetaFunction *func); - void writeVirtualMethodImplFoot(QTextStream &s, const AbstractMetaFunction *func); - void writePureVirtualMethodImplFoot(QTextStream &s, const AbstractMetaFunction *func); - void writeNonVirtualModifiedFunctionImpl(QTextStream &s, const AbstractMetaFunction *func); - void writeGlobalOperatorOverloadImpl(QTextStream& s, const AbstractMetaFunction* func); - - // helper functions - QString writeFunctionCast(QTextStream& s, const AbstractMetaFunction* func, const QString& castNameSuffix = QString(), const QString& className = QString()); - QString getFuncTypedefName(const AbstractMetaFunction *func) const; - QString getFunctionReturnType(const AbstractMetaFunction *func); - AbstractMetaFunction* findMainConstructor(const AbstractMetaClass *clazz); - QString getArgumentType(const AbstractMetaClass *cppClass, const AbstractMetaFunction *func, int idx); - QString operatorFunctionName(const AbstractMetaFunction *func); - QString getOperatorArgumentTypeName(const AbstractMetaFunction *func, int argumentIndex); - - // Field access related - void writeSetterFieldFunction(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaField *field); - void writeGetterFieldFunction(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaField *field); - void writeFieldAccess(QTextStream &s, const AbstractMetaClass *cppClass, const AbstractMetaField *field); - void writeFieldsAccessFunctions(QTextStream& s, const AbstractMetaClass* cppClass); - - // call policy related - QString verifyDefaultReturnPolicy(const AbstractMetaFunction *func, const QString &callPolicy); - QString getFunctionCallPolicy(const AbstractMetaFunction *func); - - // enum related - void writeEnums(QTextStream &s, const AbstractMetaClass *cppClass, bool useNamespace); - void writeEnum(QTextStream &s, const AbstractMetaEnum *cppEnum, const QString &nameSpace); - - // write implicitly conversions - void writeImplicitlyConversion(QTextStream &s, const AbstractMetaClass *cppClass); - void writeVirtualDefaultFunction(QTextStream &s, const AbstractMetaFunction *arg2); - - void writeHashFunction(QTextStream &s, const AbstractMetaClass *cppClass); - QString baseClassName(const QString &name); - - bool m_disableNamedArgs; -}; - -#endif // CPPGENERATOR_H - diff --git a/generators/boostpython/hppgenerator.cpp b/generators/boostpython/hppgenerator.cpp deleted file mode 100644 index 334cee505..000000000 --- a/generators/boostpython/hppgenerator.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 "hppgenerator.h" -#include - -#include -#include -#include -#include -#include - -static Indentor INDENT; - -QString HppGenerator::fileNameForClass(const AbstractMetaClass *cppClass) const -{ - return getWrapperName(cppClass) + QLatin1String(".hpp"); -} - -void HppGenerator::writeCopyCtor(QTextStream &s, const AbstractMetaClass *cppClass) -{ - s << INDENT << getWrapperName(cppClass) << "(PyObject *py_self, const " << cppClass->qualifiedCppName() << "& self)" - << " : " << cppClass->qualifiedCppName() << "(self), wrapper(py_self)" << endl - << INDENT << "{" << endl - << INDENT << "}" << endl; -} - -void HppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *cppClass) -{ - ReportHandler::debugSparse("Generating header for " + cppClass->fullName()); - Indentation indent(INDENT); - - // write license comment - s << licenseComment() << endl; - - QString wrapperName = HppGenerator::getWrapperName(cppClass); - // Header - s << "#ifndef __" << wrapperName.toUpper() << "__" << endl; - s << "#define __" << wrapperName.toUpper() << "__" << endl << endl; - - s << "#include " << endl; - //Includes - if (cppClass->typeEntry()->include().isValid()) - s << cppClass->typeEntry()->include().toString() << endl << endl; - - s << "using namespace PySide;" << endl << endl; - - 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) - held_type = "qptr"; - - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::Declaration, TypeSystem::NativeCode); - - if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) { - // Class - s << "class PYSIDE_LOCAL " << wrapperName; - if (create_wrapper) { - s << " : public " << cppClass->qualifiedCppName() << ", public PySide::wrapper"; - } - s << endl; - s << "{" << endl; - } - - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::Declaration, TypeSystem::ShellDeclaration); - - if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) { - s << endl << "private:" << endl; - className = wrapperName; - is_wrapper = true; - } else { - className = cppClass->qualifiedCppName(); - } - - // print the huge boost::python::class_ typedef - s << INDENT << "typedef boost::python::class_< " << cppClass->qualifiedCppName(); - - writeBaseClass(s, cppClass); - - if (!held_type.isEmpty()) - 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"; - - s << " > class_type;" << endl; - - if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) { - s << "public:" << endl; - - if (isCopyable(cppClass)) - writeCopyCtor(s, cppClass); - - foreach (AbstractMetaFunction *func, filterFunctions(cppClass)) - writeFunction(s, func); - - if (create_wrapper) { - //destructor - s << INDENT << "~" << wrapperName << "();" << endl; - - if (cppClass->isQObject() && (cppClass->name() != "QObject")) - s << INDENT << "using QObject::parent;" << endl; - } - } - - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::End, TypeSystem::ShellDeclaration); - } - - QString staticKeyword = cppClass->isNamespace() ? QLatin1String("") : QLatin1String("static "); - s << INDENT; - if (cppClass->isPolymorphic() && !cppClass->hasPrivateDestructor()) { - s << "//static member used to export class" << endl; - s << INDENT << staticKeyword; - } - s << "void define_python_class() throw();" << endl << endl; - - writeCodeSnips(s, cppClass->typeEntry()->codeSnips(), - CodeSnip::PrototypeInitialization, TypeSystem::NativeCode); - - - s << "};" << endl << endl; - - s << "#endif // __" << wrapperName.toUpper() << "__" << endl << endl; -} - -void HppGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction* func) -{ - // pure virtual functions need a default implementation - if ((func->isPrivate() && !func->isConstructor()) || (func->isModifiedRemoved() && !func->isAbstract())) - return; - - // do not write copy ctors here. - if (func->isCopyConstructor()) - return; - - if (func->isConstructor() || func->isAbstract() || func->isVirtual()) { - if (func->isVirtual() && !func->isAbstract() && !func->isConstructor() - && !func->ownerClass()->hasPrivateDestructor() - && func->implementingClass() == func->ownerClass()) { - s << INDENT << "static " << signatureForDefaultVirtualMethod(func, "", "_default", Generator::Options( Generator::SkipName | Generator::SkipRemovedArguments) ) << ';' << endl; - } - - if (func->isConstructor()) { - s << INDENT << getWrapperName(func->ownerClass()) << "(PyObject *py_self" << (func->arguments().size() ? "," : ""); - writeFunctionArguments(s, func, Options(OriginalTypeDescription) | SkipName); - s << ")"; - } else { - s << INDENT << functionSignature(func, "", "", Options(OriginalTypeDescription) | SkipName); - } - - if (func->isModifiedRemoved() && func->isAbstract()) - writeDefaultImplementation(s, func); - else - s << ';' << endl; - } -} - -void HppGenerator::writeDefaultImplementation(QTextStream& s, const AbstractMetaFunction* func) -{ - QString returnValue; - if (func->type()) { - if (func->type()->isObject() || func->type()->isQObject() || func->type()->name() == "void") - returnValue = "0"; - else - returnValue = functionReturnType(func) + "()"; - } - s << " { return " << returnValue << "; }" << endl; -} - -void HppGenerator::writeBaseClass(QTextStream& s, const AbstractMetaClass* cppClass) -{ - if (!cppClass->isNamespace() && !cppClass->isInterface()) { - QStringList baseClass = getBaseClasses(cppClass); - - if (baseClass.isEmpty()) { - const ComplexTypeEntry *type = cppClass->typeEntry(); - if (cppClass->name() != type->defaultSuperclass()) { - QString sc = type->defaultSuperclass(); - if (!sc.isEmpty()) - s << ", python::bases< " << sc << "> "; - } - } else { - s << ", boost::python::bases< " << baseClass.join(", ") << " > "; - } - } -} - diff --git a/generators/boostpython/hppgenerator.h b/generators/boostpython/hppgenerator.h deleted file mode 100644 index 8e0f5f03b..000000000 --- a/generators/boostpython/hppgenerator.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 HPPGENERATOR_H -#define HPPGENERATOR_H - -#include "boostpythongenerator.h" - -/** -* The HppGenerator generate the declarations of boost::python bindings classes. -*/ -class HppGenerator : public BoostPythonGenerator -{ -protected: - QString fileNameForClass(const AbstractMetaClass* cppClass) const; - void generateClass(QTextStream& s, const AbstractMetaClass* cppClass); - void finishGeneration() {} - const char* name() const - { - return "HppGenerator"; - } -private: - void writeFunction(QTextStream& s, const AbstractMetaFunction* func); - void writePureVirtualEmptyImpl(QTextStream& , const AbstractMetaFunction* func); - void writeBaseClass(QTextStream& s, const AbstractMetaClass* cppClass); - void writeCopyCtor(QTextStream &s, const AbstractMetaClass* cppClass); - void writeDefaultImplementation(QTextStream& s, const AbstractMetaFunction* func); -}; - -#endif // HPPGENERATOR_H - diff --git a/generators/boostpython/main.cpp b/generators/boostpython/main.cpp deleted file mode 100644 index b4e81a878..000000000 --- a/generators/boostpython/main.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the Boost Python Generator project. - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: PySide team - * - * 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 - -int main(int argc, char *argv[]) -{ - QStringList args; - args.append("--generatorSet=boostpython"); - for (int i = 1; i < argc; i++) - args.append(argv[i]); - return QProcess::execute("generatorrunner", args); -} - diff --git a/generators/qtdoc/main.cpp b/generators/qtdoc/main.cpp index c513147d3..76d695bf6 100644 --- a/generators/qtdoc/main.cpp +++ b/generators/qtdoc/main.cpp @@ -1,5 +1,5 @@ /* - * This file is part of the Boost Python Generator project. + * This file is part of the PySide project. * * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * diff --git a/generators/qtdoc/qtdocgenerator.cpp b/generators/qtdoc/qtdocgenerator.cpp index 67e53b187..ff05d9336 100644 --- a/generators/qtdoc/qtdocgenerator.cpp +++ b/generators/qtdoc/qtdocgenerator.cpp @@ -1,5 +1,5 @@ /* - * This file is part of the Boost Python Generator project. + * This file is part of the PySide project. * * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * diff --git a/generators/qtdoc/qtdocgenerator.h b/generators/qtdoc/qtdocgenerator.h index af25ccea5..01717a0cd 100644 --- a/generators/qtdoc/qtdocgenerator.h +++ b/generators/qtdoc/qtdocgenerator.h @@ -1,5 +1,5 @@ /* - * This file is part of the Boost Python Generator project. + * This file is part of the PySide project. * * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * diff --git a/main.cpp b/main.cpp index a8cb86d34..6c6c8f7f8 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ /* - * This file is part of the Boost Python Generator project. + * This file is part of the PySide project. * * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). * @@ -90,7 +90,7 @@ void printUsage(const GeneratorList& generators) 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"); + generalOptions.insert("generatorSet", "generatorSet to be used. e.g. qtdoc"); printOptions(s, generalOptions); foreach (Generator* generator, generators) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index b4fba105d..000000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -project(sphinxtabletest) - -# TODO -set(sphinxtabletest_SRC sphinxtabletest.cpp) -qt4_automoc(${sphinxtabletest_SRC}) -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} qtdoc_generator genrunner) -add_test("sphinxtable" sphinxtabletest) diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 054d6f576..000000000 --- a/tests/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -all: - (cd libfoo; $(MAKE)) - (cd foobinding; $(MAKE)) - - -test: - LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(PWD)/libfoo PYTHONPATH=$(PYTHONPATH):$(PWD)/foobinding/foo python foo_test.py - -clean: - (cd libfoo; $(MAKE) clean) - (cd foobinding; $(MAKE) clean) - diff --git a/tests/foo_test.py b/tests/foo_test.py deleted file mode 100644 index 45b7e80e7..000000000 --- a/tests/foo_test.py +++ /dev/null @@ -1,105 +0,0 @@ - -'''Test cases for virtual methods called through generated bindings''' - -import unittest -try: - from foo import Foo, Bar -except: - import sys - print 'You need to set correct paths for libfoo and foo bindings' - import os - sys.exit(1) - - -class DerivedFoo(Foo): - - def __init__(self): - Foo.__init__(self) - - def pureVirtual(self): - print 'DerivedFoo.pureVirtual' - - -class VirtualMethods(unittest.TestCase): - '''Test case for virtual methods''' - - def setUp(self): - self.foo = Foo() - self.bar = Bar() - self.derivedfoo = DerivedFoo() - - def tearDown(self): - self.foo = None - self.bar = None - self.derivedfoo = None - - def testDerivedClassVirtualMethod(self): - '''Test reinplemented virtual methods from derived class''' - called = True - try: - self.bar.unpureVirtual() - self.bar.pureVirtual() - except: - called = False - self.assertTrue(called) - - def testBaseClassVirtualMethod(self): - '''Test virtual method from base class''' - called = True - try: - self.foo.unpureVirtual() - except: - called = False - self.assertTrue(called) - - - def testBaseClassPureVirtualMethod(self): - '''Test pure virtual method from base class''' - called = False - try: - self.foo.pureVirtual() - except: - called = False - self.assertFalse(called) - - def testBaseClassIndirectCallToUnpureVirtualMethod(self): - '''Test call to unpure virtual method from C++ to Python''' - called = True - try: - self.foo.unpureVirtual() - except: - called = False - self.assertTrue(called) - - def testDerivedClassIndirectCallToUnpureVirtualMethod(self): - '''Test call to unpure virtual method from C++ to Python''' - called = True - try: - self.bar.unpureVirtual() - except: - called = False - self.assertTrue(called) - - def testCppDerivedClassIndirectCallToPureVirtualMethod(self): - '''Test call to pure virtual method from C++ to Python''' - called = False - try: - self.bar.callPureVirtual() - except: - called = False - self.assertFalse(called) - - - def testDerivedClassIndirectCallToPureVirtualMethod(self): - '''Test call to pure virtual method from C++ to Python''' - called = False - try: - self.derivedfoo.callPureVirtual() - except: - called = False - self.assertFalse(called) - - -if __name__ == '__main__': - unittest.main() - diff --git a/tests/foobinding/Makefile b/tests/foobinding/Makefile deleted file mode 100644 index 30909aeeb..000000000 --- a/tests/foobinding/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -all: generate - (cd foo; $(MAKE)) - -generate: - boostpythongenerator --disable-named-arg global.h \ - --include-paths=`pwd`/../libfoo \ - --typesystem-paths=. --output-directory=. \ - typesystem_foo.xml - -clean: - rm *.log .preprocessed.tmp foo/*.hpp foo/*.cpp -rf - (cd foo; $(MAKE) clean) - diff --git a/tests/foobinding/foo/Makefile b/tests/foobinding/foo/Makefile deleted file mode 100644 index 4f6896f46..000000000 --- a/tests/foobinding/foo/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -CXX_FLAGS=-DBOOST_PYTHON_NO_PY_SIGNATURES -g -fPIC -I/usr/include/python2.5 -I../../libfoo `pkg-config pyside --cflags` -CXX_LDFLAGS=-DBOOST_PYTHON_NO_PY_SIGNATURES -fPIC -shared -L../../libfoo -lfoo `pkg-config pyside --libs` - -all: foo_wrapper.o bar_wrapper.o foo_globals_wrapper.o foo_module_wrapper.o - g++ $(CXX_LDFLAGS) bar_wrapper.o foo_wrapper.o foo_globals_wrapper.o foo_module_wrapper.o -Wl,-soname,foo.so -o foo.so - -foo_wrapper.o: foo_wrapper.cpp foo_wrapper.hpp - g++ $(CXX_FLAGS) foo_wrapper.cpp -c - -bar_wrapper.o: bar_wrapper.cpp bar_wrapper.hpp - g++ $(CXX_FLAGS) bar_wrapper.cpp -c - -foo_globals_wrapper.o: foo_globals_wrapper.cpp - g++ $(CXX_FLAGS) foo_globals_wrapper.cpp -c - -foo_module_wrapper.o: foo_module_wrapper.cpp - g++ $(CXX_FLAGS) foo_module_wrapper.cpp -c - -clean: - rm *.o *.so -rf - diff --git a/tests/foobinding/global.h b/tests/foobinding/global.h deleted file mode 100644 index a23601a31..000000000 --- a/tests/foobinding/global.h +++ /dev/null @@ -1,2 +0,0 @@ -#include "foo.h" -#include "bar.h" diff --git a/tests/foobinding/typesystem_foo.xml b/tests/foobinding/typesystem_foo.xml deleted file mode 100644 index e4289e406..000000000 --- a/tests/foobinding/typesystem_foo.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/tests/libfoo/Makefile b/tests/libfoo/Makefile deleted file mode 100644 index eaf8f62f4..000000000 --- a/tests/libfoo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -all: foo.o bar.o - g++ -fPIC -shared foo.o bar.o -o libfoo.so - -foo.o: foo.h foo.cpp - g++ -fPIC foo.cpp -c - -bar.o: bar.h bar.cpp - g++ -fPIC bar.cpp -c - -test: main.cpp - g++ main.cpp -L. -lfoo -I. -o footest - -clean: - rm *.o *.so footest -rf - diff --git a/tests/libfoo/bar.cpp b/tests/libfoo/bar.cpp deleted file mode 100644 index a8f9712a4..000000000 --- a/tests/libfoo/bar.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "bar.h" - -using namespace std; - -void Bar::pureVirtual() -{ - cout << "Bar::pureVirtual()" << endl; -} - -void Bar::unpureVirtual() -{ - cout << "Bar::unpureVirtual()" << endl; -} - diff --git a/tests/libfoo/bar.h b/tests/libfoo/bar.h deleted file mode 100644 index 4a73c2deb..000000000 --- a/tests/libfoo/bar.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef BAR_H -#define BAR_H - -#include "foo.h" - -class Bar : public Foo -{ -public: - Bar() {} - virtual ~Bar() {} - virtual void pureVirtual(); - virtual void unpureVirtual(); -}; -#endif // BAR_H - diff --git a/tests/libfoo/foo.cpp b/tests/libfoo/foo.cpp deleted file mode 100644 index 22be35018..000000000 --- a/tests/libfoo/foo.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include "foo.h" - -using namespace std; - -void Foo::unpureVirtual() -{ - cout << "Foo::unpureVirtual()" << endl; -} - -void Foo::callPureVirtual() -{ - cout << "Foo::callPureVirtual() -- calling pureVirtual..." << endl; - this->pureVirtual(); - cout << " -- pureVirtual called." << endl; -} - diff --git a/tests/libfoo/foo.h b/tests/libfoo/foo.h deleted file mode 100644 index 585b844f7..000000000 --- a/tests/libfoo/foo.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef FOO_H -#define FOO_H - -class Foo -{ -public: - Foo() {} - virtual ~Foo() {} - virtual void pureVirtual() = 0; - virtual void unpureVirtual(); - virtual void callPureVirtual(); -}; -#endif // FOO_H - diff --git a/tests/libfoo/main.cpp b/tests/libfoo/main.cpp deleted file mode 100644 index 6f410addb..000000000 --- a/tests/libfoo/main.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "foo.h" -#include "bar.h" - -int -main(int argv, char **argc) -{ - Bar bar; - - bar.unpureVirtual(); - bar.pureVirtual(); - bar.callPureVirtual(); - - return 0; -} - diff --git a/tests/sphinxtabletest.cpp b/tests/sphinxtabletest.cpp deleted file mode 100644 index a35d11926..000000000 --- a/tests/sphinxtabletest.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* -* This file is part of the Boost Python Generator project. -* -* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -* -* Contact: PySide team -* -* 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 "sphinxtabletest.h" -#include "qtdocgenerator.h" -#include -#include - -QString SphinxTableTest::transformXml(const char* xml) -{ - return QtXmlToSphinx(m_generator, xml).result(); -} - -void SphinxTableTest::setUp() -{ - m_generator = new QtDocGenerator; -} - -void SphinxTableTest::tearDown() -{ - delete m_generator; -} - -void SphinxTableTest::testEmptyString() -{ - const char* xml = ""; - QCOMPARE(transformXml(xml), QString()); -} - -void SphinxTableTest::testSimpleTable() -{ - const char* xml = "\ -\ -
\ - \ - Header 1\ - \ - \ - Header 2\ - \ -
\ - \ - \ - 1 1\ - \ - \ - 1 2\ - \ - \ - \ - \ - 2 1\ - \ - \ - 2 2\ - \ - \ -
"; - QCOMPARE(transformXml(xml), QString("\ - +--------+--------+\n\ - |Header 1|Header 2|\n\ - +--------+--------+\n\ - |1 1 |1 2 |\n\ - +--------+--------+\n\ - |2 1 |2 2 |\n\ - +--------+--------+\n\ -\n")); -} - -void SphinxTableTest::testColSpan() -{ - const char* xml = "\ -\ -
\ - \ - Header 1\ - \ - \ - Header 2\ - \ -
\ - \ - \ - I'm a big text!\ - \ - \ - \ - \ - 2 1\ - \ - \ - 2 2\ - \ - \ -
"; - QCOMPARE(transformXml(xml), QString("\ - +---------------+--------+\n\ - |Header 1 |Header 2|\n\ - +---------------+--------+\n\ - |I'm a big text! |\n\ - +---------------+--------+\n\ - |2 1 |2 2 |\n\ - +---------------+--------+\n\ -\n")); -} - - -void SphinxTableTest::testRowSpan() -{ - const char* xml = "\ -\ -
\ - \ - Header 1\ - \ - \ - Header 2\ - \ -
\ - \ - \ - 1.1\ - \ - \ - 1.2\ - \ - \ - \ - \ - 2 2\ - \ - \ -
"; - QCOMPARE(transformXml(xml), QString("\ - +--------+--------+\n\ - |Header 1|Header 2|\n\ - +--------+--------+\n\ - |1.1 |1.2 |\n\ - + +--------+\n\ - | |2 2 |\n\ - +--------+--------+\n\ -\n")); -} - - -void SphinxTableTest::testComplexTable() -{ - const char* xml = "\ -\ -
\ - \ - Header 1\ - \ - \ - Header 2\ - \ - \ - Header 3\ - \ -
\ - \ - \ - 1.1\ - \ - \ - 1.2\ - \ - \ - \ - \ - 2 2\ - \ - \ - 2 3\ - \ - \ -
"; - QCOMPARE(transformXml(xml), QString("\ - +--------+--------+--------+\n\ - |Header 1|Header 2|Header 3|\n\ - +--------+--------+--------+\n\ - |1.1 |1.2 |\n\ - + +--------+--------+\n\ - | |2 2 |2 3 |\n\ - +--------+--------+--------+\n\ -\n")); -} - -void SphinxTableTest::testRowSpan2() -{ - const char* xml = "\ -\ -
\ - h1\ - h2\ - h3\ - h4\ -
\ - \ - A\ - B\ - C\ - D\ - \ - \ - E\ - F\ - \ - \ - E\ - F\ - \ - \ - E\ - F\ - \ - \ - E\ - F\ - \ - \ - E\ - F\ - \ -
"; - QCOMPARE(transformXml(xml), QString("\ - +--+--+--+--+\n\ - |h1|h2|h3|h4|\n\ - +--+--+--+--+\n\ - |A |B |C |D |\n\ - + + +--+--+\n\ - | | |E |F |\n\ - + + +--+--+\n\ - | | |E |F |\n\ - + + +--+--+\n\ - | | |E |F |\n\ - + + +--+--+\n\ - | | |E |F |\n\ - + + +--+--+\n\ - | | |E |F |\n\ - +--+--+--+--+\n\ -\n")); -} - - - -QTEST_APPLESS_MAIN( SphinxTableTest ) - -#include "sphinxtabletest.moc" diff --git a/tests/sphinxtabletest.h b/tests/sphinxtabletest.h deleted file mode 100644 index 57d8937d0..000000000 --- a/tests/sphinxtabletest.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* This file is part of the Boost Python Generator project. -* -* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -* -* Contact: PySide team -* -* 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 SPHINXTABLETEST_H -#define SPHINXTABLETEST_H - -#include - -class QtDocGenerator; -class SphinxTableTest : public QObject { - Q_OBJECT - -private slots: - void setUp(); - void tearDown(); - void testEmptyString(); - void testSimpleTable(); - void testRowSpan(); - void testColSpan(); - void testComplexTable(); - void testRowSpan2(); -private: - QtDocGenerator* m_generator; - - QString transformXml(const char* xml); -}; - -#endif -- cgit v1.2.3