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:
@@ -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.
|
||||
|
||||
@@ -8,3 +8,5 @@
|
||||
instance)
|
||||
|
||||
- Virtual operators
|
||||
|
||||
- Apply Gottfried patches
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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:
|
||||
|
||||
17
pyste/tests/abstract_test.h
Normal file
17
pyste/tests/abstract_test.h
Normal 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(); }
|
||||
|
||||
}
|
||||
3
pyste/tests/abstract_test.pyste
Normal file
3
pyste/tests/abstract_test.pyste
Normal file
@@ -0,0 +1,3 @@
|
||||
Class('abstract::A', 'abstract_test.h')
|
||||
Class('abstract::B', 'abstract_test.h')
|
||||
Function('abstract::call', 'abstract_test.h')
|
||||
22
pyste/tests/abstract_testUT.py
Normal file
22
pyste/tests/abstract_testUT.py
Normal 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()
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user