mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 16:32:16 +00:00
- fixed bug of --multiple
- new function: hold_with_shared_ptr - SPECIALIZE_TYPE_ID bug [SVN r18969]
This commit is contained in:
13
pyste/NEWS
13
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.
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
|
||||
- Virtual operators
|
||||
|
||||
|
||||
- staticmethod bug
|
||||
|
||||
- opaque pointers bug
|
||||
|
||||
@@ -81,8 +81,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";
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -58,6 +58,16 @@ For <tt>std::auto_ptr</tt>'s, use the function <tt>use_auto_ptr</tt>.</p>
|
||||
<p>
|
||||
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.</p>
|
||||
<a name="holders"></a><h2>Holders</h2><p>
|
||||
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
|
||||
<tt>hold_with_shared_ptr</tt> and <tt>hold_with_auto_ptr</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>C </span><span class=special>= </span><span class=identifier>Class</span><span class=special>(</span><span class=literal>'C'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
|
||||
</span><span class=identifier>hold_with_shared_ptr</span><span class=special>(</span><span class=identifier>C</span><span class=special>)
|
||||
</span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'newC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
|
||||
</span><span class=identifier>Function</span><span class=special>(</span><span class=literal>'printC'</span><span class=special>, </span><span class=literal>'C.h'</span><span class=special>)
|
||||
</span></pre></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
#==============================================================================
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user