2
0
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:
Bruno da Silva de Oliveira
2003-07-07 19:00:52 +00:00
parent 3e6ee799ba
commit 0c8444b8ed
17 changed files with 108 additions and 34 deletions

View File

@@ -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.

View File

@@ -9,5 +9,6 @@
- Virtual operators
- staticmethod bug
- opaque pointers bug

View File

@@ -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]

View File

@@ -55,8 +55,8 @@ Usage:
where options are:
-I &lt;path&gt; add an include path
-D &lt;symbol&gt; 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: &lt;module&gt;.cpp)
in --multiple mode, this will be a directory
--no-using do not declare &quot;using namespace boost&quot;;

View File

@@ -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>

View File

@@ -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",

View File

@@ -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
#==============================================================================

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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;

View File

@@ -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))

View File

@@ -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)

View File

@@ -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