Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01f5a81

Browse files
committed
Lots of new stuff again. Moved buffer types to some separate files.
Added some new-fangled features to bgenOutput. Generate doc strings!
1 parent 5679e56 commit 01f5a81

13 files changed

Lines changed: 1327 additions & 455 deletions

Tools/bgen/bgen/bgen.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"Export everything in the various bgen submodules."
22

33
from bgenType import *
4+
from bgenVariable import *
5+
from bgenBuffer import *
6+
from bgenStackBuffer import *
7+
from bgenHeapBuffer import *
8+
from bgenStringBuffer import *
49
from bgenOutput import *
510
from bgenGenerator import *
611
from bgenModule import *

Tools/bgen/bgen/bgenBuffer.py

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
"""Buffers are character arrays that may contain null bytes.
2+
3+
There are a number of variants depending on:
4+
- how the buffer is allocated (for output buffers), and
5+
- whether and how the size is passed into and/or out of the called function.
6+
"""
7+
8+
9+
from bgenType import Type, InputOnlyMixIn, OutputOnlyMixIn, InputOnlyType, OutputOnlyType
10+
from bgenOutput import *
11+
12+
13+
# Map common types to their format characters
14+
type2format = {
15+
'long': 'l',
16+
'int': 'i',
17+
'short': 'h',
18+
'char': 'b',
19+
'unsigned long': 'l',
20+
'unsigned int': 'i',
21+
'unsigned short': 'h',
22+
'unsigned char': 'b',
23+
}
24+
25+
26+
# ----- PART 1: Fixed character buffers -----
27+
28+
29+
class FixedInputOutputBufferType(InputOnlyType):
30+
31+
"""Fixed buffer -- passed as (inbuffer, outbuffer)."""
32+
33+
def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None):
34+
self.typeName = "Buffer"
35+
self.size = str(size)
36+
self.datatype = datatype
37+
self.sizetype = sizetype
38+
self.sizeformat = sizeformat or type2format[sizetype]
39+
40+
def declare(self, name):
41+
self.declareBuffer(name)
42+
self.declareSize(name)
43+
44+
def declareBuffer(self, name):
45+
self.declareInputBuffer(name)
46+
self.declareOutputBuffer(name)
47+
48+
def declareInputBuffer(self, name):
49+
Output("%s *%s__in__;", self.datatype, name)
50+
51+
def declareOutputBuffer(self, name):
52+
Output("%s %s__out__[%s];", self.datatype, name, self.size)
53+
54+
def declareSize(self, name):
55+
Output("%s %s__len__;", self.sizetype, name)
56+
57+
def getargsFormat(self):
58+
# XXX This only works if the size is int-sized!!!
59+
return "s#"
60+
61+
def getargsArgs(self, name):
62+
return "&%s__in__, &%s__len__" % (name, name)
63+
64+
def getargsCheck(self, name):
65+
Output("if (%s__len__ != %s)", name, self.size)
66+
OutLbrace()
67+
Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");',
68+
self.size)
69+
Output("goto %s__error__;", name)
70+
OutRbrace()
71+
72+
def passOutput(self, name):
73+
return "%s__in__, %s__out__" % (name, name)
74+
75+
def mkvalueFormat(self):
76+
return "s#"
77+
78+
def mkvalueArgs(self, name):
79+
return "%s__out__, %s" % (name, self.size)
80+
81+
def cleanup(self, name):
82+
DedentLevel()
83+
Output(" %s__error__: ;", name)
84+
IndentLevel()
85+
86+
87+
class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType):
88+
89+
"""Like fixed buffer -- but same parameter is input and output."""
90+
91+
def passOutput(self, name):
92+
return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \
93+
(self.datatype, name, name, self.size)
94+
95+
96+
class InputOnlyBufferMixIn(InputOnlyMixIn):
97+
98+
def declareOutputBuffer(self, name):
99+
pass
100+
101+
102+
class OutputOnlyBufferMixIn(OutputOnlyMixIn):
103+
104+
def declareInputBuffer(self, name):
105+
pass
106+
107+
108+
class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType):
109+
110+
"""Fixed size input buffer -- passed without size information.
111+
112+
Instantiate with the size as parameter.
113+
"""
114+
115+
def passInput(self, name):
116+
return "%s__in__" % name
117+
118+
119+
class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType):
120+
121+
"""Fixed size output buffer -- passed without size information.
122+
123+
Instantiate with the size as parameter.
124+
"""
125+
126+
def passOutput(self, name):
127+
return "%s__out__" % name
128+
129+
130+
class VarInputBufferType(FixedInputBufferType):
131+
132+
"""Variable size input buffer -- passed as (buffer, size).
133+
134+
Instantiate without size parameter.
135+
"""
136+
137+
def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
138+
FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
139+
140+
def getargsCheck(self, name):
141+
pass
142+
143+
def passInput(self, name):
144+
return "%s__in__, %s__len__" % (name, name)
145+
146+
147+
# ----- PART 2: Structure buffers -----
148+
149+
150+
class StructInputOutputBufferType(FixedInputOutputBufferType):
151+
152+
"""Structure buffer -- passed as a structure pointer.
153+
154+
Instantiate with the struct type as parameter.
155+
"""
156+
157+
def __init__(self, type):
158+
FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type)
159+
self.typeName = self.type = type
160+
161+
def declareInputBuffer(self, name):
162+
Output("%s *%s__in__;", self.type, name)
163+
164+
def declareOutputBuffer(self, name):
165+
Output("%s %s__out__;", self.type, name)
166+
167+
def getargsArgs(self, name):
168+
return "(char **)&%s__in__, &%s__len__" % (name, name)
169+
170+
def passInput(self, name):
171+
return "%s__in__" % name
172+
173+
def passOutput(self, name):
174+
return "%s__in__, &%s__out__" % (name, name)
175+
176+
def mkvalueArgs(self, name):
177+
return "(char *)&%s__out__, %s" % (name, self.size)
178+
179+
180+
class StructCombinedInputOutputBufferType(StructInputOutputBufferType):
181+
182+
"""Like structure buffer -- but same parameter is input and output."""
183+
184+
def passOutput(self, name):
185+
return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \
186+
(self.type, name, name, self.size)
187+
188+
189+
class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType):
190+
191+
"""Fixed size input buffer -- passed as a pointer to a structure.
192+
193+
Instantiate with the struct type as parameter.
194+
"""
195+
196+
197+
class StructByValueBufferType(StructInputBufferType):
198+
199+
"""Fixed size input buffer -- passed as a structure BY VALUE.
200+
201+
Instantiate with the struct type as parameter.
202+
"""
203+
204+
def passInput(self, name):
205+
return "*%s__in__" % name
206+
207+
208+
class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType):
209+
210+
"""Fixed size output buffer -- passed as a pointer to a structure.
211+
212+
Instantiate with the struct type as parameter.
213+
"""
214+
215+
def passOutput(self, name):
216+
return "&%s__out__" % name
217+
218+
219+
class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType):
220+
221+
"""Fixed size output buffer -- declared as a typedef, passed as an array.
222+
223+
Instantiate with the struct type as parameter.
224+
"""
225+
226+
def passOutput(self, name):
227+
return "%s__out__" % name

Tools/bgen/bgen/bgenGenerator.py

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from bgenOutput import *
22
from bgenType import *
3+
from bgenVariable import *
34

45

56
Error = "bgenGenerator.Error"
@@ -14,6 +15,7 @@
1415
class FunctionGenerator:
1516

1617
def __init__(self, returntype, name, *argumentList):
18+
print "<--", name
1719
self.returntype = returntype
1820
self.name = name
1921
self.argumentList = []
@@ -51,8 +53,42 @@ def parseArgumentList(self, argumentList):
5153
def reference(self, name = None):
5254
if name is None:
5355
name = self.name
54-
Output("{\"%s\", (PyCFunction)%s_%s, 1},",
55-
name, self.prefix, self.name)
56+
docstring = self.docstring()
57+
Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name)
58+
Output(" %s},", stringify(docstring))
59+
60+
def docstring(self):
61+
import string
62+
input = []
63+
output = []
64+
for arg in self.argumentList:
65+
if arg.flags == ErrorMode or arg.flags == SelfMode:
66+
continue
67+
if arg.type == None:
68+
str = 'void'
69+
else:
70+
if hasattr(arg.type, 'typeName'):
71+
typeName = arg.type.typeName
72+
if typeName is None: # Suppressed type
73+
continue
74+
else:
75+
typeName = "?"
76+
print "Nameless type", arg.type
77+
78+
str = typeName + ' ' + arg.name
79+
if arg.mode in (InMode, InOutMode):
80+
input.append(str)
81+
if arg.mode in (InOutMode, OutMode):
82+
output.append(str)
83+
if not input:
84+
instr = "()"
85+
else:
86+
instr = "(%s)" % string.joinfields(input, ", ")
87+
if not output or output == ["void"]:
88+
outstr = "None"
89+
else:
90+
outstr = "(%s)" % string.joinfields(output, ", ")
91+
return instr + " -> " + outstr
5692

5793
def generate(self):
5894
print "-->", self.name
@@ -143,9 +179,7 @@ def returnvalue(self):
143179
tmp.reverse()
144180
for arg in tmp:
145181
if not arg: continue
146-
if arg.flags == ErrorMode: continue
147-
if arg.mode in (OutMode, InOutMode):
148-
arg.mkvalueCleanup()
182+
arg.cleanup()
149183
Output("return _res;")
150184

151185
def functiontrailer(self):
@@ -174,6 +208,18 @@ def definition(self):
174208
Output("%s", self.body)
175209
self.functiontrailer()
176210

211+
_stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b',
212+
'\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'}
213+
def stringify(str):
214+
if str is None: return "None"
215+
res = '"'
216+
map = _stringify_map
217+
for c in str:
218+
if map.has_key(c): res = res + map[c]
219+
elif ' ' <= c <= '~': res = res + c
220+
else: res = res + '\\%03o' % ord(c)
221+
res = res + '"'
222+
return res
177223

178224
def _test():
179225
void = None

0 commit comments

Comments
 (0)