Skip to content

Commit da34e7f

Browse files
author
Bruno da Silva de Oliveira
committed
- Abstract methods fix
- converts \ to / on windows [SVN r19516]
1 parent a0c31b4 commit da34e7f

9 files changed

Lines changed: 107 additions & 12 deletions

File tree

pyste/NEWS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
10 August 2003
2+
Support for incremental generation of the code has been added. This changes
3+
how --multiple works; documentation of this new feature will follow. Thanks
4+
to Prabhu Ramachandran, that saw the need for this feature and discussed a
5+
solution.
6+
7+
Automatically convert \ to / in Windows systems before passing the paths to
8+
gccxml.
9+
110
7 July 2003
211
Applied 2 patches by Prabhu Ramachandran: a fix in the new --multiple method,
312
and two new functions "hold_with_shared_ptr" and its counterpart for auto_ptr.

pyste/TODO

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
instance)
99

1010
- Virtual operators
11+
12+
- Apply Gottfried patches

pyste/src/Pyste/ClassExporter.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -698,25 +698,33 @@ def Declaration(self, method, indent):
698698
# default implementations (with overloading)
699699
def DefaultImpl(method, param_names):
700700
'Return the body of a default implementation wrapper'
701+
indent2 = indent * 2
701702
wrapper = self.info[method.name].wrapper
702703
if not wrapper:
703704
# return the default implementation of the class
704-
return '%s%s(%s);\n' % \
705+
if method.abstract:
706+
s = indent2 + 'PyErr_SetString(PyExc_RuntimeError, "abstract function called");\n' +\
707+
indent2 + 'throw_error_already_set();\n'
708+
if method.result.FullName() != 'void':
709+
s += indent2 + 'return %s();\n' % method.result.FullName()
710+
return s
711+
else:
712+
return indent2 + '%s%s(%s);\n' % \
705713
(return_str, method.FullName(), ', '.join(param_names))
706714
else:
707715
# return a call for the wrapper
708716
params = ', '.join(['this'] + param_names)
709-
return '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
717+
return indent2 + '%s%s(%s);\n' % (return_str, wrapper.FullName(), params)
710718

711-
if not method.abstract and method.visibility != Scope.private:
719+
if method.visibility != Scope.private:
712720
minArgs = method.minArgs
713721
maxArgs = method.maxArgs
714722
impl_names = self.DefaultImplementationNames(method)
715723
for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)):
716724
params, param_names, param_types = _ParamsInfo(method, argNum)
717725
decl += '\n'
718726
decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness)
719-
decl += indent*2 + DefaultImpl(method, param_names)
727+
decl += DefaultImpl(method, param_names)
720728
decl += indent + '}\n'
721729
return decl
722730

@@ -823,7 +831,7 @@ def GenerateDefinitions(self):
823831
for method in self.virtual_methods:
824832
exclude = self.info[method.name].exclude
825833
# generate definitions only for public methods and non-abstract methods
826-
if method.visibility == Scope.public and not method.abstract and not exclude:
834+
if method.visibility == Scope.public and not exclude:
827835
defs.extend(self.MethodDefinition(method))
828836
return defs
829837

pyste/src/Pyste/CppParser.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(self, includes=None, defines=None, cache_dir=None):
3636
self.delete_cache = False
3737
self.cache_dir = cache_dir
3838
self.cache_files = []
39+
self.mem_cache = {}
3940
# create the cache dir
4041
if cache_dir:
4142
try:
@@ -142,8 +143,7 @@ def Parse(self, header, interface, tail=None):
142143
declarations = self.GetCache(header, interface, tail)
143144
if declarations is None:
144145
declarations = self.ParseWithGCCXML(header, tail)
145-
if self.cache_dir is not None:
146-
self.CreateCache(header, interface, tail, declarations)
146+
self.CreateCache(header, interface, tail, declarations)
147147
return declarations, header
148148

149149

@@ -158,13 +158,19 @@ def CacheFileName(self, interface):
158158
def GetCache(self, header, interface, tail):
159159
if self.cache_dir is None:
160160
return None
161+
162+
key = (header, interface, tail)
163+
# try memory cache first
164+
if key in self.mem_cache:
165+
return self.mem_cache[key]
166+
167+
# get the cache from the disk
161168
header = self.FindHeader(header)
162169
cache_file = self.CacheFileName(interface)
163170
if os.path.isfile(cache_file):
164171
f = file(cache_file, 'rb')
165172
try:
166173
cache = load(f)
167-
key = (header, interface, tail)
168174
if cache.has_key(key):
169175
self.cache_files.append(cache_file)
170176
return cache[key]
@@ -177,6 +183,15 @@ def GetCache(self, header, interface, tail):
177183

178184

179185
def CreateCache(self, header, interface, tail, declarations):
186+
key = (header, interface, tail)
187+
188+
# our memory cache only holds one item
189+
self.mem_cache.clear()
190+
self.mem_cache[key] = declarations
191+
192+
# save the cache in the disk
193+
if self.cache_dir is None:
194+
return
180195
header = self.FindHeader(header)
181196
cache_file = self.CacheFileName(interface)
182197
if os.path.isfile(cache_file):
@@ -187,7 +202,6 @@ def CreateCache(self, header, interface, tail, declarations):
187202
f.close()
188203
else:
189204
cache = {}
190-
key = (header, interface, tail)
191205
cache[key] = declarations
192206
self.cache_files.append(cache_file)
193207
f = file(cache_file, 'wb')

pyste/src/Pyste/pyste.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@
4141
from policies import *
4242
from CppParser import CppParser, CppParserError
4343
import time
44+
from declarations import Typedef
4445

45-
__VERSION__ = '0.9.10'
46+
__VERSION__ = '0.9.11'
4647

4748
def RecursiveIncludes(include):
4849
'Return a list containg the include dir and all its subdirectories'
@@ -63,6 +64,14 @@ def GetDefaultIncludes():
6364
return []
6465

6566

67+
def ProcessIncludes(includes):
68+
if sys.platform == 'win32':
69+
index = 0
70+
for include in includes:
71+
includes[index] = include.replace('\\', '/')
72+
index += 1
73+
74+
6675
def ParseArguments():
6776

6877
def Usage():
@@ -147,6 +156,7 @@ def Usage():
147156
Usage()
148157
sys.exit(3)
149158

159+
ProcessIncludes(includes)
150160
return includes, defines, module, out, files, multiple, cache_dir, create_cache, generate_main
151161

152162

@@ -313,6 +323,7 @@ def GenerateCode(parser, module, out, interfaces, multiple):
313323
else:
314324
declarations = []
315325
parsed_header = None
326+
ExpandTypedefs(declarations, exported_names)
316327
export.SetDeclarations(declarations)
317328
export.SetParsedHeader(parsed_header)
318329
if multiple:
@@ -330,6 +341,15 @@ def GenerateCode(parser, module, out, interfaces, multiple):
330341
return 0
331342

332343

344+
def ExpandTypedefs(declarations, exported_names):
345+
'''Check if the names in exported_names are a typedef, and add the real class
346+
name in the dict.
347+
'''
348+
for name in exported_names.keys():
349+
for decl in declarations:
350+
if isinstance(decl, Typedef):
351+
exported_names[decl.type.FullName()] = None
352+
333353
def UsePsyco():
334354
'Tries to use psyco if possible'
335355
try:

pyste/tests/abstract_test.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <vector>
2+
#include <string>
3+
4+
namespace abstract {
5+
6+
struct A {
7+
virtual ~A() {}
8+
virtual std::string f()=0;
9+
};
10+
11+
struct B: A {
12+
std::string f() { return "B::f"; }
13+
};
14+
15+
std::string call(A* a) { return a->f(); }
16+
17+
}

pyste/tests/abstract_test.pyste

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Class('abstract::A', 'abstract_test.h')
2+
Class('abstract::B', 'abstract_test.h')
3+
Function('abstract::call', 'abstract_test.h')

pyste/tests/abstract_testUT.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import unittest
2+
from _abstract_test import *
3+
4+
class AbstractTest(unittest.TestCase):
5+
6+
def testIt(self):
7+
class C(A):
8+
def f(self):
9+
return 'C::f'
10+
11+
a = A()
12+
b = B()
13+
c = C()
14+
self.assertRaises(RuntimeError, a.f)
15+
self.assertEqual(b.f(), 'B::f')
16+
self.assertEqual(call(b), 'B::f')
17+
self.assertEqual(c.f(), 'C::f')
18+
self.assertEqual(call(c), 'C::f')
19+
20+
21+
if __name__ == '__main__':
22+
unittest.main()

pyste/tests/test_all.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
if sys.platform == 'win32':
1212

1313
includes = '-ID:/programming/libraries/boost-cvs/boost -ID:/Bin/Python/include'
14-
build_pyste_cmd = 'python ../src/Pyste/pyste.py %s ' % includes
14+
build_pyste_cmd = 'python ../src/Pyste/pyste.py --cache-dir=cache %s ' % includes
1515
compile_single_cmd = 'icl /nologo /GR /GX -c %s -I. ' % includes
1616
link_single_cmd = 'link /nologo /DLL '\
1717
'/libpath:D:/programming/libraries/boost-cvs/lib /libpath:D:/Bin/Python/libs '\
@@ -118,7 +118,7 @@ def getname(file):
118118
else:
119119
module = None
120120
try:
121-
#main('--multiple', module)
121+
# main('--multiple', module)
122122
main('', module)
123123
except RuntimeError, e:
124124
print e

0 commit comments

Comments
 (0)