diff --git a/pyste/NEWS b/pyste/NEWS index dd8573fa..1b8f768a 100644 --- a/pyste/NEWS +++ b/pyste/NEWS @@ -1,3 +1,16 @@ +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! + +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. diff --git a/pyste/TODO b/pyste/TODO index f9a54bbe..fa2207f2 100644 --- a/pyste/TODO +++ b/pyste/TODO @@ -9,5 +9,6 @@ - Virtual operators - - staticmethod bug + +- opaque pointers bug diff --git a/pyste/doc/pyste.txt b/pyste/doc/pyste.txt index 105aedaf..9b0ee96f 100644 --- a/pyste/doc/pyste.txt +++ b/pyste/doc/pyste.txt @@ -81,8 +81,8 @@ Usage: where options are: -I add an include path -D define symbol - --multiple create various cpps, instead of only one - (useful during development) + --multiple create various cpps (one for each pyste file), 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"; @@ -480,6 +480,16 @@ 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] diff --git a/pyste/doc/running_pyste.html b/pyste/doc/running_pyste.html index db02af8a..6acfbcd0 100644 --- a/pyste/doc/running_pyste.html +++ b/pyste/doc/running_pyste.html @@ -55,8 +55,8 @@ Usage: where options are: -I <path> add an include path -D <symbol> define symbol - --multiple create various cpps, instead of only one - (useful during development) + --multiple create various cpps (one for each pyste file), instead + of only one (useful during development) --out specify output filename (default: <module>.cpp) in --multiple mode, this will be a directory --no-using do not declare "using namespace boost"; diff --git a/pyste/doc/smart_pointers.html b/pyste/doc/smart_pointers.html index 7563d864..2b77a429 100644 --- a/pyste/doc/smart_pointers.html +++ b/pyste/doc/smart_pointers.html @@ -58,6 +58,16 @@ 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/install/setup.py b/pyste/install/setup.py index 8d4e86aa..fff6db87 100644 --- a/pyste/install/setup.py +++ b/pyste/install/setup.py @@ -4,7 +4,7 @@ from distutils.core import setup import sys setup (name = "Pyste", - version = "0.9.8", + version = "0.9.9", description = "Pyste - Python Semi-Automatic Exporter", maintainer = "Bruno da Silva de Oliveira", maintainer_email = "nicodemus@globalite.com.br", diff --git a/pyste/src/Pyste/ClassExporter.py b/pyste/src/Pyste/ClassExporter.py index e507584e..05b1e3b9 100644 --- a/pyste/src/Pyste/ClassExporter.py +++ b/pyste/src/Pyste/ClassExporter.py @@ -42,7 +42,6 @@ class ClassExporter(Exporter): self.wrapper_generator = None # a list of code units, generated by nested declarations self.nested_codeunits = [] - self._exported_opaque_pointers = {} def ScopeName(self): @@ -195,8 +194,14 @@ class ClassExporter(Exporter): def ExportBasics(self): - 'Export the name of the class and its class_ statement' - self.Add('template', self.class_.FullName()) + '''Export the name of the class and its class_ statement. + Also export the held_type if specified.''' + class_name = self.class_.FullName() + self.Add('template', class_name) + held_type = self.info.held_type + if held_type: + held_type = held_type % class_name + self.Add('template', held_type) name = self.info.rename or self.class_.name self.Add('constructor', '"%s"' % name) @@ -605,10 +610,9 @@ class ClassExporter(Exporter): for method in methods: return_opaque_policy = return_value_policy(return_opaque_pointer) if self.info[method.name].policy == return_opaque_policy: - macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % method.result.name - if macro not in self._exported_opaque_pointers: + macro = exporterutils.EspecializeTypeID(method.result.name) + if macro: self.Add('declaration-outside', macro) - self._exported_opaque_pointers[macro] = 1 #============================================================================== diff --git a/pyste/src/Pyste/FunctionExporter.py b/pyste/src/Pyste/FunctionExporter.py index 18380dfe..25c004e3 100644 --- a/pyste/src/Pyste/FunctionExporter.py +++ b/pyste/src/Pyste/FunctionExporter.py @@ -14,7 +14,6 @@ class FunctionExporter(Exporter): def __init__(self, info, tail=None): Exporter.__init__(self, info, tail) - self._exported_opaque_pointers = {} def Export(self, codeunit, exported_names): @@ -77,12 +76,10 @@ class FunctionExporter(Exporter): def ExportOpaquePointer(self, function, codeunit): if self.info.policy == return_value_policy(return_opaque_pointer): - type = function.result.name - macro = 'BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(%s)' % type - if macro not in self._exported_opaque_pointers: + typename = function.result.name + macro = exporterutils.EspecializeTypeID(typename) + if macro: codeunit.Write('declaration-outside', macro) - self._exported_opaque_pointers[macro] = 1 - def Order(self): return self.info.name diff --git a/pyste/src/Pyste/HeaderExporter.py b/pyste/src/Pyste/HeaderExporter.py index 89fe1ed3..3ba1ecd8 100644 --- a/pyste/src/Pyste/HeaderExporter.py +++ b/pyste/src/Pyste/HeaderExporter.py @@ -7,6 +7,7 @@ from infos import * from declarations import * import os.path import exporters +import MultipleCodeUnit #============================================================================== # HeaderExporter @@ -64,7 +65,10 @@ class HeaderExporter(Exporter): exporter = exporter_type(info) exporter.SetDeclarations(self.declarations) exporter.SetParsedHeader(self.parser_header) - codeunit.SetCurrent(self.interface_file, exporter.Unit()) + if isinstance(codeunit, MultipleCodeUnit.MultipleCodeUnit): + codeunit.SetCurrent(self.interface_file, exporter.Unit()) + else: + codeunit.SetCurrent(exporter.Unit()) exporter.GenerateCode(codeunit, exported_names) diff --git a/pyste/src/Pyste/MultipleCodeUnit.py b/pyste/src/Pyste/MultipleCodeUnit.py index 57e25f14..5e8d9429 100644 --- a/pyste/src/Pyste/MultipleCodeUnit.py +++ b/pyste/src/Pyste/MultipleCodeUnit.py @@ -79,24 +79,27 @@ class MultipleCodeUnit(object): self._CreateOutputDir(); # order all code units by filename, and merge them all codeunits = {} # filename => list of codeunits - # the main_unit holds all the include, declaration and declaration-outside sections - # to keep them all in the top of the source file - main_unit = None + + # 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: + if filename not in codeunits: + # this codeunit is the main codeunit. codeunits[filename] = [codeunit] - main_unit = codeunit - main_unit.Merge(self.all) + 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) - # write all the codeunits, merging first the contents of - # the special code unit named __all__ - for codeunits in codeunits.values(): + + # Now write all the codeunits appending them correctly. + for file_units in codeunits.values(): append = False - for codeunit in codeunits: + for codeunit in file_units: codeunit.Save(append) if not append: append = True diff --git a/pyste/src/Pyste/exporterutils.py b/pyste/src/Pyste/exporterutils.py index c71a1476..99aedd58 100644 --- a/pyste/src/Pyste/exporterutils.py +++ b/pyste/src/Pyste/exporterutils.py @@ -68,5 +68,15 @@ def HandlePolicy(function, policy): 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 index a7d644a6..43b0581a 100644 --- a/pyste/src/Pyste/infos.py +++ b/pyste/src/Pyste/infos.py @@ -215,6 +215,12 @@ def use_shared_ptr(info): def use_auto_ptr(info): info._Attribute('smart_ptr', 'std::auto_ptr< %s >') +def hold_with_shared_ptr(info): + info._Attribute('held_type', 'boost::shared_ptr< %s >') + +def hold_with_auto_ptr(info): + info._Attribute('held_type', 'std::auto_ptr< %s >') + def add_method(info, name, rename=None): added = info._Attribute('__added__') if added is None: diff --git a/pyste/src/Pyste/pyste.py b/pyste/src/Pyste/pyste.py index 4e940483..a16a8e37 100644 --- a/pyste/src/Pyste/pyste.py +++ b/pyste/src/Pyste/pyste.py @@ -39,7 +39,7 @@ from policies import * from CppParser import CppParser, CppParserError import time -__VERSION__ = '0.9.8' +__VERSION__ = '0.9.9' def RecursiveIncludes(include): 'Return a list containg the include dir and all its subdirectories' @@ -117,6 +117,11 @@ def ParseArguments(): 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) + return includes, defines, module, out, files, multiple @@ -138,6 +143,8 @@ def CreateContext(): context['set_wrapper'] = infos.set_wrapper context['use_shared_ptr'] = infos.use_shared_ptr context['use_auto_ptr'] = infos.use_auto_ptr + context['hold_with_shared_ptr'] = infos.hold_with_shared_ptr + context['hold_with_auto_ptr'] = infos.hold_with_auto_ptr context['add_method'] = infos.add_method context['final'] = infos.final # policies diff --git a/pyste/tests/opaque.h b/pyste/tests/opaque.h index 50ebf508..84ea3423 100644 --- a/pyste/tests/opaque.h +++ b/pyste/tests/opaque.h @@ -17,6 +17,11 @@ 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; diff --git a/pyste/tests/opaque.pyste b/pyste/tests/opaque.pyste index 2e6a3bc5..8180d251 100644 --- a/pyste/tests/opaque.pyste +++ b/pyste/tests/opaque.pyste @@ -1,5 +1,7 @@ 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 index 1c0ae845..2be26b83 100644 --- a/pyste/tests/opaqueUT.py +++ b/pyste/tests/opaqueUT.py @@ -7,6 +7,8 @@ class OpaqueTest(unittest.TestCase): 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) diff --git a/pyste/tests/test_all.py b/pyste/tests/test_all.py index e9cdd381..a0305752 100644 --- a/pyste/tests/test_all.py +++ b/pyste/tests/test_all.py @@ -118,7 +118,7 @@ if __name__ == '__main__': else: module = None try: - main('--multiple', module) - #main('', module) + #main('--multiple', module) + main('', module) except RuntimeError, e: print e