From 482219f20abae9d1602d77790c8542310a64a087 Mon Sep 17 00:00:00 2001 From: Stefan Seefeld Date: Thu, 29 Sep 2016 23:18:00 -0400 Subject: [PATCH] Remove a bunch of obsolete files. --- build/python_v1.zip | Bin 236665 -> 0 bytes class.cpp | 28 - index.html | 12 - pyste/NEWS | 212 ----- pyste/README | 35 - pyste/TODO | 18 - pyste/dist/create_build.py | 55 -- pyste/dist/setup.py | 10 - pyste/doc/adding_new_methods.html | 79 -- pyste/doc/exporting_an_entire_header.html | 85 -- pyste/doc/global_variables.html | 49 -- pyste/doc/inserting_code.html | 72 -- pyste/doc/introduction.html | 73 -- pyste/doc/policies.html | 90 --- pyste/doc/pyste.txt | 664 ---------------- pyste/doc/renaming_and_excluding.html | 87 -- pyste/doc/running_pyste.html | 200 ----- pyste/doc/smart_pointers.html | 84 -- pyste/doc/templates.html | 102 --- pyste/doc/the_interface_files.html | 102 --- pyste/doc/theme/alert.gif | Bin 577 -> 0 bytes pyste/doc/theme/arrow.gif | Bin 70 -> 0 bytes pyste/doc/theme/bkd.gif | Bin 1317 -> 0 bytes pyste/doc/theme/bkd2.gif | Bin 2543 -> 0 bytes pyste/doc/theme/bulb.gif | Bin 944 -> 0 bytes pyste/doc/theme/bullet.gif | Bin 152 -> 0 bytes pyste/doc/theme/l_arr.gif | Bin 147 -> 0 bytes pyste/doc/theme/l_arr_disabled.gif | Bin 91 -> 0 bytes pyste/doc/theme/note.gif | Bin 151 -> 0 bytes pyste/doc/theme/r_arr.gif | Bin 147 -> 0 bytes pyste/doc/theme/r_arr_disabled.gif | Bin 91 -> 0 bytes pyste/doc/theme/smiley.gif | Bin 879 -> 0 bytes pyste/doc/theme/style.css | 178 ----- pyste/doc/theme/u_arr.gif | Bin 170 -> 0 bytes pyste/doc/wrappers.html | 124 --- pyste/index.html | 90 --- pyste/install/pyste.py | 8 - pyste/install/setup.py | 20 - pyste/src/Pyste/ClassExporter.py | 918 ---------------------- pyste/src/Pyste/CodeExporter.py | 26 - pyste/src/Pyste/CppParser.py | 247 ------ pyste/src/Pyste/EnumExporter.py | 58 -- pyste/src/Pyste/Exporter.py | 94 --- pyste/src/Pyste/FunctionExporter.py | 92 --- pyste/src/Pyste/GCCXMLParser.py | 478 ----------- pyste/src/Pyste/HeaderExporter.py | 81 -- pyste/src/Pyste/MultipleCodeUnit.py | 135 ---- pyste/src/Pyste/SingleCodeUnit.py | 121 --- pyste/src/Pyste/SmartFile.py | 60 -- pyste/src/Pyste/VarExporter.py | 40 - pyste/src/Pyste/__init__.py | 6 - pyste/src/Pyste/declarations.py | 653 --------------- pyste/src/Pyste/exporters.py | 12 - pyste/src/Pyste/exporterutils.py | 87 -- pyste/src/Pyste/infos.py | 259 ------ pyste/src/Pyste/policies.py | 95 --- pyste/src/Pyste/pyste.py | 424 ---------- pyste/src/Pyste/settings.py | 21 - pyste/src/Pyste/utils.py | 78 -- pyste/tests/GCCXMLParserUT.py | 341 -------- pyste/tests/SmartFileUT.py | 84 -- pyste/tests/abstract_test.h | 22 - pyste/tests/abstract_test.pyste | 3 - pyste/tests/abstract_testUT.py | 26 - pyste/tests/add_test.h | 18 - pyste/tests/add_test.pyste | 2 - pyste/tests/add_testUT.py | 16 - pyste/tests/basic.cpp | 13 - pyste/tests/basic.h | 69 -- pyste/tests/basic.pyste | 5 - pyste/tests/basicUT.py | 73 -- pyste/tests/code_test.h | 8 - pyste/tests/code_test.pyste | 9 - pyste/tests/code_testUT.py | 18 - pyste/tests/enums.h | 34 - pyste/tests/enums.pyste | 8 - pyste/tests/enumsUT.py | 24 - pyste/tests/header_test.h | 43 - pyste/tests/header_test.pyste | 4 - pyste/tests/header_testUT.py | 27 - pyste/tests/infosUT.py | 55 -- pyste/tests/inherit.cpp | 8 - pyste/tests/inherit.h | 43 - pyste/tests/inherit.pyste | 8 - pyste/tests/inherit2.h | 35 - pyste/tests/inherit2.pyste | 2 - pyste/tests/inherit2UT.py | 31 - pyste/tests/inherit3.h | 46 -- pyste/tests/inherit3.pyste | 2 - pyste/tests/inherit3UT.py | 27 - pyste/tests/inherit4.h | 23 - pyste/tests/inherit4.pyste | 3 - pyste/tests/inherit4UT.py | 31 - pyste/tests/inheritUT.py | 33 - pyste/tests/nested.cpp | 9 - pyste/tests/nested.h | 32 - pyste/tests/nested.pyste | 1 - pyste/tests/nestedUT.py | 19 - pyste/tests/opaque.h | 57 -- pyste/tests/opaque.pyste | 7 - pyste/tests/opaqueUT.py | 24 - pyste/tests/operators.cpp | 8 - pyste/tests/operators.h | 52 -- pyste/tests/operators.pyste | 2 - pyste/tests/operatorsUT.py | 30 - pyste/tests/policiesUT.py | 67 -- pyste/tests/runtests.py | 21 - pyste/tests/smart_ptr.h | 50 -- pyste/tests/smart_ptr.pyste | 13 - pyste/tests/smart_ptrUT.py | 22 - pyste/tests/templates.h | 15 - pyste/tests/templates.pyste | 8 - pyste/tests/templatesUT.py | 30 - pyste/tests/test_all.py | 140 ---- pyste/tests/vars.cpp | 12 - pyste/tests/vars.h | 24 - pyste/tests/vars.pyste | 1 - pyste/tests/varsUT.py | 22 - pyste/tests/virtual.cpp | 75 -- pyste/tests/virtual.h | 41 - pyste/tests/virtual.pyste | 6 - pyste/tests/virtual2.h | 34 - pyste/tests/virtual2.pyste | 6 - pyste/tests/virtual2UT.py | 40 - pyste/tests/virtualUT.py | 55 -- pyste/tests/wrappertest.h | 51 -- pyste/tests/wrappertest.pyste | 21 - pyste/tests/wrappertestUT.py | 24 - pyste/tests/wrappertest_wrappers.h | 33 - release_notes.txt | 223 ------ todo.html | 240 ------ 131 files changed, 9171 deletions(-) delete mode 100644 build/python_v1.zip delete mode 100644 class.cpp delete mode 100644 index.html delete mode 100644 pyste/NEWS delete mode 100644 pyste/README delete mode 100644 pyste/TODO delete mode 100644 pyste/dist/create_build.py delete mode 100644 pyste/dist/setup.py delete mode 100644 pyste/doc/adding_new_methods.html delete mode 100644 pyste/doc/exporting_an_entire_header.html delete mode 100644 pyste/doc/global_variables.html delete mode 100644 pyste/doc/inserting_code.html delete mode 100644 pyste/doc/introduction.html delete mode 100644 pyste/doc/policies.html delete mode 100644 pyste/doc/pyste.txt delete mode 100644 pyste/doc/renaming_and_excluding.html delete mode 100644 pyste/doc/running_pyste.html delete mode 100644 pyste/doc/smart_pointers.html delete mode 100644 pyste/doc/templates.html delete mode 100644 pyste/doc/the_interface_files.html delete mode 100644 pyste/doc/theme/alert.gif delete mode 100644 pyste/doc/theme/arrow.gif delete mode 100644 pyste/doc/theme/bkd.gif delete mode 100644 pyste/doc/theme/bkd2.gif delete mode 100644 pyste/doc/theme/bulb.gif delete mode 100644 pyste/doc/theme/bullet.gif delete mode 100644 pyste/doc/theme/l_arr.gif delete mode 100644 pyste/doc/theme/l_arr_disabled.gif delete mode 100644 pyste/doc/theme/note.gif delete mode 100644 pyste/doc/theme/r_arr.gif delete mode 100644 pyste/doc/theme/r_arr_disabled.gif delete mode 100644 pyste/doc/theme/smiley.gif delete mode 100644 pyste/doc/theme/style.css delete mode 100644 pyste/doc/theme/u_arr.gif delete mode 100644 pyste/doc/wrappers.html delete mode 100644 pyste/index.html delete mode 100644 pyste/install/pyste.py delete mode 100644 pyste/install/setup.py delete mode 100644 pyste/src/Pyste/ClassExporter.py delete mode 100644 pyste/src/Pyste/CodeExporter.py delete mode 100644 pyste/src/Pyste/CppParser.py delete mode 100644 pyste/src/Pyste/EnumExporter.py delete mode 100644 pyste/src/Pyste/Exporter.py delete mode 100644 pyste/src/Pyste/FunctionExporter.py delete mode 100644 pyste/src/Pyste/GCCXMLParser.py delete mode 100644 pyste/src/Pyste/HeaderExporter.py delete mode 100644 pyste/src/Pyste/MultipleCodeUnit.py delete mode 100644 pyste/src/Pyste/SingleCodeUnit.py delete mode 100644 pyste/src/Pyste/SmartFile.py delete mode 100644 pyste/src/Pyste/VarExporter.py delete mode 100644 pyste/src/Pyste/__init__.py delete mode 100644 pyste/src/Pyste/declarations.py delete mode 100644 pyste/src/Pyste/exporters.py delete mode 100644 pyste/src/Pyste/exporterutils.py delete mode 100644 pyste/src/Pyste/infos.py delete mode 100644 pyste/src/Pyste/policies.py delete mode 100644 pyste/src/Pyste/pyste.py delete mode 100644 pyste/src/Pyste/settings.py delete mode 100644 pyste/src/Pyste/utils.py delete mode 100644 pyste/tests/GCCXMLParserUT.py delete mode 100644 pyste/tests/SmartFileUT.py delete mode 100644 pyste/tests/abstract_test.h delete mode 100644 pyste/tests/abstract_test.pyste delete mode 100644 pyste/tests/abstract_testUT.py delete mode 100644 pyste/tests/add_test.h delete mode 100644 pyste/tests/add_test.pyste delete mode 100644 pyste/tests/add_testUT.py delete mode 100644 pyste/tests/basic.cpp delete mode 100644 pyste/tests/basic.h delete mode 100644 pyste/tests/basic.pyste delete mode 100644 pyste/tests/basicUT.py delete mode 100644 pyste/tests/code_test.h delete mode 100644 pyste/tests/code_test.pyste delete mode 100644 pyste/tests/code_testUT.py delete mode 100644 pyste/tests/enums.h delete mode 100644 pyste/tests/enums.pyste delete mode 100644 pyste/tests/enumsUT.py delete mode 100644 pyste/tests/header_test.h delete mode 100644 pyste/tests/header_test.pyste delete mode 100644 pyste/tests/header_testUT.py delete mode 100644 pyste/tests/infosUT.py delete mode 100644 pyste/tests/inherit.cpp delete mode 100644 pyste/tests/inherit.h delete mode 100644 pyste/tests/inherit.pyste delete mode 100644 pyste/tests/inherit2.h delete mode 100644 pyste/tests/inherit2.pyste delete mode 100644 pyste/tests/inherit2UT.py delete mode 100644 pyste/tests/inherit3.h delete mode 100644 pyste/tests/inherit3.pyste delete mode 100644 pyste/tests/inherit3UT.py delete mode 100644 pyste/tests/inherit4.h delete mode 100644 pyste/tests/inherit4.pyste delete mode 100644 pyste/tests/inherit4UT.py delete mode 100644 pyste/tests/inheritUT.py delete mode 100644 pyste/tests/nested.cpp delete mode 100644 pyste/tests/nested.h delete mode 100644 pyste/tests/nested.pyste delete mode 100644 pyste/tests/nestedUT.py delete mode 100644 pyste/tests/opaque.h delete mode 100644 pyste/tests/opaque.pyste delete mode 100644 pyste/tests/opaqueUT.py delete mode 100644 pyste/tests/operators.cpp delete mode 100644 pyste/tests/operators.h delete mode 100644 pyste/tests/operators.pyste delete mode 100644 pyste/tests/operatorsUT.py delete mode 100644 pyste/tests/policiesUT.py delete mode 100644 pyste/tests/runtests.py delete mode 100644 pyste/tests/smart_ptr.h delete mode 100644 pyste/tests/smart_ptr.pyste delete mode 100644 pyste/tests/smart_ptrUT.py delete mode 100644 pyste/tests/templates.h delete mode 100644 pyste/tests/templates.pyste delete mode 100644 pyste/tests/templatesUT.py delete mode 100644 pyste/tests/test_all.py delete mode 100644 pyste/tests/vars.cpp delete mode 100644 pyste/tests/vars.h delete mode 100644 pyste/tests/vars.pyste delete mode 100644 pyste/tests/varsUT.py delete mode 100644 pyste/tests/virtual.cpp delete mode 100644 pyste/tests/virtual.h delete mode 100644 pyste/tests/virtual.pyste delete mode 100644 pyste/tests/virtual2.h delete mode 100644 pyste/tests/virtual2.pyste delete mode 100644 pyste/tests/virtual2UT.py delete mode 100644 pyste/tests/virtualUT.py delete mode 100644 pyste/tests/wrappertest.h delete mode 100644 pyste/tests/wrappertest.pyste delete mode 100644 pyste/tests/wrappertestUT.py delete mode 100644 pyste/tests/wrappertest_wrappers.h delete mode 100644 release_notes.txt delete mode 100755 todo.html diff --git a/build/python_v1.zip b/build/python_v1.zip deleted file mode 100644 index 0377a07bb35337fd47e14de78bc55819015567fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236665 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 ! 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 diff --git a/class.cpp b/class.cpp deleted file mode 100644 index 078bebdf..00000000 --- a/class.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -#include -#include -#include -#include - -using namespace boost::python; - -struct X -{ - int x; - X(int n) : x(n) { } -}; - -int x_function(X& x) -{ return x.x; -} - - -BOOST_PYTHON_MODULE(class_ext) -{ - class_("X", init()); - def("x_function", x_function); -} - -#include "module_tail.cpp" diff --git a/index.html b/index.html deleted file mode 100644 index 9c6acc88..00000000 --- a/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - -Automatically loading index page... if nothing happens, please go to -doc/index.html. - - diff --git a/pyste/NEWS b/pyste/NEWS deleted file mode 100644 index 31a5ceba..00000000 --- a/pyste/NEWS +++ /dev/null @@ -1,212 +0,0 @@ -.. Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost -.. Software License, Version 1.0. (See accompanying -.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -25 April 2005 -- Fixed bug where the code for wrappers of member functions were defined outside -the pyste namespace. Reported by Dan Haffey. - -9 October 2004 -- Applied a patch by Christian Hudon that fixed an issue with files -that had a tail and relative includes. - -18 July 2004 -- Applied a patch by Paul Bridger that solves some problems for wrapper -methods. -- Applied a patch by Baptiste Lepilleur that allows the user to inject -code inside the class definition. -- Applied another patch by Baptiste Lepilleur that inserts two new command-line -options that helps with writing makefiles. - -27 May 2004 -Applied patch by Paul Bridger that solves a problem on windows regarding -spaces on paths. Thanks Paul! - -Applied another patch that fixes the module name if pyste is run from -another directory of where the .pyste file is located. Patch contributted -by Paul Bridger. - -17 May 2004 -Applied a patch by Roman Yakovenko that makes the export of unnamed enums -better. Thanks Roman! - -23 October 2003 -Fixed bug where a class would appear more than one in the generated code. - -6 October 2003 -Fixed bug reported by Niall Douglas (using his patch) about UniqueInt not -appearing correctly with --multiple. - -Added precompiled header support on windows systems (using #pragma hdrstop). -Suggested by Niall Douglas. - -Fixed a bug with -I directive and AllFromHeader. Reported by Scott Snyder. - -4 October 2003 -Added return_self, thanks for Niall Douglas for pointing out that it was -missing. - -Added --file-list, where you can pass a file where the pyste files are listed -one per line. Also suggested by Niall Douglas. - -Documentation has been finally updated, after a long wait. Please let me know -if you spot any mistake! - -2 October 2003 -Scott Snyder found a typo in ClassExporter that prevented -= and *= operators -from being exported. Thanks Scott! - -20 September 2003 -Added return_by_value in the list of policies supported. Thanks to Niall -Douglas for the remainder. - -19 September 2003 -Better support for unnamed enums, plus they are by default exported to the -parent's namespace. Normal enums can have the same behaviour using the function -export_values on the Enum object. Feature requested by Niall Douglas. - -10 September 2003 -A new variable is accessible in the Pyste files: INTERFACE_FILE contains the -full path of the pyste file. - -4 September 2003 -Now it is possible to override protected and private pure virtual functions -in Python, as requested by Roman Yakovenko. - -23 August 2003 -Fixed bug where some Imports where not writing their include files. -Now whenever the declarations change, the cache files are rebuilt -automatically. - -19 August 2003 -Fixed a bug related to the generation of the bases<> template. - -17 August 2003 -Added support for insertion of user code in the generated code. - -16 August 2003 -Applied a patch by Gottfried Ganssauge that adds exception specifiers to -wrapper functions and pointer declarations. Thanks a lot Gottfried!! - -Applied a patch by Prabhu Ramachandran that fixes ae problem with the -pure virtual method generation. Thanks again Prabhu! - -10 August 2003 -Support for incremental generation of the code has been added. This changes -how --multiple works; documentation of this new feature will follow. Thanks -to Prabhu Ramachandran, that saw the need for this feature and discussed a -solution. - -Automatically convert \ to / in Windows systems before passing the paths to -gccxml. - -Fixed a bug reported by Prabhu Ramachandran, where in some classes the virtual -methods were being definied incorrectly. Thanks a lot Prabhu! - -7 July 2003 -Applied 2 patches by Prabhu Ramachandran: a fix in the new --multiple method, -and two new functions "hold_with_shared_ptr" and its counterpart for auto_ptr. -Thanks a lot Prabhu! - -Fixed a bug where the macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID was being -called multiple times for the same type. -Thanks to Gottfried Ganßauge for reporting this! - -Fixed bug where using AllFromHeader didn't use bases<> when exporting -hierarchies. - -Fixed the staticmethod bug. - -5 July 2003 -Changed how --multiple works: now it generates one cpp file for each pyste -file, makeing easier to integrate Pyste with build systems. - -4 July 2003 -Applied patch that solved a bug in ClassExporter and added a distutils install -script (install/setup.py), both contributed by Prabhu Ramachandran. -Thanks Prabhu! - -2 July 2003 -Jim Wilson found a bug where types like "char**" were being interpreted as -"char*". Thanks Jim! - -16 June 2003 -Thanks to discussions with David Abrahams and Roman Sulzhyk, some behaviours -have changed: - -- If you export a derived class without exporting its base classes, the derived - class will explicitly export the bases's methods and attributes. Before, if - you were interested in the bases's methods, you had to export the base - classes too. - -- Added a new function, no_override. When a member function is specified as - "no_override", no virtual wrappers are generated for it, improving - performance and letting the code more clean. - -- There was a bug in which the policy of virtual member functions was being - ignored (patch by Roman Sulzhyk). - -Thanks again to Roman Sulzhyk for the patches and discussion in the c++-sig. - -4 June 2003 -Major improvements in memory usage. - -3 June 2003 -Appliced a patch from Giulio Eulisse that allows unnamed enumerations to be -exported with an AllFromHeader construct. Thanks a lot Giulio! - -2 June 2003 -Added a new construct, add_method. See documentation. - -23 May 2003 -Support for global variables added. -Various bug fixes. - -08 May 2003 -Fixed bug where in a certain cases the GCCXMLParser would end up with multiple -declarations of the same class - -22 Apr 2003 -- Now shows a warning when the user tries to export a forward-declared class. - Forward-declared classes are ignored by the AllFromHeader construct. -- Fixed a bug where classes, functions and enums where being exported, even if - excluded from a AllFromHeader construct. - -16 Apr 2003 -Added a more generic (but ugly) code to declare the smart pointer converters. - -07 Apr 2003 -- Removed the warnings about forward declarations: it was not accurate enough. - Another strategy must be thought of. -- Fixed bug in the --multiple mode, where the order of the class instantiations - could end up wrong. -- Lots of fixes in the documentation, pointed out by Dirk Gerrits. Thanks Dirk! -- Fixed support for the return_opaque_pointer policy (the support macro was not - being declared). - - -06 Apr 2003 -Support for the improved static data members support of Boost.Python. - -05 Apr 2003 -New option for generating the bindings: --multiple. - -02 Apr 2003 -Forward declarations are now detected and a warning is generated. - -24 Mar 2003 -Default policy for functions/methods that return const T& is now -return_value_policy(). - -22 Mar 2003 -Exporting virtual methods of the base classes in the derived classes too. - -21 Mar 2003 -Added manual support for boost::shared_ptr and std::auto_ptr (see doc). - -19 Mar 2003 -Added support for int, double, float and long operators acting as expected in -python. - -14 Mar 2003 -Fixed bug: Wrappers for protected and virtual methods were not being generated. diff --git a/pyste/README b/pyste/README deleted file mode 100644 index c378f391..00000000 --- a/pyste/README +++ /dev/null @@ -1,35 +0,0 @@ -.. Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost -.. Software License, Version 1.0. (See accompanying -.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -Pyste - Python Semi-Automatic Exporter -====================================== - -Pyste is a Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple interface file, which following the -Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code. - -The documentation can be found in the file index.html accompaning this README. - -Enjoy! -Bruno da Silva de Oliveira (nicodemus@esss.com.br) - -Thanks -====== - -- David Abrahams, creator of Boost.Python, for tips on the syntax of the interface - file and support. -- Marcelo Camelo, for design tips, support and inspiration for this project. - Also, the name was his idea. 8) -- Brad King, creator of the excellent GCCXML (http://www.gccxml.org) -- Fredrik Lundh, creator of the elementtree library (http://effbot.org) - -Bugs -==== - -Pyste is a young tool, so please help it to get better! Send bug reports to -nicodemus@esss.com.br, accompaining the stack trace in case of exceptions. -If possible, run pyste with --debug, and send the resulting xmls too (pyste -will output a xml file with the same of each header it parsed). diff --git a/pyste/TODO b/pyste/TODO deleted file mode 100644 index 0b3c9024..00000000 --- a/pyste/TODO +++ /dev/null @@ -1,18 +0,0 @@ -.. Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost -.. Software License, Version 1.0. (See accompanying -.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -- Make Pyste accept already-generated xml files - -- throw() declaration in virtual wrapper's member functions - -- Allow protected methods to be overriden in Python - -- Expose programmability to the Pyste files (listing members of a class, for - instance) - -- Virtual operators - -- args() support - -- set policies to methods with the same name diff --git a/pyste/dist/create_build.py b/pyste/dist/create_build.py deleted file mode 100644 index a6836995..00000000 --- a/pyste/dist/create_build.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost -# Software License, Version 1.0. (See accompanying -# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -import os -import sys -import shutil -import fnmatch -from zipfile import ZipFile, ZIP_DEFLATED - -def findfiles(directory, mask): - def visit(files, dir, names): - for name in names: - if fnmatch.fnmatch(name, mask): - files.append(os.path.join(dir, name)) - files = [] - os.path.walk(directory, visit, files) - return files - - -def main(): - # test if PyXML is installed - try: - import _xmlplus.parsers.expat - pyxml = '--includes _xmlplus.parsers.expat' - except ImportError: - pyxml = '' - # create exe - status = os.system('python setup.py py2exe %s >& build.log' % pyxml) - if status != 0: - raise RuntimeError, 'Error creating EXE' - - # create distribution - import pyste - version = pyste.__VERSION__ - zip = ZipFile('pyste-%s.zip' % version, 'w', ZIP_DEFLATED) - # include the base files - dist_dir = 'dist/pyste' - for basefile in os.listdir(dist_dir): - zip.write(os.path.join(dist_dir, basefile), os.path.join('pyste', basefile)) - # include documentation - for doc_file in findfiles('../doc', '*.*'): - dest_name = os.path.join('pyste/doc', doc_file[3:]) - zip.write(doc_file, dest_name) - zip.write('../index.html', 'pyste/doc/index.html') - zip.close() - # cleanup - os.remove('build.log') - shutil.rmtree('build') - shutil.rmtree('dist') - - -if __name__ == '__main__': - sys.path.append('../src') - main() diff --git a/pyste/dist/setup.py b/pyste/dist/setup.py deleted file mode 100644 index fc7c74e2..00000000 --- a/pyste/dist/setup.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost -# Software License, Version 1.0. (See accompanying -# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -from distutils.core import setup -import py2exe -import sys - -sys.path.append('../src') -setup(name='pyste', scripts=['../src/pyste.py']) diff --git a/pyste/doc/adding_new_methods.html b/pyste/doc/adding_new_methods.html deleted file mode 100644 index afa772bc..00000000 --- a/pyste/doc/adding_new_methods.html +++ /dev/null @@ -1,79 +0,0 @@ - - - -Adding New Methods - - - - - - - - - - -
- - Adding New Methods -
-
- - - - - - -
-

-Suppose that you want to add a function to a class, turning it into a member -function:

-
-    struct World
-    {
-        void set(std::string msg) { this->msg = msg; }
-        std::string msg;
-    };
-
-    std::string greet(World& w)
-    {
-        return w.msg;
-    }
-
-

-Here, we want to make greet work as a member function of the class World. We do -that using the add_method construct:

-
-    W = Class("World", "hello.h")
-    add_method(W, "greet")
-
-

-Notice also that then you can rename it, set its policy, just like a regular -member function:

-
-    rename(W.greet, 'Greet')
-
-

-Now from Python:

-
-    >>> import hello
-    >>> w = hello.World()
-    >>> w.set('Ni')
-    >>> w.greet()
-    'Ni'
-    >>> print 'Oh no! The knights who say Ni!'
-    Oh no! The knights who say Ni!
-
- - - - - - -
-
-
- - diff --git a/pyste/doc/exporting_an_entire_header.html b/pyste/doc/exporting_an_entire_header.html deleted file mode 100644 index db25325c..00000000 --- a/pyste/doc/exporting_an_entire_header.html +++ /dev/null @@ -1,85 +0,0 @@ - - - -Exporting An Entire Header - - - - - - - - - - -
- - Exporting An Entire Header -
-
- - - - - - -
-

-Pyste also supports a mechanism to export all declarations found in a header -file. Suppose again our file, hello.h:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} 
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-    enum choice { red, blue };
-    
-    void show(choice c) { std::cout << "value: " << (int)c << std::endl; } 
-
-

-You can just use the AllFromHeader construct:

-
-    hello = AllFromHeader("hello.h")
-
-

-this will export all the declarations found in hello.h, which is equivalent -to write:

-
-    Class("World", "hello.h")
-    Enum("choice", "hello.h")
-    Function("show", "hello.h")
-
-

-Note that you can still use the functions rename, set_policy, exclude, etc. Just access -the members of the header object like this:

-
-    rename(hello.World.greet, "Greet")
-    exclude(hello.World.set, "Set")
-
- - - - -
- - AllFromHeader is broken in some cases. Until it is fixed, -use at you own risk. -
- - - - - - -
-
-
- - diff --git a/pyste/doc/global_variables.html b/pyste/doc/global_variables.html deleted file mode 100644 index 0efd2950..00000000 --- a/pyste/doc/global_variables.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Global Variables - - - - - - - - - - -
- - Global Variables -
-
- - - - - - -
-

-To export global variables, use the Var construct:

-
-    Var("myglobal", "foo.h")
-
-

-Beware of non-const global variables: changes in Python won't reflect in C++! -If you really must change them in Python, you will have to write some accessor -functions, and export those.

- - - - - - -
-
-
- - diff --git a/pyste/doc/inserting_code.html b/pyste/doc/inserting_code.html deleted file mode 100644 index 97eb70f3..00000000 --- a/pyste/doc/inserting_code.html +++ /dev/null @@ -1,72 +0,0 @@ - - - -Inserting Code - - - - - - - - - -
- - Inserting Code -
-
- - - - - - -
-

-You can insert arbitrary code in the generated cpps, just use the functions -declaration_code and module_code. This will insert the given string in the -respective sections. Example:

-
-    ##file A.pyste
-    Class("A", "A.h")
-    declaration_code("/* declaration_code() comes here */\n")
-    module_code("/* module_code() comes here */\n")
-
-

-Will generate:

-
-    // Includes ====================================================================
-    #include <boost/python.hpp>
-
-    // Using =======================================================================
-    using namespace boost::python;
-
-    // Declarations ================================================================
-
-    /* declaration_code() comes here */
-
-    // Module ======================================================================
-    BOOST_PYTHON_MODULE(A)
-    {
-        class_< A >("A", init<  >())
-            .def(init< const A& >())
-        ;
-
-    /* module_code() comes here */
-    }
-
- - - - - - -
-
-
- - diff --git a/pyste/doc/introduction.html b/pyste/doc/introduction.html deleted file mode 100644 index 94388493..00000000 --- a/pyste/doc/introduction.html +++ /dev/null @@ -1,73 +0,0 @@ - - - -Introduction - - - - - - - - - -
- - Introduction -
-
- - - - - - -
-

What is Pyste?

-Pyste is a -Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple interface file, which following the - -Boost.Python's philosophy, is simple Python code. Pyste then uses -GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code.

-

Example

-Let's borrow the class World from the -tutorial:

-
-    struct World
-    {
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-

-Here's the interface file for it, named world.pyste:

-
-    Class("World", "world.h")
-
-

-and that's it!

-

-The next step is invoke Pyste in the command-line:

-
python pyste.py --module=hello world.pyste

-this will create a file "hello.cpp" in the directory where the command was -run.

-

-Pyste supports the following features:

-
  • Functions
  • Classes
  • Class Templates
  • Virtual Methods
  • Overloading
  • Attributes
  • Enums (both "free" enums and class enums)
  • Nested Classes
  • Support for boost::shared_ptr and std::auto_ptr
  • Global Variables
- - - - - -
-
-
- - diff --git a/pyste/doc/policies.html b/pyste/doc/policies.html deleted file mode 100644 index 3628093b..00000000 --- a/pyste/doc/policies.html +++ /dev/null @@ -1,90 +0,0 @@ - - - -Policies - - - - - - - - - - -
- - Policies -
-
- - - - - - -
-

-Even thought Pyste can identify various elements in the C++ code, like virtual -member functions, attributes, and so on, one thing that it can't do is to -guess the semantics of functions that return pointers or references. In this -case, the user must manually specify the policy. Policies are explained in the - -tutorial.

-

-The policies in Pyste are named exactly as in -Boost.Python, only the syntax is -slightly different. For instance, this policy:

-
-    return_internal_reference<1, with_custodian_and_ward<1, 2> >()
-
-

-becomes in Pyste:

-
-    return_internal_reference(1, with_custodian_and_ward(1, 2))
-
-

-The user can specify policies for functions and virtual member functions with -the set_policy function:

-
-    set_policy(f, return_internal_reference())
-    set_policy(C.foo, return_value_policy(manage_new_object))
-
- - - - -
- - What if a function or member function needs a policy and -the user doesn't set one?

If a function needs a policy and one -was not set, Pyste will issue a error. The user should then go in the -interface file and set the policy for it, otherwise the generated cpp won't -compile. -
- - - - -
- - -Note that for functions that return const T&, the policy -return_value_policy<copy_const_reference>() wil be used by default, because -that's normally what you want. You can change it to something else if you need -to, though. -
- - - - - - -
-
-
- - diff --git a/pyste/doc/pyste.txt b/pyste/doc/pyste.txt deleted file mode 100644 index 186a31cb..00000000 --- a/pyste/doc/pyste.txt +++ /dev/null @@ -1,664 +0,0 @@ -[doc Pyste Documentation] - -[/ Copyright 2003 Bruno da Silva de Oliveira and Joel de Guzman. -Distributed under the Boost Software License, Version 1.0. (See -accompanying file LICENSE_1_0.txt or copy at -http://www.boost.org/LICENSE_1_0.txt) ] - -[def GCCXML [@http://www.gccxml.org GCCXML]] -[def Boost.Python [@../../index.html Boost.Python]] - -[page Introduction] - -[h2 What is Pyste?] - -Pyste is a Boost.Python code generator. The user specifies the classes and -functions to be exported using a simple ['interface file], which following the -Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to -parse all the headers and extract the necessary information to automatically -generate C++ code. - -[h2 Example] - -Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - -Here's the interface file for it, named [^world.pyste]: - - Class("World", "world.h") - -and that's it! - -The next step is invoke Pyste in the command-line: - -[pre python pyste.py --module=hello world.pyste] - -this will create a file "[^hello.cpp]" in the directory where the command was -run. - -Pyste supports the following features: - -* Functions -* Classes -* Class Templates -* Virtual Methods -* Overloading -* Attributes -* Enums (both "free" enums and class enums) -* Nested Classes -* Support for [^boost::shared_ptr] and [^std::auto_ptr] -* Global Variables - -[page Running Pyste] - -To run Pyste, you will need: - -* Python 2.2, available at [@http://www.python.org python's website]. -* The great [@http://effbot.org elementtree] library, from Fredrik Lundh. -* The excellent GCCXML, from Brad King. - -Installation for the tools is available in their respective webpages. - -[blurb -[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so -that Pyste can call it. How to do this varies from platform to platform. -] - -[h2 Ok, now what?] - -Well, now let's fire it up: - -[pre -''' ->python pyste.py - -Pyste version 0.9.26 - -Usage: - pyste [options] interface-files - -where options are: - --module= The name of the module that will be generated; - defaults to the first interface filename, without - the extension. - -I Add an include path - -D Define symbol - --multiple Create various cpps, instead of only one - (useful during development) - --out= Specify output filename (default: .cpp) - in --multiple mode, this will be a directory - --no-using Do not declare "using namespace boost"; - use explicit declarations instead - --pyste-ns= Set the namespace where new types will be declared; - default is the empty namespace - --debug Writes the xml for each file parsed in the current - directory - --cache-dir= Directory for cache files (speeds up future runs) - --only-create-cache Recreates all caches (doesn't generate code). - --generate-main Generates the _main.cpp file (in multiple mode) - --file-list A file with one pyste file per line. Use as a - substitute for passing the files in the command - line. - -h, --help Print this help and exit - -v, --version Print version information - -''' -] - -Options explained: - -The [^-I] and [^-D] are preprocessor flags, which are needed by GCCXML to parse -the header files correctly and by Pyste to find the header files declared in the -interface files. - -[^--out] names the output file (default: [^.cpp]), or in multiple mode, -names a output directory for the files (default: [^]). - -[^--no-using] tells Pyste to don't declare "[^using namespace boost;]" in the -generated cpp, using the namespace boost::python explicitly in all declarations. -Use only if you're having a name conflict in one of the files. - -Use [^--pyste-ns] to change the namespace where new types are declared (for -instance, the virtual wrappers). Use only if you are having any problems. By -default, Pyste uses the empty namespace. - -[^--debug] will write in the current directory a xml file as outputted by GCCXML -for each header parsed. Useful for bug reports. - -[^--file-list] names a file where each line points to a Pyste file. Use this instead -to pass the pyste files if you have a lot of them and your shell has some command line -size limit. - -The other options are explained below, in [@#multiple_mode [*Multiple Mode]] and -[@#cache [*Cache]]. - -[^-h, --help, -v, --version] are self-explaining, I believe. ;) - -So, the usage is simple enough: - -[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...] - -will generate a file [^mymodule.cpp] in the same dir where the command was -executed. Now you can compile the file using the same instructions of the -[@../../doc/tutorial/doc/building_hello_world.html tutorial]. - -[h2 Wait... how do I set those I and D flags?] - -Don't worry: normally GCCXML is already configured correctly for your plataform, -so the search path to the standard libraries and the standard defines should -already be set. You only have to set the paths to other libraries that your code -needs, like Boost, for example. - -Plus, Pyste automatically uses the contents of the environment variable -[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file, -which for Visual C++ 6 is normally located at: - - C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat - -with that, you should have little trouble setting up the flags. - -[blurb [$theme/note.gif][*A note about Psyco][br][br] -Although you don't have to install [@http://psyco.sourceforge.net/ Psyco] to -use Pyste, if you do, Pyste will make use of it to speed up the wrapper -generation. Speed ups of 30% can be achieved, so it's highly recommended. -] - - -[h2 Multiple Mode] - -The multiple mode is useful in large projects, where the presence of multiple -classes in a single file makes the compilation unpractical (excessive memory -usage, mostly). - -The solution is make Pyste generate multiple files, more specifically one cpp -file for each Pyste file. This files will contain a function named after the -file, for instance Export_MyPysteFile, which will contain all the code to export -the classes, enums, etc. You can pass as much files as you want this way: - -[pre >python pyste.py --module=mymodule file1.pyste file2.pyste] - -This will create the files [^mymodule/file1.cpp] and [^mymodule/file2.cpp]. You -can then later do: - -[pre >python pyste.py --module=mymodule file3.pyste] - -and [^mymodule/file3.cpp] will be generated. - -But compiling and linking this files won't be sufficient to generate your -extension. You have to also generate a file named [^main.cpp]; call pyste with -[*all] the Pyste files of your extension, and use the [^--generate-main] option: - -[pre >python pyste.py --module=mymodule --generate-main file1.pyste file2.pyste file3.pyste] - -Now compile and link all this files together and your extension is ready for -use. - -[h2 Cache] - -Pyste now supports a form of cache, which is a way to speed up the code -generation. Most of the time that Pyste takes to generate the code comes from -having to execute GCCXML (since being a front-end to GCC, it has to compile the -header files) and reading back the XML generated. - -When you use the [^--cache-dir=] option, Pyste will dump in the specified -directory the generated XMLs to a file named after the Pyste file, with the -extension [^.pystec]. The next time you run with this option, Pyste will use -the cache, instead of calling GCCXML again: - -[pre >python pyste.py --module=mymodule --cache-dir=cache file1.pyste] - -Will generate [^file1.cpp] and [^cache/file1.pystec]. Next time you execute -this command, the cache file will be used. Note that Pyste doesn't do any check -to ensure that the cache is up to date, but you can configure your build system to do that for you. - -When you run Pyste with [^--only-create-cache], all the cache files will be -created again, but no code will be generated. - -[page The Interface Files] - -The interface files are the heart of Pyste. The user creates one or more -interface files declaring the classes and functions he wants to export, and then -invokes Pyste passing the interface files to it. Pyste then generates a single -cpp file with Boost.Python code, with all the classes and functions exported. - -Besides declaring the classes and functions, the user has a number of other -options, like renaming e excluding classes and member functionis. Those are -explained later on. - -[h2 Basics] - -Suppose we have a class and some functions that we want to expose to Python -declared in the header [^hello.h]: - - struct World - { - World(std::string msg): msg(msg) {} - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - - enum choice { red, blue }; - - namespace test { - - void show(choice c) { std::cout << "value: " << (int)c << std::endl; } - - } - -We create a file named [^hello.pyste] and create instances of the classes -[^Function], [^Class] and [^Enum]: - - Function("test::show", "hello.h") - Class("World", "hello.h") - Enum("choice", "hello.h") - -That will expose the class, the free function and the enum found in [^hello.h]. - -[h2 Inheritance] - -Pyste automatically generates the correct code (specifying [^bases<>] in the -[^class_] declaration) [*if] the Class() function that exports the base classes -and their children are in the same Pyste file. If that's not the case, you have -to indicate that there's a relationship between the Pyste files using the -[^Import] function specifying the other Pyste file. - -Suppose we have two classes, [^A] and [^B], and A is a base class for B. We -create two Pyste files: - -[^A.pyste]: - - Class("A", "A.h") - -[^B.pyste]: - - Import("A.pyste") - Class("B", "B.h") - -Note that we specify that [^B] needs to know about [^A] to be properly exported. - -[page:1 Renaming and Excluding] - -You can easily rename functions, classes, member functions, attributes, etc. Just use the -function [^rename], like this: - - World = Class("World", "hello.h") - rename(World, "IWorld") - show = Function("choice", "hello.h") - rename(show, "Show") - -You can rename member functions and attributes using this syntax: - - rename(World.greet, "Greet") - rename(World.set, "Set") - choice = Enum("choice", "hello.h") - rename(choice.red, "Red") - rename(choice.blue, "Blue") - -You can exclude functions, classes, member functions, attributes, etc, in the same way, -with the function [^exclude]: - - exclude(World.greet) - exclude(World.msg) - -To access the operators of a class, access the member [^operator] like this -(supposing that [^C] is a class being exported): - - exclude(C.operator['+']) - exclude(C.operator['*']) - exclude(C.operator['<<']) - -The string inside the brackets is the same as the name of the operator in C++.[br] - -[h2 Virtual Member Functions] - -Pyste automatically generates wrappers for virtual member functions, but you may -want to disable this behaviour (for performance reasons, for instance) if you do -not plan to override the functions in Python. To do this, use the function -[^final]: - - C = Class('C', 'C.h') - final(C.foo) # C::foo is a virtual member function - -No virtual wrapper code will be generated for the virtual member function -C::foo that way. - -[page:1 Policies] - -Even thought Pyste can identify various elements in the C++ code, like virtual -member functions, attributes, and so on, one thing that it can't do is to -guess the semantics of functions that return pointers or references. In this -case, the user must manually specify the policy. Policies are explained in the -[@../../doc/tutorial/doc/call_policies.html tutorial]. - -The policies in Pyste are named exactly as in Boost.Python, only the syntax is -slightly different. For instance, this policy: - - return_internal_reference<1, with_custodian_and_ward<1, 2> >() - -becomes in Pyste: - - return_internal_reference(1, with_custodian_and_ward(1, 2)) - -The user can specify policies for functions and virtual member functions with -the [^set_policy] function: - - set_policy(f, return_internal_reference()) - set_policy(C.foo, return_value_policy(manage_new_object)) - -[blurb -[$theme/note.gif] [*What if a function or member function needs a policy and -the user doesn't set one?][br][br] If a function needs a policy and one -was not set, Pyste will issue a error. The user should then go in the -interface file and set the policy for it, otherwise the generated cpp won't -compile. -] - -[blurb -[$theme/note.gif] -Note that for functions that return [^const T&], the policy -[^return_value_policy()] wil be used by default, because -that's normally what you want. You can change it to something else if you need -to, though. -] - -[page:1 Templates] - -Template classes can easily be exported too, but you can't export the template -itself... you have to export instantiations of it! So, if you want to export a -[^std::vector], you will have to export vectors of int, doubles, etc. - -Suppose we have this code: - - template - struct Point - { - T x; - T y; - }; - -And we want to export [^Point]s of int and double: - - Point = Template("Point", "point.h") - Point("int") - Point("double") - -Pyste will assign default names for each instantiation. In this example, those -would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to -rename the instantiations: - - Point("int", "IPoint") // renames the instantiation - double_inst = Point("double") // another way to do the same - rename(double_inst, "DPoint") - -Note that you can rename, exclude, set policies, etc, in the [^Template] object -like you would do with a [^Function] or a [^Class]. This changes affect all -[*future] instantiations: - - Point = Template("Point", "point.h") - Point("float", "FPoint") // will have x and y as data members - rename(Point.x, "X") - rename(Point.y, "Y") - Point("int", "IPoint") // will have X and Y as data members - Point("double", "DPoint") // also will have X and Y as data member - -If you want to change a option of a particular instantiation, you can do so: - - Point = Template("Point", "point.h") - Point("int", "IPoint") - d_inst = Point("double", "DPoint") - rename(d_inst.x, "X") // only DPoint is affect by this renames, - rename(d_inst.y, "Y") // IPoint stays intact - -[blurb [$theme/note.gif] [*What if my template accepts more than one type?] -[br][br] -When you want to instantiate a template with more than one type, you can pass -either a string with the types separated by whitespace, or a list of strings -'''("int double" or ["int", "double"]''' would both work). -] - -[page:1 Wrappers] - -Suppose you have this function: - - std::vector names(); - -But you don't want to [@../../doc/v2/faq.html#question2 to export std::vector], -you want this function to return a python list of strings. Boost.Python has -excellent support for things like that: - - list names_wrapper() - { - list result; - // call original function - vector v = names(); - // put all the strings inside the python list - vector::iterator it; - for (it = v.begin(); it != v.end(); ++it){ - result.append(*it); - } - return result; - } - - BOOST_PYTHON_MODULE(test) - { - def("names", &names_wrapper); - } - -Nice heh? Pyste supports this mechanism too. You declare the [^names_wrapper] -function in a header named "[^test_wrappers.h]" and in the interface file: - - Include("test_wrappers.h") - names = Function("names", "test.h") - set_wrapper(names, "names_wrapper") - -You can optionally declare the function in the interface file itself: - - names_wrapper = Wrapper("names_wrapper", - """ - list names_wrapper() - { - // code to call name() and convert the vector to a list... - } - """) - names = Function("names", "test.h") - set_wrapper(names, names_wrapper) - -The same mechanism can be used with member functions too. Just remember that -the first parameter of wrappers for member functions is a pointer to the -class, as in: - - struct C - { - std::vector names(); - } - - list names_wrapper(C* c) - { - // same as before, calling c->names() and converting result to a list - } - -And then in the interface file: - - C = Class("C", "test.h") - set_wrapper(C.names, "names_wrapper") - -[blurb -[$theme/note.gif]Even though Boost.Python accepts either a pointer or a -reference to the class in wrappers for member functions as the first parameter, -Pyste expects them to be a [*pointer]. Doing otherwise will prevent your -code to compile when you set a wrapper for a virtual member function. -] - -[page:1 Exporting An Entire Header] - -Pyste also supports a mechanism to export all declarations found in a header -file. Suppose again our file, [^hello.h]: - - struct World - { - World(std::string msg): msg(msg) {} - void set(std::string msg) { this->msg = msg; } - std::string greet() { return msg; } - std::string msg; - }; - - enum choice { red, blue }; - - void show(choice c) { std::cout << "value: " << (int)c << std::endl; } - -You can just use the [^AllFromHeader] construct: - - hello = AllFromHeader("hello.h") - -this will export all the declarations found in [^hello.h], which is equivalent -to write: - - Class("World", "hello.h") - Enum("choice", "hello.h") - Function("show", "hello.h") - -Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access -the members of the header object like this: - - rename(hello.World.greet, "Greet") - exclude(hello.World.set, "Set") - -[blurb -[$theme/note.gif] [*AllFromHeader is broken] in some cases. Until it is fixed, -use at you own risk. -] - - -[page:1 Smart Pointers] - -Pyste for now has manual support for smart pointers. Suppose: - - struct C - { - int value; - }; - - boost::shared_ptr newC(int value) - { - boost::shared_ptr c( new C() ); - c->value = value; - return c; - } - - void printC(boost::shared_ptr c) - { - std::cout << c->value << std::endl; - } - -To make [^newC] and [^printC] work correctly, you have to tell Pyste that a -convertor for [^boost::shared_ptr] is needed. - - C = Class('C', 'C.h') - use_shared_ptr(C) - Function('newC', 'C.h') - Function('printC', 'C.h') - -For [^std::auto_ptr]'s, use the function [^use_auto_ptr]. - -This system is temporary, and in the future the converters will automatically be -exported if needed, without the need to tell Pyste about them explicitly. - -[h2 Holders] - -If only the converter for the smart pointers is not enough and you need to -specify the smart pointer as the holder for a class, use the functions -[^hold_with_shared_ptr] and [^hold_with_auto_ptr]: - - C = Class('C', 'C.h') - hold_with_shared_ptr(C) - Function('newC', 'C.h') - Function('printC', 'C.h') - -[page:1 Global Variables] - -To export global variables, use the [^Var] construct: - - Var("myglobal", "foo.h") - -Beware of non-const global variables: changes in Python won't reflect in C++! -If you really must change them in Python, you will have to write some accessor -functions, and export those. - - -[page:1 Adding New Methods] - -Suppose that you want to add a function to a class, turning it into a member -function: - - struct World - { - void set(std::string msg) { this->msg = msg; } - std::string msg; - }; - - std::string greet(World& w) - { - return w.msg; - } - -Here, we want to make [^greet] work as a member function of the class [^World]. We do -that using the [^add_method] construct: - - W = Class("World", "hello.h") - add_method(W, "greet") - -Notice also that then you can rename it, set its policy, just like a regular -member function: - - rename(W.greet, 'Greet') - -Now from Python: - - >>> import hello - >>> w = hello.World() - >>> w.set('Ni') - >>> w.greet() - 'Ni' - >>> print 'Oh no! The knights who say Ni!' - Oh no! The knights who say Ni! - - -[page:1 Inserting Code] - -You can insert arbitrary code in the generated cpps, just use the functions -[^declaration_code] and [^module_code]. This will insert the given string in the -respective sections. Example: - - # file A.pyste - Class("A", "A.h") - declaration_code("/* declaration_code() comes here */\n") - module_code("/* module_code() comes here */\n") - -Will generate: - - // Includes ==================================================================== - #include - - // Using ======================================================================= - using namespace boost::python; - - // Declarations ================================================================ - - /* declaration_code() comes here */ - - // Module ====================================================================== - BOOST_PYTHON_MODULE(A) - { - class_< A >("A", init< >()) - .def(init< const A& >()) - ; - - /* module_code() comes here */ - } diff --git a/pyste/doc/renaming_and_excluding.html b/pyste/doc/renaming_and_excluding.html deleted file mode 100644 index ce6654c4..00000000 --- a/pyste/doc/renaming_and_excluding.html +++ /dev/null @@ -1,87 +0,0 @@ - - - -Renaming and Excluding - - - - - - - - - - -
- - Renaming and Excluding -
-
- - - - - - -
-

-You can easily rename functions, classes, member functions, attributes, etc. Just use the -function rename, like this:

-
-    World = Class("World", "hello.h")
-    rename(World, "IWorld")
-    show = Function("choice", "hello.h")
-    rename(show, "Show")
-
-

-You can rename member functions and attributes using this syntax:

-
-    rename(World.greet, "Greet")
-    rename(World.set, "Set")
-    choice = Enum("choice", "hello.h")
-    rename(choice.red, "Red")
-    rename(choice.blue, "Blue")
-
-

-You can exclude functions, classes, member functions, attributes, etc, in the same way, -with the function exclude:

-
-    exclude(World.greet)
-    exclude(World.msg)
-
-

-To access the operators of a class, access the member operator like this -(supposing that C is a class being exported):

-
-    exclude(C.operator['+'])
-    exclude(C.operator['*'])
-    exclude(C.operator['<<'])
-
-

-The string inside the brackets is the same as the name of the operator in C++.

-

Virtual Member Functions

-Pyste automatically generates wrappers for virtual member functions, but you may -want to disable this behaviour (for performance reasons, for instance) if you do -not plan to override the functions in Python. To do this, use the function -final:

-
-    C = Class('C', 'C.h')
-    final(C.foo) ##C::foo is a virtual member function
-
-

-No virtual wrapper code will be generated for the virtual member function -C::foo that way.

- - - - - - -
-
-
- - diff --git a/pyste/doc/running_pyste.html b/pyste/doc/running_pyste.html deleted file mode 100644 index 9bd9a3ae..00000000 --- a/pyste/doc/running_pyste.html +++ /dev/null @@ -1,200 +0,0 @@ - - - -Running Pyste - - - - - - - - - - -
- - Running Pyste -
-
- - - - - - -
-

-To run Pyste, you will need:

-

-Installation for the tools is available in their respective webpages.

- - - - -
- - -GCCXML must be accessible in the PATH environment variable, so -that Pyste can call it. How to do this varies from platform to platform. -
-

Ok, now what?

-Well, now let's fire it up:

-
-
->python pyste.py
-
-Pyste version 0.9.26
-
-Usage:
-    pyste [options] interface-files
-
-where options are:
-    --module=<name>         The name of the module that will be generated;
-                            defaults to the first interface filename, without
-                            the extension.
-    -I <path>               Add an include path
-    -D <symbol>             Define symbol
-    --multiple              Create various cpps, instead of only one
-                            (useful during development)
-    --out=<name>            Specify output filename (default: <module>.cpp)
-                            in --multiple mode, this will be a directory
-    --no-using              Do not declare "using namespace boost";
-                            use explicit declarations instead
-    --pyste-ns=<name>       Set the namespace where new types will be declared;
-                            default is the empty namespace
-    --debug                 Writes the xml for each file parsed in the current
-                            directory
-    --cache-dir=<dir>       Directory for cache files (speeds up future runs)
-    --only-create-cache     Recreates all caches (doesn't generate code).
-    --generate-main         Generates the _main.cpp file (in multiple mode)
-    --file-list             A file with one pyste file per line. Use as a 
-                            substitute for passing the files in the command
-                            line.
-    -h, --help              Print this help and exit
-    -v, --version           Print version information
-  
-                        
-

-Options explained:

-

-The -I and -D are preprocessor flags, which are needed by -GCCXML to parse -the header files correctly and by Pyste to find the header files declared in the -interface files.

-

---out names the output file (default: <module>.cpp), or in multiple mode, -names a output directory for the files (default: <module>).

-

---no-using tells Pyste to don't declare "using namespace boost;" in the -generated cpp, using the namespace boost::python explicitly in all declarations. -Use only if you're having a name conflict in one of the files.

-

-Use --pyste-ns to change the namespace where new types are declared (for -instance, the virtual wrappers). Use only if you are having any problems. By -default, Pyste uses the empty namespace.

-

---debug will write in the current directory a xml file as outputted by -GCCXML -for each header parsed. Useful for bug reports.

-

---file-list names a file where each line points to a Pyste file. Use this instead -to pass the pyste files if you have a lot of them and your shell has some command line -size limit.

-

-The other options are explained below, in -Multiple Mode and - -Cache.

-

--h, --help, -v, --version are self-explaining, I believe. ;)

-

-So, the usage is simple enough:

-
>python pyste.py --module=mymodule file.pyste file2.pyste ...

-will generate a file mymodule.cpp in the same dir where the command was -executed. Now you can compile the file using the same instructions of the - -tutorial.

-

Wait... how do I set those I and D flags?

-Don't worry: normally -GCCXML is already configured correctly for your plataform, -so the search path to the standard libraries and the standard defines should -already be set. You only have to set the paths to other libraries that your code -needs, like Boost, for example.

-

-Plus, Pyste automatically uses the contents of the environment variable -INCLUDE if it exists. Visual C++ users should run the Vcvars32.bat file, -which for Visual C++ 6 is normally located at:

-
-    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
-
-

-with that, you should have little trouble setting up the flags.

- - - - -
-A note about Psyco

-Although you don't have to install -Psyco to -use Pyste, if you do, Pyste will make use of it to speed up the wrapper -generation. Speed ups of 30% can be achieved, so it's highly recommended. -
-

Multiple Mode

-The multiple mode is useful in large projects, where the presence of multiple -classes in a single file makes the compilation unpractical (excessive memory -usage, mostly).

-

-The solution is make Pyste generate multiple files, more specifically one cpp -file for each Pyste file. This files will contain a function named after the -file, for instance Export_MyPysteFile, which will contain all the code to export -the classes, enums, etc. You can pass as much files as you want this way:

-
>python pyste.py --module=mymodule file1.pyste file2.pyste

-This will create the files mymodule/file1.cpp and mymodule/file2.cpp. You -can then later do:

-
>python pyste.py --module=mymodule file3.pyste

-and mymodule/file3.cpp will be generated.

-

-But compiling and linking this files won't be sufficient to generate your -extension. You have to also generate a file named main.cpp; call pyste with -all the Pyste files of your extension, and use the --generate-main option:

-
>python pyste.py --module=mymodule --generate-main file1.pyste file2.pyste file3.pyste

-Now compile and link all this files together and your extension is ready for -use.

-

Cache

-Pyste now supports a form of cache, which is a way to speed up the code -generation. Most of the time that Pyste takes to generate the code comes from -having to execute -GCCXML (since being a front-end to GCC, it has to compile the -header files) and reading back the XML generated.

-

-When you use the --cache-dir=<dir> option, Pyste will dump in the specified -directory the generated XMLs to a file named after the Pyste file, with the -extension .pystec. The next time you run with this option, Pyste will use -the cache, instead of calling -GCCXML again:

-
>python pyste.py --module=mymodule --cache-dir=cache file1.pyste

-Will generate file1.cpp and cache/file1.pystec. Next time you execute -this command, the cache file will be used. Note that Pyste doesn't do any check -to ensure that the cache is up to date, but you can configure your build system to do that for you.

-

-When you run Pyste with --only-create-cache, all the cache files will be -created again, but no code will be generated.

- - - - - - -
-
-
- - diff --git a/pyste/doc/smart_pointers.html b/pyste/doc/smart_pointers.html deleted file mode 100644 index cddc96f2..00000000 --- a/pyste/doc/smart_pointers.html +++ /dev/null @@ -1,84 +0,0 @@ - - - -Smart Pointers - - - - - - - - - - -
- - Smart Pointers -
-
- - - - - - -
-

-Pyste for now has manual support for smart pointers. Suppose:

-
-    struct C
-    {
-        int value;
-    };
-
-    boost::shared_ptr<C> newC(int value)
-    {
-        boost::shared_ptr<C> c( new C() );
-        c->value = value;
-        return c;
-    }
-
-    void printC(boost::shared_ptr<C> c)
-    {
-        std::cout << c->value << std::endl;
-    }
-
-

-To make newC and printC work correctly, you have to tell Pyste that a -convertor for boost::shared_ptr<C> is needed.

-
-    C = Class('C', 'C.h')
-    use_shared_ptr(C)
-    Function('newC', 'C.h')
-    Function('printC', 'C.h')
-
-

-For std::auto_ptr's, use the function use_auto_ptr.

-

-This system is temporary, and in the future the converters will automatically be -exported if needed, without the need to tell Pyste about them explicitly.

-

Holders

-If only the converter for the smart pointers is not enough and you need to -specify the smart pointer as the holder for a class, use the functions -hold_with_shared_ptr and hold_with_auto_ptr:

-
-    C = Class('C', 'C.h')
-    hold_with_shared_ptr(C)
-    Function('newC', 'C.h')
-    Function('printC', 'C.h') 
-
- - - - - - -
-
-
- - diff --git a/pyste/doc/templates.html b/pyste/doc/templates.html deleted file mode 100644 index a1c1cfef..00000000 --- a/pyste/doc/templates.html +++ /dev/null @@ -1,102 +0,0 @@ - - - -Templates - - - - - - - - - - -
- - Templates -
-
- - - - - - -
-

-Template classes can easily be exported too, but you can't export the template -itself... you have to export instantiations of it! So, if you want to export a -std::vector, you will have to export vectors of int, doubles, etc.

-

-Suppose we have this code:

-
-    template <class T>
-    struct Point
-    {
-        T x;
-        T y;
-    };
-
-

-And we want to export Points of int and double:

-
-    Point = Template("Point", "point.h")
-    Point("int")
-    Point("double")
-
-

-Pyste will assign default names for each instantiation. In this example, those -would be "Point_int" and "Point_double", but most of the time users will want to -rename the instantiations:

-
-    Point("int", "IPoint")         // renames the instantiation
-    double_inst = Point("double")  // another way to do the same
-    rename(double_inst, "DPoint")
-
-

-Note that you can rename, exclude, set policies, etc, in the Template object -like you would do with a Function or a Class. This changes affect all -future instantiations:

-
-    Point = Template("Point", "point.h")
-    Point("float", "FPoint")        // will have x and y as data members
-    rename(Point.x, "X")
-    rename(Point.y, "Y")
-    Point("int", "IPoint")          // will have X and Y as data members
-    Point("double", "DPoint")       // also will have X and Y as data member
-
-

-If you want to change a option of a particular instantiation, you can do so:

-
-    Point = Template("Point", "point.h")
-    Point("int", "IPoint")          
-    d_inst = Point("double", "DPoint")       
-    rename(d_inst.x, "X")           // only DPoint is affect by this renames,
-    rename(d_inst.y, "Y")           // IPoint stays intact
-
- - - - -
- What if my template accepts more than one type? -

-When you want to instantiate a template with more than one type, you can pass -either a string with the types separated by whitespace, or a list of strings -("int double" or ["int", "double"] would both work). -
- - - - - - -
-
-
- - diff --git a/pyste/doc/the_interface_files.html b/pyste/doc/the_interface_files.html deleted file mode 100644 index 9c020043..00000000 --- a/pyste/doc/the_interface_files.html +++ /dev/null @@ -1,102 +0,0 @@ - - - -The Interface Files - - - - - - - - - - -
- - The Interface Files -
-
- - - - - - -
-

-The interface files are the heart of Pyste. The user creates one or more -interface files declaring the classes and functions he wants to export, and then -invokes Pyste passing the interface files to it. Pyste then generates a single -cpp file with -Boost.Python code, with all the classes and functions exported.

-

-Besides declaring the classes and functions, the user has a number of other -options, like renaming e excluding classes and member functionis. Those are -explained later on.

-

Basics

-Suppose we have a class and some functions that we want to expose to Python -declared in the header hello.h:

-
-    struct World
-    {
-        World(std::string msg): msg(msg) {} 
-        void set(std::string msg) { this->msg = msg; }
-        std::string greet() { return msg; }
-        std::string msg;
-    };
-
-    enum choice { red, blue };
-    
-    namespace test {
-    
-    void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
-    
-    }
-
-

-We create a file named hello.pyste and create instances of the classes -Function, Class and Enum:

-
-    Function("test::show", "hello.h")
-    Class("World", "hello.h")
-    Enum("choice", "hello.h")
-
-

-That will expose the class, the free function and the enum found in hello.h.

-

Inheritance

-Pyste automatically generates the correct code (specifying bases<> in the -class_ declaration) if the Class() function that exports the base classes -and their children are in the same Pyste file. If that's not the case, you have -to indicate that there's a relationship between the Pyste files using the -Import function specifying the other Pyste file.

-

-Suppose we have two classes, A and B, and A is a base class for B. We -create two Pyste files:

-

-A.pyste:

-
-    Class("A", "A.h")
-
-

-B.pyste:

-
-    Import("A.pyste")
-    Class("B", "B.h")
-
-

-Note that we specify that B needs to know about A to be properly exported.

- - - - - - -
-
-
- - diff --git a/pyste/doc/theme/alert.gif b/pyste/doc/theme/alert.gif deleted file mode 100644 index 270764cc58716d36f8545c07ffbccb76a3dbc7f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 577 zcmZ?wbhEHb6krfwc*el+^5x4HFJ3%)^yuNkhj;GW`TvCB_N{CGA2IyD%W(C|x&OBr z{@-G_a_Q{m__~8F~vDYEl>qqZpDSjq@WJa>5z1Lm6Vd z86rG+L!23`^cb|27{rAb*jO1D7#RNl{|}<5jTL{gu!=AwGw6T}2E_>j`@DwarsiZ7 zvzCqy8~4s$Mnes@-VRGi5tqr$%yz7-+I%yUbrd6_%=Konm?$SD`KoeGb{17nO!DDy z>t(PKkWWZ*<cQAmnAE=fsD%$UE$ROUW+NUZ1+QQKJ-!ms2) z!wk-f=<_sLpE#kg){9r_k3+JcmI}v|3yP=3Bn5<=JQ5$B644M)RP)^A(&gG6!^Fs7 F4FJH#(p~@n diff --git a/pyste/doc/theme/arrow.gif b/pyste/doc/theme/arrow.gif deleted file mode 100644 index e33db0fb4dd85e0fe527343d95a3f28a0ebb74f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70 zcmZ?wbhEHb6lLIGn8?8J9}E~6W->4^DE?&OC-XFJFH7^5yH-udiOcdjJ0Y=g*&CzkdDw`}cS6-hKG+ zVdct|pFVy1_U+rhfB)XRdGq$|+aEuEeEj(F|NsB1R;~K`_wVY}tN;A@vu4ej6)RT! z{{8#cuU~7|u3fio-TL+GfByWrapT4f8#Zj(v}yC^&D*wZ+q!k@mMvR$@7{gjz=7@C zx9{A!bMM~0yLRo`vuDr#{rh+9*s*WlzC(u&9X)#V)TvV^Po6w- zyLay%Jb3Wz*|X1|Kfizf{+Tmpu3fwK^y$-^H*a3Qe*M|AXXnnHJAeNCg$oysA3uKe z>eWk^E+4<0lBLU*@T^?5dd(`K^&2*BTFEI`2zd3>o;z)v)s9R@BSUeM~|O8Wn_5q^405CHt*hl`1r~B%hzw;zdQW;{pasr zF9v2V8Hs|fgUuYmej5*MSa`TSY=y@hkBv&AY7)j-cRDt)dE zU9$D{^$pSTGkte&%f01a^!nae>+L=F4>WVj`|WA_`1r(RZF9M$J3l|aF#GrnzrDM@ zzP^$C;>NkXyT8BJIMglgzi&_FC%sFnlY$n!TsEid z)yw4z+N54FEt!_}YUPS$t6r^IvuM`A)fY$|rssS*xogRqPp5XWJpOdrfW7(58I$WZ zJ;oN#*L*&AD&X$RBj zw_mR(wCjGmkup8^+s%ySYroyf+5Yz1?SkXF-|v)M&;5S4;`!R|_iFabaxho}0O~&E Au>b%7 diff --git a/pyste/doc/theme/bkd2.gif b/pyste/doc/theme/bkd2.gif deleted file mode 100644 index b03d9ba97ca7a4c4de297b5413fd3d3df8e0fb49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2543 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 diff --git a/pyste/doc/theme/bulb.gif b/pyste/doc/theme/bulb.gif deleted file mode 100644 index 74f3baac42f12ac0551040a00f78cb573360a0ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 944 zcmZ?wbhEHbU2JX=yWO8qb`WHgo38Gifu=q@6jF_W#UGhBGsb&&*6a zGjrydnP<+-{D0;Q!i=IrIPje+GvC495Q% z(*85d1W7Xd|8LCj-`M!SaoT_5nIN^s|No~k{7*CfpO*GNZ6-)-+W-GE8UD{S{y#JA z|IC>nlV<+^e}>`z8RP$8cYq8A8~y)3Nb~>yAnE^L0P?^n9t{C$ zm!W3VRz=HX0SO5P1_s5SEQ|~c3=BFT0%V2*i>ts1&-4h1-QU}6JQPJ#9Az#qP{_IL z>m8xcQ#>ccK&B>uvC-M7@I$1?63NFG4AfGLn>kr6)<~>7uC&oZb>E%VNA7Gc3=Gx) DZ>u*X diff --git a/pyste/doc/theme/l_arr.gif b/pyste/doc/theme/l_arr.gif deleted file mode 100644 index 5b3cb1cbf07e316c3655ac84c9ba72dfbe2e25a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#U2JX=yW!8D`F$dFITS|7mIeXEOYsnf8C?%>QSM|DT!p z|3Ab3|7ZS#f#OdVMg|6c1|5)2kQodtE+0;Mrh1v)&NktlbFtDU2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#&gTE>G6muSe93zS-%fd>Q)&EUbx3v}%NcRk;>%V0Cvz}Z0{|MoM2G+Y diff --git a/pyste/doc/theme/r_arr_disabled.gif b/pyste/doc/theme/r_arr_disabled.gif deleted file mode 100644 index 2100f78bf35a47e09ca76ffcc6e80c5a2b11e359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91 zcmZ?wbhEHb6k!l%n8?5|bLPzZ_wWDz|DS<@LGdRGs|W)VgAM}&0|Q8&fk|gd|H|rv v@(cz3o}Svfg4O3$GVLgQHgm3)*?|1&XIvGFi0itr1TiFoeP&p1C|3gi5M|Dy8)Dq>pVFYM_y+=U^T ztHBMdj+tQ(A2Y*wF$RYE_4D-@jtU##9xMTW{_9v6c`wK7#J8B1sE6<80-`n z7><}aTg5mA1O&%;g!uX}*f26MGK54pa~u~3ne&L_xcGT71qKC%`|QWX?G$<#K=P%G z=f$!jvLf=G=8H2hFfyd8*(n?_D`m7(uv4gs=yaGbo~{-bxlJUa@tDY4zP5<9g6(Q8 z@$VV#2iy??g*_vVXy`OS*Qv? diff --git a/pyste/doc/theme/style.css b/pyste/doc/theme/style.css deleted file mode 100644 index 643df02a..00000000 --- a/pyste/doc/theme/style.css +++ /dev/null @@ -1,178 +0,0 @@ -/*============================================================================= - Copyright (c) 2003 Bruno da Silva de Oliveira - - Use, modification and distribution is subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ - -body -{ - background-image: url(bkd.gif); - background-color: #FFFFFF; - margin: 1em 2em 1em 2em; -} - -h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } -h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } -h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } -h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } -h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } -h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } - -pre -{ - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-top: 2pt; - padding-right: 2pt; - padding-left: 2pt; - padding-bottom: 2pt; - - display: block; - font-family: "courier new", courier, mono; - background-color: #eeeeee; font-size: small -} - -code -{ - font-family: "Courier New", Courier, mono; - font-size: small -} - -tt -{ - display: inline; - font-family: "Courier New", Courier, mono; - color: #000099; - font-size: small -} - -p -{ - text-align: justify; - font-family: Georgia, "Times New Roman", Times, serif -} - -ul -{ - list-style-image: url(bullet.gif); - font-family: Georgia, "Times New Roman", Times, serif -} - -ol -{ - font-family: Georgia, "Times New Roman", Times, serif -} - -a -{ - font-weight: bold; - color: #003366; - text-decoration: none; -} - -a:hover { color: #8080FF; } - -.literal { color: #666666; font-style: italic} -.keyword { color: #000099} -.identifier {} -.comment { font-style: italic; color: #990000} -.special { color: #800040} -.preprocessor { color: #FF0000} -.string { font-style: italic; color: #666666} -.copyright { color: #666666; font-size: small} -.white_bkd { background-color: #FFFFFF} -.dk_grey_bkd { background-color: #999999} -.quotes { color: #666666; font-style: italic; font-weight: bold} - -.note_box -{ - display: block; - - border-top: gray 1pt solid; - border-right: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - - padding-right: 12pt; - padding-left: 12pt; - padding-bottom: 12pt; - padding-top: 12pt; - - font-family: Arial, Helvetica, sans-serif; - background-color: #E2E9EF; - font-size: small; text-align: justify -} - -.table_title -{ - background-color: #648CCA; - - font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; - font-weight: bold -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.table_cells -{ - background-color: #E2E9EF; - - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px -} - -.toc -{ - DISPLAY: block; - background-color: #E2E9EF - font-family: Arial, Helvetica, sans-serif; - - border-top: gray 1pt solid; - border-left: gray 1pt solid; - border-bottom: gray 1pt solid; - border-right: gray 1pt solid; - - padding-top: 24pt; - padding-right: 24pt; - padding-left: 24pt; - padding-bottom: 24pt; -} - -.toc_title -{ - background-color: #648CCA; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - color: #FFFFFF; - font-weight: bold -} - -.toc_cells -{ - background-color: #E2E9EF; - padding-top: 4px; - padding-right: 4px; - padding-bottom: 4px; - padding-left: 4px; - font-family: Geneva, Arial, Helvetica, san-serif; - font-size: small -} - -div.logo -{ - float: right; -} - -.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } -.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/pyste/doc/theme/u_arr.gif b/pyste/doc/theme/u_arr.gif deleted file mode 100644 index ada3d6e043d2e4314a20d6783f2800f2f21d89c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#pCE@bTiY5O-A{7vV42g%c7%l^E8u0x - - -Wrappers - - - - - - - - - - -
- - Wrappers -
-
- - - - - - -
-

-Suppose you have this function:

-
-    std::vector<std::string> names();
-
-

-But you don't want to -to export std::vector<std::string>, -you want this function to return a python list of strings. -Boost.Python has -excellent support for things like that:

-
-    list names_wrapper()
-    {
-        list result;
-        // call original function
-        vector<string> v = names();
-        // put all the strings inside the python list
-        vector<string>::iterator it;
-        for (it = v.begin(); it != v.end(); ++it){
-            result.append(*it);    
-        }
-        return result;
-    }
-    
-    BOOST_PYTHON_MODULE(test)
-    {
-        def("names", &names_wrapper);
-    }
-
-

-Nice heh? Pyste supports this mechanism too. You declare the names_wrapper -function in a header named "test_wrappers.h" and in the interface file:

-
-    Include("test_wrappers.h")
-    names = Function("names", "test.h")
-    set_wrapper(names, "names_wrapper")
-
-

-You can optionally declare the function in the interface file itself:

-
-    names_wrapper = Wrapper("names_wrapper",
-    """
-    list names_wrapper()
-    {
-        // code to call name() and convert the vector to a list...
-    }
-    """)
-    names = Function("names", "test.h")
-    set_wrapper(names, names_wrapper)
-
-

-The same mechanism can be used with member functions too. Just remember that -the first parameter of wrappers for member functions is a pointer to the -class, as in:

-
-    struct C
-    {
-        std::vector<std::string> names();
-    }
-
-    list names_wrapper(C* c)
-    {
-        // same as before, calling c->names() and converting result to a list 
-    }
-
-

-And then in the interface file:

-
-    C = Class("C", "test.h")
-    set_wrapper(C.names, "names_wrapper")
-
- - - - -
- -Even though -Boost.Python accepts either a pointer or a -reference to the class in wrappers for member functions as the first parameter, -Pyste expects them to be a pointer. Doing otherwise will prevent your -code to compile when you set a wrapper for a virtual member function. -
- - - - - - -
-
-
- - diff --git a/pyste/index.html b/pyste/index.html deleted file mode 100644 index 953b37c1..00000000 --- a/pyste/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - -Pyste Documentation - - - - - - - - - -
- - Pyste Documentation -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table of contents
- Introduction -
- Running Pyste -
- The Interface Files -
- Renaming and Excluding -
- Policies -
- Templates -
- Wrappers -
- Exporting An Entire Header -
- Smart Pointers -
- Global Variables -
- Adding New Methods -
- Inserting Code -
-
-
- - diff --git a/pyste/install/pyste.py b/pyste/install/pyste.py deleted file mode 100644 index da926235..00000000 --- a/pyste/install/pyste.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -# Copyright Bruno da Silva de Oliveira 2006. Distributed under the Boost -# Software License, Version 1.0. (See accompanying -# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -from Pyste import pyste -pyste.main() diff --git a/pyste/install/setup.py b/pyste/install/setup.py deleted file mode 100644 index c1703981..00000000 --- a/pyste/install/setup.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright Prabhu Ramachandran 2006. Distributed under the Boost -# Software License, Version 1.0. (See accompanying -# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -from distutils.core import setup -import sys - -setup (name = "Pyste", - version = "0.9.10", - description = "Pyste - Python Semi-Automatic Exporter", - maintainer = "Bruno da Silva de Oliveira", - maintainer_email = "nicodemus@globalite.com.br", - licence = "Boost License", - long_description = "Pyste is a Boost.Python code generator", - url = "http://www.boost.org/libs/python/pyste/index.html", - platforms = ['Any'], - packages = ['Pyste'], - scripts = ['pyste.py'], - package_dir = {'Pyste': '../src/Pyste'}, - ) diff --git a/pyste/src/Pyste/ClassExporter.py b/pyste/src/Pyste/ClassExporter.py deleted file mode 100644 index decaf628..00000000 --- a/pyste/src/Pyste/ClassExporter.py +++ /dev/null @@ -1,918 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import exporters -from Exporter import Exporter -from declarations import * -from settings import * -from policies import * -from SingleCodeUnit import SingleCodeUnit -from EnumExporter import EnumExporter -from utils import makeid, enumerate -import copy -import exporterutils -import re - -#============================================================================== -# ClassExporter -#============================================================================== -class ClassExporter(Exporter): - 'Generates boost.python code to export a class declaration' - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - # sections of code - self.sections = {} - # template: each item in the list is an item into the class_<...> - # section. - self.sections['template'] = [] - # constructor: each item in the list is a parameter to the class_ - # constructor, like class_(...) - self.sections['constructor'] = [] - # inside: everything within the class_<> statement - self.sections['inside'] = [] - # scope: items outside the class statement but within its scope. - # scope* s = new scope(class<>()); - # ... - # delete s; - self.sections['scope'] = [] - # declarations: outside the BOOST_PYTHON_MODULE macro - self.sections['declaration'] = [] - self.sections['declaration-outside'] = [] - self.sections['include'] = [] - # a list of Constructor instances - self.constructors = [] - # a list of code units, generated by nested declarations - self.nested_codeunits = [] - - - def ScopeName(self): - return makeid(self.class_.FullName()) + '_scope' - - - def Name(self): - return self.info.name - - - def SetDeclarations(self, declarations): - Exporter.SetDeclarations(self, declarations) - if self.declarations: - decl = self.GetDeclaration(self.info.name) - if isinstance(decl, Typedef): - self.class_ = self.GetDeclaration(decl.type.name) - if not self.info.rename: - self.info.rename = decl.name - else: - self.class_ = decl - self.class_ = copy.deepcopy(self.class_) - else: - self.class_ = None - - - def ClassBases(self): - all_bases = [] - for level in self.class_.hierarchy: - for base in level: - all_bases.append(base) - return [self.GetDeclaration(x.name) for x in all_bases] - - - def Order(self): - '''Return the TOTAL number of bases that this class has, including the - bases' bases. Do this because base classes must be instantialized - before the derived classes in the module definition. - ''' - num_bases = len(self.ClassBases()) - return num_bases, self.class_.FullName() - - - def Export(self, codeunit, exported_names): - self.InheritMethods(exported_names) - self.MakeNonVirtual() - if not self.info.exclude: - self.ExportBasics() - self.ExportBases(exported_names) - self.ExportConstructors() - self.ExportVariables() - self.ExportVirtualMethods(codeunit) - self.ExportMethods() - self.ExportOperators() - self.ExportNestedClasses(exported_names) - self.ExportNestedEnums(exported_names) - self.ExportSmartPointer() - self.ExportOpaquePointerPolicies() - self.ExportAddedCode() - self.Write(codeunit) - exported_names[self.Name()] = 1 - - - def InheritMethods(self, exported_names): - '''Go up in the class hierarchy looking for classes that were not - exported yet, and then add their public members to this classes - members, as if they were members of this class. This allows the user to - just export one type and automatically get all the members from the - base classes. - ''' - valid_members = (Method, ClassVariable, NestedClass, ClassEnumeration) - fullnames = [x.FullName() for x in self.class_] - pointers = [x.PointerDeclaration(True) for x in self.class_ if isinstance(x, Method)] - fullnames = dict([(x, None) for x in fullnames]) - pointers = dict([(x, None) for x in pointers]) - for level in self.class_.hierarchy: - level_exported = False - for base in level: - base = self.GetDeclaration(base.name) - if base.FullName() not in exported_names: - for member in base: - if type(member) in valid_members: - member_copy = copy.deepcopy(member) - member_copy.class_ = self.class_.FullName() - if isinstance(member_copy, Method): - pointer = member_copy.PointerDeclaration(True) - if pointer not in pointers: - self.class_.AddMember(member) - pointers[pointer] = None - elif member_copy.FullName() not in fullnames: - self.class_.AddMember(member) - else: - level_exported = True - if level_exported: - break - def IsValid(member): - return isinstance(member, valid_members) and member.visibility == Scope.public - self.public_members = [x for x in self.class_ if IsValid(x)] - - - def Write(self, codeunit): - indent = self.INDENT - boost_ns = namespaces.python - pyste_ns = namespaces.pyste - code = '' - # begin a scope for this class if needed - nested_codeunits = self.nested_codeunits - needs_scope = self.sections['scope'] or nested_codeunits - if needs_scope: - scope_name = self.ScopeName() - code += indent + boost_ns + 'scope* %s = new %sscope(\n' %\ - (scope_name, boost_ns) - # export the template section - template_params = ', '.join(self.sections['template']) - code += indent + boost_ns + 'class_< %s >' % template_params - # export the constructor section - constructor_params = ', '.join(self.sections['constructor']) - code += '(%s)\n' % constructor_params - # export the inside section - in_indent = indent*2 - for line in self.sections['inside']: - code += in_indent + line + '\n' - # write the scope section and end it - if not needs_scope: - code += indent + ';\n' - else: - code += indent + ');\n' - for line in self.sections['scope']: - code += indent + line + '\n' - # write the contents of the nested classes - for nested_unit in nested_codeunits: - code += '\n' + nested_unit.Section('module') - # close the scope - code += indent + 'delete %s;\n' % scope_name - - # write the code to the module section in the codeunit - codeunit.Write('module', code + '\n') - - # write the declarations to the codeunit - declarations = '\n'.join(self.sections['declaration']) - for nested_unit in nested_codeunits: - declarations += nested_unit.Section('declaration') - if declarations: - codeunit.Write('declaration', declarations + '\n') - declarations_outside = '\n'.join(self.sections['declaration-outside']) - if declarations_outside: - codeunit.Write('declaration-outside', declarations_outside + '\n') - - # write the includes to the codeunit - includes = '\n'.join(self.sections['include']) - for nested_unit in nested_codeunits: - includes += nested_unit.Section('include') - if includes: - codeunit.Write('include', includes) - - - def Add(self, section, item): - 'Add the item into the corresponding section' - self.sections[section].append(item) - - - def ExportBasics(self): - '''Export the name of the class and its class_ statement.''' - class_name = self.class_.FullName() - self.Add('template', class_name) - name = self.info.rename or self.class_.name - self.Add('constructor', '"%s"' % name) - - - def ExportBases(self, exported_names): - 'Expose the bases of the class into the template section' - hierarchy = self.class_.hierarchy - exported = [] - for level in hierarchy: - for base in level: - if base.visibility == Scope.public and base.name in exported_names: - exported.append(base.name) - if exported: - break - if exported: - code = namespaces.python + 'bases< %s > ' % (', '.join(exported)) - self.Add('template', code) - - - def ExportConstructors(self): - '''Exports all the public contructors of the class, plus indicates if the - class is noncopyable. - ''' - py_ns = namespaces.python - indent = self.INDENT - - def init_code(cons): - 'return the init<>() code for the given contructor' - param_list = [p.FullName() for p in cons.parameters] - min_params_list = param_list[:cons.minArgs] - max_params_list = param_list[cons.minArgs:] - min_params = ', '.join(min_params_list) - max_params = ', '.join(max_params_list) - init = py_ns + 'init< ' - init += min_params - if max_params: - if min_params: - init += ', ' - init += py_ns + ('optional< %s >' % max_params) - init += ' >()' - return init - - constructors = [x for x in self.public_members if isinstance(x, Constructor)] - # don't export copy constructors if the class is abstract - # we could remove all constructors, but this will have the effect of - # inserting no_init in the declaration, which would not allow - # even subclasses to be instantiated. - self.constructors = constructors[:] - if self.class_.abstract: - for cons in constructors: - if cons.IsCopy(): - constructors.remove(cons) - break - - if not constructors: - # declare no_init - self.Add('constructor', py_ns + 'no_init') - else: - # write the constructor with less parameters to the constructor section - smaller = None - for cons in constructors: - if smaller is None or len(cons.parameters) < len(smaller.parameters): - smaller = cons - assert smaller is not None - self.Add('constructor', init_code(smaller)) - constructors.remove(smaller) - # write the rest to the inside section, using def() - for cons in constructors: - code = '.def(%s)' % init_code(cons) - self.Add('inside', code) - - # check if the class is copyable - if not self.class_.HasCopyConstructor() or self.class_.abstract: - self.Add('template', namespaces.boost + 'noncopyable') - - - def ExportVariables(self): - 'Export the variables of the class, both static and simple variables' - vars = [x for x in self.public_members if isinstance(x, Variable)] - for var in vars: - if self.info[var.name].exclude: - continue - name = self.info[var.name].rename or var.name - fullname = var.FullName() - if var.type.const: - def_ = '.def_readonly' - else: - def_ = '.def_readwrite' - code = '%s("%s", &%s)' % (def_, name, fullname) - self.Add('inside', code) - - - def OverloadName(self, method): - 'Returns the name of the overloads struct for the given method' - name = makeid(method.FullName()) - overloads = '_overloads_%i_%i' % (method.minArgs, method.maxArgs) - return name + overloads - - - def GetAddedMethods(self): - added_methods = self.info.__added__ - result = [] - if added_methods: - for name, rename in added_methods: - decl = self.GetDeclaration(name) - self.info[name].rename = rename - result.append(decl) - return result - - - def ExportMethods(self): - '''Export all the non-virtual methods of this class, plus any function - that is to be exported as a method''' - - declared = {} - def DeclareOverloads(m): - 'Declares the macro for the generation of the overloads' - if (isinstance(m, Method) and m.static) or type(m) == Function: - func = m.FullName() - macro = 'BOOST_PYTHON_FUNCTION_OVERLOADS' - else: - func = m.name - macro = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS' - code = '%s(%s, %s, %i, %i)\n' % (macro, self.OverloadName(m), func, m.minArgs, m.maxArgs) - if code not in declared: - declared[code] = True - self.Add('declaration', code) - - - def Pointer(m): - 'returns the correct pointer declaration for the method m' - # check if this method has a wrapper set for him - wrapper = self.info[m.name].wrapper - if wrapper: - return '&' + wrapper.FullName() - else: - return m.PointerDeclaration() - - def IsExportable(m): - 'Returns true if the given method is exportable by this routine' - ignore = (Constructor, ClassOperator, Destructor) - return isinstance(m, Function) and not isinstance(m, ignore) and not m.virtual - - methods = [x for x in self.public_members if IsExportable(x)] - methods.extend(self.GetAddedMethods()) - - staticmethods = {} - - for method in methods: - method_info = self.info[method.name] - - # skip this method if it was excluded by the user - if method_info.exclude: - continue - - # rename the method if the user requested - name = method_info.rename or method.name - - # warn the user if this method needs a policy and doesn't have one - method_info.policy = exporterutils.HandlePolicy(method, method_info.policy) - - # check for policies - policy = method_info.policy or '' - if policy: - policy = ', %s%s()' % (namespaces.python, policy.Code()) - # check for overloads - overload = '' - if method.minArgs != method.maxArgs and not method_info.wrapper: - # add the overloads for this method - DeclareOverloads(method) - overload_name = self.OverloadName(method) - overload = ', %s%s()' % (namespaces.pyste, overload_name) - - # build the .def string to export the method - pointer = Pointer(method) - code = '.def("%s", %s' % (name, pointer) - code += policy - code += overload - code += ')' - self.Add('inside', code) - # static method - if isinstance(method, Method) and method.static: - staticmethods[name] = 1 - # add wrapper code if this method has one - wrapper = method_info.wrapper - if wrapper and wrapper.code: - self.Add('declaration', wrapper.code) - - # export staticmethod statements - for name in staticmethods: - code = '.staticmethod("%s")' % name - self.Add('inside', code) - - - - def MakeNonVirtual(self): - '''Make all methods that the user indicated to no_override no more virtual, delegating their - export to the ExportMethods routine''' - for member in self.class_: - if type(member) == Method and member.virtual: - member.virtual = not self.info[member.name].no_override - - - def ExportVirtualMethods(self, codeunit): - # check if this class has any virtual methods - has_virtual_methods = False - for member in self.class_: - if type(member) == Method and member.virtual: - has_virtual_methods = True - break - - holder = self.info.holder - if has_virtual_methods: - generator = _VirtualWrapperGenerator(self.class_, self.ClassBases(), self.info, codeunit) - if holder: - self.Add('template', holder(generator.FullName())) - else: - self.Add('template', generator.FullName()) - for definition in generator.GenerateDefinitions(): - self.Add('inside', definition) - self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT)) - else: - if holder: - self.Add('template', holder(self.class_.FullName())) - - # operators natively supported by boost - BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -= '\ - '*= /= %= ^= &= |= <<= >>='.split() - # create a map for faster lookup - BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS)))) - - # a dict of operators that are not directly supported by boost, but can be exposed - # simply as a function with a special name - BOOST_RENAME_OPERATORS = { - '()' : '__call__', - } - - # converters which have a special name in python - # it's a map of a regular expression of the converter's result to the - # appropriate python name - SPECIAL_CONVERTERS = { - re.compile(r'(const)?\s*double$') : '__float__', - re.compile(r'(const)?\s*float$') : '__float__', - re.compile(r'(const)?\s*int$') : '__int__', - re.compile(r'(const)?\s*long$') : '__long__', - re.compile(r'(const)?\s*char\s*\*?$') : '__str__', - re.compile(r'(const)?.*::basic_string<.*>\s*(\*|\&)?$') : '__str__', - } - - - def ExportOperators(self): - 'Export all member operators and free operators related to this class' - - def GetFreeOperators(): - 'Get all the free (global) operators related to this class' - operators = [] - for decl in self.declarations: - if isinstance(decl, Operator): - # check if one of the params is this class - for param in decl.parameters: - if param.name == self.class_.FullName(): - operators.append(decl) - break - return operators - - def GetOperand(param): - 'Returns the operand of this parameter (either "self", or "other")' - if param.name == self.class_.FullName(): - return namespaces.python + 'self' - else: - return namespaces.python + ('other< %s >()' % param.name) - - - def HandleSpecialOperator(operator): - # gatter information about the operator and its parameters - result_name = operator.result.name - param1_name = '' - if operator.parameters: - param1_name = operator.parameters[0].name - - # check for str - ostream = 'basic_ostream' - is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1 - if is_str: - namespace = namespaces.python + 'self_ns::' - self_ = namespaces.python + 'self' - return '.def(%sstr(%s))' % (namespace, self_) - - # is not a special operator - return None - - - - frees = GetFreeOperators() - members = [x for x in self.public_members if type(x) == ClassOperator] - all_operators = frees + members - operators = [x for x in all_operators if not self.info['operator'][x.name].exclude] - - for operator in operators: - # gatter information about the operator, for use later - wrapper = self.info['operator'][operator.name].wrapper - if wrapper: - pointer = '&' + wrapper.FullName() - if wrapper.code: - self.Add('declaration-outside', wrapper.code) - else: - pointer = operator.PointerDeclaration() - rename = self.info['operator'][operator.name].rename - - # check if this operator will be exported as a method - export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS - - # check if this operator has a special representation in boost - special_code = HandleSpecialOperator(operator) - has_special_representation = special_code is not None - - if export_as_method: - # export this operator as a normal method, renaming or using the given wrapper - if not rename: - if wrapper: - rename = wrapper.name - else: - rename = self.BOOST_RENAME_OPERATORS[operator.name] - policy = '' - policy_obj = self.info['operator'][operator.name].policy - if policy_obj: - policy = ', %s()' % policy_obj.Code() - self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy)) - - elif has_special_representation: - self.Add('inside', special_code) - - elif operator.name in self.BOOST_SUPPORTED_OPERATORS: - # export this operator using boost's facilities - op = operator - is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\ - isinstance(op, ClassOperator) and len(op.parameters) == 0 - if is_unary: - self.Add('inside', '.def( %s%sself )' % \ - (operator.name, namespaces.python)) - else: - # binary operator - if len(operator.parameters) == 2: - left_operand = GetOperand(operator.parameters[0]) - right_operand = GetOperand(operator.parameters[1]) - else: - left_operand = namespaces.python + 'self' - right_operand = GetOperand(operator.parameters[0]) - self.Add('inside', '.def( %s %s %s )' % \ - (left_operand, operator.name, right_operand)) - - # export the converters. - # export them as simple functions with a pre-determined name - - converters = [x for x in self.public_members if type(x) == ConverterOperator] - - def ConverterMethodName(converter): - result_fullname = converter.result.FullName() - result_name = converter.result.name - for regex, method_name in self.SPECIAL_CONVERTERS.items(): - if regex.match(result_fullname): - return method_name - else: - # extract the last name from the full name - result_name = makeid(result_name) - return 'to_' + result_name - - for converter in converters: - info = self.info['operator'][converter.result.FullName()] - # check if this operator should be excluded - if info.exclude: - continue - - special_code = HandleSpecialOperator(converter) - if info.rename or not special_code: - # export as method - name = info.rename or ConverterMethodName(converter) - pointer = converter.PointerDeclaration() - policy_code = '' - if info.policy: - policy_code = ', %s()' % info.policy.Code() - self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code)) - - elif special_code: - self.Add('inside', special_code) - - - - def ExportNestedClasses(self, exported_names): - nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)] - for nested_class in nested_classes: - nested_info = self.info[nested_class.name] - nested_info.include = self.info.include - nested_info.name = nested_class.FullName() - exporter = self.__class__(nested_info) - exporter.SetDeclarations(self.declarations) - codeunit = SingleCodeUnit(None, None) - exporter.Export(codeunit, exported_names) - self.nested_codeunits.append(codeunit) - - - def ExportNestedEnums(self, exported_names): - nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)] - for enum in nested_enums: - enum_info = self.info[enum.name] - enum_info.include = self.info.include - enum_info.name = enum.FullName() - exporter = EnumExporter(enum_info) - exporter.SetDeclarations(self.declarations) - codeunit = SingleCodeUnit(None, None) - exporter.Export(codeunit, exported_names) - self.nested_codeunits.append(codeunit) - - - def ExportSmartPointer(self): - smart_ptr = self.info.smart_ptr - if smart_ptr: - class_name = self.class_.FullName() - smart_ptr = smart_ptr % class_name - self.Add('scope', '%sregister_ptr_to_python< %s >();' % (namespaces.python, smart_ptr)) - - - def ExportOpaquePointerPolicies(self): - # check all methods for 'return_opaque_pointer' policies - methods = [x for x in self.public_members if isinstance(x, Method)] - for method in methods: - return_opaque_policy = return_value_policy(return_opaque_pointer) - if self.info[method.name].policy == return_opaque_policy: - macro = exporterutils.EspecializeTypeID(method.result.name) - if macro: - self.Add('declaration-outside', macro) - - def ExportAddedCode(self): - if self.info.__code__: - for code in self.info.__code__: - self.Add('inside', code) - - -#============================================================================== -# Virtual Wrapper utils -#============================================================================== - -def _ParamsInfo(m, count=None): - if count is None: - count = len(m.parameters) - param_names = ['p%i' % i for i in range(count)] - param_types = [x.FullName() for x in m.parameters[:count]] - params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)] - #for i, p in enumerate(m.parameters[:count]): - # if p.default is not None: - # #params[i] += '=%s' % p.default - # params[i] += '=%s' % (p.name + '()') - params = ', '.join(params) - return params, param_names, param_types - - -class _VirtualWrapperGenerator(object): - 'Generates code to export the virtual methods of the given class' - - def __init__(self, class_, bases, info, codeunit): - self.class_ = copy.deepcopy(class_) - self.bases = bases[:] - self.info = info - self.wrapper_name = makeid(class_.FullName()) + '_Wrapper' - self.virtual_methods = None - self._method_count = {} - self.codeunit = codeunit - self.GenerateVirtualMethods() - - - SELF = 'py_self' - - - def DefaultImplementationNames(self, method): - '''Returns a list of default implementations for this method, one for each - number of default arguments. Always returns at least one name, and return from - the one with most arguments to the one with the least. - ''' - base_name = 'default_' + method.name - minArgs = method.minArgs - maxArgs = method.maxArgs - if minArgs == maxArgs: - return [base_name] - else: - return [base_name + ('_%i' % i) for i in range(minArgs, maxArgs+1)] - - - def Declaration(self, method, indent): - '''Returns a string with the declarations of the virtual wrapper and - its default implementations. This string must be put inside the Wrapper - body. - ''' - pyste = namespaces.pyste - python = namespaces.python - rename = self.info[method.name].rename or method.name - result = method.result.FullName() - return_str = 'return ' - if result == 'void': - return_str = '' - params, param_names, param_types = _ParamsInfo(method) - constantness = '' - if method.const: - constantness = ' const' - - # call_method callback - decl = indent + '%s %s(%s)%s%s {\n' % (result, method.name, params, constantness, method.Exceptions()) - param_names_str = ', '.join(param_names) - if param_names_str: - param_names_str = ', ' + param_names_str - - self_str = self.SELF - - decl += indent*2 + '%(return_str)s%(python)scall_method< %(result)s >' \ - '(%(self_str)s, "%(rename)s"%(param_names_str)s);\n' % locals() - decl += indent + '}\n' - - # default implementations (with overloading) - def DefaultImpl(method, param_names): - 'Return the body of a default implementation wrapper' - indent2 = indent * 2 - wrapper = self.info[method.name].wrapper - if not wrapper: - # return the default implementation of the class - return indent2 + '%s%s(%s);\n' % \ - (return_str, method.FullName(), ', '.join(param_names)) - else: - if wrapper.code: - self.codeunit.Write('declaration-outside', wrapper.code) - # return a call for the wrapper - params = ', '.join(['this'] + param_names) - return indent2 + '%s%s(%s);\n' % (return_str, wrapper.FullName(), params) - - if not method.abstract and method.visibility != Scope.private: - minArgs = method.minArgs - maxArgs = method.maxArgs - impl_names = self.DefaultImplementationNames(method) - for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)): - params, param_names, param_types = _ParamsInfo(method, argNum) - decl += '\n' - decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness) - decl += DefaultImpl(method, param_names) - decl += indent + '}\n' - return decl - - - def MethodDefinition(self, method): - '''Returns a list of lines, which should be put inside the class_ - statement to export this method.''' - # dont define abstract methods - pyste = namespaces.pyste - rename = self.info[method.name].rename or method.name - default_names = self.DefaultImplementationNames(method) - class_name = self.class_.FullName() - wrapper_name = pyste + self.wrapper_name - result = method.result.FullName() - is_method_unique = method.is_unique - constantness = '' - if method.const: - constantness = ' const' - - # create a list of default-impl pointers - minArgs = method.minArgs - maxArgs = method.maxArgs - if method.abstract: - default_pointers = [] - elif is_method_unique: - default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names] - else: - default_pointers = [] - for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)): - param_list = [x.FullName() for x in method.parameters[:argNum]] - params = ', '.join(param_list) - signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness) - default_pointer = '(%s)&%s::%s' % (signature, wrapper_name, impl_name) - default_pointers.append(default_pointer) - - # get the pointer of the method - pointer = method.PointerDeclaration() - if method.abstract: - pointer = namespaces.python + ('pure_virtual(%s)' % pointer) - - # warn the user if this method needs a policy and doesn't have one - method_info = self.info[method.name] - method_info.policy = exporterutils.HandlePolicy(method, method_info.policy) - - # Add policy to overloaded methods also - policy = method_info.policy or '' - if policy: - policy = ', %s%s()' % (namespaces.python, policy.Code()) - - # generate the defs - definitions = [] - # basic def - if default_pointers: - definitions.append('.def("%s", %s, %s%s)' % (rename, pointer, default_pointers[-1], policy)) - for default_pointer in default_pointers[:-1]: - definitions.append('.def("%s", %s%s)' % (rename, default_pointer, policy)) - else: - definitions.append('.def("%s", %s%s)' % (rename, pointer, policy)) - return definitions - - - def FullName(self): - return namespaces.pyste + self.wrapper_name - - - def GenerateVirtualMethods(self): - '''To correctly export all virtual methods, we must also make wrappers - for the virtual methods of the bases of this class, as if the methods - were from this class itself. - This method creates the instance variable self.virtual_methods. - ''' - def IsVirtual(m): - if type(m) is Method: - pure_virtual = m.abstract and m.virtual - virtual = m.virtual and m.visibility != Scope.private - return virtual or pure_virtual - else: - return False - - # extract the virtual methods, avoiding duplications. The duplication - # must take in account the full signature without the class name, so - # that inherited members are correctly excluded if the subclass overrides - # them. - def MethodSig(method): - if method.const: - const = ' const' - else: - const = '' - if method.result: - result = method.result.FullName() - else: - result = '' - params = ', '.join([x.FullName() for x in method.parameters]) - return '%s %s(%s)%s%s' % ( - result, method.name, params, const, method.Exceptions()) - - already_added = {} - self.virtual_methods = [] - for member in self.class_: - if IsVirtual(member): - already_added[MethodSig(member)] = None - self.virtual_methods.append(member) - - for base in self.bases: - base_methods = [copy.deepcopy(x) for x in base if IsVirtual(x)] - for base_method in base_methods: - self.class_.AddMember(base_method) - - all_methods = [x for x in self.class_ if IsVirtual(x)] - - for member in all_methods: - sig = MethodSig(member) - if IsVirtual(member) and not sig in already_added: - self.virtual_methods.append(member) - already_added[sig] = 0 - - - def Constructors(self): - return self.class_.Constructors(publics_only=True) - - - def GenerateDefinitions(self): - defs = [] - for method in self.virtual_methods: - exclude = self.info[method.name].exclude - # generate definitions only for public methods and non-abstract methods - if method.visibility == Scope.public and not exclude: - defs.extend(self.MethodDefinition(method)) - return defs - - - def GenerateVirtualWrapper(self, indent): - 'Return the wrapper for this class' - - # generate the class code - class_name = self.class_.FullName() - code = 'struct %s: %s\n' % (self.wrapper_name, class_name) - code += '{\n' - # generate constructors (with the overloads for each one) - for cons in self.Constructors(): # only public constructors - minArgs = cons.minArgs - maxArgs = cons.maxArgs - # from the min number of arguments to the max number, generate - # all version of the given constructor - cons_code = '' - for argNum in range(minArgs, maxArgs+1): - params, param_names, param_types = _ParamsInfo(cons, argNum) - if params: - params = ', ' + params - cons_code += indent + '%s(PyObject* %s_%s):\n' % \ - (self.wrapper_name, self.SELF, params) - cons_code += indent*2 + '%s(%s), %s(%s_) {}\n\n' % \ - (class_name, ', '.join(param_names), self.SELF, self.SELF) - code += cons_code - # generate the body - body = [] - for method in self.virtual_methods: - if not self.info[method.name].exclude: - body.append(self.Declaration(method, indent)) - body = '\n'.join(body) - code += body + '\n' - # add the self member - code += indent + 'PyObject* %s;\n' % self.SELF - code += '};\n' - return code diff --git a/pyste/src/Pyste/CodeExporter.py b/pyste/src/Pyste/CodeExporter.py deleted file mode 100644 index 382fffbd..00000000 --- a/pyste/src/Pyste/CodeExporter.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from Exporter import Exporter - -#============================================================================== -# CodeExporter -#============================================================================== -class CodeExporter(Exporter): - - def __init__(self, info): - Exporter.__init__(self, info) - - - def Name(self): - return self.info.code - - - def Export(self, codeunit, exported_names): - codeunit.Write(self.info.section, self.info.code) - - - def WriteInclude(self, codeunit): - pass diff --git a/pyste/src/Pyste/CppParser.py b/pyste/src/Pyste/CppParser.py deleted file mode 100644 index be68a448..00000000 --- a/pyste/src/Pyste/CppParser.py +++ /dev/null @@ -1,247 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from GCCXMLParser import ParseDeclarations -import tempfile -import shutil -import os -import sys -import os.path -import settings -import shutil -import shelve -from cPickle import dump, load - -#============================================================================== -# exceptions -#============================================================================== -class CppParserError(Exception): pass - -#============================================================================== -# CppParser -#============================================================================== -class CppParser: - 'Parses a header file and returns a list of declarations' - - def __init__(self, includes=None, defines=None, cache_dir=None, version=None, gccxml_path = 'gccxml'): - 'includes and defines ar the directives given to gcc' - if includes is None: - includes = [] - if defines is None: - defines = [] - self.includes = includes - self.gccxml_path = gccxml_path - self.defines = defines - self.version = version - #if cache_dir is None: - # cache_dir = tempfile.mktemp() - # self.delete_cache = True - #else: - # self.delete_cache = False - self.delete_cache = False - self.cache_dir = cache_dir - self.cache_files = [] - self.mem_cache = {} - # create the cache dir - if cache_dir: - try: - os.makedirs(cache_dir) - except OSError: pass - - - def __del__(self): - self.Close() - - - def _IncludeParams(self, filename): - includes = self.includes[:] - filedir = os.path.dirname(filename) - if not filedir: - filedir = '.' - includes.insert(0, filedir) - includes = ['-I "%s"' % self.Unixfy(x) for x in includes] - return ' '.join(includes) - - - def _DefineParams(self): - defines = ['-D "%s"' % x for x in self.defines] - return ' '.join(defines) - - - def FindHeader(self, header): - if os.path.isfile(header): - return header - for path in self.includes: - filename = os.path.join(path, header) - if os.path.isfile(filename): - return filename - else: - name = os.path.basename(header) - raise RuntimeError, 'Header file "%s" not found!' % name - - - def AppendTail(self, filename, tail): - '''Creates a temporary file, appends the text tail to it, and returns - the filename of the file. - ''' - if hasattr(tempfile, 'mkstemp'): - f_no, temp = tempfile.mkstemp('.h') - f = file(temp, 'a') - os.close(f_no) - else: - temp = tempfile.mktemp('.h') - f = file(temp, 'a') - f.write('#include "%s"\n\n' % os.path.abspath(filename)) - f.write(tail) - f.write('\n') - f.close() - return temp - - - def Unixfy(self, path): - return path.replace('\\', '/') - - - def ParseWithGCCXML(self, header, tail): - '''Parses the given header using gccxml and GCCXMLParser. - ''' - header = self.FindHeader(header) - if tail: - filename = self.AppendTail(header, tail) - else: - filename = header - xmlfile = tempfile.mktemp('.xml') - try: - # get the params - includes = self._IncludeParams(filename) - defines = self._DefineParams() - # call gccxml - cmd = '%s %s %s "%s" -fxml=%s' - filename = self.Unixfy(filename) - xmlfile = self.Unixfy(xmlfile) - status = os.system(cmd % (self.gccxml_path, includes, defines, filename, xmlfile)) - if status != 0 or not os.path.isfile(xmlfile): - raise CppParserError, 'Error executing gccxml' - # parse the resulting xml - declarations = ParseDeclarations(xmlfile) - # make the declarations' location to point to the original file - if tail: - for decl in declarations: - decl_filename = os.path.normpath(os.path.normcase(decl.location[0])) - filename = os.path.normpath(os.path.normcase(filename)) - if decl_filename == filename: - decl.location = header, decl.location[1] - # return the declarations - return declarations - finally: - if settings.DEBUG and os.path.isfile(xmlfile): - debugname = os.path.basename(header) - debugname = os.path.splitext(debugname)[0] + '.xml' - print 'DEBUG:', debugname - shutil.copy(xmlfile, debugname) - # delete the temporary files - try: - os.remove(xmlfile) - if tail: - os.remove(filename) - except OSError: pass - - - def Parse(self, header, interface, tail=None): - '''Parses the given filename related to the given interface and returns - the (declarations, headerfile). The header returned is normally the - same as the given to this method (except that it is the full path), - except if tail is not None: in this case, the header is copied to a temp - filename and the tail code is appended to it before being passed on to - gccxml. This temp filename is then returned. - ''' - if tail is None: - tail = '' - tail = tail.strip() - declarations = self.GetCache(header, interface, tail) - if declarations is None: - declarations = self.ParseWithGCCXML(header, tail) - self.CreateCache(header, interface, tail, declarations) - header_fullpath = os.path.abspath(self.FindHeader(header)) - return declarations, header_fullpath - - - def CacheFileName(self, interface): - interface_name = os.path.basename(interface) - cache_file = os.path.splitext(interface_name)[0] + '.pystec' - cache_file = os.path.join(self.cache_dir, cache_file) - return cache_file - - - def GetCache(self, header, interface, tail): - key = (header, interface, tail) - # try memory cache first - if key in self.mem_cache: - return self.mem_cache[key] - - # get the cache from the disk - if self.cache_dir is None: - return None - header = self.FindHeader(header) - cache_file = self.CacheFileName(interface) - if os.path.isfile(cache_file): - f = file(cache_file, 'rb') - try: - version = load(f) - if version != self.version: - return None - cache = load(f) - if cache.has_key(key): - self.cache_files.append(cache_file) - return cache[key] - else: - return None - finally: - f.close() - else: - return None - - - def CreateCache(self, header, interface, tail, declarations): - key = (header, interface, tail) - - # our memory cache only holds one item - self.mem_cache.clear() - self.mem_cache[key] = declarations - - # save the cache in the disk - if self.cache_dir is None: - return - header = self.FindHeader(header) - cache_file = self.CacheFileName(interface) - if os.path.isfile(cache_file): - f = file(cache_file, 'rb') - try: - version = load(f) - cache = load(f) - finally: - f.close() - else: - cache = {} - cache[key] = declarations - self.cache_files.append(cache_file) - f = file(cache_file, 'wb') - try: - dump(self.version, f, 1) - dump(cache, f, 1) - finally: - f.close() - return cache_file - - - def Close(self): - if self.delete_cache and self.cache_files: - for filename in self.cache_files: - try: - os.remove(filename) - except OSError: - pass - self.cache_files = [] - shutil.rmtree(self.cache_dir) diff --git a/pyste/src/Pyste/EnumExporter.py b/pyste/src/Pyste/EnumExporter.py deleted file mode 100644 index 0107fbee..00000000 --- a/pyste/src/Pyste/EnumExporter.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from Exporter import Exporter -from settings import * -import utils - -#============================================================================== -# EnumExporter -#============================================================================== -class EnumExporter(Exporter): - 'Exports enumerators' - - def __init__(self, info): - Exporter.__init__(self, info) - - - def SetDeclarations(self, declarations): - Exporter.SetDeclarations(self, declarations) - if self.declarations: - self.enum = self.GetDeclaration(self.info.name) - else: - self.enum = None - - def Export(self, codeunit, exported_names): - if self.info.exclude: - return - indent = self.INDENT - in_indent = self.INDENT*2 - rename = self.info.rename or self.enum.name - full_name = self.enum.FullName() - unnamed_enum = False - if rename.startswith('$_') or rename.startswith('._'): - unnamed_enum = True - code = '' - if not unnamed_enum: - code += indent + namespaces.python - code += 'enum_< %s >("%s")\n' % (full_name, rename) - for name in self.enum.values: - rename = self.info[name].rename or name - value_fullname = self.enum.ValueFullName(name) - if not unnamed_enum: - code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname) - else: - code += indent + namespaces.python - code += 'scope().attr("%s") = (int)%s;\n' % (rename, value_fullname ) - if self.info.export_values and not unnamed_enum: - code += in_indent + '.export_values()\n' - if not unnamed_enum: - code += indent + ';\n' - code += '\n' - codeunit.Write('module', code) - exported_names[self.enum.FullName()] = 1 - - def Name(self): - return self.info.name diff --git a/pyste/src/Pyste/Exporter.py b/pyste/src/Pyste/Exporter.py deleted file mode 100644 index d87b37c5..00000000 --- a/pyste/src/Pyste/Exporter.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import os.path - -#============================================================================== -# Exporter -#============================================================================== -class Exporter(object): - 'Base class for objects capable to generate boost.python code.' - - INDENT = ' ' * 4 - - def __init__(self, info, parser_tail=None): - self.info = info - self.parser_tail = parser_tail - self.interface_file = None - self.declarations = [] - - - def Name(self): - raise NotImplementedError(self.__class__.__name__) - - - def Tail(self): - return self.parser_tail - - - def Parse(self, parser): - self.parser = parser - header = self.info.include - tail = self.parser_tail - declarations, parser_header = parser.parse(header, tail) - self.parser_header = parser_header - self.SetDeclarations(declarations) - - - def SetParsedHeader(self, parsed_header): - self.parser_header = parsed_header - - - def SetDeclarations(self, declarations): - self.declarations = declarations - - - def GenerateCode(self, codeunit, exported_names): - self.WriteInclude(codeunit) - self.Export(codeunit, exported_names) - - - def WriteInclude(self, codeunit): - codeunit.Write('include', '#include <%s>\n' % self.info.include) - - - def Export(self, codeunit, exported_names): - 'subclasses must override this to do the real work' - pass - - - def GetDeclarations(self, fullname): - decls = [] - for decl in self.declarations: - if decl.FullName() == fullname: - decls.append(decl) - if not decls: - raise RuntimeError, 'no %s declaration found!' % fullname - return decls - - - def GetDeclaration(self, fullname): - decls = self.GetDeclarations(fullname) - #assert len(decls) == 1 - return decls[0] - - - def Order(self): - '''Returns a string that uniquely identifies this instance. All - exporters will be sorted by Order before being exported. - ''' - return 0, self.info.name - - - def Header(self): - return self.info.include - - - def __eq__(self, other): - return type(self) is type(other) and self.Name() == other.Name() \ - and self.interface_file == other.interface_file - - def __ne__(self, other): - return not self == other diff --git a/pyste/src/Pyste/FunctionExporter.py b/pyste/src/Pyste/FunctionExporter.py deleted file mode 100644 index 5765f65e..00000000 --- a/pyste/src/Pyste/FunctionExporter.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from Exporter import Exporter -from policies import * -from declarations import * -from settings import * -import utils -import exporterutils - - -#============================================================================== -# FunctionExporter -#============================================================================== -class FunctionExporter(Exporter): - 'Generates boost.python code to export the given function.' - - def __init__(self, info, tail=None): - Exporter.__init__(self, info, tail) - - - def Export(self, codeunit, exported_names): - if not self.info.exclude: - decls = self.GetDeclarations(self.info.name) - for decl in decls: - self.info.policy = exporterutils.HandlePolicy(decl, self.info.policy) - self.ExportDeclaration(decl, len(decls) == 1, codeunit) - self.ExportOpaquePointer(decl, codeunit) - self.GenerateOverloads(decls, codeunit) - exported_names[self.Name()] = 1 - - - def ExportDeclaration(self, decl, unique, codeunit): - name = self.info.rename or decl.name - defs = namespaces.python + 'def("%s", ' % name - wrapper = self.info.wrapper - if wrapper: - pointer = '&' + wrapper.FullName() - else: - pointer = decl.PointerDeclaration() - defs += pointer - defs += self.PolicyCode() - overload = self.OverloadName(decl) - if overload: - defs += ', %s()' % (namespaces.pyste + overload) - defs += ');' - codeunit.Write('module', self.INDENT + defs + '\n') - # add the code of the wrapper - if wrapper and wrapper.code: - codeunit.Write('declaration', wrapper.code + '\n') - - - def OverloadName(self, decl): - if decl.minArgs != decl.maxArgs: - return '%s_overloads_%i_%i' % \ - (decl.name, decl.minArgs, decl.maxArgs) - else: - return '' - - - def GenerateOverloads(self, declarations, codeunit): - codes = {} - for decl in declarations: - overload = self.OverloadName(decl) - if overload and overload not in codes: - code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\ - (overload, decl.FullName(), decl.minArgs, decl.maxArgs) - codeunit.Write('declaration', code + '\n') - codes[overload] = None - - - def PolicyCode(self): - policy = self.info.policy - if policy is not None: - assert isinstance(policy, Policy) - return ', %s()' % policy.Code() - else: - return '' - - - def ExportOpaquePointer(self, function, codeunit): - if self.info.policy == return_value_policy(return_opaque_pointer): - typename = function.result.name - macro = exporterutils.EspecializeTypeID(typename) - if macro: - codeunit.Write('declaration-outside', macro) - - - def Name(self): - return self.info.name diff --git a/pyste/src/Pyste/GCCXMLParser.py b/pyste/src/Pyste/GCCXMLParser.py deleted file mode 100644 index 4a101720..00000000 --- a/pyste/src/Pyste/GCCXMLParser.py +++ /dev/null @@ -1,478 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from declarations import * -try: - # try to use internal elementtree - from xml.etree.cElementTree import ElementTree -except ImportError: - # try to use cElementTree if avaiable - try: - from cElementTree import ElementTree - except ImportError: - # fall back to the normal elementtree - from elementtree.ElementTree import ElementTree -from xml.parsers.expat import ExpatError -from copy import deepcopy -from utils import enumerate - - -#============================================================================== -# Exceptions -#============================================================================== -class InvalidXMLError(Exception): pass - -class ParserError(Exception): pass - -class InvalidContextError(ParserError): pass - - -#============================================================================== -# GCCXMLParser -#============================================================================== -class GCCXMLParser(object): - 'Parse a GCC_XML file and extract the top-level declarations.' - - interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0} - - def Parse(self, filename): - self.elements = self.GetElementsFromXML(filename) - # high level declarations - self.declarations = [] - self._names = {} - # parse the elements - for id in self.elements: - element, decl = self.elements[id] - if decl is None: - try: - self.ParseElement(id, element) - except InvalidContextError: - pass # ignore those nodes with invalid context - # (workaround gccxml bug) - - - def Declarations(self): - return self.declarations - - - def AddDecl(self, decl): - if decl.FullName() in self._names: - decl.is_unique= False - for d in self.declarations: - if d.FullName() == decl.FullName(): - d.is_unique = False - self._names[decl.FullName()] = 0 - self.declarations.append(decl) - - - def ParseElement(self, id, element): - method = 'Parse' + element.tag - if hasattr(self, method): - func = getattr(self, method) - func(id, element) - else: - self.ParseUnknown(id, element) - - - def GetElementsFromXML(self,filename): - 'Extracts a dictionary of elements from the gcc_xml file.' - - tree = ElementTree() - try: - tree.parse(filename) - except ExpatError: - raise InvalidXMLError, 'Not a XML file: %s' % filename - - root = tree.getroot() - if root.tag != 'GCC_XML': - raise InvalidXMLError, 'Not a valid GCC_XML file' - - # build a dictionary of id -> element, None - elementlist = root.getchildren() - elements = {} - for element in elementlist: - id = element.get('id') - if id: - elements[id] = element, None - return elements - - - def GetDecl(self, id): - if id not in self.elements: - if id == '_0': - raise InvalidContextError, 'Invalid context found in the xml file.' - else: - msg = 'ID not found in elements: %s' % id - raise ParserError, msg - - elem, decl = self.elements[id] - if decl is None: - self.ParseElement(id, elem) - elem, decl = self.elements[id] - if decl is None: - raise ParserError, 'Could not parse element: %s' % elem.tag - return decl - - - def GetType(self, id): - def Check(id, feature): - pos = id.find(feature) - if pos != -1: - id = id[:pos] + id[pos+1:] - return True, id - else: - return False, id - const, id = Check(id, 'c') - volatile, id = Check(id, 'v') - restricted, id = Check(id, 'r') - decl = self.GetDecl(id) - if isinstance(decl, Type): - res = deepcopy(decl) - if const: - res.const = const - if volatile: - res.volatile = volatile - if restricted: - res.restricted = restricted - else: - res = Type(decl.FullName(), const) - res.volatile = volatile - res.restricted = restricted - return res - - - def GetLocation(self, location): - file, line = location.split(':') - file = self.GetDecl(file) - return file, int(line) - - - def Update(self, id, decl): - element, _ = self.elements[id] - self.elements[id] = element, decl - - - def ParseUnknown(self, id, element): - name = '__Unknown_Element_%s' % id - decl = Unknown(name) - self.Update(id, decl) - - - def ParseNamespace(self, id, element): - namespace = element.get('name') - context = element.get('context') - if context: - outer = self.GetDecl(context) - if not outer.endswith('::'): - outer += '::' - namespace = outer + namespace - if namespace.startswith('::'): - namespace = namespace[2:] - self.Update(id, namespace) - - - def ParseFile(self, id, element): - filename = element.get('name') - self.Update(id, filename) - - - def ParseVariable(self, id, element): - # in gcc_xml, a static Field is declared as a Variable, so we check - # this and call the Field parser. - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - self.ParseField(id, element) - elem, decl = self.elements[id] - decl.static = True - else: - namespace = context - name = element.get('name') - type_ = self.GetType(element.get('type')) - location = self.GetLocation(element.get('location')) - variable = Variable(type_, name, namespace) - variable.location = location - self.AddDecl(variable) - self.Update(id, variable) - - - def GetArguments(self, element): - args = [] - for child in element: - if child.tag == 'Argument': - type = self.GetType(child.get('type')) - type.default = child.get('default') - args.append(type) - return args - - - def GetExceptions(self, exception_list): - if exception_list is None: - return None - - exceptions = [] - for t in exception_list.split(): - exceptions.append(self.GetType(t)) - - return exceptions - - - def ParseFunction(self, id, element, functionType=Function): - '''functionType is used because a Operator is identical to a normal - function, only the type of the function changes.''' - name = element.get('name') - returns = self.GetType(element.get('returns')) - namespace = self.GetDecl(element.get('context')) - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - incomplete = bool(int(element.get('incomplete', 0))) - throws = self.GetExceptions(element.get('throw', None)) - function = functionType(name, namespace, returns, params, throws) - function.location = location - self.AddDecl(function) - self.Update(id, function) - - - def ParseOperatorFunction(self, id, element): - self.ParseFunction(id, element, Operator) - - - def GetHierarchy(self, bases): - '''Parses the string "bases" from the xml into a list of tuples of Base - instances. The first tuple is the most direct inheritance, and then it - goes up in the hierarchy. - ''' - - if bases is None: - return [] - base_names = bases.split() - this_level = [] - next_levels = [] - for base in base_names: - # get the visibility - split = base.split(':') - if len(split) == 2: - visib = split[0] - base = split[1] - else: - visib = Scope.public - decl = self.GetDecl(base) - if not isinstance(decl, Class): - # on windows, there are some classes which "bases" points to an - # "Unimplemented" tag, but we are not interested in this classes - # anyway - continue - base = Base(decl.FullName(), visib) - this_level.append(base) - # normalize with the other levels - for index, level in enumerate(decl.hierarchy): - if index < len(next_levels): - next_levels[index] = next_levels[index] + level - else: - next_levels.append(level) - hierarchy = [] - if this_level: - hierarchy.append(tuple(this_level)) - if next_levels: - hierarchy.extend(next_levels) - return hierarchy - - - def GetMembers(self, member_list): - # members must be a string with the ids of the members - if member_list is None: - return [] - members = [] - for member in member_list.split(): - decl = self.GetDecl(member) - if type(decl) in Class.ValidMemberTypes(): - members.append(decl) - return members - - - def ParseClass(self, id, element): - name = element.get('name') - abstract = bool(int(element.get('abstract', '0'))) - location = self.GetLocation(element.get('location')) - context = self.GetDecl(element.get('context')) - incomplete = bool(int(element.get('incomplete', 0))) - if isinstance(context, str): - class_ = Class(name, context, [], abstract) - else: - # a nested class - visib = element.get('access', Scope.public) - class_ = NestedClass( - name, context.FullName(), visib, [], abstract) - class_.incomplete = incomplete - # we have to add the declaration of the class before trying - # to parse its members and bases, to avoid recursion. - self.AddDecl(class_) - class_.location = location - self.Update(id, class_) - # now we can get the members and the bases - class_.hierarchy = self.GetHierarchy(element.get('bases')) - if class_.hierarchy: - class_.bases = class_.hierarchy[0] - members = self.GetMembers(element.get('members')) - for member in members: - class_.AddMember(member) - - - def ParseStruct(self, id, element): - self.ParseClass(id, element) - - - FUNDAMENTAL_RENAME = { - 'long long int' : 'boost::int64_t', - 'long long unsigned int' : 'boost::uint64_t', - } - - def ParseFundamentalType(self, id, element): - name = element.get('name') - name = self.FUNDAMENTAL_RENAME.get(name, name) - type_ = FundamentalType(name) - self.Update(id, type_) - - - def ParseArrayType(self, id, element): - type = self.GetType(element.get('type')) - min = element.get('min') - max = element.get('max') - array = ArrayType(type.name, type.const, min, max) - self.Update(id, array) - - - def ParseReferenceType(self, id, element): - type = self.GetType(element.get('type')) - expand = not isinstance(type, FunctionType) - ref = ReferenceType(type.name, type.const, None, expand, type.suffix) - self.Update(id, ref) - - - def ParsePointerType(self, id, element): - type = self.GetType(element.get('type')) - expand = not isinstance(type, FunctionType) - ref = PointerType(type.name, type.const, None, expand, type.suffix) - self.Update(id, ref) - - - def ParseFunctionType(self, id, element): - result = self.GetType(element.get('returns')) - args = self.GetArguments(element) - func = FunctionType(result, args) - self.Update(id, func) - - - def ParseMethodType(self, id, element): - class_ = self.GetDecl(element.get('basetype')).FullName() - result = self.GetType(element.get('returns')) - args = self.GetArguments(element) - method = MethodType(result, args, class_) - self.Update(id, method) - - - def ParseField(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - type_ = self.GetType(element.get('type')) - static = bool(int(element.get('extern', '0'))) - location = self.GetLocation(element.get('location')) - var = ClassVariable(type_, name, classname, visib, static) - var.location = location - self.Update(id, var) - - - def ParseMethod(self, id, element, methodType=Method): - name = element.get('name') - result = self.GetType(element.get('returns')) - classname = self.GetDecl(element.get('context')).FullName() - visib = element.get('access', Scope.public) - static = bool(int(element.get('static', '0'))) - virtual = bool(int(element.get('virtual', '0'))) - abstract = bool(int(element.get('pure_virtual', '0'))) - const = bool(int(element.get('const', '0'))) - location = self.GetLocation(element.get('location')) - throws = self.GetExceptions(element.get('throw', None)) - params = self.GetArguments(element) - method = methodType( - name, classname, result, params, visib, virtual, abstract, static, const, throws) - method.location = location - self.Update(id, method) - - - def ParseOperatorMethod(self, id, element): - self.ParseMethod(id, element, ClassOperator) - - - def ParseConstructor(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - location = self.GetLocation(element.get('location')) - params = self.GetArguments(element) - artificial = element.get('artificial', False) - ctor = Constructor(name, classname, params, visib) - ctor.location = location - self.Update(id, ctor) - - - def ParseDestructor(self, id, element): - name = element.get('name') - visib = element.get('access', Scope.public) - classname = self.GetDecl(element.get('context')).FullName() - virtual = bool(int(element.get('virtual', '0'))) - location = self.GetLocation(element.get('location')) - des = Destructor(name, classname, visib, virtual) - des.location = location - self.Update(id, des) - - - def ParseConverter(self, id, element): - self.ParseMethod(id, element, ConverterOperator) - - - def ParseTypedef(self, id, element): - name = element.get('name') - type = self.GetType(element.get('type')) - context = self.GetDecl(element.get('context')) - if isinstance(context, Class): - context = context.FullName() - typedef = Typedef(type, name, context) - self.Update(id, typedef) - self.AddDecl(typedef) - - - def ParseEnumeration(self, id, element): - name = element.get('name') - location = self.GetLocation(element.get('location')) - context = self.GetDecl(element.get('context')) - incomplete = bool(int(element.get('incomplete', 0))) - if isinstance(context, str): - enum = Enumeration(name, context) - else: - visib = element.get('access', Scope.public) - enum = ClassEnumeration(name, context.FullName(), visib) - self.AddDecl(enum) - enum.location = location - for child in element: - if child.tag == 'EnumValue': - name = child.get('name') - value = int(child.get('init')) - enum.values[name] = value - enum.incomplete = incomplete - self.Update(id, enum) - - - -def ParseDeclarations(filename): - 'Returns a list of the top declarations found in the gcc_xml file.' - - parser = GCCXMLParser() - parser.Parse(filename) - return parser.Declarations() - - -if __name__ == '__main__': - ParseDeclarations(r'D:\Programming\Libraries\boost-cvs\boost\libs\python\pyste\example\test.xml') diff --git a/pyste/src/Pyste/HeaderExporter.py b/pyste/src/Pyste/HeaderExporter.py deleted file mode 100644 index 47651ba7..00000000 --- a/pyste/src/Pyste/HeaderExporter.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from Exporter import Exporter -from ClassExporter import ClassExporter -from FunctionExporter import FunctionExporter -from EnumExporter import EnumExporter -from VarExporter import VarExporter -from infos import * -from declarations import * -import os.path -import exporters -import MultipleCodeUnit - -#============================================================================== -# HeaderExporter -#============================================================================== -class HeaderExporter(Exporter): - 'Exports all declarations found in the given header' - - def __init__(self, info, parser_tail=None): - Exporter.__init__(self, info, parser_tail) - - - def WriteInclude(self, codeunit): - pass - - - def IsInternalName(self, name): - '''Returns true if the given name looks like a internal compiler - structure''' - return name.startswith('_') - - - def Export(self, codeunit, exported_names): - header = os.path.normpath(self.parser_header) - for decl in self.declarations: - # check if this declaration is in the header - location = os.path.abspath(decl.location[0]) - if location == header and not self.IsInternalName(decl.name): - # ok, check the type of the declaration and export it accordingly - self.HandleDeclaration(decl, codeunit, exported_names) - - - def HandleDeclaration(self, decl, codeunit, exported_names): - '''Dispatch the declaration to the appropriate method, that must create - a suitable info object for a Exporter, create a Exporter, set its - declarations and append it to the list of exporters. - ''' - dispatch_table = { - Class : ClassExporter, - Enumeration : EnumExporter, - Function : FunctionExporter, - Variable : VarExporter, - } - - exporter_class = dispatch_table.get(type(decl)) - if exporter_class is not None: - self.HandleExporter(decl, exporter_class, codeunit, exported_names) - - - def HandleExporter(self, decl, exporter_type, codeunit, exported_names): - # only export complete declarations - if not decl.incomplete: - info = self.info[decl.name] - info.name = decl.FullName() - info.include = self.info.include - exporter = exporter_type(info) - exporter.SetDeclarations(self.declarations) - exporter.SetParsedHeader(self.parser_header) - if isinstance(codeunit, MultipleCodeUnit.MultipleCodeUnit): - codeunit.SetCurrent(self.interface_file, exporter.Name()) - else: - codeunit.SetCurrent(exporter.Name()) - exporter.GenerateCode(codeunit, exported_names) - - - def Name(self): - return self.info.include diff --git a/pyste/src/Pyste/MultipleCodeUnit.py b/pyste/src/Pyste/MultipleCodeUnit.py deleted file mode 100644 index 65faad45..00000000 --- a/pyste/src/Pyste/MultipleCodeUnit.py +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from SingleCodeUnit import SingleCodeUnit -import os -import utils -from SmartFile import SmartFile - - -#============================================================================== -# MultipleCodeUnit -#============================================================================== -class MultipleCodeUnit(object): - ''' - Represents a bunch of cpp files, where each cpp file represents a header - to be exported by pyste. Another cpp, named .cpp is created too. - ''' - - def __init__(self, modulename, outdir): - self.modulename = modulename - self.outdir = outdir - self.codeunits = {} # maps from a (filename, function) to a SingleCodeUnit - self.functions = [] - self._current = None - self.all = SingleCodeUnit(None, None) - - - def _FunctionName(self, interface_file): - name = os.path.splitext(interface_file)[0] - return 'Export_%s' % utils.makeid(name) - - - def _FileName(self, interface_file): - filename = os.path.basename(interface_file) - filename = '_%s.cpp' % os.path.splitext(filename)[0] - return os.path.join(self.outdir, filename) - - - def SetCurrent(self, interface_file, export_name): - 'Changes the current code unit' - if export_name is None: - self._current = None - elif export_name is '__all__': - self._current = self.all - else: - filename = self._FileName(interface_file) - function = self._FunctionName(interface_file) - try: - codeunit = self.codeunits[filename] - except KeyError: - codeunit = SingleCodeUnit(None, filename) - codeunit.module_definition = 'void %s()' % function - self.codeunits[filename] = codeunit - if function not in self.functions: - self.functions.append(function) - self._current = codeunit - - - def Current(self): - return self._current - - current = property(Current, SetCurrent) - - - def Write(self, section, code): - if self._current is not None: - self.current.Write(section, code) - - - def Section(self, section): - if self._current is not None: - return self.current.Section(section) - - - def _CreateOutputDir(self): - try: - os.mkdir(self.outdir) - except OSError: pass # already created - - - def Save(self): - # create the directory where all the files will go - self._CreateOutputDir(); - # order all code units by filename, and merge them all - codeunits = {} # filename => list of codeunits - - # While ordering all code units by file name, the first code - # unit in the list of code units is used as the main unit - # which dumps all the include, declaration and - # declaration-outside sections at the top of the file. - for filename, codeunit in self.codeunits.items(): - if filename not in codeunits: - # this codeunit is the main codeunit. - codeunits[filename] = [codeunit] - codeunit.Merge(self.all) - else: - main_unit = codeunits[filename][0] - for section in ('include', 'declaration', 'declaration-outside'): - main_unit.code[section] = main_unit.code[section] + codeunit.code[section] - codeunit.code[section] = '' - codeunits[filename].append(codeunit) - - # Now write all the codeunits appending them correctly. - for file_units in codeunits.values(): - append = False - for codeunit in file_units: - codeunit.Save(append) - if not append: - append = True - - - def GenerateMain(self, interfaces): - # generate the main cpp - filename = os.path.join(self.outdir, '_main.cpp') - fout = SmartFile(filename, 'w') - fout.write(utils.left_equals('Include')) - fout.write('#include \n\n') - fout.write(utils.left_equals('Exports')) - functions = [self._FunctionName(x) for x in interfaces] - for function in functions: - fout.write('void %s();\n' % function) - fout.write('\n') - fout.write(utils.left_equals('Module')) - fout.write('BOOST_PYTHON_MODULE(%s)\n' % self.modulename) - fout.write('{\n') - indent = ' ' * 4 - for function in functions: - fout.write(indent) - fout.write('%s();\n' % function) - fout.write('}\n') - - - diff --git a/pyste/src/Pyste/SingleCodeUnit.py b/pyste/src/Pyste/SingleCodeUnit.py deleted file mode 100644 index 2e59dbb8..00000000 --- a/pyste/src/Pyste/SingleCodeUnit.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from settings import namespaces -import settings -from utils import remove_duplicated_lines, left_equals -from SmartFile import SmartFile - - -#============================================================================== -# SingleCodeUnit -#============================================================================== -class SingleCodeUnit: - ''' - Represents a cpp file, where other objects can write in one of the - predefined sections. - The avaiable sections are: - pchinclude - The pre-compiled header area - include - The include area of the cpp file - declaration - The part before the module definition - module - Inside the BOOST_PYTHON_MODULE macro - ''' - - def __init__(self, modulename, filename): - self.modulename = modulename - self.filename = filename - # define the avaiable sections - self.code = {} - # include section - self.code['pchinclude'] = '' - # include section - self.code['include'] = '' - # declaration section (inside namespace) - self.code['declaration'] = '' - # declaration (outside namespace) - self.code['declaration-outside'] = '' - # inside BOOST_PYTHON_MACRO - self.code['module'] = '' - # create the default module definition - self.module_definition = 'BOOST_PYTHON_MODULE(%s)' % modulename - - - def Write(self, section, code): - 'write the given code in the section of the code unit' - if section not in self.code: - raise RuntimeError, 'Invalid CodeUnit section: %s' % section - self.code[section] += code - - - def Merge(self, other): - for section in ('include', 'declaration', 'declaration-outside', 'module'): - self.code[section] = self.code[section] + other.code[section] - - - def Section(self, section): - return self.code[section] - - - def SetCurrent(self, *args): - pass - - - def Current(self): - pass - - - def Save(self, append=False): - 'Writes this code unit to the filename' - space = '\n\n' - if not append: - flag = 'w' - else: - flag = 'a' - fout = SmartFile(self.filename, flag) - fout.write('\n') - # includes - # boost.python header - if self.code['pchinclude']: - fout.write(left_equals('PCH')) - fout.write(self.code['pchinclude']+'\n') - fout.write('#ifdef _MSC_VER\n') - fout.write('#pragma hdrstop\n') - fout.write('#endif\n') - else: - fout.write(left_equals('Boost Includes')) - fout.write('#include \n') - # include numerical boost for int64 definitions - fout.write('#include \n') - fout.write('\n') - # other includes - if self.code['include']: - fout.write(left_equals('Includes')) - includes = remove_duplicated_lines(self.code['include']) - fout.write(includes) - fout.write(space) - # using - if settings.USING_BOOST_NS and not append: - fout.write(left_equals('Using')) - fout.write('using namespace boost::python;\n\n') - # declarations - declaration = self.code['declaration'] - declaration_outside = self.code['declaration-outside'] - if declaration_outside or declaration: - fout.write(left_equals('Declarations')) - if declaration_outside: - fout.write(declaration_outside + '\n\n') - if declaration: - pyste_namespace = namespaces.pyste[:-2] - fout.write('namespace %s {\n\n' % pyste_namespace) - fout.write(declaration) - fout.write('\n}// namespace %s\n' % pyste_namespace) - fout.write(space) - # module - fout.write(left_equals('Module')) - fout.write(self.module_definition + '\n') - fout.write('{\n') - fout.write(self.code['module']) - fout.write('}\n\n') - fout.close() diff --git a/pyste/src/Pyste/SmartFile.py b/pyste/src/Pyste/SmartFile.py deleted file mode 100644 index 039579e3..00000000 --- a/pyste/src/Pyste/SmartFile.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import os -import md5 - -#============================================================================== -# SmartFile -#============================================================================== -class SmartFile(object): - ''' - A file-like object used for writing files. The given file will only be - actually written to disk if there's not a file with the same name, or if - the existing file is *different* from the file to be written. - ''' - - def __init__(self, filename, mode='w'): - self.filename = filename - self.mode = mode - self._contents = [] - self._closed = False - - - def __del__(self): - if not self._closed: - self.close() - - - def write(self, string): - self._contents.append(string) - - - def _dowrite(self, contents): - f = file(self.filename, self.mode) - f.write(contents) - f.close() - - - def _GetMD5(self, string): - return md5.new(string).digest() - - - def close(self): - # if the filename doesn't exist, write the file right away - this_contents = ''.join(self._contents) - if not os.path.isfile(self.filename): - self._dowrite(this_contents) - else: - # read the contents of the file already in disk - f = file(self.filename) - other_contents = f.read() - f.close() - # test the md5 for both files - this_md5 = self._GetMD5(this_contents) - other_md5 = self._GetMD5(other_contents) - if this_md5 != other_md5: - self._dowrite(this_contents) - self._closed = True diff --git a/pyste/src/Pyste/VarExporter.py b/pyste/src/Pyste/VarExporter.py deleted file mode 100644 index d3571e75..00000000 --- a/pyste/src/Pyste/VarExporter.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from Exporter import Exporter -from settings import * -import utils - -#============================================================================== -# VarExporter -#============================================================================== -class VarExporter(Exporter): - '''Exports a global variable. - ''' - - def __init__(self, info): - Exporter.__init__(self, info) - - - def Export(self, codeunit, exported_names): - if self.info.exclude: return - decl = self.GetDeclaration(self.info.name) - if not decl.type.const: - msg = '---> Warning: The global variable "%s" is non-const:\n' \ - ' changes in Python will not reflect in C++.' - print msg % self.info.name - print - rename = self.info.rename or self.info.name - code = self.INDENT + namespaces.python - code += 'scope().attr("%s") = %s;\n' % (rename, self.info.name) - codeunit.Write('module', code) - - - def Order(self): - return 0, self.info.name - - - def Name(self): - return self.info.name diff --git a/pyste/src/Pyste/__init__.py b/pyste/src/Pyste/__init__.py deleted file mode 100644 index 02eec64b..00000000 --- a/pyste/src/Pyste/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - - diff --git a/pyste/src/Pyste/declarations.py b/pyste/src/Pyste/declarations.py deleted file mode 100644 index 6eff97dc..00000000 --- a/pyste/src/Pyste/declarations.py +++ /dev/null @@ -1,653 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -''' -Defines classes that represent declarations found in C++ header files. - -''' - -# version indicates the version of the declarations. Whenever a declaration -# changes, this variable should be updated, so that the caches can be rebuilt -# automatically -version = '1.0' - -#============================================================================== -# Declaration -#============================================================================== -class Declaration(object): - '''Base class for all declarations. - @ivar name: The name of the declaration. - @ivar namespace: The namespace of the declaration. - ''' - - def __init__(self, name, namespace): - ''' - @type name: string - @param name: The name of this declaration - @type namespace: string - @param namespace: the full namespace where this declaration resides. - ''' - self.name = name - self.namespace = namespace - self.location = '', -1 # (filename, line) - self.incomplete = False - self.is_unique = True - - - def FullName(self): - ''' - Returns the full qualified name: "boost::inner::Test" - @rtype: string - @return: The full name of the declaration. - ''' - namespace = self.namespace or '' - if namespace and not namespace.endswith('::'): - namespace += '::' - return namespace + self.name - - - def __repr__(self): - return '' % (self.FullName(), id(self)) - - - def __str__(self): - return 'Declaration of %s' % self.FullName() - - -#============================================================================== -# Class -#============================================================================== -class Class(Declaration): - ''' - Represents a C++ class or struct. Iteration through it yields its members. - - @type abstract: bool - @ivar abstract: if the class has any abstract methods. - - @type bases: tuple - @ivar bases: tuple with L{Base} instances, representing the most direct - inheritance. - - @type hierarchy: list - @ivar hierarchy: a list of tuples of L{Base} instances, representing - the entire hierarchy tree of this object. The first tuple is the parent - classes, and the other ones go up in the hierarchy. - ''' - - def __init__(self, name, namespace, members, abstract): - Declaration.__init__(self, name, namespace) - self.__members = members - self.__member_names = {} - self.abstract = abstract - self.bases = () - self.hierarchy = () - self.operator = {} - - - def __iter__(self): - '''iterates through the class' members. - ''' - return iter(self.__members) - - - def Constructors(self, publics_only=True): - '''Returns a list of the constructors for this class. - @rtype: list - ''' - constructors = [] - for member in self: - if isinstance(member, Constructor): - if publics_only and member.visibility != Scope.public: - continue - constructors.append(member) - return constructors - - - def HasCopyConstructor(self): - '''Returns true if this class has a public copy constructor. - @rtype: bool - ''' - for cons in self.Constructors(): - if cons.IsCopy(): - return True - return False - - - def HasDefaultConstructor(self): - '''Returns true if this class has a public default constructor. - @rtype: bool - ''' - for cons in self.Constructors(): - if cons.IsDefault(): - return True - return False - - - def AddMember(self, member): - if member.name in self.__member_names: - member.is_unique = False - for m in self: - if m.name == member.name: - m.is_unique = False - else: - member.is_unique = True - self.__member_names[member.name] = 1 - self.__members.append(member) - if isinstance(member, ClassOperator): - self.operator[member.name] = member - - - def ValidMemberTypes(): - return (NestedClass, Method, Constructor, Destructor, ClassVariable, - ClassOperator, ConverterOperator, ClassEnumeration) - ValidMemberTypes = staticmethod(ValidMemberTypes) - - -#============================================================================== -# NestedClass -#============================================================================== -class NestedClass(Class): - '''The declaration of a class/struct inside another class/struct. - - @type class: string - @ivar class: fullname of the class where this class is contained. - - @type visibility: L{Scope} - @ivar visibility: the visibility of this class. - ''' - - def __init__(self, name, class_, visib, members, abstract): - Class.__init__(self, name, None, members, abstract) - self.class_ = class_ - self.visibility = visib - - - def FullName(self): - '''The full name of this class, like ns::outer::inner. - @rtype: string - ''' - return '%s::%s' % (self.class_, self.name) - - -#============================================================================== -# Scope -#============================================================================== -class Scope: - '''Used to represent the visibility of various members inside a class. - @cvar public: public visibility - @cvar private: private visibility - @cvar protected: protected visibility - ''' - public = 'public' - private = 'private' - protected = 'protected' - - -#============================================================================== -# Base -#============================================================================== -class Base: - '''Represents a base class of another class. - @ivar _name: the full name of the base class. - @ivar _visibility: the visibility of the derivation. - ''' - - def __init__(self, name, visibility=Scope.public): - self.name = name - self.visibility = visibility - - -#============================================================================== -# Function -#============================================================================== -class Function(Declaration): - '''The declaration of a function. - @ivar _result: instance of L{Type} or None. - @ivar _parameters: list of L{Type} instances. - @ivar _throws: exception specifiers or None - ''' - - def __init__(self, name, namespace, result, params, throws=None): - Declaration.__init__(self, name, namespace) - # the result type: instance of Type, or None (constructors) - self.result = result - # the parameters: instances of Type - self.parameters = params - # the exception specification - self.throws = throws - - - def Exceptions(self): - if self.throws is None: - return "" - else: - return " throw(%s)" % ', '.join ([x.FullName() for x in self.throws]) - - - def PointerDeclaration(self, force=False): - '''Returns a declaration of a pointer to this function. - @param force: If True, returns a complete pointer declaration regardless - if this function is unique or not. - ''' - if self.is_unique and not force: - return '&%s' % self.FullName() - else: - result = self.result.FullName() - params = ', '.join([x.FullName() for x in self.parameters]) - return '(%s (*)(%s)%s)&%s' % (result, params, self.Exceptions(), self.FullName()) - - - def MinArgs(self): - min = 0 - for arg in self.parameters: - if arg.default is None: - min += 1 - return min - - minArgs = property(MinArgs) - - - def MaxArgs(self): - return len(self.parameters) - - maxArgs = property(MaxArgs) - - - -#============================================================================== -# Operator -#============================================================================== -class Operator(Function): - '''The declaration of a custom operator. Its name is the same as the - operator name in C++, ie, the name of the declaration "operator+(..)" is - "+". - ''' - - def FullName(self): - namespace = self.namespace or '' - if not namespace.endswith('::'): - namespace += '::' - return namespace + 'operator' + self.name - - -#============================================================================== -# Method -#============================================================================== -class Method(Function): - '''The declaration of a method. - - @ivar _visibility: the visibility of this method. - @ivar _virtual: if this method is declared as virtual. - @ivar _abstract: if this method is virtual but has no default implementation. - @ivar _static: if this method is static. - @ivar _class: the full name of the class where this method was declared. - @ivar _const: if this method is declared as const. - @ivar _throws: list of exception specificiers or None - ''' - - def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const, throws=None): - Function.__init__(self, name, None, result, params, throws) - self.visibility = visib - self.virtual = virtual - self.abstract = abstract - self.static = static - self.class_ = class_ - self.const = const - - - def FullName(self): - return self.class_ + '::' + self.name - - - def PointerDeclaration(self, force=False): - '''Returns a declaration of a pointer to this member function. - @param force: If True, returns a complete pointer declaration regardless - if this function is unique or not. - ''' - if self.static: - # static methods are like normal functions - return Function.PointerDeclaration(self, force) - if self.is_unique and not force: - return '&%s' % self.FullName() - else: - result = self.result.FullName() - params = ', '.join([x.FullName() for x in self.parameters]) - const = '' - if self.const: - const = 'const' - return '(%s (%s::*)(%s) %s%s)&%s' %\ - (result, self.class_, params, const, self.Exceptions(), self.FullName()) - - -#============================================================================== -# Constructor -#============================================================================== -class Constructor(Method): - '''A class' constructor. - ''' - - def __init__(self, name, class_, params, visib): - Method.__init__(self, name, class_, None, params, visib, False, False, False, False) - - - def IsDefault(self): - '''Returns True if this constructor is a default constructor. - ''' - return len(self.parameters) == 0 and self.visibility == Scope.public - - - def IsCopy(self): - '''Returns True if this constructor is a copy constructor. - ''' - if len(self.parameters) != 1: - return False - param = self.parameters[0] - class_as_param = self.parameters[0].name == self.class_ - param_reference = isinstance(param, ReferenceType) - is_public = self.visibility == Scope.public - return param_reference and class_as_param and param.const and is_public - - - def PointerDeclaration(self, force=False): - return '' - - -#============================================================================== -# Destructor -#============================================================================== -class Destructor(Method): - 'The destructor of a class.' - - def __init__(self, name, class_, visib, virtual): - Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False) - - def FullName(self): - return self.class_ + '::~' + self.name - - - def PointerDeclaration(self, force=False): - return '' - - - -#============================================================================== -# ClassOperator -#============================================================================== -class ClassOperator(Method): - 'A custom operator in a class.' - - def FullName(self): - return self.class_ + '::operator ' + self.name - - - -#============================================================================== -# ConverterOperator -#============================================================================== -class ConverterOperator(ClassOperator): - 'An operator in the form "operator OtherClass()".' - - def FullName(self): - return self.class_ + '::operator ' + self.result.FullName() - - - -#============================================================================== -# Type -#============================================================================== -class Type(Declaration): - '''Represents the type of a variable or parameter. - @ivar _const: if the type is constant. - @ivar _default: if this type has a default value associated with it. - @ivar _volatile: if this type was declared with the keyword volatile. - @ivar _restricted: if this type was declared with the keyword restricted. - @ivar _suffix: Suffix to get the full type name. '*' for pointers, for - example. - ''' - - def __init__(self, name, const=False, default=None, suffix=''): - Declaration.__init__(self, name, None) - # whatever the type is constant or not - self.const = const - # used when the Type is a function argument - self.default = default - self.volatile = False - self.restricted = False - self.suffix = suffix - - def __repr__(self): - if self.const: - const = 'const ' - else: - const = '' - return '' - - - def FullName(self): - if self.const: - const = 'const ' - else: - const = '' - return const + self.name + self.suffix - - -#============================================================================== -# ArrayType -#============================================================================== -class ArrayType(Type): - '''Represents an array. - @ivar min: the lower bound of the array, usually 0. Can be None. - @ivar max: the upper bound of the array. Can be None. - ''' - - def __init__(self, name, const, min, max): - 'min and max can be None.' - Type.__init__(self, name, const) - self.min = min - self.max = max - - - -#============================================================================== -# ReferenceType -#============================================================================== -class ReferenceType(Type): - '''A reference type.''' - - def __init__(self, name, const=False, default=None, expandRef=True, suffix=''): - Type.__init__(self, name, const, default) - if expandRef: - self.suffix = suffix + '&' - - -#============================================================================== -# PointerType -#============================================================================== -class PointerType(Type): - 'A pointer type.' - - def __init__(self, name, const=False, default=None, expandPointer=False, suffix=''): - Type.__init__(self, name, const, default) - if expandPointer: - self.suffix = suffix + '*' - - -#============================================================================== -# FundamentalType -#============================================================================== -class FundamentalType(Type): - 'One of the fundamental types, like int, void, etc.' - - def __init__(self, name, const=False, default=None): - Type.__init__(self, name, const, default) - - - -#============================================================================== -# FunctionType -#============================================================================== -class FunctionType(Type): - '''A pointer to a function. - @ivar _result: the return value - @ivar _parameters: a list of Types, indicating the parameters of the function. - @ivar _name: the name of the function. - ''' - - def __init__(self, result, parameters): - Type.__init__(self, '', False) - self.result = result - self.parameters = parameters - self.name = self.FullName() - - - def FullName(self): - full = '%s (*)' % self.result.FullName() - params = [x.FullName() for x in self.parameters] - full += '(%s)' % ', '.join(params) - return full - - -#============================================================================== -# MethodType -#============================================================================== -class MethodType(FunctionType): - '''A pointer to a member function of a class. - @ivar _class: The fullname of the class that the method belongs to. - ''' - - def __init__(self, result, parameters, class_): - self.class_ = class_ - FunctionType.__init__(self, result, parameters) - - - def FullName(self): - full = '%s (%s::*)' % (self.result.FullName(), self.class_) - params = [x.FullName() for x in self.parameters] - full += '(%s)' % ', '.join(params) - return full - - -#============================================================================== -# Variable -#============================================================================== -class Variable(Declaration): - '''Represents a global variable. - - @type _type: L{Type} - @ivar _type: The type of the variable. - ''' - - def __init__(self, type, name, namespace): - Declaration.__init__(self, name, namespace) - self.type = type - - -#============================================================================== -# ClassVariable -#============================================================================== -class ClassVariable(Variable): - '''Represents a class variable. - - @type _visibility: L{Scope} - @ivar _visibility: The visibility of this variable within the class. - - @type _static: bool - @ivar _static: Indicates if the variable is static. - - @ivar _class: Full name of the class that this variable belongs to. - ''' - - def __init__(self, type, name, class_, visib, static): - Variable.__init__(self, type, name, None) - self.visibility = visib - self.static = static - self.class_ = class_ - - - def FullName(self): - return self.class_ + '::' + self.name - - -#============================================================================== -# Enumeration -#============================================================================== -class Enumeration(Declaration): - '''Represents an enum. - - @type _values: dict of str => int - @ivar _values: holds the values for this enum. - ''' - - def __init__(self, name, namespace): - Declaration.__init__(self, name, namespace) - self.values = {} # dict of str => int - - - def ValueFullName(self, name): - '''Returns the full name for a value in the enum. - ''' - assert name in self.values - namespace = self.namespace - if namespace: - namespace += '::' - return namespace + name - - -#============================================================================== -# ClassEnumeration -#============================================================================== -class ClassEnumeration(Enumeration): - '''Represents an enum inside a class. - - @ivar _class: The full name of the class where this enum belongs. - @ivar _visibility: The visibility of this enum inside his class. - ''' - - def __init__(self, name, class_, visib): - Enumeration.__init__(self, name, None) - self.class_ = class_ - self.visibility = visib - - - def FullName(self): - return '%s::%s' % (self.class_, self.name) - - - def ValueFullName(self, name): - assert name in self.values - return '%s::%s' % (self.class_, name) - - -#============================================================================== -# Typedef -#============================================================================== -class Typedef(Declaration): - '''A Typedef declaration. - - @type _type: L{Type} - @ivar _type: The type of the typedef. - - @type _visibility: L{Scope} - @ivar _visibility: The visibility of this typedef. - ''' - - def __init__(self, type, name, namespace): - Declaration.__init__(self, name, namespace) - self.type = type - self.visibility = Scope.public - - - - - -#============================================================================== -# Unknown -#============================================================================== -class Unknown(Declaration): - '''A declaration that Pyste does not know how to handle. - ''' - - def __init__(self, name): - Declaration.__init__(self, name, None) diff --git a/pyste/src/Pyste/exporters.py b/pyste/src/Pyste/exporters.py deleted file mode 100644 index f573d01b..00000000 --- a/pyste/src/Pyste/exporters.py +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - - -# a list of Exporter instances -exporters = [] - -current_interface = None # the current interface file being processed -importing = False # whetever we are now importing a pyste file. - # exporters created here shouldn't export themselves diff --git a/pyste/src/Pyste/exporterutils.py b/pyste/src/Pyste/exporterutils.py deleted file mode 100644 index 363700d2..00000000 --- a/pyste/src/Pyste/exporterutils.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -''' -Various helpers for interface files. -''' - -from settings import * -from policies import * -from declarations import * - -#============================================================================== -# FunctionWrapper -#============================================================================== -class FunctionWrapper(object): - '''Holds information about a wrapper for a function or a method. It is - divided in 2 parts: the name of the Wrapper, and its code. The code is - placed in the declaration section of the module, while the name is used to - def' the function or method (with the pyste namespace prepend to it). If - code is None, the name is left unchanged. - ''' - - def __init__(self, name, code=None): - self.name = name - self.code = code - - def FullName(self): - if self.code: - return namespaces.pyste + self.name - else: - return self.name - - -_printed_warnings = {} # used to avoid double-prints of warnings - -#============================================================================== -# HandlePolicy -#============================================================================== -def HandlePolicy(function, policy): - '''Show a warning to the user if the function needs a policy and doesn't - have one. Return a policy to the function, which is the given policy itself - if it is not None, or a default policy for this method. - ''' - - def IsString(type): - 'Return True if the Type instance can be considered a string' - return type.FullName() == 'const char*' - - def IsPyObject(type): - return type.FullName() == '_object *' # internal name of PyObject - - result = function.result - # if the function returns const char*, a policy is not needed - if IsString(result) or IsPyObject(result): - return policy - # if returns a const T&, set the default policy - if policy is None and result.const and isinstance(result, ReferenceType): - policy = return_value_policy(copy_const_reference) - # basic test if the result type demands a policy - needs_policy = isinstance(result, (ReferenceType, PointerType)) - # show a warning to the user, if needed - if needs_policy and policy is None: - global _printed_warnings - warning = '---> Error: %s returns a pointer or a reference, ' \ - 'but no policy was specified.' % function.FullName() - if warning not in _printed_warnings: - print warning - print - # avoid double prints of the same warning - _printed_warnings[warning] = 1 - return policy - - -#============================================================================== -# EspecializeTypeID -#============================================================================== -_exported_type_ids = {} -def EspecializeTypeID(typename): - global _exported_type_ids - macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)\n' % typename - if macro not in _exported_type_ids: - _exported_type_ids[macro] = 1 - return macro - else: - return None diff --git a/pyste/src/Pyste/infos.py b/pyste/src/Pyste/infos.py deleted file mode 100644 index 2a4f01ea..00000000 --- a/pyste/src/Pyste/infos.py +++ /dev/null @@ -1,259 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import os.path -import copy -import exporters -from ClassExporter import ClassExporter -from FunctionExporter import FunctionExporter -from EnumExporter import EnumExporter -from HeaderExporter import HeaderExporter -from VarExporter import VarExporter -from CodeExporter import CodeExporter -from exporterutils import FunctionWrapper -from utils import makeid -import warnings - -#============================================================================== -# DeclarationInfo -#============================================================================== -class DeclarationInfo: - - def __init__(self, otherInfo=None): - self.__infos = {} - self.__attributes = {} - if otherInfo is not None: - self.__infos = copy.deepcopy(otherInfo.__infos) - self.__attributes = copy.deepcopy(otherInfo.__attributes) - - - def __getitem__(self, name): - 'Used to access sub-infos' - if name.startswith('__'): - raise AttributeError - default = DeclarationInfo() - default._Attribute('name', name) - return self.__infos.setdefault(name, default) - - - def __getattr__(self, name): - return self[name] - - - def _Attribute(self, name, value=None): - if value is None: - # get value - return self.__attributes.get(name) - else: - # set value - self.__attributes[name] = value - - - def AddExporter(self, exporter): - # this was causing a much serious bug, as reported by Niall Douglas: - # another solution must be found! - #if not exporters.importing: - if exporter not in exporters.exporters: - exporters.exporters.append(exporter) - exporter.interface_file = exporters.current_interface - - -#============================================================================== -# FunctionInfo -#============================================================================== -class FunctionInfo(DeclarationInfo): - - def __init__(self, name, include, tail=None, otherOption=None, - exporter_class = FunctionExporter): - DeclarationInfo.__init__(self, otherOption) - self._Attribute('name', name) - self._Attribute('include', include) - self._Attribute('exclude', False) - # create a FunctionExporter - exporter = exporter_class(InfoWrapper(self), tail) - self.AddExporter(exporter) - - -#============================================================================== -# ClassInfo -#============================================================================== -class ClassInfo(DeclarationInfo): - - def __init__(self, name, include, tail=None, otherInfo=None, - exporter_class = ClassExporter): - DeclarationInfo.__init__(self, otherInfo) - self._Attribute('name', name) - self._Attribute('include', include) - self._Attribute('exclude', False) - # create a ClassExporter - exporter = exporter_class(InfoWrapper(self), tail) - self.AddExporter(exporter) - - -#============================================================================== -# templates -#============================================================================== -def GenerateName(name, type_list): - name = name.replace('::', '_') - names = [name] + type_list - return makeid('_'.join(names)) - - -class ClassTemplateInfo(DeclarationInfo): - - def __init__(self, name, include, - exporter_class = ClassExporter): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - self._exporter_class = exporter_class - - - def Instantiate(self, type_list, rename=None): - if not rename: - rename = GenerateName(self._Attribute('name'), type_list) - # generate code to instantiate the template - types = ', '.join(type_list) - tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename) - tail += 'void __instantiate_%s()\n' % rename - tail += '{ sizeof(%s); }\n\n' % rename - # create a ClassInfo - class_ = ClassInfo(rename, self._Attribute('include'), tail, self, - exporter_class = self._exporter_class) - return class_ - - - def __call__(self, types, rename=None): - if isinstance(types, str): - types = types.split() - return self.Instantiate(types, rename) - -#============================================================================== -# EnumInfo -#============================================================================== -class EnumInfo(DeclarationInfo): - - def __init__(self, name, include, exporter_class = EnumExporter): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - self._Attribute('exclude', False) - self._Attribute('export_values', False) - exporter = exporter_class(InfoWrapper(self)) - self.AddExporter(exporter) - - -#============================================================================== -# HeaderInfo -#============================================================================== -class HeaderInfo(DeclarationInfo): - - def __init__(self, include, exporter_class = HeaderExporter): - warnings.warn('AllFromHeader is not working in all cases in the current version.') - DeclarationInfo.__init__(self) - self._Attribute('include', include) - exporter = exporter_class(InfoWrapper(self)) - self.AddExporter(exporter) - - -#============================================================================== -# VarInfo -#============================================================================== -class VarInfo(DeclarationInfo): - - def __init__(self, name, include, exporter_class = VarExporter): - DeclarationInfo.__init__(self) - self._Attribute('name', name) - self._Attribute('include', include) - exporter = exporter_class(InfoWrapper(self)) - self.AddExporter(exporter) - - -#============================================================================== -# CodeInfo -#============================================================================== -class CodeInfo(DeclarationInfo): - - def __init__(self, code, section, exporter_class = CodeExporter): - DeclarationInfo.__init__(self) - self._Attribute('code', code) - self._Attribute('section', section) - exporter = exporter_class(InfoWrapper(self)) - self.AddExporter(exporter) - - -#============================================================================== -# InfoWrapper -#============================================================================== -class InfoWrapper: - 'Provides a nicer interface for a info' - - def __init__(self, info): - self.__dict__['_info'] = info # so __setattr__ is not called - - def __getitem__(self, name): - return InfoWrapper(self._info[name]) - - def __getattr__(self, name): - return self._info._Attribute(name) - - def __setattr__(self, name, value): - self._info._Attribute(name, value) - - -#============================================================================== -# Functions -#============================================================================== -def exclude(info): - info._Attribute('exclude', True) - -def set_policy(info, policy): - info._Attribute('policy', policy) - -def rename(info, name): - info._Attribute('rename', name) - -def set_wrapper(info, wrapper): - if isinstance(wrapper, str): - wrapper = FunctionWrapper(wrapper) - info._Attribute('wrapper', wrapper) - -def instantiate(template, types, rename=None): - if isinstance(types, str): - types = types.split() - return template.Instantiate(types, rename) - -def use_shared_ptr(info): - info._Attribute('smart_ptr', 'boost::shared_ptr< %s >') - -def use_auto_ptr(info): - info._Attribute('smart_ptr', 'std::auto_ptr< %s >') - -def holder(info, function): - msg = "Expected a callable that accepts one string argument." - assert callable(function), msg - info._Attribute('holder', function) - -def add_method(info, name, rename=None): - added = info._Attribute('__added__') - if added is None: - info._Attribute('__added__', [(name, rename)]) - else: - added.append((name, rename)) - - -def class_code(info, code): - added = info._Attribute('__code__') - if added is None: - info._Attribute('__code__', [code]) - else: - added.append(code) - -def final(info): - info._Attribute('no_override', True) - - -def export_values(info): - info._Attribute('export_values', True) diff --git a/pyste/src/Pyste/policies.py b/pyste/src/Pyste/policies.py deleted file mode 100644 index 57ebd0de..00000000 --- a/pyste/src/Pyste/policies.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - - - -class Policy(object): - 'Represents one of the call policies of boost.python.' - - def __init__(self): - if type(self) is Policy: - raise RuntimeError, "Can't create an instance of the class Policy" - - - def Code(self): - 'Returns the string corresponding to a instancialization of the policy.' - pass - - - def _next(self): - if self.next is not None: - return ', %s >' % self.next.Code() - else: - return ' >' - - - def __eq__(self, other): - try: - return self.Code() == other.Code() - except AttributeError: - return False - - - -class return_internal_reference(Policy): - 'Ties the return value to one of the parameters.' - - def __init__(self, param=1, next=None): - ''' - param is the position of the parameter, or None for "self". - next indicates the next policy, or None. - ''' - self.param = param - self.next=next - - - def Code(self): - c = 'return_internal_reference< %i' % self.param - c += self._next() - return c - - - -class with_custodian_and_ward(Policy): - 'Ties lifetime of two arguments of a function.' - - def __init__(self, custodian, ward, next=None): - self.custodian = custodian - self.ward = ward - self.next = next - - def Code(self): - c = 'with_custodian_and_ward< %i, %i' % (self.custodian, self.ward) - c += self._next() - return c - - - -class return_value_policy(Policy): - 'Policy to convert return values.' - - def __init__(self, which, next=None): - self.which = which - self.next = next - - - def Code(self): - c = 'return_value_policy< %s' % self.which - c += self._next() - return c - -class return_self(Policy): - - def Code(self): - return 'return_self<>' - - -# values for return_value_policy -reference_existing_object = 'reference_existing_object' -copy_const_reference = 'copy_const_reference' -copy_non_const_reference = 'copy_non_const_reference' -manage_new_object = 'manage_new_object' -return_opaque_pointer = 'return_opaque_pointer' -return_by_value = 'return_by_value' diff --git a/pyste/src/Pyste/pyste.py b/pyste/src/Pyste/pyste.py deleted file mode 100644 index cedffff5..00000000 --- a/pyste/src/Pyste/pyste.py +++ /dev/null @@ -1,424 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -""" -Pyste version %s - -Usage: - pyste [options] interface-files - -where options are: - --module= The name of the module that will be generated; - defaults to the first interface filename, without - the extension. - -I Add an include path - -D Define symbol - --multiple Create various cpps, instead of only one - (useful during development) - --out= Specify output filename (default: .cpp) - in --multiple mode, this will be a directory - --no-using Do not declare "using namespace boost"; - use explicit declarations instead - --pyste-ns= Set the namespace where new types will be declared; - default is the empty namespace - --debug Writes the xml for each file parsed in the current - directory - --cache-dir= Directory for cache files (speeds up future runs) - --only-create-cache Recreates all caches (doesn't generate code). - --generate-main Generates the _main.cpp file (in multiple mode) - --file-list A file with one pyste file per line. Use as a - substitute for passing the files in the command - line. - --gccxml-path= Path to gccxml executable (default: gccxml) - --no-default-include Do not use INCLUDE environment variable for include - files to pass along gccxml. - -h, --help Print this help and exit - -v, --version Print version information -""" - -import sys -import os -import getopt -import exporters -import SingleCodeUnit -import MultipleCodeUnit -import infos -import exporterutils -import settings -import gc -import sys -from policies import * -from CppParser import CppParser, CppParserError -import time -import declarations - -__version__ = '0.9.30' - -def RecursiveIncludes(include): - 'Return a list containg the include dir and all its subdirectories' - dirs = [include] - def visit(arg, dir, names): - # ignore CVS dirs - if os.path.split(dir)[1] != 'CVS': - dirs.append(dir) - os.path.walk(include, visit, None) - return dirs - - -def GetDefaultIncludes(): - if 'INCLUDE' in os.environ: - include = os.environ['INCLUDE'] - return include.split(os.pathsep) - else: - return [] - - -def ProcessIncludes(includes): - if sys.platform == 'win32': - index = 0 - for include in includes: - includes[index] = include.replace('\\', '/') - index += 1 - - -def ReadFileList(filename): - f = file(filename) - files = [] - try: - for line in f: - line = line.strip() - if line: - files.append(line) - finally: - f.close() - return files - - -def ParseArguments(): - - def Usage(): - print __doc__ % __version__ - sys.exit(1) - - try: - options, files = getopt.getopt( - sys.argv[1:], - 'R:I:D:vh', - ['module=', 'multiple', 'out=', 'no-using', 'pyste-ns=', 'debug', 'cache-dir=', - 'only-create-cache', 'version', 'generate-main', 'file-list=', 'help', - 'gccxml-path=', 'no-default-include']) - except getopt.GetoptError, e: - print - print 'ERROR:', e - Usage() - - default_includes = GetDefaultIncludes() - includes = [] - defines = [] - module = None - out = None - multiple = False - cache_dir = None - create_cache = False - generate_main = False - gccxml_path = 'gccxml' - - for opt, value in options: - if opt == '-I': - includes.append(value) - elif opt == '-D': - defines.append(value) - elif opt == '-R': - includes.extend(RecursiveIncludes(value)) - elif opt == '--module': - module = value - elif opt == '--out': - out = value - elif opt == '--no-using': - settings.namespaces.python = 'boost::python::' - settings.USING_BOOST_NS = False - elif opt == '--pyste-ns': - settings.namespaces.pyste = value + '::' - elif opt == '--debug': - settings.DEBUG = True - elif opt == '--multiple': - multiple = True - elif opt == '--cache-dir': - cache_dir = value - elif opt == '--only-create-cache': - create_cache = True - elif opt == '--file-list': - files += ReadFileList(value) - elif opt in ['-h', '--help']: - Usage() - elif opt in ['-v', '--version']: - print 'Pyste version %s' % __version__ - sys.exit(2) - elif opt == '--generate-main': - generate_main = True - elif opt == '--gccxml-path': - gccxml_path = value - elif opt == '--no-default-include': - default_includes = [] - else: - print 'Unknown option:', opt - Usage() - - includes[0:0] = default_includes - if not files: - Usage() - if not module: - module = os.path.splitext(os.path.basename(files[0]))[0] - if not out: - out = module - if not multiple: - out += '.cpp' - for file in files: - d = os.path.dirname(os.path.abspath(file)) - if d not in sys.path: - sys.path.append(d) - - if create_cache and not cache_dir: - print 'Error: Use --cache-dir to indicate where to create the cache files!' - Usage() - sys.exit(3) - - if generate_main and not multiple: - print 'Error: --generate-main only valid in multiple mode.' - Usage() - sys.exit(3) - - ProcessIncludes(includes) - return includes, defines, module, out, files, multiple, cache_dir, create_cache, \ - generate_main, gccxml_path - - -def PCHInclude(*headers): - code = '\n'.join(['#include <%s>' % x for x in headers]) - infos.CodeInfo(code, 'pchinclude') - - -def CreateContext(): - 'create the context where a interface file will be executed' - context = {} - context['Import'] = Import - # infos - context['Function'] = infos.FunctionInfo - context['Class'] = infos.ClassInfo - context['Include'] = lambda header: infos.CodeInfo('#include <%s>\n' % header, 'include') - context['PCHInclude'] = PCHInclude - context['Template'] = infos.ClassTemplateInfo - context['Enum'] = infos.EnumInfo - context['AllFromHeader'] = infos.HeaderInfo - context['Var'] = infos.VarInfo - # functions - context['rename'] = infos.rename - context['set_policy'] = infos.set_policy - context['exclude'] = infos.exclude - context['set_wrapper'] = infos.set_wrapper - context['use_shared_ptr'] = infos.use_shared_ptr - context['use_auto_ptr'] = infos.use_auto_ptr - context['holder'] = infos.holder - context['add_method'] = infos.add_method - context['final'] = infos.final - context['export_values'] = infos.export_values - # policies - context['return_internal_reference'] = return_internal_reference - context['with_custodian_and_ward'] = with_custodian_and_ward - context['return_value_policy'] = return_value_policy - context['reference_existing_object'] = reference_existing_object - context['copy_const_reference'] = copy_const_reference - context['copy_non_const_reference'] = copy_non_const_reference - context['return_opaque_pointer'] = return_opaque_pointer - context['manage_new_object'] = manage_new_object - context['return_by_value'] = return_by_value - context['return_self'] = return_self - # utils - context['Wrapper'] = exporterutils.FunctionWrapper - context['declaration_code'] = lambda code: infos.CodeInfo(code, 'declaration-outside') - context['module_code'] = lambda code: infos.CodeInfo(code, 'module') - context['class_code'] = infos.class_code - return context - - -def Begin(): - # parse arguments - includes, defines, module, out, interfaces, multiple, cache_dir, create_cache, generate_main, gccxml_path = ParseArguments() - # run pyste scripts - for interface in interfaces: - ExecuteInterface(interface) - # create the parser - parser = CppParser(includes, defines, cache_dir, declarations.version, gccxml_path) - try: - if not create_cache: - if not generate_main: - return GenerateCode(parser, module, out, interfaces, multiple) - else: - return GenerateMain(module, out, OrderInterfaces(interfaces)) - else: - return CreateCaches(parser) - finally: - parser.Close() - - -def CreateCaches(parser): - # There is one cache file per interface so we organize the headers - # by interfaces. For each interface collect the tails from the - # exporters sharing the same header. - tails = JoinTails(exporters.exporters) - - # now for each interface file take each header, and using the tail - # get the declarations and cache them. - for interface, header in tails: - tail = tails[(interface, header)] - declarations = parser.ParseWithGCCXML(header, tail) - cachefile = parser.CreateCache(header, interface, tail, declarations) - print 'Cached', cachefile - - return 0 - - -_imported_count = {} # interface => count - -def ExecuteInterface(interface): - old_interface = exporters.current_interface - if not os.path.exists(interface): - if old_interface and os.path.exists(old_interface): - d = os.path.dirname(old_interface) - interface = os.path.join(d, interface) - if not os.path.exists(interface): - raise IOError, "Cannot find interface file %s."%interface - - _imported_count[interface] = _imported_count.get(interface, 0) + 1 - exporters.current_interface = interface - context = CreateContext() - context['INTERFACE_FILE'] = os.path.abspath(interface) - execfile(interface, context) - exporters.current_interface = old_interface - - -def Import(interface): - exporters.importing = True - ExecuteInterface(interface) - exporters.importing = False - - -def JoinTails(exports): - '''Returns a dict of {(interface, header): tail}, where tail is the - joining of all tails of all exports for the header. - ''' - tails = {} - for export in exports: - interface = export.interface_file - header = export.Header() - tail = export.Tail() or '' - if (interface, header) in tails: - all_tails = tails[(interface,header)] - all_tails += '\n' + tail - tails[(interface, header)] = all_tails - else: - tails[(interface, header)] = tail - - return tails - - - -def OrderInterfaces(interfaces): - interfaces_order = [(_imported_count[x], x) for x in interfaces] - interfaces_order.sort() - interfaces_order.reverse() - return [x for _, x in interfaces_order] - - - -def GenerateMain(module, out, interfaces): - codeunit = MultipleCodeUnit.MultipleCodeUnit(module, out) - codeunit.GenerateMain(interfaces) - return 0 - - -def GenerateCode(parser, module, out, interfaces, multiple): - # prepare to generate the wrapper code - if multiple: - codeunit = MultipleCodeUnit.MultipleCodeUnit(module, out) - else: - codeunit = SingleCodeUnit.SingleCodeUnit(module, out) - # stop referencing the exporters here - exports = exporters.exporters - exporters.exporters = None - exported_names = dict([(x.Name(), None) for x in exports]) - - # order the exports - order = {} - for export in exports: - if export.interface_file in order: - order[export.interface_file].append(export) - else: - order[export.interface_file] = [export] - exports = [] - interfaces_order = OrderInterfaces(interfaces) - for interface in interfaces_order: - exports.extend(order[interface]) - del order - del interfaces_order - - # now generate the code in the correct order - #print exported_names - tails = JoinTails(exports) - for i in xrange(len(exports)): - export = exports[i] - interface = export.interface_file - header = export.Header() - if header: - tail = tails[(interface, header)] - declarations, parsed_header = parser.Parse(header, interface, tail) - else: - declarations = [] - parsed_header = None - ExpandTypedefs(declarations, exported_names) - export.SetDeclarations(declarations) - export.SetParsedHeader(parsed_header) - if multiple: - codeunit.SetCurrent(export.interface_file, export.Name()) - export.GenerateCode(codeunit, exported_names) - # force collect of cyclic references - exports[i] = None - del declarations - del export - gc.collect() - # finally save the code unit - codeunit.Save() - if not multiple: - print 'Module %s generated' % module - return 0 - - -def ExpandTypedefs(decls, exported_names): - '''Check if the names in exported_names are a typedef, and add the real class - name in the dict. - ''' - for name in exported_names.keys(): - for decl in decls: - if isinstance(decl, declarations.Typedef): - exported_names[decl.type.FullName()] = None - -def UsePsyco(): - 'Tries to use psyco if possible' - try: - import psyco - psyco.profile() - except: pass - - -def main(): - start = time.clock() - UsePsyco() - status = Begin() - print '%0.2f seconds' % (time.clock()-start) - sys.exit(status) - - -if __name__ == '__main__': - main() diff --git a/pyste/src/Pyste/settings.py b/pyste/src/Pyste/settings.py deleted file mode 100644 index ba613b23..00000000 --- a/pyste/src/Pyste/settings.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - - -#============================================================================== -# Global information -#============================================================================== - -DEBUG = False -USING_BOOST_NS = True - -class namespaces: - boost = 'boost::' - pyste = '' - python = '' # default is to not use boost::python namespace explicitly, so - # use the "using namespace" statement instead - -import sys -msvc = sys.platform == 'win32' diff --git a/pyste/src/Pyste/utils.py b/pyste/src/Pyste/utils.py deleted file mode 100644 index a8843e3f..00000000 --- a/pyste/src/Pyste/utils.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -from __future__ import generators -import string -import sys - -#============================================================================== -# enumerate -#============================================================================== -def enumerate(seq): - i = 0 - for x in seq: - yield i, x - i += 1 - - -#============================================================================== -# makeid -#============================================================================== -_valid_chars = string.ascii_letters + string.digits + '_' -_valid_chars = dict(zip(_valid_chars, _valid_chars)) - -def makeid(name): - 'Returns the name as a valid identifier' - if type(name) != str: - print type(name), name - newname = [] - for char in name: - if char not in _valid_chars: - char = '_' - newname.append(char) - newname = ''.join(newname) - # avoid duplications of '_' chars - names = [x for x in newname.split('_') if x] - return '_'.join(names) - - -#============================================================================== -# remove_duplicated_lines -#============================================================================== -def remove_duplicated_lines(text): - includes = text.splitlines() - d = dict([(include, 0) for include in includes]) - includes = d.keys() - includes.sort() - return '\n'.join(includes) - - -#============================================================================== -# left_equals -#============================================================================== -def left_equals(s): - s = '// %s ' % s - return s + ('='*(80-len(s))) + '\n' - - -#============================================================================== -# post_mortem -#============================================================================== -def post_mortem(): - - def info(type, value, tb): - if hasattr(sys, 'ps1') or not sys.stderr.isatty(): - # we are in interactive mode or we don't have a tty-like - # device, so we call the default hook - sys.__excepthook__(type, value, tb) - else: - import traceback, pdb - # we are NOT in interactive mode, print the exception... - traceback.print_exception(type, value, tb) - print - # ...then start the debugger in post-mortem mode. - pdb.pm() - - sys.excepthook = info diff --git a/pyste/tests/GCCXMLParserUT.py b/pyste/tests/GCCXMLParserUT.py deleted file mode 100644 index 7175c9c6..00000000 --- a/pyste/tests/GCCXMLParserUT.py +++ /dev/null @@ -1,341 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import sys -sys.path.append('../src') -import unittest -import tempfile -import os.path -from Pyste import GCCXMLParser -from Pyste.declarations import * - - -class Tester(unittest.TestCase): - - def TestConstructor(self, class_, method, visib): - self.assert_(isinstance(method, Constructor)) - self.assertEqual(method.FullName(), class_.FullName() + '::' + method.name) - self.assertEqual(method.result, None) - self.assertEqual(method.visibility, visib) - self.assert_(not method.virtual) - self.assert_(not method.abstract) - self.assert_(not method.static) - - def TestDefaultConstructor(self, class_, method, visib): - self.TestConstructor(class_, method, visib) - self.assert_(method.IsDefault()) - - def TestCopyConstructor(self, class_, method, visib): - self.TestConstructor(class_, method, visib) - self.assertEqual(len(method.parameters), 1) - param = method.parameters[0] - self.TestType( - param, - ReferenceType, - class_.FullName(), - 'const %s&' % class_.FullName(), - True) - self.assert_(method.IsCopy()) - - - def TestType(self, type_, classtype_, name, fullname, const): - self.assert_(isinstance(type_, classtype_)) - self.assertEqual(type_.name, name) - self.assertEqual(type_.namespace, None) - self.assertEqual(type_.FullName(), fullname) - self.assertEqual(type_.const, const) - - -class ClassBaseTest(Tester): - - def setUp(self): - self.base = GetDecl('Base') - - def testClass(self): - 'test the properties of the class Base' - self.assert_(isinstance(self.base, Class)) - self.assert_(self.base.abstract) - - - def testFoo(self): - 'test function foo in class Base' - foo = GetMember(self.base, 'foo') - self.assert_(isinstance(foo, Method)) - self.assertEqual(foo.visibility, Scope.public) - self.assert_(foo.virtual) - self.assert_(foo.abstract) - self.failIf(foo.static) - self.assertEqual(foo.class_, 'test::Base') - self.failIf(foo.const) - self.assertEqual(foo.FullName(), 'test::Base::foo') - self.assertEqual(foo.result.name, 'void') - self.assertEqual(len(foo.parameters), 1) - param = foo.parameters[0] - self.TestType(param, FundamentalType, 'int', 'int', False) - self.assertEqual(foo.namespace, None) - self.assertEqual( - foo.PointerDeclaration(1), '(void (test::Base::*)(int) )&test::Base::foo') - - def testX(self): - 'test the member x in class Base' - x = GetMember(self.base, 'x') - self.assertEqual(x.class_, 'test::Base') - self.assertEqual(x.FullName(), 'test::Base::x') - self.assertEqual(x.namespace, None) - self.assertEqual(x.visibility, Scope.private) - self.TestType(x.type, FundamentalType, 'int', 'int', False) - self.assertEqual(x.static, False) - - def testConstructors(self): - 'test constructors in class Base' - constructors = GetMembers(self.base, 'Base') - for cons in constructors: - if len(cons.parameters) == 0: - self.TestDefaultConstructor(self.base, cons, Scope.public) - elif len(cons.parameters) == 1: # copy constructor - self.TestCopyConstructor(self.base, cons, Scope.public) - elif len(cons.parameters) == 2: # other constructor - intp, floatp = cons.parameters - self.TestType(intp, FundamentalType, 'int', 'int', False) - self.TestType(floatp, FundamentalType, 'float', 'float', False) - - def testSimple(self): - 'test function simple in class Base' - simple = GetMember(self.base, 'simple') - self.assert_(isinstance(simple, Method)) - self.assertEqual(simple.visibility, Scope.protected) - self.assertEqual(simple.FullName(), 'test::Base::simple') - self.assertEqual(len(simple.parameters), 1) - param = simple.parameters[0] - self.TestType(param, ReferenceType, 'std::string', 'const std::string&', True) - self.TestType(simple.result, FundamentalType, 'bool', 'bool', False) - self.assertEqual( - simple.PointerDeclaration(1), - '(bool (test::Base::*)(const std::string&) )&test::Base::simple') - - - def testZ(self): - z = GetMember(self.base, 'z') - self.assert_(isinstance(z, Variable)) - self.assertEqual(z.visibility, Scope.public) - self.assertEqual(z.FullName(), 'test::Base::z') - self.assertEqual(z.type.name, 'int') - self.assertEqual(z.type.const, False) - self.assert_(z.static) - - -class ClassTemplateTest(Tester): - - def setUp(self): - self.template = GetDecl('Template') - - def testClass(self): - 'test the properties of the Template class' - self.assert_(isinstance(self.template, Class)) - self.assert_(not self.template.abstract) - self.assertEqual(self.template.FullName(), 'Template') - self.assertEqual(self.template.namespace, '') - self.assertEqual(self.template.name, 'Template') - - def testConstructors(self): - 'test the automatic constructors of the class Template' - constructors = GetMembers(self.template, 'Template') - for cons in constructors: - if len(cons.parameters) == 0: - self.TestDefaultConstructor(self.template, cons, Scope.public) - elif len(cons.parameters) == 1: - self.TestCopyConstructor(self.template, cons, Scope.public) - - - def testValue(self): - 'test the class variable value' - value = GetMember(self.template, 'value') - self.assert_(isinstance(value, ClassVariable)) - self.assert_(value.name, 'value') - self.TestType(value.type, FundamentalType, 'int', 'int', False) - self.assert_(not value.static) - self.assertEqual(value.visibility, Scope.public) - self.assertEqual(value.class_, 'Template') - self.assertEqual(value.FullName(), 'Template::value') - - def testBase(self): - 'test the superclasses of Template' - bases = self.template.bases - self.assertEqual(len(bases), 1) - base = bases[0] - self.assert_(isinstance(base, Base)) - self.assertEqual(base.name, 'test::Base') - self.assertEqual(base.visibility, Scope.protected) - - - -class FreeFuncTest(Tester): - - def setUp(self): - self.func = GetDecl('FreeFunc') - - def testFunc(self): - 'test attributes of FreeFunc' - self.assert_(isinstance(self.func, Function)) - self.assertEqual(self.func.name, 'FreeFunc') - self.assertEqual(self.func.FullName(), 'test::FreeFunc') - self.assertEqual(self.func.namespace, 'test') - self.assertEqual( - self.func.PointerDeclaration(1), - '(const test::Base& (*)(const std::string&, int))&test::FreeFunc') - - - def testResult(self): - 'test the return value of FreeFunc' - res = self.func.result - self.TestType(res, ReferenceType, 'test::Base', 'const test::Base&', True) - - def testParameters(self): - 'test the parameters of FreeFunc' - self.assertEqual(len(self.func.parameters), 2) - strp, intp = self.func.parameters - self.TestType(strp, ReferenceType, 'std::string', 'const std::string&', True) - self.assertEqual(strp.default, None) - self.TestType(intp, FundamentalType, 'int', 'int', False) - self.assertEqual(intp.default, '10') - - - -class testFunctionPointers(Tester): - - def testMethodPointer(self): - 'test declaration of a pointer-to-method' - meth = GetDecl('MethodTester') - param = meth.parameters[0] - fullname = 'void (test::Base::*)(int)' - self.TestType(param, PointerType, fullname, fullname, False) - - def testFunctionPointer(self): - 'test declaration of a pointer-to-function' - func = GetDecl('FunctionTester') - param = func.parameters[0] - fullname = 'void (*)(int)' - self.TestType(param, PointerType, fullname, fullname, False) - - - -# ============================================================================= -# Support routines -# ============================================================================= - -cppcode = ''' -namespace std { - class string; -} -namespace test { -class Base -{ -public: - Base(); - Base(const Base&); - Base(int, float); - - virtual void foo(int = 0.0) = 0; - static int z; -protected: - bool simple(const std::string&); -private: - int x; -}; - -void MethodTester( void (Base::*)(int) ); -void FunctionTester( void (*)(int) ); - - -const Base & FreeFunc(const std::string&, int=10); - -} - -template -struct Template: protected test::Base -{ - T value; - virtual void foo(int); -}; - -Template __aTemplateInt; -''' - -def GetXMLFile(): - '''Generates an gccxml file using the code from the global cppcode. - Returns the xml's filename.''' - # write the code to a header file - tmpfile = tempfile.mktemp() + '.h' - f = file(tmpfile, 'w') - f.write(cppcode) - f.close() - # run gccxml - outfile = tmpfile + '.xml' - if os.system('gccxml "%s" "-fxml=%s"' % (tmpfile, outfile)) != 0: - raise RuntimeError, 'Error executing GCCXML.' - # read the output file into the xmlcode - f = file(outfile) - xmlcode = f.read() - #print xmlcode - f.close() - # remove the header - os.remove(tmpfile) - return outfile - - - -def GetDeclarations(): - 'Uses the GCCXMLParser module to get the declarations.' - xmlfile = GetXMLFile() - declarations = GCCXMLParser.ParseDeclarations(xmlfile) - os.remove(xmlfile) - return declarations - -# the declarations to be analysed -declarations = GetDeclarations() - - -def GetDecl(name): - 'returns one of the top declarations given its name' - for decl in declarations: - if decl.name == name: - return decl - else: - raise RuntimeError, 'Declaration not found: %s' % name - - -def GetMember(class_, name): - 'gets the member of the given class by its name' - - res = None - multipleFound = False - for member in class_: - if member.name == name: - if res is not None: - multipleFound = True - break - res = member - if res is None or multipleFound: - raise RuntimeError, \ - 'No member or more than one member found in class %s: %s' \ - % (class_.name, name) - return res - - -def GetMembers(class_, name): - 'gets the members of the given class by its name' - res = [] - for member in class_: - if member.name == name: - res.append(member) - if len(res) in (0, 1): - raise RuntimeError, \ - 'GetMembers: 0 or 1 members found in class %s: %s' \ - % (class_.name, name) - return res - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/SmartFileUT.py b/pyste/tests/SmartFileUT.py deleted file mode 100644 index 9e4e9988..00000000 --- a/pyste/tests/SmartFileUT.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import sys -sys.path.append('../src') -from SmartFile import * -import unittest -import tempfile -import os -import time - - -class SmartFileTest(unittest.TestCase): - - FILENAME = tempfile.mktemp() - - def setUp(self): - self._Clean() - - def tearDown(self): - self._Clean() - - def _Clean(self): - try: - os.remove(self.FILENAME) - except OSError: pass - - - def testNonExistant(self): - "Must override the file, as there's no file in the disk yet" - self.assert_(not os.path.isfile(self.FILENAME)) - f = SmartFile(self.FILENAME, 'w') - f.write('Testing 123\nTesting again.') - f.close() - self.assert_(os.path.isfile(self.FILENAME)) - - - def testOverride(self): - "Must override the file, because the contents are different" - contents = 'Contents!\nContents!' - # create the file normally first - f = file(self.FILENAME, 'w') - f.write(contents) - f.close() - file_time = os.path.getmtime(self.FILENAME) - self.assert_(os.path.isfile(self.FILENAME)) - time.sleep(2) - f = SmartFile(self.FILENAME, 'w') - f.write(contents + '_') - f.close() - new_file_time = os.path.getmtime(self.FILENAME) - self.assert_(new_file_time != file_time) - - - def testNoOverride(self): - "Must not override the file, because the contents are the same" - contents = 'Contents!\nContents!' - # create the file normally first - f = file(self.FILENAME, 'w') - f.write(contents) - f.close() - file_time = os.path.getmtime(self.FILENAME) - self.assert_(os.path.isfile(self.FILENAME)) - time.sleep(2) - f = SmartFile(self.FILENAME, 'w') - f.write(contents) - f.close() - new_file_time = os.path.getmtime(self.FILENAME) - self.assert_(new_file_time == file_time) - - - def testAutoClose(self): - "Must be closed when garbage-collected" - def foo(): - f = SmartFile(self.FILENAME) - f.write('testing') - self.assert_(not os.path.isfile(self.FILENAME)) - foo() - self.assert_(os.path.isfile(self.FILENAME)) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/abstract_test.h b/pyste/tests/abstract_test.h deleted file mode 100644 index e0fba2b2..00000000 --- a/pyste/tests/abstract_test.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#include -#include - -namespace abstract { - -struct A { - virtual ~A() {} - virtual std::string f()=0; -}; - -struct B: A { - std::string f() { return "B::f"; } -}; - -std::string call(A* a) { return a->f(); } - -} diff --git a/pyste/tests/abstract_test.pyste b/pyste/tests/abstract_test.pyste deleted file mode 100644 index c65bb3ad..00000000 --- a/pyste/tests/abstract_test.pyste +++ /dev/null @@ -1,3 +0,0 @@ -Class('abstract::A', 'abstract_test.h') -Class('abstract::B', 'abstract_test.h') -Function('abstract::call', 'abstract_test.h') diff --git a/pyste/tests/abstract_testUT.py b/pyste/tests/abstract_testUT.py deleted file mode 100644 index 4dc61a26..00000000 --- a/pyste/tests/abstract_testUT.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _abstract_test import * - -class AbstractTest(unittest.TestCase): - - def testIt(self): - class C(A): - def f(self): - return 'C::f' - - a = A() - b = B() - c = C() - self.assertRaises(RuntimeError, a.f) - self.assertEqual(b.f(), 'B::f') - self.assertEqual(call(b), 'B::f') - self.assertEqual(c.f(), 'C::f') - self.assertEqual(call(c), 'C::f') - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/add_test.h b/pyste/tests/add_test.h deleted file mode 100644 index 447e8814..00000000 --- a/pyste/tests/add_test.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -namespace add_test { - -struct C -{ - int x; -}; - -const int get_x(C& c) -{ - return c.x; -} - -} diff --git a/pyste/tests/add_test.pyste b/pyste/tests/add_test.pyste deleted file mode 100644 index cc7faa9e..00000000 --- a/pyste/tests/add_test.pyste +++ /dev/null @@ -1,2 +0,0 @@ -C = Class('add_test::C', 'add_test.h') -add_method(C, 'add_test::get_x') diff --git a/pyste/tests/add_testUT.py b/pyste/tests/add_testUT.py deleted file mode 100644 index 16f57a32..00000000 --- a/pyste/tests/add_testUT.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _add_test import * - -class AddMethodTest(unittest.TestCase): - - def testIt(self): - c = C() - c.x = 10 - self.assertEqual(c.get_x(), 10) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/basic.cpp b/pyste/tests/basic.cpp deleted file mode 100644 index d07b6da6..00000000 --- a/pyste/tests/basic.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#include "basic.h" - -namespace basic { - - int C::static_value = 3; - const int C::const_static_value = 100; - -} diff --git a/pyste/tests/basic.h b/pyste/tests/basic.h deleted file mode 100644 index 690fed2d..00000000 --- a/pyste/tests/basic.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef BASIC_H -#define BASIC_H - - -#include - -namespace basic { - -struct C -{ - // test virtuallity - C(): value(1), const_value(0) {} - virtual int f(int x = 10) - { - return x*2; - } - - int foo(int x=1){ - return x+1; - } - - const std::string& get_name() { return name; } - void set_name(const std::string& name) { this->name = name; } -private: - std::string name; - -public: - // test data members - static int static_value; - static const int const_static_value; - - int value; - const int const_value; - - // test static functions - static int mul(int x, int y) { return x*y; } - static double mul(double x, double y) { return x*y; } - - static int square(int x=2) { return x*x; } -}; - -inline int call_f(C& c) -{ - return c.f(); -} - -inline int call_f(C& c, int x) -{ - return c.f(x); -} - -inline int get_static() -{ - return C::static_value; -} - -inline int get_value(C& c) -{ - return c.value; -} - -} - -#endif diff --git a/pyste/tests/basic.pyste b/pyste/tests/basic.pyste deleted file mode 100644 index 4fe0b5b3..00000000 --- a/pyste/tests/basic.pyste +++ /dev/null @@ -1,5 +0,0 @@ -Class('basic::C', 'basic.h') -Function('basic::call_f', 'basic.h') -Function('basic::get_static', 'basic.h') -Function('basic::get_value', 'basic.h') - diff --git a/pyste/tests/basicUT.py b/pyste/tests/basicUT.py deleted file mode 100644 index 9a18bcbf..00000000 --- a/pyste/tests/basicUT.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _basic import * - -class BasicExampleTest(unittest.TestCase): - - def testIt(self): - - # test virtual functions - class D(C): - def f(self, x=10): - return x+1 - - d = D() - c = C() - - self.assertEqual(c.f(), 20) - self.assertEqual(c.f(3), 6) - self.assertEqual(d.f(), 11) - self.assertEqual(d.f(3), 4) - self.assertEqual(call_f(c), 20) - self.assertEqual(call_f(c, 4), 8) - self.assertEqual(call_f(d), 11) - self.assertEqual(call_f(d, 3), 4) - - # test data members - def testValue(value): - self.assertEqual(c.value, value) - self.assertEqual(d.value, value) - self.assertEqual(get_value(c), value) - self.assertEqual(get_value(d), value) - testValue(1) - c.value = 30 - d.value = 30 - testValue(30) - self.assertEqual(c.const_value, 0) - self.assertEqual(d.const_value, 0) - def set_const_value(): - c.const_value = 12 - self.assertRaises(AttributeError, set_const_value) - - # test static data-members - def testStatic(value): - self.assertEqual(C.static_value, value) - self.assertEqual(c.static_value, value) - self.assertEqual(D.static_value, value) - self.assertEqual(d.static_value, value) - self.assertEqual(get_static(), value) - testStatic(3) - C.static_value = 10 - testStatic(10) - self.assertEqual(C.const_static_value, 100) - def set_const_static(): - C.const_static_value = 1 - self.assertRaises(AttributeError, set_const_static) - - # test static function - def test_mul(result, *args): - self.assertEqual(C.mul(*args), result) - self.assertEqual(c.mul(*args), result) - test_mul(16, 8, 2) - test_mul(6.0, 2.0, 3.0) - self.assertEqual(C.square(), 4) - self.assertEqual(c.square(), 4) - self.assertEqual(C.square(3), 9) - self.assertEqual(c.square(3), 9) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/code_test.h b/pyste/tests/code_test.h deleted file mode 100644 index 0a31205a..00000000 --- a/pyste/tests/code_test.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -struct A { - int x; -}; diff --git a/pyste/tests/code_test.pyste b/pyste/tests/code_test.pyste deleted file mode 100644 index 467996fd..00000000 --- a/pyste/tests/code_test.pyste +++ /dev/null @@ -1,9 +0,0 @@ -Class('A', 'code_test.h') -Include('string') -declaration_code(''' -int get(A& a) { return a.x; } - -std::string foo() { return "Hello!"; } -''') -module_code(' def("get", &get);\n') -module_code(' def("foo", &foo);\n') diff --git a/pyste/tests/code_testUT.py b/pyste/tests/code_testUT.py deleted file mode 100644 index 1059570a..00000000 --- a/pyste/tests/code_testUT.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _code_test import * - -class CodeTest(unittest.TestCase): - - def testIt(self): - a = A() - a.x = 12 - self.assertEqual(get(a), 12) - self.assertEqual(foo(), "Hello!") - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/enums.h b/pyste/tests/enums.h deleted file mode 100644 index afe33ca4..00000000 --- a/pyste/tests/enums.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef ENUMS_H -#define ENUMS_H - -namespace enums { - -enum color { red, blue }; - -struct X -{ - enum choices - { - good = 1, - bad = 2 - }; - - int set(choices c) - { - return (int)c; - } -}; - -enum { - x = 0, - y = 1 -}; - -} - -#endif diff --git a/pyste/tests/enums.pyste b/pyste/tests/enums.pyste deleted file mode 100644 index c18a1244..00000000 --- a/pyste/tests/enums.pyste +++ /dev/null @@ -1,8 +0,0 @@ -h = AllFromHeader('enums.h') -rename(h.color.red, 'Red') -rename(h.color.blue, 'Blue') -export_values(h.color) -rename(h.X.choices.bad, 'Bad') -rename(h.X.choices.good, 'Good') -rename(h.X.choices, 'Choices') - diff --git a/pyste/tests/enumsUT.py b/pyste/tests/enumsUT.py deleted file mode 100644 index 7c7720dc..00000000 --- a/pyste/tests/enumsUT.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _enums import * - -class EnumsTest(unittest.TestCase): - - def testIt(self): - self.assertEqual(int(Red), 0) - self.assertEqual(int(Blue), 1) - - self.assertEqual(int(X.Choices.Good), 1) - self.assertEqual(int(X.Choices.Bad), 2) - a = X() - self.assertEqual(a.set(a.Choices.Good), 1) - self.assertEqual(a.set(a.Choices.Bad), 2) - self.assertEqual(x, 0) - self.assertEqual(y, 1) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/header_test.h b/pyste/tests/header_test.h deleted file mode 100644 index 030d0d26..00000000 --- a/pyste/tests/header_test.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef HEADER_TEST_H -#define HEADER_TEST_H - -#include -#include - -namespace header_test { - -enum choice { red, blue }; - -inline std::string choice_str(choice c) -{ - std::map choice_map; - choice_map[red] = "red"; - choice_map[blue] = "blue"; - return choice_map[c]; -} - -struct C -{ - choice c; - - std::string get() - { - return choice_str(c); - } -}; - -// test the exclusion of the following - -struct ForwardDeclared; // should be excluded automatically -struct A {}; -void foo(); -enum bar { value }; - -} - -#endif diff --git a/pyste/tests/header_test.pyste b/pyste/tests/header_test.pyste deleted file mode 100644 index 3bd55501..00000000 --- a/pyste/tests/header_test.pyste +++ /dev/null @@ -1,4 +0,0 @@ -h = AllFromHeader('header_test.h') -exclude(h.A) -exclude(h.foo) -exclude(h.bar) diff --git a/pyste/tests/header_testUT.py b/pyste/tests/header_testUT.py deleted file mode 100644 index aa0d4a16..00000000 --- a/pyste/tests/header_testUT.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _header_test import * - -class HeaderTest(unittest.TestCase): - - def testIt(self): - self.assertEqual(choice.red, 0) - self.assertEqual(choice.blue, 1) - self.assertEqual(choice_str(choice.blue), 'blue') - self.assertEqual(choice_str(choice.red), 'red') - c = C() - c.c = choice.blue - self.assertEqual(c.get(), 'blue') - c.c = choice.red - self.assertEqual(c.get(), 'red') - # the following classes/functions should not have being exported - self.assertRaises(NameError, lambda: A()) - self.assertRaises(NameError, lambda: foo()) - self.assertRaises(NameError, lambda: bar.value) - self.assertRaises(NameError, lambda: ForwardDeclared()) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/infosUT.py b/pyste/tests/infosUT.py deleted file mode 100644 index 93769f34..00000000 --- a/pyste/tests/infosUT.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import sys -from Pyste.infos import * -from Pyste.policies import * -from Pyste.exporterutils import * -import unittest - -#================================================================================ -# InfosTest -#================================================================================ -class InfosTest(unittest.TestCase): - - def testFunctionInfo(self): - info = FunctionInfo('test::foo', 'foo.h') - rename(info, 'hello') - set_policy(info, return_internal_reference()) - set_wrapper(info, FunctionWrapper('foo_wrapper')) - - info = InfoWrapper(info) - - self.assertEqual(info.rename, 'hello') - self.assertEqual(info.policy.Code(), 'return_internal_reference< 1 >') - self.assertEqual(info.wrapper.name, 'foo_wrapper') - - - def testClassInfo(self): - info = ClassInfo('test::IFoo', 'foo.h') - rename(info.name, 'Name') - rename(info.exclude, 'Exclude') - rename(info, 'Foo') - rename(info.Bar, 'bar') - set_policy(info.Baz, return_internal_reference()) - rename(info.operator['>>'], 'from_string') - exclude(info.Bar) - set_wrapper(info.Baz, FunctionWrapper('baz_wrapper')) - - info = InfoWrapper(info) - - self.assertEqual(info.rename, 'Foo') - self.assertEqual(info['Bar'].rename, 'bar') - self.assertEqual(info['name'].rename, 'Name') - self.assertEqual(info['exclude'].rename, 'Exclude') - self.assertEqual(info['Bar'].exclude, True) - self.assertEqual(info['Baz'].policy.Code(), 'return_internal_reference< 1 >') - self.assertEqual(info['Baz'].wrapper.name, 'baz_wrapper') - self.assertEqual(info['operator']['>>'].rename, 'from_string') - - - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/inherit.cpp b/pyste/tests/inherit.cpp deleted file mode 100644 index a75e8389..00000000 --- a/pyste/tests/inherit.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#include "inherit.h" - -int inherit::C::s = 1; diff --git a/pyste/tests/inherit.h b/pyste/tests/inherit.h deleted file mode 100644 index 8f903f4f..00000000 --- a/pyste/tests/inherit.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -namespace inherit { - -template -class A -{ -public: - void set(T v) { mData = v; } - - T get() const { return mData; } - -private: - T mData; -}; - - -class B : public A -{ -public: - int go() { return get(); } -}; - -struct C : B -{ - enum ab { a = 1, b = 2 }; - int f1() { return 1; } - int x; - static int s; -}; - -struct D : C -{ - int f2() { return 2; } - int y; -}; - -struct X {}; -struct E: X, D {}; -} diff --git a/pyste/tests/inherit.pyste b/pyste/tests/inherit.pyste deleted file mode 100644 index 0dc02998..00000000 --- a/pyste/tests/inherit.pyste +++ /dev/null @@ -1,8 +0,0 @@ -A = Template('inherit::A', 'inherit.h') -A_int = A('int', 'A_int') - -Class('inherit::B', 'inherit.h') -Class('inherit::D', 'inherit.h') -E = Class('inherit::E', 'inherit.h') -exclude(E.s) -exclude(E.ab) diff --git a/pyste/tests/inherit2.h b/pyste/tests/inherit2.h deleted file mode 100644 index af9387bd..00000000 --- a/pyste/tests/inherit2.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -namespace inherit2 { - -struct A -{ - int x; - int getx() { return x; } - int foo() { return 0; } - int foo(int x) { return x; } -}; - -struct B : A -{ - int y; - int gety() { return y; } - int foo() { return 1; } -}; - -struct C : B -{ - int z; - int getz() { return z; } -}; - -struct D : C -{ - int w; - int getw() { return w; } -}; - -} diff --git a/pyste/tests/inherit2.pyste b/pyste/tests/inherit2.pyste deleted file mode 100644 index 38082139..00000000 --- a/pyste/tests/inherit2.pyste +++ /dev/null @@ -1,2 +0,0 @@ -Class('inherit2::B', 'inherit2.h') -Class('inherit2::D', 'inherit2.h') diff --git a/pyste/tests/inherit2UT.py b/pyste/tests/inherit2UT.py deleted file mode 100644 index 85afce61..00000000 --- a/pyste/tests/inherit2UT.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _inherit2 import * - -class InheritExampleTest(unittest.TestCase): - - def testIt(self): - b = B() - d = D() - - self.assert_(issubclass(D, B)) - b.x, b.y = 10, 5 - self.assertEqual(b.getx(), 10) - self.assertEqual(b.gety(), 5) - d.x, d.y, d.z, d.w = 20, 15, 10, 5 - self.assertEqual(d.getx(), 20) - self.assertEqual(d.gety(), 15) - self.assertEqual(d.getz(), 10) - self.assertEqual(d.getw(), 5) - self.assertEqual(b.foo(), 1) - self.assertEqual(b.foo(3), 3) - - def wrong(): - return b.getw() - self.assertRaises(AttributeError, wrong) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/inherit3.h b/pyste/tests/inherit3.h deleted file mode 100644 index 1945fb51..00000000 --- a/pyste/tests/inherit3.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ - -namespace inherit3 { - -struct A -{ - A() { x = 0; } - struct X { int y; }; - int x; - virtual int foo() { return 0; } - virtual int foo(int x) { return x; } - A operator+(A o) const - { - A r; - r.x = o.x + x; - return r; - } - enum E { i, j }; - -}; - -struct B: A -{ - B() { x = 0; } - struct X { int y; }; - int x; - int foo() { return 1; } - A operator+(A o) const - { - A r; - r.x = o.x + x; - return r; - } - enum E { i, j }; - -}; - -struct C: A -{ -}; - -} diff --git a/pyste/tests/inherit3.pyste b/pyste/tests/inherit3.pyste deleted file mode 100644 index f95c0605..00000000 --- a/pyste/tests/inherit3.pyste +++ /dev/null @@ -1,2 +0,0 @@ -Class('inherit3::B', 'inherit3.h') -Class('inherit3::C', 'inherit3.h') diff --git a/pyste/tests/inherit3UT.py b/pyste/tests/inherit3UT.py deleted file mode 100644 index b7dba1e9..00000000 --- a/pyste/tests/inherit3UT.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _inherit3 import * - -class testInherit3(unittest.TestCase): - - def testIt(self): - def testInst(c): - self.assertEqual(c.x, 0) - self.assertEqual(c.foo(3), 3) - x = c.X() - self.assertEqual(x.y, 0) - self.assertEqual(c.E.i, 0) - self.assertEqual(c.E.j, 1) - b = B() - c = C() - testInst(b) - testInst(c) - self.assertEqual(b.foo(), 1) - self.assertEqual(c.foo(), 0) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/inherit4.h b/pyste/tests/inherit4.h deleted file mode 100644 index a1cecfbc..00000000 --- a/pyste/tests/inherit4.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -namespace inherit4 { - -struct A -{ - int x; -}; - -struct B: A -{ - int y; -}; - -struct C: B -{ - int z; -}; - -} diff --git a/pyste/tests/inherit4.pyste b/pyste/tests/inherit4.pyste deleted file mode 100644 index 4809e022..00000000 --- a/pyste/tests/inherit4.pyste +++ /dev/null @@ -1,3 +0,0 @@ -Class('inherit4::A', 'inherit4.h') -Class('inherit4::B', 'inherit4.h') -Class('inherit4::C', 'inherit4.h') diff --git a/pyste/tests/inherit4UT.py b/pyste/tests/inherit4UT.py deleted file mode 100644 index f2c75c55..00000000 --- a/pyste/tests/inherit4UT.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _inherit4 import * - -class TestInherit4(unittest.TestCase): - - def testIt(self): - self.assert_(issubclass(B, A)) - self.assert_(issubclass(C, A)) - self.assert_(issubclass(C, B)) - a = A() - a.x = 1 - b = B() - b.x = 10 - b.y = 20 - c = C() - c.x = 100 - c.y = 200 - c.z = 300 - self.assertEqual(a.x, 1) - self.assertEqual(b.x, 10) - self.assertEqual(b.y, 20) - self.assertEqual(c.x, 100) - self.assertEqual(c.y, 200) - self.assertEqual(c.z, 300) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/inheritUT.py b/pyste/tests/inheritUT.py deleted file mode 100644 index f3e7b406..00000000 --- a/pyste/tests/inheritUT.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _inherit import * - -class InheritExampleTest(unittest.TestCase): - - def testIt(self): - a = A_int() - b = B() - self.assert_(isinstance(b, A_int)) - self.assert_(issubclass(B, A_int)) - a.set(10) - self.assertEqual(a.get(), 10) - b.set(1) - self.assertEqual(b.go(), 1) - self.assertEqual(b.get(), 1) - - d = D() - self.assert_(issubclass(D, B)) - self.assertEqual(d.x, 0) - self.assertEqual(d.y, 0) - self.assertEqual(d.s, 1) - self.assertEqual(D.s, 1) - self.assertEqual(d.f1(), 1) - self.assertEqual(d.f2(), 2) - - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/nested.cpp b/pyste/tests/nested.cpp deleted file mode 100644 index 6e167ab0..00000000 --- a/pyste/tests/nested.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#include "nested.h" - -int nested::X::staticXValue = 10; -int nested::X::Y::staticYValue = 20; diff --git a/pyste/tests/nested.h b/pyste/tests/nested.h deleted file mode 100644 index 13ed6085..00000000 --- a/pyste/tests/nested.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef NESTED_H -#define NESTED_H - -namespace nested { - -struct X -{ - struct Y - { - int valueY; - static int staticYValue; - struct Z - { - int valueZ; - }; - }; - - static int staticXValue; - int valueX; -}; - -typedef X Root; - -} - -#endif diff --git a/pyste/tests/nested.pyste b/pyste/tests/nested.pyste deleted file mode 100644 index 48bb26b5..00000000 --- a/pyste/tests/nested.pyste +++ /dev/null @@ -1 +0,0 @@ -Class('nested::Root', 'nested.h') diff --git a/pyste/tests/nestedUT.py b/pyste/tests/nestedUT.py deleted file mode 100644 index 06c1c7be..00000000 --- a/pyste/tests/nestedUT.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _nested import * - -class NestedTest(unittest.TestCase): - - def testIt(self): - self.assertEqual(Root.staticXValue, 10) - self.assertEqual(Root.Y.staticYValue, 20) - z = Root.Y.Z() - z.valueZ = 3 - self.assertEqual(z.valueZ, 3) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/opaque.h b/pyste/tests/opaque.h deleted file mode 100644 index 1947830e..00000000 --- a/pyste/tests/opaque.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef OPAQUE_H -#define OPAQUE_H - -#include - -namespace opaque { - - -struct C { - C(int v): value(v) {} - int value; -}; - - -inline C* new_C() -{ - return new C(10); -} - -inline C* new_C_zero() -{ - return new C(0); -} - -inline int get(C* c) -{ - return c->value; -} - -struct D { - D(double v): value(v) {} - double value; -}; - -struct A -{ - D* new_handle() - { - return new D(3.0); - } - - double get(D* d) - { - return d->value; - } - - int f(int x=0) { return x; } -}; - -} - -#endif diff --git a/pyste/tests/opaque.pyste b/pyste/tests/opaque.pyste deleted file mode 100644 index 8180d251..00000000 --- a/pyste/tests/opaque.pyste +++ /dev/null @@ -1,7 +0,0 @@ -foo = Function('opaque::new_C', 'opaque.h') -set_policy(foo, return_value_policy(return_opaque_pointer)) -foo = Function('opaque::new_C_zero', 'opaque.h') -set_policy(foo, return_value_policy(return_opaque_pointer)) -Function('opaque::get', 'opaque.h' ) -A = Class('opaque::A', 'opaque.h') -set_policy(A.new_handle, return_value_policy(return_opaque_pointer)) diff --git a/pyste/tests/opaqueUT.py b/pyste/tests/opaqueUT.py deleted file mode 100644 index 0f3e1e07..00000000 --- a/pyste/tests/opaqueUT.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _opaque import * - -class OpaqueTest(unittest.TestCase): - - def testIt(self): - - c = new_C() - self.assertEqual(get(c), 10) - c = new_C_zero() - self.assertEqual(get(c), 0) - a = A() - d = a.new_handle() - self.assertEqual(a.get(d), 3.0) - self.assertEqual(a.f(), 0) - self.assertEqual(a.f(3), 3) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/operators.cpp b/pyste/tests/operators.cpp deleted file mode 100644 index cecdaca0..00000000 --- a/pyste/tests/operators.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#include "operators.h" - -double operators::C::x = 10; diff --git a/pyste/tests/operators.h b/pyste/tests/operators.h deleted file mode 100644 index 5d394421..00000000 --- a/pyste/tests/operators.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef OPERATORS_H -#define OPERATORS_H - - -namespace operators { - -struct C -{ - static double x; - double value; - - const C operator+(const C other) const - { - C c; - c.value = value + other.value; - return c; - } - operator int() const - { - return (int)value; - } - - double operator()() - { - return C::x; - } - - double operator()(double other) - { - return C::x + other; - } - - operator const char*() { return "C"; } -}; - -inline const C operator*(const C& lhs, const C& rhs) -{ - C c; - c.value = lhs.value * rhs.value; - return c; -} - - -} - - -#endif diff --git a/pyste/tests/operators.pyste b/pyste/tests/operators.pyste deleted file mode 100644 index 4ab7a370..00000000 --- a/pyste/tests/operators.pyste +++ /dev/null @@ -1,2 +0,0 @@ -C = Class('operators::C', 'operators.h') -#exclude(C.operator['+']) diff --git a/pyste/tests/operatorsUT.py b/pyste/tests/operatorsUT.py deleted file mode 100644 index beb19317..00000000 --- a/pyste/tests/operatorsUT.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _operators import * - -class OperatorTest(unittest.TestCase): - - def testIt(self): - c = C() - c.value = 3.0 - d = C() - d.value = 2.0 - self.assertEqual(c.x, 10) - self.assertEqual(C.x, 10) - self.assertEqual(C.x, 10) - self.assertEqual((c * d).value, 6.0) - self.assertEqual((c + d).value, 5.0) - self.assertEqual(int(c), 3) - self.assertEqual(int(d), 2) - self.assertEqual(c(), 10) - self.assertEqual(d(), 10) - self.assertEqual(c(3.0), 13.0) - self.assertEqual(d(6.0), 16.0) - self.assertEqual(str(c), "C") - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/policiesUT.py b/pyste/tests/policiesUT.py deleted file mode 100644 index 7255baeb..00000000 --- a/pyste/tests/policiesUT.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import sys -import unittest -from Pyste.policies import * - - -#================================================================================ -# PolicicesTest -#================================================================================ -class PoliciesTest(unittest.TestCase): - - def testReturnInternal(self): - 'tests the code from a simple internal_reference' - - x = return_internal_reference(1) - self.assertEqual(x.Code(), 'return_internal_reference< 1 >') - x = return_internal_reference(3) - self.assertEqual(x.Code(), 'return_internal_reference< 3 >') - - - def testCustodian(self): - 'tests the code from a simple custodian_and_ward' - - x = with_custodian_and_ward(1,2) - self.assertEqual(x.Code(), 'with_custodian_and_ward< 1, 2 >') - x = with_custodian_and_ward(3,4) - self.assertEqual(x.Code(), 'with_custodian_and_ward< 3, 4 >') - - - def testReturnPolicies(self): - 'tests all the return_value_policies' - - ret = 'return_value_policy< %s >' - x = return_value_policy(reference_existing_object) - self.assertEqual(x.Code(), ret % 'reference_existing_object') - x = return_value_policy(copy_const_reference) - self.assertEqual(x.Code(), ret % 'copy_const_reference') - x = return_value_policy(copy_non_const_reference) - self.assertEqual(x.Code(), ret % 'copy_non_const_reference') - x = return_value_policy(manage_new_object) - self.assertEqual(x.Code(), ret % 'manage_new_object') - x = return_value_policy(return_opaque_pointer) - self.assertEqual(x.Code(), ret % 'return_opaque_pointer') - - def testReturnWithCustodiam(self): - 'test the mix of return_internal with custodian' - - x = return_internal_reference(1, with_custodian_and_ward(3,2)) - self.assertEqual( - x.Code(), - 'return_internal_reference< 1, with_custodian_and_ward< 3, 2 > >') - - - def testReturnPoliciesWithInternal(self): - 'test the mix of return_internal with return_policy' - - x = return_internal_reference(1, return_value_policy(manage_new_object)) - self.assertEqual( - x.Code(), - 'return_internal_reference< 1, return_value_policy< manage_new_object > >') - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/runtests.py b/pyste/tests/runtests.py deleted file mode 100644 index 4bf83b34..00000000 --- a/pyste/tests/runtests.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -#!/usr/bin/python - -import sys -sys.path.append('../src/Pyste') -import unittest -import os.path -from glob import glob - -if __name__ == '__main__': - loader = unittest.defaultTestLoader - tests = [] - for name in glob('*UT.py'): - module = __import__(os.path.splitext(name)[0]) - tests.append(loader.loadTestsFromModule(module)) - runner = unittest.TextTestRunner() - result = runner.run(unittest.TestSuite(tests)) - sys.exit(not result.wasSuccessful()) diff --git a/pyste/tests/smart_ptr.h b/pyste/tests/smart_ptr.h deleted file mode 100644 index b230b917..00000000 --- a/pyste/tests/smart_ptr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef SMART_PTR_H -#define SMART_PTR_H - - -#include -#include - -namespace smart_ptr { - -struct C -{ - int value; -}; - -inline boost::shared_ptr NewC() { return boost::shared_ptr( new C() ); } - -struct D -{ - boost::shared_ptr Get() { return ptr; } - void Set( boost::shared_ptr c ) { ptr = c; } -private: - boost::shared_ptr ptr; -}; - -inline std::auto_ptr NewD() { return std::auto_ptr( new D() ); } - - -// test an abstract class -struct A -{ - virtual int f() = 0; -}; - -struct B: A -{ - virtual int f(){ return 1; } -}; - -inline boost::shared_ptr NewA() { return boost::shared_ptr(new B()); } -inline int GetA(boost::shared_ptr a) { return a->f(); } - -} - -#endif diff --git a/pyste/tests/smart_ptr.pyste b/pyste/tests/smart_ptr.pyste deleted file mode 100644 index cfbdd81a..00000000 --- a/pyste/tests/smart_ptr.pyste +++ /dev/null @@ -1,13 +0,0 @@ -C = Class('smart_ptr::C', 'smart_ptr.h') -use_shared_ptr(C) - -D = Class('smart_ptr::D', 'smart_ptr.h') -use_auto_ptr(D) - -A = Class('smart_ptr::A', 'smart_ptr.h') -use_shared_ptr(A) - -Function('smart_ptr::NewC', 'smart_ptr.h') -Function('smart_ptr::NewD', 'smart_ptr.h') -Function('smart_ptr::NewA', 'smart_ptr.h') -Function('smart_ptr::GetA', 'smart_ptr.h') diff --git a/pyste/tests/smart_ptrUT.py b/pyste/tests/smart_ptrUT.py deleted file mode 100644 index 9d81f08d..00000000 --- a/pyste/tests/smart_ptrUT.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _smart_ptr import * - -class BasicExampleTest(unittest.TestCase): - - def testIt(self): - c = NewC() - d = NewD() - c.value = 3 - d.Set(c) - c1 = d.Get() - c1.value = 6 - self.assertEqual(c.value, 6) - a = NewA() - self.assertEqual(GetA(a), 1) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/templates.h b/pyste/tests/templates.h deleted file mode 100644 index 7258e91c..00000000 --- a/pyste/tests/templates.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -namespace templates { - -template -struct Point -{ - T x; - T y; -}; - -} diff --git a/pyste/tests/templates.pyste b/pyste/tests/templates.pyste deleted file mode 100644 index 77eaceaa..00000000 --- a/pyste/tests/templates.pyste +++ /dev/null @@ -1,8 +0,0 @@ -Point = Template('templates::Point', 'templates.h') -rename(Point.x, 'i') -rename(Point.y, 'j') -IPoint = Point('int') -FPoint = Point('double', 'FPoint') -rename(IPoint, 'IPoint') -rename(IPoint.x, 'x') -rename(IPoint.y, 'y') diff --git a/pyste/tests/templatesUT.py b/pyste/tests/templatesUT.py deleted file mode 100644 index 0c4b08b5..00000000 --- a/pyste/tests/templatesUT.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _templates import * - -class TemplatesTest(unittest.TestCase): - - def testIt(self): - fp = FPoint() - fp.i = 3.0 - fp.j = 4.0 - ip = IPoint() - ip.x = 10 - ip.y = 3 - - self.assertEqual(fp.i, 3.0) - self.assertEqual(fp.j, 4.0) - self.assertEqual(ip.x, 10) - self.assertEqual(ip.y, 3) - self.assertEqual(type(fp.i), float) - self.assertEqual(type(fp.j), float) - self.assertEqual(type(ip.x), int) - self.assertEqual(type(ip.y), int) - - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/test_all.py b/pyste/tests/test_all.py deleted file mode 100644 index ba3c54de..00000000 --- a/pyste/tests/test_all.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/python -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import os -import glob -import shutil -import sys -import time - -#============================================================================= -# win32 configuration -#============================================================================= -if sys.platform == 'win32': - - includes = '-ID:/programming/libraries/boost-cvs/boost -ID:/Bin/Python/include' - build_pyste_cmd = 'python ../src/Pyste/pyste.py --pyste-ns=pyste --cache-dir=cache %s ' % includes - compile_single_cmd = 'cl /nologo /GR /GX -c %s -I. ' % includes - link_single_cmd = 'link /nologo /DLL '\ - '/libpath:D:/programming/libraries/boost-cvs/lib /libpath:D:/Bin/Python/libs '\ - 'boost_python.lib python24.lib /out:_%s.dll ' - obj_ext = 'obj' - -#============================================================================= -# linux configuration -#============================================================================= -elif sys.platform == 'linux2': - - build_pyste_cmd = 'python ../src/Pyste/pyste.py -I. ' - compile_single_cmd = 'g++ -shared -c -I. -I/usr/include/python2.4 ' - link_single_cmd = 'g++ -shared -o _%s.so -lboost_python ' - obj_ext = 'o' - - - -def build_pyste(multiple, module): - rest = '%s --module=_%s %s.pyste' % (multiple, module, module) - execute(build_pyste_cmd + rest) - - -def compile_single(module): - module_obj = '' - if os.path.isfile(module+'.cpp'): - execute(compile_single_cmd + module+'.cpp') - module_obj = module + '.' + obj_ext - execute(compile_single_cmd + ('_%s.cpp' % module)) - link = link_single_cmd % module - execute(link + ('_%s.%s ' % (module, obj_ext)) + module_obj) - - -def compile_multiple(module): - module_obj = '' - if os.path.isfile(module+'.cpp'): - execute(compile_single_cmd + module+'.cpp') - module_obj = module + '.' + obj_ext - files = glob.glob('_%s/*.cpp' % module) - for f in files: - execute(compile_single_cmd + f) - def basename(name): - return os.path.basename(os.path.splitext(name)[0]) - objs = [basename(x) + '.' + obj_ext for x in files] - objs.append(module_obj) - execute((link_single_cmd % module) + ' '.join(objs)) - - -def execute(cmd): - os.system(cmd) - - -def run_tests(): - if os.system('python runtests.py') != 0: - raise RuntimeError, 'tests failed' - - -def cleanup(): - modules = get_modules() - extensions = '*.dll *.pyc *.obj *.exp *.lib *.o *.so' - files = [] - for module in modules: - files.append('_' + module + '.cpp') - for ext in extensions.split(): - files += glob.glob(ext) - files.append('build.log') - for file in files: - try: - os.remove(file) - except OSError: pass - - for module in modules: - try: - shutil.rmtree('_' + module) - except OSError: pass - - -def main(multiple, module=None): - if module is None: - modules = get_modules() - else: - modules = [module] - - start = time.clock() - for module in modules: - build_pyste(multiple, module) - print '-'*50 - print 'Building pyste files: %0.2f seconds' % (time.clock()-start) - print - - start = time.clock() - for module in modules: - if multiple: - compile_multiple(module) - else: - compile_single(module) - print '-'*50 - print 'Compiling files: %0.2f seconds' % (time.clock()-start) - print - if len(modules) == 1: - os.system('python %sUT.py' % modules[0]) - else: - run_tests() - #cleanup() - - -def get_modules(): - def getname(file): - return os.path.splitext(os.path.basename(file))[0] - return [getname(x) for x in glob.glob('*.pyste')] - -if __name__ == '__main__': - if len(sys.argv) > 1: - module = sys.argv[1] - else: - module = None - try: -# main('--multiple', module) - main('', module) - except RuntimeError, e: - print e diff --git a/pyste/tests/vars.cpp b/pyste/tests/vars.cpp deleted file mode 100644 index e2abcd33..00000000 --- a/pyste/tests/vars.cpp +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#include "vars.h" - -const Color black = Color(0, 0, 0); -const Color red = Color(255, 0, 0); -const Color green = Color(0, 255, 0); -const Color blue = Color(0, 0, 255); -Color in_use = black; diff --git a/pyste/tests/vars.h b/pyste/tests/vars.h deleted file mode 100644 index 24e87d80..00000000 --- a/pyste/tests/vars.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ - -struct Color -{ - Color(int r_ = 0, int g_ = 0, int b_ = 0): - r(r_), g(g_), b(b_) - {} - Color( const Color &c): - r(c.r), g(c.g), b(c.b) - {} - int r; - int g; - int b; -}; - -extern const Color black; -extern const Color red; -extern const Color green; -extern const Color blue; -extern Color in_use; diff --git a/pyste/tests/vars.pyste b/pyste/tests/vars.pyste deleted file mode 100644 index 3fd9d689..00000000 --- a/pyste/tests/vars.pyste +++ /dev/null @@ -1 +0,0 @@ -AllFromHeader('vars.h') diff --git a/pyste/tests/varsUT.py b/pyste/tests/varsUT.py deleted file mode 100644 index 4c32cbb2..00000000 --- a/pyste/tests/varsUT.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -import _vars - - -class VarsTest(unittest.TestCase): - - def testIt(self): - def testColor(c, r, g, b): - self.assertEqual(c.r, r) - self.assertEqual(c.g, g) - self.assertEqual(c.b, b) - testColor(_vars.black, 0, 0, 0) - testColor(_vars.red, 255, 0, 0) - testColor(_vars.green, 0, 255, 0) - testColor(_vars.blue, 0, 0, 255) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/virtual.cpp b/pyste/tests/virtual.cpp deleted file mode 100644 index 070d9d34..00000000 --- a/pyste/tests/virtual.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ - -// Includes ==================================================================== -#include -#include - -// Using ======================================================================= -using namespace boost::python; - -// Declarations ================================================================ - - -namespace { - - -struct virtual_C_Wrapper: virtual_::C -{ - virtual_C_Wrapper(PyObject* self_, const virtual_::C & p0): - virtual_::C(p0), self(self_) {} - - virtual_C_Wrapper(PyObject* self_): - virtual_::C(), self(self_) {} - - int f() { - return call_method< int >(self, "f"); - } - - int default_f() { - return virtual_::C::f(); - } - - void bar(int p0) { - call_method< void >(self, "bar", p0); - } - - void default_bar(int p0) { - virtual_::C::bar(p0); - } - - void bar(char * p0) { - call_method< void >(self, "bar", p0); - } - - void default_bar(char * p0) { - virtual_::C::bar(p0); - } - - int f_abs() { - return call_method< int >(self, "f_abs"); - } - - PyObject* self; -}; - - - -}// namespace - - -// Module ====================================================================== -BOOST_PYTHON_MODULE(virtual) -{ - class_< virtual_::C, boost::noncopyable, virtual_C_Wrapper >("C", init< >()) - .def("get_name", &virtual_::C::get_name) - .def("f", &virtual_::C::f, &virtual_C_Wrapper::default_f) - .def("bar", (void (virtual_::C::*)(int) )&virtual_::C::bar, (void (virtual_C_Wrapper::*)(int))&virtual_C_Wrapper::default_bar) - .def("bar", (void (virtual_::C::*)(char *) )&virtual_::C::bar, (void (virtual_C_Wrapper::*)(char *))&virtual_C_Wrapper::default_bar) - ; - - def("call_f", &virtual_::call_f); -} diff --git a/pyste/tests/virtual.h b/pyste/tests/virtual.h deleted file mode 100644 index d0bb194a..00000000 --- a/pyste/tests/virtual.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -namespace virtual_ { - -struct C -{ -public: - virtual int f() - { - return f_abs(); - } - - virtual void bar(int) {} - virtual void bar(char*) {} - - const char* get_name() - { - return name(); - } - virtual int dummy() { return 0; } - -protected: - virtual int f_abs() = 0; - -private: - virtual const char* name() { return "C"; } -}; - -struct D -{ - virtual int dummy() { return 0; } -}; - -inline int call_f(C& c) { return c.f(); } -inline int call_dummy(C* c) { return c->dummy(); } -inline int call_dummy(D* d) { return d->dummy(); } - -} diff --git a/pyste/tests/virtual.pyste b/pyste/tests/virtual.pyste deleted file mode 100644 index ef966412..00000000 --- a/pyste/tests/virtual.pyste +++ /dev/null @@ -1,6 +0,0 @@ -C = Class('virtual_::C', 'virtual.h') -final(C.dummy) -D = Class('virtual_::D', 'virtual.h') -final(D.dummy) -Function('virtual_::call_f', 'virtual.h') -Function('virtual_::call_dummy', 'virtual.h') diff --git a/pyste/tests/virtual2.h b/pyste/tests/virtual2.h deleted file mode 100644 index a6677ad1..00000000 --- a/pyste/tests/virtual2.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ - -namespace virtual2 { - -struct A -{ - virtual int f() { return 0; } - virtual int f1() { return 10; } - virtual A* make_new() { return new A; } -}; - -struct B: A -{ - virtual int f() { return 1; } - virtual int f2() { return 20; } - virtual A* make_new() { return new B; } -}; - -inline int call_fs(A*a) -{ - int r = a->f1(); - B* b = dynamic_cast(a); - return r + b->f2(); -} - -inline int call_f(A* a) -{ - return a->f(); -} -} diff --git a/pyste/tests/virtual2.pyste b/pyste/tests/virtual2.pyste deleted file mode 100644 index 785b819c..00000000 --- a/pyste/tests/virtual2.pyste +++ /dev/null @@ -1,6 +0,0 @@ -A = Class('virtual2::A', 'virtual2.h') -set_policy(A.make_new, return_value_policy(manage_new_object)) -B = Class('virtual2::B', 'virtual2.h') -set_policy(B.make_new, return_value_policy(manage_new_object)) -Function('virtual2::call_fs', 'virtual2.h') -Function('virtual2::call_f', 'virtual2.h') diff --git a/pyste/tests/virtual2UT.py b/pyste/tests/virtual2UT.py deleted file mode 100644 index 312277d2..00000000 --- a/pyste/tests/virtual2UT.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import unittest -from _virtual2 import * - -class Virtual2Test(unittest.TestCase): - - def testIt(self): - a = A() - self.assertEqual(a.f1(), 10) - b = B() - self.assertEqual(b.f1(), 10) - self.assertEqual(b.f2(), 20) - self.assertEqual(call_fs(b), 30) - self.assertEqual(call_f(a), 0) - self.assertEqual(call_f(b), 1) - nb = b.make_new() - na = a.make_new() - self.assertEqual(na.f1(), 10) - self.assertEqual(nb.f1(), 10) - self.assertEqual(nb.f2(), 20) - self.assertEqual(call_fs(nb), 30) - self.assertEqual(call_f(na), 0) - self.assertEqual(call_f(nb), 1) - class C(B): - def f1(self): return 1 - def f2(self): return 2 - def f(self): return 100 - - c = C() - self.assertEqual(call_fs(c), 3) - self.assertEqual(call_fs(c), 3) - self.assertEqual(call_f(c), 100) - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/virtualUT.py b/pyste/tests/virtualUT.py deleted file mode 100644 index deff6818..00000000 --- a/pyste/tests/virtualUT.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _virtual import * - -class VirtualTest(unittest.TestCase): - - def testIt(self): - - class E(C): - def f_abs(self): - return 3 - def dummy(self): - # override should not work - return 100 - - class F(C): - def f(self): - return 10 - def name(self): - return 'F' - - class G(D): - def dummy(self): - # override should not work - return 100 - - e = E() - f = F() - - self.assertEqual(e.f(), 3) - self.assertEqual(call_f(e), 3) - self.assertEqual(f.f(), 10) - self.assertEqual(call_f(f), 10) - self.assertEqual(e.get_name(), 'C') - #self.assertEqual(e.get_name(), 'E') check this later - - c = C() - c.bar(1) # ok - c.bar('a') # ok - self.assertRaises(TypeError, c.bar, 1.0) - - # test no_overrides - d = G() - self.assertEqual(e.dummy(), 100) - self.assertEqual(call_dummy(e), 0) - self.assertEqual(d.dummy(), 100) - self.assertEqual(call_dummy(d), 0) - - - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/wrappertest.h b/pyste/tests/wrappertest.h deleted file mode 100644 index 2304fd84..00000000 --- a/pyste/tests/wrappertest.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef WRAPPER_TEST -#define WRAPPER_TEST - - -#include - -namespace wrappertest { - -inline std::vector Range(int count) -{ - std::vector v; - v.reserve(count); - for (int i = 0; i < count; ++i){ - v.push_back(i); - } - return v; -} - - -struct C -{ - C() {} - - std::vector Mul(int value) - { - std::vector res; - res.reserve(value); - std::vector::const_iterator it; - std::vector v(Range(value)); - for (it = v.begin(); it != v.end(); ++it){ - res.push_back(*it * value); - } - return res; - } -}; - - -struct A -{ - virtual int f() { return 1; }; -}; - -inline int call_foo(A* a){ return a->f(); } -} -#endif - diff --git a/pyste/tests/wrappertest.pyste b/pyste/tests/wrappertest.pyste deleted file mode 100644 index 12ba47b6..00000000 --- a/pyste/tests/wrappertest.pyste +++ /dev/null @@ -1,21 +0,0 @@ -Include('wrappertest_wrappers.h') - -f = Function('wrappertest::Range', 'wrappertest.h') -set_wrapper(f, 'RangeWrapper') - -mul = Wrapper('MulWrapper', -''' -list MulWrapper(wrappertest::C& c, int value){ - return VectorToList(c.Mul(value)); -} -''' -) - -C = Class('wrappertest::C', 'wrappertest.h') -set_wrapper(C.Mul, mul) - - -A = Class('wrappertest::A', 'wrappertest.h') -set_wrapper(A.f, 'f_wrapper') - -Function('wrappertest::call_foo', 'wrappertest.h') diff --git a/pyste/tests/wrappertestUT.py b/pyste/tests/wrappertestUT.py deleted file mode 100644 index d770408b..00000000 --- a/pyste/tests/wrappertestUT.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright Bruno da Silva de Oliveira 2003. Use, modification and -# distribution is subject to the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -import unittest -from _wrappertest import * - -class WrapperTest(unittest.TestCase): - - def testIt(self): - self.assertEqual(Range(10), range(10)) - self.assertEqual(C().Mul(10), [x*10 for x in range(10)]) - - a = A() - self.assertEqual(a.f(), 10) - self.assertEqual(call_foo(a), 10) - class D(A): - def f(self): return 2 - d = D() - self.assertEqual(d.f(), 2) - self.assertEqual(call_foo(d), 2) - -if __name__ == '__main__': - unittest.main() diff --git a/pyste/tests/wrappertest_wrappers.h b/pyste/tests/wrappertest_wrappers.h deleted file mode 100644 index 31570a05..00000000 --- a/pyste/tests/wrappertest_wrappers.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright Bruno da Silva de Oliveira 2003. Use, modification and - distribution is subject to the Boost Software License, Version 1.0. - (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef WRAPPER_TEST_WRAPPERS -#define WRAPPER_TEST_WRAPPERS - -#include -#include -#include "wrappertest.h" - -using namespace boost::python; - -template -list VectorToList(const std::vector & v) -{ - list res; - typename std::vector::const_iterator it; - for(it = v.begin(); it != v.end(); ++it){ - res.append(*it); - } - Py_XINCREF(res.ptr()); - return res; -} - -inline list RangeWrapper(int count){ - return VectorToList(wrappertest::Range(count)); -} - -inline int f_wrapper(wrappertest::A*) { return 10; } - -#endif diff --git a/release_notes.txt b/release_notes.txt deleted file mode 100644 index 1fd0f1b1..00000000 --- a/release_notes.txt +++ /dev/null @@ -1,223 +0,0 @@ -.. Copyright David Abrahams 2006. Distributed under the Boost -.. Software License, Version 1.0. (See accompanying -.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -These are old release notes for Boost.Python v1 - -2000-11-22 10:00 - Ullrich fixed bug in operator_dispatcher. - -2000-11-21 10:00 - Changed all class and function names into lower_case. - - Ullrich updated documentation for operator wrapping. - -2000-11-20 10:00 - Ullrich renamed ExtensionClass:register_coerce() into - ExtensionClass:def_standard_coerce() and made it public - - Ullrich improved shared_pod_manager. - -2000-11-17 15:04 - Changed allocation strategy of shared_pod_manager to make it portable. - - Added pickling support + tests thanks to "Ralf W. Grosse-Kunstleve" - - - Added a specialization of Callback to prevent unsafe usage. - - Fixed Ullrich's operator_dispatcher refcount bug - - Removed const char* return values from virtual functions in tests; that - usage was unsafe. - - Ullrich changed Module::add() so that it steals a reference (fix of refcount bug) - - Ullrich added operator_dispatcher::create() optimization - - Ullrich changed design and implementation of TypeObjectBase::enable() (to eliminate low-level - code) and added shared_pod_manager optimization. - - -2000-11-15 12:01 - Fixed refcount bugs in operator calls. - - Added callback_adjust_refcount(PyObject*, Type) to account for different ownership - semantics of Callback's return types and Caller's arguments (which both use from_python()) - This bug caused refcount errors during operator calls. - - Moved operator_dispatcher into extclass.cpp - Gave it shared ownership of the objects it wraps - - Introduced sequence points in extension_class_coerce for exception-safety - - UPPER_CASE_MACRO_NAMES - - MixedCase template type argument names - - Changed internal error reporting to use Python exceptions so we don't force the - user to link in iostreams code - - Changed error return value of call_cmp to -1 - - Moved unwrap_* functions out of operator_dispatcher. This was transitional: when - I realized they didn't need to be declared in extclass.h I moved them out, but - now that operator_dispatcher itself is in extclass.cpp they could go back in. - - Numerous formatting tweaks - - Updated the BoundFunction::create() optimization and enabled it so it could actually be used! - -2000-11-15 00:26 - - Made Ullrich's operators support work with MSVC - - Cleaned up operators.h such that invalid define_operator<0> is no longer needed. - - Ullrich created operators.h to support wrapping of C++ operators (including the "__r*__" forms). - He added several auxiliary classes to extclass.h and extclass.cpp (most importantly, - py::detail::operator_dispatcher and py::operators) - -2000-11-13 22:29 - - removed obsolete ExtensionClassFromPython for good. - - removed unused class ExtensionType forward declaration - -2000-11-12 13:08 - - Added enum_as_int_converters for easier enum wrapping - - Introduced new conversion namespace macros: - PY_BEGIN_CONVERSION_NAMESPACE, - PY_END_CONVERSION_NAMESPACE, - PY_CONVERSION - - callback.h, gen_callback.py: - Added call() function so that a regular python function (as opposed to - method or other function-as-attribute) can be called. - - Added newlines for readability. - - class_wrapper.h: - Fixed a bug in add(), which allows non-method class attributes - - Ullrich has added def_raw for simple varargs and keyword support. - - Fixed version number check for __MWERKS__ - - Added tests for enums and non-method class attributes - - objects.h/objects.cpp: - Added py::String operator*= and operator* for repetition - - Change Dict::items(), keys(), and values() to return a List - - Added template versions of set_item, etc., methods so that users can optionally - use C++ types that have to_python() functions as parameters. - - Changed various Ptr by-value parameters to const Ptr& - - -======= Release ======= -2000-11-06 0:22 - Lots of documentation updates - - added 4-argument template constructor to py::Tuple - - added "add" member function to ClassWrapper<> to allow arbitrary Python - objects to be added to an extension class. - - gen_all.py now generates support for n argument member functions and n+1 - argument member functions at the suggestion of "Ralf W. Grosse-Kunstleve" - - - Added regression tests and re-ordered declare_base calls to verify that the - phantom base class issue is resolved. - -2000-11-04 17:35 - - Integrated Ullrich Koethe's brilliant from_python_experiment for better - error-reporting in many cases. - - extclass.h, gen_extclass.py: - removed special-case MSVC code - added much commentary - removed unused py_copy_to_new_value_holder - - init_function.h, gen_init_function.py: - added missing 'template' keyword on type-dependent template member usage - removed special-case MSVC code - added much commentary - -2000-11-04 0:36 - - Removed the need for the phantom base class that screwed up inheritance - hierarchies, introduced error-prone ordering dependencies, and complexified - logic in many places! - - extclass.h: Added some explanatory comments, removed wasteful m_self member - of HeldInstance - - extclass_demo.cpp: Added #pragmas which allow compilation in ansi strict - mode under Metrowerks - - functions.h: Added virtual_function as part of phantom base class removal; - expanded commentary - - pyptr.h: Added some missing 'typename's and a GCC workaround fix - - subclass.cpp: Added missing string literal const_cast<>s. - -2000-11-03 10:58 - - Fix friend function instantiation bug caught by Metrowerks (thanks - Metrowerks!) - - Add proof-of-concept for one technique of wrapping function that return a - pointer - - Worked around MSVC optimizer bug by writing to_python(double) and - to_python(float) out-of-line - -2000-11-02 23:25 - - Add /Zm200 option to vc6_prj to deal with MSVC resource limitations - - Remove conflicting /Ot option from vc6_prj release build - -======= Release ======= -2000-11-02 17:42 - - Added a fix for interactions between default virtual function - implementations and declare_base(). You still need to write your - declare_base() /after/ all member functions have been def()d for the two - classes concerned. Many, many thanks to Ullrich Koethe - for all his work on this. - - Added missing conversions: - to_python(float) - from_python(const char* const&) - from_python(const double&) - from_python(const float&) - - Added a Regression test for a reference-counting bug thanks to Mark Evans - () - - const-ify ClassBase::getattr() - - Add repr() function to Class - - Add to_python/from_python conversions for PyPtr - - Standardize set_item/get_item interfaces (instead of proxies) for Dict and List - - Add Reprable<> template to newtypes.h - - Fix a bug wherein the __module__ attribute would be lost for classes that have a - default virtual function implementation. - - Remove extra ';' in module.cpp thanks to "Ralf W. Grosse-Kunstleve" - - - Fix a bug in the code of example1.html diff --git a/todo.html b/todo.html deleted file mode 100755 index c2c4bdf7..00000000 --- a/todo.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - -Boost.Python TODO list Boost - - - - - - -