2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 17:32:55 +00:00

- Abstract methods fix

- converts \ to / on windows


[SVN r19516]
This commit is contained in:
Bruno da Silva de Oliveira
2003-08-10 21:47:50 +00:00
parent a0c31b47e5
commit da34e7f507
9 changed files with 107 additions and 12 deletions

View File

@@ -1,3 +1,12 @@
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.
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.

View File

@@ -8,3 +8,5 @@
instance)
- Virtual operators
- Apply Gottfried patches

View File

@@ -698,17 +698,25 @@ class _VirtualWrapperGenerator(object):
# 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 '%s%s(%s);\n' % \
if method.abstract:
s = indent2 + 'PyErr_SetString(PyExc_RuntimeError, "abstract function called");\n' +\
indent2 + 'throw_error_already_set();\n'
if method.result.FullName() != 'void':
s += indent2 + 'return %s();\n' % method.result.FullName()
return s
else:
return indent2 + '%s%s(%s);\n' % \
(return_str, method.FullName(), ', '.join(param_names))
else:
# return a call for the wrapper
params = ', '.join(['this'] + param_names)
return '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
return indent2 + '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
if not method.abstract and method.visibility != Scope.private:
if method.visibility != Scope.private:
minArgs = method.minArgs
maxArgs = method.maxArgs
impl_names = self.DefaultImplementationNames(method)
@@ -716,7 +724,7 @@ class _VirtualWrapperGenerator(object):
params, param_names, param_types = _ParamsInfo(method, argNum)
decl += '\n'
decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness)
decl += indent*2 + DefaultImpl(method, param_names)
decl += DefaultImpl(method, param_names)
decl += indent + '}\n'
return decl
@@ -823,7 +831,7 @@ class _VirtualWrapperGenerator(object):
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 method.abstract and not exclude:
if method.visibility == Scope.public and not exclude:
defs.extend(self.MethodDefinition(method))
return defs

View File

@@ -36,6 +36,7 @@ class CppParser:
self.delete_cache = False
self.cache_dir = cache_dir
self.cache_files = []
self.mem_cache = {}
# create the cache dir
if cache_dir:
try:
@@ -142,8 +143,7 @@ class CppParser:
declarations = self.GetCache(header, interface, tail)
if declarations is None:
declarations = self.ParseWithGCCXML(header, tail)
if self.cache_dir is not None:
self.CreateCache(header, interface, tail, declarations)
self.CreateCache(header, interface, tail, declarations)
return declarations, header
@@ -158,13 +158,19 @@ class CppParser:
def GetCache(self, header, interface, tail):
if self.cache_dir is None:
return None
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
header = self.FindHeader(header)
cache_file = self.CacheFileName(interface)
if os.path.isfile(cache_file):
f = file(cache_file, 'rb')
try:
cache = load(f)
key = (header, interface, tail)
if cache.has_key(key):
self.cache_files.append(cache_file)
return cache[key]
@@ -177,6 +183,15 @@ class CppParser:
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):
@@ -187,7 +202,6 @@ class CppParser:
f.close()
else:
cache = {}
key = (header, interface, tail)
cache[key] = declarations
self.cache_files.append(cache_file)
f = file(cache_file, 'wb')

View File

@@ -41,8 +41,9 @@ import sys
from policies import *
from CppParser import CppParser, CppParserError
import time
from declarations import Typedef
__VERSION__ = '0.9.10'
__VERSION__ = '0.9.11'
def RecursiveIncludes(include):
'Return a list containg the include dir and all its subdirectories'
@@ -63,6 +64,14 @@ def GetDefaultIncludes():
return []
def ProcessIncludes(includes):
if sys.platform == 'win32':
index = 0
for include in includes:
includes[index] = include.replace('\\', '/')
index += 1
def ParseArguments():
def Usage():
@@ -147,6 +156,7 @@ def ParseArguments():
Usage()
sys.exit(3)
ProcessIncludes(includes)
return includes, defines, module, out, files, multiple, cache_dir, create_cache, generate_main
@@ -313,6 +323,7 @@ def GenerateCode(parser, module, out, interfaces, multiple):
else:
declarations = []
parsed_header = None
ExpandTypedefs(declarations, exported_names)
export.SetDeclarations(declarations)
export.SetParsedHeader(parsed_header)
if multiple:
@@ -330,6 +341,15 @@ def GenerateCode(parser, module, out, interfaces, multiple):
return 0
def ExpandTypedefs(declarations, 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 declarations:
if isinstance(decl, Typedef):
exported_names[decl.type.FullName()] = None
def UsePsyco():
'Tries to use psyco if possible'
try:

View File

@@ -0,0 +1,17 @@
#include <vector>
#include <string>
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(); }
}

View File

@@ -0,0 +1,3 @@
Class('abstract::A', 'abstract_test.h')
Class('abstract::B', 'abstract_test.h')
Function('abstract::call', 'abstract_test.h')

View File

@@ -0,0 +1,22 @@
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()

View File

@@ -11,7 +11,7 @@ import sys
if sys.platform == 'win32':
includes = '-ID:/programming/libraries/boost-cvs/boost -ID:/Bin/Python/include'
build_pyste_cmd = 'python ../src/Pyste/pyste.py %s ' % includes
build_pyste_cmd = 'python ../src/Pyste/pyste.py --cache-dir=cache %s ' % includes
compile_single_cmd = 'icl /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 '\
@@ -118,7 +118,7 @@ if __name__ == '__main__':
else:
module = None
try:
#main('--multiple', module)
# main('--multiple', module)
main('', module)
except RuntimeError, e:
print e