Sigh, due to sloppiness on my part bgen has become pretty mixed up wrt. tabs

and spaces. Detabbed the lot.
This commit is contained in:
Jack Jansen 2003-01-19 21:53:57 +00:00
parent 28256f276e
commit 2cf08ab4c2
13 changed files with 2043 additions and 2043 deletions

View file

@ -12,14 +12,14 @@ from bgenOutput import *
# Map common types to their format characters # Map common types to their format characters
type2format = { type2format = {
'long': 'l', 'long': 'l',
'int': 'i', 'int': 'i',
'short': 'h', 'short': 'h',
'char': 'b', 'char': 'b',
'unsigned long': 'l', 'unsigned long': 'l',
'unsigned int': 'i', 'unsigned int': 'i',
'unsigned short': 'h', 'unsigned short': 'h',
'unsigned char': 'b', 'unsigned char': 'b',
} }
@ -27,238 +27,238 @@ type2format = {
class FixedInputOutputBufferType(InputOnlyType): class FixedInputOutputBufferType(InputOnlyType):
"""Fixed buffer -- passed as (inbuffer, outbuffer).""" """Fixed buffer -- passed as (inbuffer, outbuffer)."""
def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None): def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None):
self.typeName = "Buffer" self.typeName = "Buffer"
self.size = str(size) self.size = str(size)
self.datatype = datatype self.datatype = datatype
self.sizetype = sizetype self.sizetype = sizetype
self.sizeformat = sizeformat or type2format[sizetype] self.sizeformat = sizeformat or type2format[sizetype]
self.label_needed = 0 self.label_needed = 0
def declare(self, name): def declare(self, name):
self.declareBuffer(name) self.declareBuffer(name)
self.declareSize(name) self.declareSize(name)
def declareBuffer(self, name): def declareBuffer(self, name):
self.declareInputBuffer(name) self.declareInputBuffer(name)
self.declareOutputBuffer(name) self.declareOutputBuffer(name)
def declareInputBuffer(self, name): def declareInputBuffer(self, name):
Output("%s *%s__in__;", self.datatype, name) Output("%s *%s__in__;", self.datatype, name)
def declareOutputBuffer(self, name): def declareOutputBuffer(self, name):
Output("%s %s__out__[%s];", self.datatype, name, self.size) Output("%s %s__out__[%s];", self.datatype, name, self.size)
def declareSize(self, name): def declareSize(self, name):
Output("%s %s__len__;", self.sizetype, name) Output("%s %s__len__;", self.sizetype, name)
Output("int %s__in_len__;", name) Output("int %s__in_len__;", name)
def getargsFormat(self): def getargsFormat(self):
return "s#" return "s#"
def getargsArgs(self, name): def getargsArgs(self, name):
return "&%s__in__, &%s__in_len__" % (name, name) return "&%s__in__, &%s__in_len__" % (name, name)
def getargsCheck(self, name): def getargsCheck(self, name):
Output("if (%s__in_len__ != %s)", name, self.size) Output("if (%s__in_len__ != %s)", name, self.size)
OutLbrace() OutLbrace()
Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");', Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");',
self.size) self.size)
Output("goto %s__error__;", name) Output("goto %s__error__;", name)
self.label_needed = 1 self.label_needed = 1
OutRbrace() OutRbrace()
self.transferSize(name) self.transferSize(name)
def transferSize(self, name): def transferSize(self, name):
Output("%s__len__ = %s__in_len__;", name, name) Output("%s__len__ = %s__in_len__;", name, name)
def passOutput(self, name): def passOutput(self, name):
return "%s__in__, %s__out__" % (name, name) return "%s__in__, %s__out__" % (name, name)
def mkvalueFormat(self): def mkvalueFormat(self):
return "s#" return "s#"
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s__out__, (int)%s" % (name, self.size) return "%s__out__, (int)%s" % (name, self.size)
def cleanup(self, name): def cleanup(self, name):
if self.label_needed: if self.label_needed:
DedentLevel() DedentLevel()
Output(" %s__error__: ;", name) Output(" %s__error__: ;", name)
IndentLevel() IndentLevel()
class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType): class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType):
"""Like fixed buffer -- but same parameter is input and output.""" """Like fixed buffer -- but same parameter is input and output."""
def passOutput(self, name): def passOutput(self, name):
return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \ return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \
(self.datatype, name, name, self.size) (self.datatype, name, name, self.size)
class InputOnlyBufferMixIn(InputOnlyMixIn): class InputOnlyBufferMixIn(InputOnlyMixIn):
def declareOutputBuffer(self, name): def declareOutputBuffer(self, name):
pass pass
class OutputOnlyBufferMixIn(OutputOnlyMixIn): class OutputOnlyBufferMixIn(OutputOnlyMixIn):
def declareInputBuffer(self, name): def declareInputBuffer(self, name):
pass pass
class OptionalInputBufferMixIn: class OptionalInputBufferMixIn:
"""Add to input buffers if the buffer may be omitted: pass None in Python """Add to input buffers if the buffer may be omitted: pass None in Python
and the C code will get a NULL pointer and zero size""" and the C code will get a NULL pointer and zero size"""
def getargsFormat(self): def getargsFormat(self):
return "z#" return "z#"
class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType): class FixedInputBufferType(InputOnlyBufferMixIn, FixedInputOutputBufferType):
"""Fixed size input buffer -- passed without size information. """Fixed size input buffer -- passed without size information.
Instantiate with the size as parameter. Instantiate with the size as parameter.
""" """
def passInput(self, name): def passInput(self, name):
return "%s__in__" % name return "%s__in__" % name
class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType): class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType):
pass pass
class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType): class FixedOutputBufferType(OutputOnlyBufferMixIn, FixedInputOutputBufferType):
"""Fixed size output buffer -- passed without size information. """Fixed size output buffer -- passed without size information.
Instantiate with the size as parameter. Instantiate with the size as parameter.
""" """
def passOutput(self, name): def passOutput(self, name):
return "%s__out__" % name return "%s__out__" % name
class VarInputBufferType(FixedInputBufferType): class VarInputBufferType(FixedInputBufferType):
"""Variable size input buffer -- passed as (buffer, size). """Variable size input buffer -- passed as (buffer, size).
Instantiate without size parameter. Instantiate without size parameter.
""" """
def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
def getargsCheck(self, name): def getargsCheck(self, name):
Output("%s__len__ = %s__in_len__;", name, name) Output("%s__len__ = %s__in_len__;", name, name)
def passInput(self, name): def passInput(self, name):
return "%s__in__, %s__len__" % (name, name) return "%s__in__, %s__len__" % (name, name)
class ReverseInputBufferMixin: class ReverseInputBufferMixin:
""" Mixin for input buffers that are passed as (size, buffer) """ """ Mixin for input buffers that are passed as (size, buffer) """
def passInput(self, name): def passInput(self, name):
return "%s__len__, %s__in__" % (name, name) return "%s__len__, %s__in__" % (name, name)
class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType): class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType):
pass pass
# ----- PART 2: Structure buffers ----- # ----- PART 2: Structure buffers -----
class StructInputOutputBufferType(FixedInputOutputBufferType): class StructInputOutputBufferType(FixedInputOutputBufferType):
"""Structure buffer -- passed as a structure pointer. """Structure buffer -- passed as a structure pointer.
Instantiate with the struct type as parameter. Instantiate with the struct type as parameter.
""" """
def __init__(self, type): def __init__(self, type):
FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type) FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type)
self.typeName = self.type = type self.typeName = self.type = type
def declareInputBuffer(self, name): def declareInputBuffer(self, name):
Output("%s *%s__in__;", self.type, name) Output("%s *%s__in__;", self.type, name)
def declareSize(self, name): def declareSize(self, name):
Output("int %s__in_len__;", name) Output("int %s__in_len__;", name)
def declareOutputBuffer(self, name): def declareOutputBuffer(self, name):
Output("%s %s__out__;", self.type, name) Output("%s %s__out__;", self.type, name)
def getargsArgs(self, name): def getargsArgs(self, name):
return "(char **)&%s__in__, &%s__in_len__" % (name, name) return "(char **)&%s__in__, &%s__in_len__" % (name, name)
def transferSize(self, name): def transferSize(self, name):
pass pass
def passInput(self, name): def passInput(self, name):
return "%s__in__" % name return "%s__in__" % name
def passOutput(self, name): def passOutput(self, name):
return "%s__in__, &%s__out__" % (name, name) return "%s__in__, &%s__out__" % (name, name)
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "(char *)&%s__out__, (int)%s" % (name, self.size) return "(char *)&%s__out__, (int)%s" % (name, self.size)
class StructCombinedInputOutputBufferType(StructInputOutputBufferType): class StructCombinedInputOutputBufferType(StructInputOutputBufferType):
"""Like structure buffer -- but same parameter is input and output.""" """Like structure buffer -- but same parameter is input and output."""
def passOutput(self, name): def passOutput(self, name):
return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \ return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \
(self.type, name, name, self.size) (self.type, name, name, self.size)
class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType): class StructInputBufferType(InputOnlyBufferMixIn, StructInputOutputBufferType):
"""Fixed size input buffer -- passed as a pointer to a structure. """Fixed size input buffer -- passed as a pointer to a structure.
Instantiate with the struct type as parameter. Instantiate with the struct type as parameter.
""" """
class StructByValueBufferType(StructInputBufferType): class StructByValueBufferType(StructInputBufferType):
"""Fixed size input buffer -- passed as a structure BY VALUE. """Fixed size input buffer -- passed as a structure BY VALUE.
Instantiate with the struct type as parameter. Instantiate with the struct type as parameter.
""" """
def passInput(self, name): def passInput(self, name):
return "*%s__in__" % name return "*%s__in__" % name
class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): class StructOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType):
"""Fixed size output buffer -- passed as a pointer to a structure. """Fixed size output buffer -- passed as a pointer to a structure.
Instantiate with the struct type as parameter. Instantiate with the struct type as parameter.
""" """
def declareSize(self, name): def declareSize(self, name):
pass pass
def passOutput(self, name): def passOutput(self, name):
return "&%s__out__" % name return "&%s__out__" % name
class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType): class ArrayOutputBufferType(OutputOnlyBufferMixIn, StructInputOutputBufferType):
"""Fixed size output buffer -- declared as a typedef, passed as an array. """Fixed size output buffer -- declared as a typedef, passed as an array.
Instantiate with the struct type as parameter. Instantiate with the struct type as parameter.
""" """
def declareSize(self, name): def declareSize(self, name):
pass pass
def passOutput(self, name): def passOutput(self, name):
return "%s__out__" % name return "%s__out__" % name

View file

@ -15,260 +15,260 @@ INOUT = IN_OUT = "in-out"
class BaseFunctionGenerator: class BaseFunctionGenerator:
def __init__(self, name, condition=None): def __init__(self, name, condition=None):
if DEBUG: print "<--", name if DEBUG: print "<--", name
self.name = name self.name = name
self.prefix = name self.prefix = name
self.objecttype = "PyObject" # Type of _self argument to function self.objecttype = "PyObject" # Type of _self argument to function
self.condition = condition self.condition = condition
def setprefix(self, prefix): def setprefix(self, prefix):
self.prefix = prefix self.prefix = prefix
def generate(self): def generate(self):
if DEBUG: print "-->", self.name if DEBUG: print "-->", self.name
if self.condition: if self.condition:
Output() Output()
Output(self.condition) Output(self.condition)
self.functionheader() self.functionheader()
self.functionbody() self.functionbody()
self.functiontrailer() self.functiontrailer()
if self.condition: if self.condition:
Output("#endif") Output("#endif")
def functionheader(self): def functionheader(self):
Output() Output()
Output("static PyObject *%s_%s(%s *_self, PyObject *_args)", Output("static PyObject *%s_%s(%s *_self, PyObject *_args)",
self.prefix, self.name, self.objecttype) self.prefix, self.name, self.objecttype)
OutLbrace() OutLbrace()
Output("PyObject *_res = NULL;") Output("PyObject *_res = NULL;")
def functionbody(self): def functionbody(self):
Output("/* XXX To be provided */") Output("/* XXX To be provided */")
def functiontrailer(self): def functiontrailer(self):
OutRbrace() OutRbrace()
def reference(self, name = None): def reference(self, name = None):
if name is None: if name is None:
name = self.name name = self.name
docstring = self.docstring() docstring = self.docstring()
if self.condition: if self.condition:
Output() Output()
Output(self.condition) Output(self.condition)
Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name) Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name)
Output(" PyDoc_STR(%s)},", stringify(docstring)) Output(" PyDoc_STR(%s)},", stringify(docstring))
if self.condition: if self.condition:
Output("#endif") Output("#endif")
def docstring(self): def docstring(self):
return None return None
def __cmp__(self, other): def __cmp__(self, other):
if not hasattr(other, 'name'): if not hasattr(other, 'name'):
return cmp(id(self), id(other)) return cmp(id(self), id(other))
return cmp(self.name, other.name) return cmp(self.name, other.name)
_stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b', _stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b',
'\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'} '\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'}
def stringify(str): def stringify(str):
if str is None: return "NULL" if str is None: return "NULL"
res = '"' res = '"'
map = _stringify_map map = _stringify_map
for c in str: for c in str:
if map.has_key(c): res = res + map[c] if map.has_key(c): res = res + map[c]
elif ' ' <= c <= '~': res = res + c elif ' ' <= c <= '~': res = res + c
else: res = res + '\\%03o' % ord(c) else: res = res + '\\%03o' % ord(c)
res = res + '"' res = res + '"'
return res return res
class ManualGenerator(BaseFunctionGenerator): class ManualGenerator(BaseFunctionGenerator):
def __init__(self, name, body, condition=None): def __init__(self, name, body, condition=None):
BaseFunctionGenerator.__init__(self, name, condition=condition) BaseFunctionGenerator.__init__(self, name, condition=condition)
self.body = body self.body = body
def functionbody(self): def functionbody(self):
Output("%s", self.body) Output("%s", self.body)
def setselftype(self, selftype, itselftype): def setselftype(self, selftype, itselftype):
self.objecttype = selftype self.objecttype = selftype
self.itselftype = itselftype self.itselftype = itselftype
class FunctionGenerator(BaseFunctionGenerator): class FunctionGenerator(BaseFunctionGenerator):
def __init__(self, returntype, name, *argumentList, **conditionlist): def __init__(self, returntype, name, *argumentList, **conditionlist):
BaseFunctionGenerator.__init__(self, name, **conditionlist) BaseFunctionGenerator.__init__(self, name, **conditionlist)
self.returntype = returntype self.returntype = returntype
self.argumentList = [] self.argumentList = []
self.setreturnvar() self.setreturnvar()
self.parseArgumentList(argumentList) self.parseArgumentList(argumentList)
self.prefix = "XXX" # Will be changed by setprefix() call self.prefix = "XXX" # Will be changed by setprefix() call
self.itselftype = None # Type of _self->ob_itself, if defined self.itselftype = None # Type of _self->ob_itself, if defined
def setreturnvar(self): def setreturnvar(self):
if self.returntype: if self.returntype:
self.rv = self.makereturnvar() self.rv = self.makereturnvar()
self.argumentList.append(self.rv) self.argumentList.append(self.rv)
else: else:
self.rv = None self.rv = None
def makereturnvar(self): def makereturnvar(self):
return Variable(self.returntype, "_rv", OutMode) return Variable(self.returntype, "_rv", OutMode)
def setselftype(self, selftype, itselftype): def setselftype(self, selftype, itselftype):
self.objecttype = selftype self.objecttype = selftype
self.itselftype = itselftype self.itselftype = itselftype
def parseArgumentList(self, argumentList): def parseArgumentList(self, argumentList):
iarg = 0 iarg = 0
for type, name, mode in argumentList: for type, name, mode in argumentList:
iarg = iarg + 1 iarg = iarg + 1
if name is None: name = "_arg%d" % iarg if name is None: name = "_arg%d" % iarg
arg = Variable(type, name, mode) arg = Variable(type, name, mode)
self.argumentList.append(arg) self.argumentList.append(arg)
def docstring(self): def docstring(self):
input = [] input = []
output = [] output = []
for arg in self.argumentList: for arg in self.argumentList:
if arg.flags == ErrorMode or arg.flags == SelfMode: if arg.flags == ErrorMode or arg.flags == SelfMode:
continue continue
if arg.type == None: if arg.type == None:
str = 'void' str = 'void'
else: else:
if hasattr(arg.type, 'typeName'): if hasattr(arg.type, 'typeName'):
typeName = arg.type.typeName typeName = arg.type.typeName
if typeName is None: # Suppressed type if typeName is None: # Suppressed type
continue continue
else: else:
typeName = "?" typeName = "?"
print "Nameless type", arg.type print "Nameless type", arg.type
str = typeName + ' ' + arg.name str = typeName + ' ' + arg.name
if arg.mode in (InMode, InOutMode): if arg.mode in (InMode, InOutMode):
input.append(str) input.append(str)
if arg.mode in (InOutMode, OutMode): if arg.mode in (InOutMode, OutMode):
output.append(str) output.append(str)
if not input: if not input:
instr = "()" instr = "()"
else: else:
instr = "(%s)" % ", ".join(input) instr = "(%s)" % ", ".join(input)
if not output or output == ["void"]: if not output or output == ["void"]:
outstr = "None" outstr = "None"
else: else:
outstr = "(%s)" % ", ".join(output) outstr = "(%s)" % ", ".join(output)
return instr + " -> " + outstr return instr + " -> " + outstr
def functionbody(self): def functionbody(self):
self.declarations() self.declarations()
self.precheck() self.precheck()
self.getargs() self.getargs()
self.callit() self.callit()
self.checkit() self.checkit()
self.returnvalue() self.returnvalue()
def declarations(self): def declarations(self):
for arg in self.argumentList: for arg in self.argumentList:
arg.declare() arg.declare()
def getargs(self): def getargs(self):
fmt = "" fmt = ""
lst = "" lst = ""
sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(") sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(")
for arg in self.argumentList: for arg in self.argumentList:
if arg.flags == SelfMode: if arg.flags == SelfMode:
continue continue
if arg.mode in (InMode, InOutMode): if arg.mode in (InMode, InOutMode):
fmt = fmt + arg.getargsFormat() fmt = fmt + arg.getargsFormat()
args = arg.getargsArgs() args = arg.getargsArgs()
if args: if args:
lst = lst + sep + args lst = lst + sep + args
Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst) Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst)
IndentLevel() IndentLevel()
Output("return NULL;") Output("return NULL;")
DedentLevel() DedentLevel()
for arg in self.argumentList: for arg in self.argumentList:
if arg.flags == SelfMode: if arg.flags == SelfMode:
continue continue
if arg.mode in (InMode, InOutMode): if arg.mode in (InMode, InOutMode):
arg.getargsCheck() arg.getargsCheck()
def precheck(self): def precheck(self):
pass pass
def callit(self): def callit(self):
args = "" args = ""
if self.rv: if self.rv:
s = "%s = %s(" % (self.rv.name, self.name) s = "%s = %s(" % (self.rv.name, self.name)
else: else:
s = "%s(" % self.name s = "%s(" % self.name
sep = ",\n" + ' '*len(s) sep = ",\n" + ' '*len(s)
for arg in self.argumentList: for arg in self.argumentList:
if arg is self.rv: if arg is self.rv:
continue continue
s = arg.passArgument() s = arg.passArgument()
if args: s = sep + s if args: s = sep + s
args = args + s args = args + s
if self.rv: if self.rv:
Output("%s = %s(%s);", Output("%s = %s(%s);",
self.rv.name, self.name, args) self.rv.name, self.name, args)
else: else:
Output("%s(%s);", self.name, args) Output("%s(%s);", self.name, args)
def checkit(self): def checkit(self):
for arg in self.argumentList: for arg in self.argumentList:
arg.errorCheck() arg.errorCheck()
def returnvalue(self): def returnvalue(self):
fmt = "" fmt = ""
lst = "" lst = ""
sep = ",\n" + ' '*len("return Py_BuildValue(") sep = ",\n" + ' '*len("return Py_BuildValue(")
for arg in self.argumentList: for arg in self.argumentList:
if not arg: continue if not arg: continue
if arg.flags == ErrorMode: continue if arg.flags == ErrorMode: continue
if arg.mode in (OutMode, InOutMode): if arg.mode in (OutMode, InOutMode):
fmt = fmt + arg.mkvalueFormat() fmt = fmt + arg.mkvalueFormat()
lst = lst + sep + arg.mkvalueArgs() lst = lst + sep + arg.mkvalueArgs()
if fmt == "": if fmt == "":
Output("Py_INCREF(Py_None);") Output("Py_INCREF(Py_None);")
Output("_res = Py_None;"); Output("_res = Py_None;");
else: else:
Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst) Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst)
tmp = self.argumentList[:] tmp = self.argumentList[:]
tmp.reverse() tmp.reverse()
for arg in tmp: for arg in tmp:
if not arg: continue if not arg: continue
arg.cleanup() arg.cleanup()
Output("return _res;") Output("return _res;")
class MethodGenerator(FunctionGenerator): class MethodGenerator(FunctionGenerator):
def parseArgumentList(self, args): def parseArgumentList(self, args):
a0, args = args[0], args[1:] a0, args = args[0], args[1:]
t0, n0, m0 = a0 t0, n0, m0 = a0
if m0 != InMode: if m0 != InMode:
raise ValueError, "method's 'self' must be 'InMode'" raise ValueError, "method's 'self' must be 'InMode'"
self.itself = Variable(t0, "_self->ob_itself", SelfMode) self.itself = Variable(t0, "_self->ob_itself", SelfMode)
self.argumentList.append(self.itself) self.argumentList.append(self.itself)
FunctionGenerator.parseArgumentList(self, args) FunctionGenerator.parseArgumentList(self, args)
def _test(): def _test():
void = None void = None
eggs = FunctionGenerator(void, "eggs", eggs = FunctionGenerator(void, "eggs",
(stringptr, 'cmd', InMode), (stringptr, 'cmd', InMode),
(int, 'x', InMode), (int, 'x', InMode),
(double, 'y', InOutMode), (double, 'y', InOutMode),
(int, 'status', ErrorMode), (int, 'status', ErrorMode),
) )
eggs.setprefix("spam") eggs.setprefix("spam")
print "/* START */" print "/* START */"
eggs.generate() eggs.generate()
if __name__ == "__main__": if __name__ == "__main__":
_test() _test()

View file

@ -2,39 +2,39 @@ from bgenOutput import *
class GeneratorGroup: class GeneratorGroup:
def __init__(self, prefix): def __init__(self, prefix):
self.prefix = prefix self.prefix = prefix
self.generators = [] self.generators = []
def add(self, g, dupcheck=0): def add(self, g, dupcheck=0):
if dupcheck: if dupcheck:
if g in self.generators: if g in self.generators:
print 'DUP', g.name print 'DUP', g.name
return return
g.setprefix(self.prefix) g.setprefix(self.prefix)
self.generators.append(g) self.generators.append(g)
def generate(self): def generate(self):
for g in self.generators: for g in self.generators:
g.generate() g.generate()
Output() Output()
Output("static PyMethodDef %s_methods[] = {", self.prefix) Output("static PyMethodDef %s_methods[] = {", self.prefix)
IndentLevel() IndentLevel()
for g in self.generators: for g in self.generators:
g.reference() g.reference()
Output("{NULL, NULL, 0}") Output("{NULL, NULL, 0}")
DedentLevel() DedentLevel()
Output("};") Output("};")
def _test(): def _test():
void = None void = None
from bgenGenerator import FunctionGenerator from bgenGenerator import FunctionGenerator
group = GeneratorGroup("spam") group = GeneratorGroup("spam")
eggs = FunctionGenerator(void, "eggs") eggs = FunctionGenerator(void, "eggs")
group.add(eggs) group.add(eggs)
print "/* START */" print "/* START */"
group.generate() group.generate()
if __name__ == "__main__": if __name__ == "__main__":
_test() _test()

View file

@ -7,105 +7,105 @@ from bgenBuffer import FixedInputOutputBufferType
class HeapInputOutputBufferType(FixedInputOutputBufferType): class HeapInputOutputBufferType(FixedInputOutputBufferType):
"""Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size). """Input-output buffer allocated on the heap -- passed as (inbuffer, outbuffer, size).
Instantiate without parameters. Instantiate without parameters.
Call from Python with input buffer. Call from Python with input buffer.
""" """
def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None):
FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat)
def declareOutputBuffer(self, name): def declareOutputBuffer(self, name):
Output("%s *%s__out__;", self.datatype, name) Output("%s *%s__out__;", self.datatype, name)
def getargsCheck(self, name): def getargsCheck(self, name):
Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name) Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name)
OutLbrace() OutLbrace()
Output('PyErr_NoMemory();') Output('PyErr_NoMemory();')
Output("goto %s__error__;", name) Output("goto %s__error__;", name)
self.label_needed = 1 self.label_needed = 1
OutRbrace() OutRbrace()
Output("%s__len__ = %s__in_len__;", name, name) Output("%s__len__ = %s__in_len__;", name, name)
def passOutput(self, name): def passOutput(self, name):
return "%s__in__, %s__out__, (%s)%s__len__" % \ return "%s__in__, %s__out__, (%s)%s__len__" % \
(name, name, self.sizetype, name) (name, name, self.sizetype, name)
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s__out__, (int)%s__len__" % (name, name) return "%s__out__, (int)%s__len__" % (name, name)
def cleanup(self, name): def cleanup(self, name):
Output("free(%s__out__);", name) Output("free(%s__out__);", name)
FixedInputOutputBufferType.cleanup(self, name) FixedInputOutputBufferType.cleanup(self, name)
class VarHeapInputOutputBufferType(HeapInputOutputBufferType): class VarHeapInputOutputBufferType(HeapInputOutputBufferType):
"""same as base class, but passed as (inbuffer, outbuffer, &size)""" """same as base class, but passed as (inbuffer, outbuffer, &size)"""
def passOutput(self, name): def passOutput(self, name):
return "%s__in__, %s__out__, &%s__len__" % (name, name, name) return "%s__in__, %s__out__, &%s__len__" % (name, name, name)
class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType): class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType):
"""same as base class, but passed as (inoutbuffer, size)""" """same as base class, but passed as (inoutbuffer, size)"""
def passOutput(self, name): def passOutput(self, name):
return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \ return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \
(self.datatype, name, name, name) (self.datatype, name, name, name)
class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType): class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType):
"""same as base class, but passed as (inoutbuffer, &size)""" """same as base class, but passed as (inoutbuffer, &size)"""
def passOutput(self, name): def passOutput(self, name):
return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \ return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \
(self.datatype, name, name, name) (self.datatype, name, name, name)
class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType): class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType):
"""Output buffer allocated on the heap -- passed as (buffer, size). """Output buffer allocated on the heap -- passed as (buffer, size).
Instantiate without parameters. Instantiate without parameters.
Call from Python with buffer size. Call from Python with buffer size.
""" """
def declareInputBuffer(self, name): def declareInputBuffer(self, name):
pass pass
def getargsFormat(self): def getargsFormat(self):
return "i" return "i"
def getargsArgs(self, name): def getargsArgs(self, name):
return "&%s__in_len__" % name return "&%s__in_len__" % name
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, %s__len__" % (name, name) return "%s__out__, %s__len__" % (name, name)
class VarHeapOutputBufferType(HeapOutputBufferType): class VarHeapOutputBufferType(HeapOutputBufferType):
"""Output buffer allocated on the heap -- passed as (buffer, &size). """Output buffer allocated on the heap -- passed as (buffer, &size).
Instantiate without parameters. Instantiate without parameters.
Call from Python with buffer size. Call from Python with buffer size.
""" """
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, &%s__len__" % (name, name) return "%s__out__, &%s__len__" % (name, name)
class VarVarHeapOutputBufferType(VarHeapOutputBufferType): class VarVarHeapOutputBufferType(VarHeapOutputBufferType):
"""Output buffer allocated on the heap -- passed as (buffer, size, &size). """Output buffer allocated on the heap -- passed as (buffer, size, &size).
Instantiate without parameters. Instantiate without parameters.
Call from Python with buffer size. Call from Python with buffer size.
""" """
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, %s__len__, &%s__len__" % (name, name, name) return "%s__out__, %s__len__, &%s__len__" % (name, name, name)

View file

@ -3,92 +3,92 @@ from bgenGeneratorGroup import GeneratorGroup
class Module(GeneratorGroup): class Module(GeneratorGroup):
def __init__(self, name, prefix = None, def __init__(self, name, prefix = None,
includestuff = None, includestuff = None,
finalstuff = None, finalstuff = None,
initstuff = None, initstuff = None,
variablestuff = None, variablestuff = None,
longname = None): longname = None):
GeneratorGroup.__init__(self, prefix or name) GeneratorGroup.__init__(self, prefix or name)
self.name = name self.name = name
if longname: if longname:
self.longname = longname self.longname = longname
else: else:
self.longname = name self.longname = name
self.includestuff = includestuff self.includestuff = includestuff
self.initstuff = initstuff self.initstuff = initstuff
self.finalstuff = finalstuff self.finalstuff = finalstuff
self.variablestuff = variablestuff self.variablestuff = variablestuff
self.typeobjects = [] self.typeobjects = []
def addobject(self, od): def addobject(self, od):
self.generators.append(od) self.generators.append(od)
self.typeobjects.append(od) self.typeobjects.append(od)
od.setmodulename(self.longname) od.setmodulename(self.longname)
def generate(self): def generate(self):
OutHeader1("Module " + self.name) OutHeader1("Module " + self.name)
Output("#include \"Python.h\"") Output("#include \"Python.h\"")
Output() Output()
if self.includestuff: if self.includestuff:
Output() Output()
Output("%s", self.includestuff) Output("%s", self.includestuff)
self.declareModuleVariables() self.declareModuleVariables()
GeneratorGroup.generate(self) GeneratorGroup.generate(self)
if self.finalstuff: if self.finalstuff:
Output() Output()
Output("%s", self.finalstuff) Output("%s", self.finalstuff)
Output() Output()
Output("void init%s(void)", self.name) Output("void init%s(void)", self.name)
OutLbrace() OutLbrace()
Output("PyObject *m;") Output("PyObject *m;")
Output("PyObject *d;") Output("PyObject *d;")
Output() Output()
if self.initstuff: if self.initstuff:
Output("%s", self.initstuff) Output("%s", self.initstuff)
Output() Output()
Output("m = Py_InitModule(\"%s\", %s_methods);", Output("m = Py_InitModule(\"%s\", %s_methods);",
self.name, self.prefix) self.name, self.prefix)
Output("d = PyModule_GetDict(m);") Output("d = PyModule_GetDict(m);")
self.createModuleVariables() self.createModuleVariables()
OutRbrace() OutRbrace()
OutHeader1("End module " + self.name) OutHeader1("End module " + self.name)
def declareModuleVariables(self): def declareModuleVariables(self):
self.errorname = self.prefix + "_Error" self.errorname = self.prefix + "_Error"
Output("static PyObject *%s;", self.errorname) Output("static PyObject *%s;", self.errorname)
def createModuleVariables(self): def createModuleVariables(self):
Output("""%s = %s;""", self.errorname, self.exceptionInitializer()) Output("""%s = %s;""", self.errorname, self.exceptionInitializer())
Output("""if (%s == NULL ||""", self.errorname) Output("""if (%s == NULL ||""", self.errorname)
Output(""" PyDict_SetItemString(d, "Error", %s) != 0)""", Output(""" PyDict_SetItemString(d, "Error", %s) != 0)""",
self.errorname) self.errorname)
IndentLevel() IndentLevel()
Output("""return;""") Output("""return;""")
DedentLevel() DedentLevel()
for tp in self.typeobjects: for tp in self.typeobjects:
tp.outputTypeObjectInitializer() tp.outputTypeObjectInitializer()
if self.variablestuff: if self.variablestuff:
Output("%s", self.variablestuff) Output("%s", self.variablestuff)
Output() Output()
def exceptionInitializer(self): def exceptionInitializer(self):
return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name
def _test(): def _test():
from bgenGenerator import FunctionGenerator from bgenGenerator import FunctionGenerator
m = Module("spam", "", "#include <stdio.h>") m = Module("spam", "", "#include <stdio.h>")
g = FunctionGenerator(None, "bacon") g = FunctionGenerator(None, "bacon")
m.add(g) m.add(g)
m.generate() m.generate()
if __name__ == "__main__": if __name__ == "__main__":
_test() _test()

View file

@ -2,485 +2,485 @@ from bgenOutput import *
from bgenGeneratorGroup import GeneratorGroup from bgenGeneratorGroup import GeneratorGroup
class ObjectDefinition(GeneratorGroup): class ObjectDefinition(GeneratorGroup):
"Spit out code that together defines a new Python object type" "Spit out code that together defines a new Python object type"
basechain = "NULL" basechain = "NULL"
tp_flags = "Py_TPFLAGS_DEFAULT" tp_flags = "Py_TPFLAGS_DEFAULT"
basetype = None basetype = None
def __init__(self, name, prefix, itselftype): def __init__(self, name, prefix, itselftype):
"""ObjectDefinition constructor. May be extended, but do not override. """ObjectDefinition constructor. May be extended, but do not override.
- name: the object's official name, e.g. 'SndChannel'. - name: the object's official name, e.g. 'SndChannel'.
- prefix: the prefix used for the object's functions and data, e.g. 'SndCh'. - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'.
- itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'. - itselftype: the C type actually contained in the object, e.g. 'SndChannelPtr'.
XXX For official Python data types, rules for the 'Py' prefix are a problem. XXX For official Python data types, rules for the 'Py' prefix are a problem.
""" """
GeneratorGroup.__init__(self, prefix or name) GeneratorGroup.__init__(self, prefix or name)
self.name = name self.name = name
self.itselftype = itselftype self.itselftype = itselftype
self.objecttype = name + 'Object' self.objecttype = name + 'Object'
self.typename = name + '_Type' self.typename = name + '_Type'
self.argref = "" # set to "*" if arg to <type>_New should be pointer self.argref = "" # set to "*" if arg to <type>_New should be pointer
self.static = "static " # set to "" to make <type>_New and <type>_Convert public self.static = "static " # set to "" to make <type>_New and <type>_Convert public
self.modulename = None self.modulename = None
if hasattr(self, "assertions"): if hasattr(self, "assertions"):
self.assertions() self.assertions()
def add(self, g, dupcheck=0): def add(self, g, dupcheck=0):
g.setselftype(self.objecttype, self.itselftype) g.setselftype(self.objecttype, self.itselftype)
GeneratorGroup.add(self, g, dupcheck) GeneratorGroup.add(self, g, dupcheck)
def reference(self): def reference(self):
# In case we are referenced from a module # In case we are referenced from a module
pass pass
def setmodulename(self, name): def setmodulename(self, name):
self.modulename = name self.modulename = name
def generate(self): def generate(self):
# XXX This should use long strings and %(varname)s substitution! # XXX This should use long strings and %(varname)s substitution!
OutHeader2("Object type " + self.name) OutHeader2("Object type " + self.name)
sf = self.static and "static " sf = self.static and "static "
Output("%sPyTypeObject %s;", sf, self.typename) Output("%sPyTypeObject %s;", sf, self.typename)
Output() Output()
Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))",
self.prefix, self.typename, self.typename) self.prefix, self.typename, self.typename)
Output() Output()
Output("typedef struct %s {", self.objecttype) Output("typedef struct %s {", self.objecttype)
IndentLevel() IndentLevel()
Output("PyObject_HEAD") Output("PyObject_HEAD")
self.outputStructMembers() self.outputStructMembers()
DedentLevel() DedentLevel()
Output("} %s;", self.objecttype) Output("} %s;", self.objecttype)
self.outputNew() self.outputNew()
self.outputConvert() self.outputConvert()
self.outputDealloc() self.outputDealloc()
GeneratorGroup.generate(self) GeneratorGroup.generate(self)
Output() Output()
self.outputMethodChain() self.outputMethodChain()
self.outputGetattr() self.outputGetattr()
self.outputSetattr() self.outputSetattr()
self.outputCompare() self.outputCompare()
self.outputRepr() self.outputRepr()
self.outputHash() self.outputHash()
self.outputPEP253Hooks() self.outputPEP253Hooks()
self.outputTypeObject() self.outputTypeObject()
OutHeader2("End object type " + self.name) OutHeader2("End object type " + self.name)
def outputMethodChain(self): def outputMethodChain(self):
Output("%sPyMethodChain %s_chain = { %s_methods, %s };", Output("%sPyMethodChain %s_chain = { %s_methods, %s };",
self.static, self.prefix, self.prefix, self.basechain) self.static, self.prefix, self.prefix, self.basechain)
def outputStructMembers(self): def outputStructMembers(self):
Output("%s ob_itself;", self.itselftype) Output("%s ob_itself;", self.itselftype)
def outputNew(self): def outputNew(self):
Output() Output()
Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix, Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix,
self.itselftype, self.argref) self.itselftype, self.argref)
OutLbrace() OutLbrace()
Output("%s *it;", self.objecttype) Output("%s *it;", self.objecttype)
self.outputCheckNewArg() self.outputCheckNewArg()
Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
Output("if (it == NULL) return NULL;") Output("if (it == NULL) return NULL;")
if self.basetype: if self.basetype:
Output("/* XXXX Should we tp_init or tp_new our basetype? */") Output("/* XXXX Should we tp_init or tp_new our basetype? */")
self.outputInitStructMembers() self.outputInitStructMembers()
Output("return (PyObject *)it;") Output("return (PyObject *)it;")
OutRbrace() OutRbrace()
def outputInitStructMembers(self): def outputInitStructMembers(self):
Output("it->ob_itself = %sitself;", self.argref) Output("it->ob_itself = %sitself;", self.argref)
def outputCheckNewArg(self): def outputCheckNewArg(self):
"Override this method to apply additional checks/conversions" "Override this method to apply additional checks/conversions"
def outputConvert(self): def outputConvert(self):
Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix,
self.itselftype) self.itselftype)
OutLbrace() OutLbrace()
self.outputCheckConvertArg() self.outputCheckConvertArg()
Output("if (!%s_Check(v))", self.prefix) Output("if (!%s_Check(v))", self.prefix)
OutLbrace() OutLbrace()
Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name) Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name)
Output("return 0;") Output("return 0;")
OutRbrace() OutRbrace()
Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype) Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype)
Output("return 1;") Output("return 1;")
OutRbrace() OutRbrace()
def outputCheckConvertArg(self): def outputCheckConvertArg(self):
"Override this method to apply additional conversions" "Override this method to apply additional conversions"
def outputDealloc(self): def outputDealloc(self):
Output() Output()
Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype) Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype)
OutLbrace() OutLbrace()
self.outputCleanupStructMembers() self.outputCleanupStructMembers()
if self.basetype: if self.basetype:
Output("%s.tp_dealloc(self)", self.basetype) Output("%s.tp_dealloc(self)", self.basetype)
elif hasattr(self, 'output_tp_free'): elif hasattr(self, 'output_tp_free'):
# This is a new-style object with tp_free slot # This is a new-style object with tp_free slot
Output("self->ob_type->tp_free((PyObject *)self);") Output("self->ob_type->tp_free((PyObject *)self);")
else: else:
Output("PyObject_Free((PyObject *)self);") Output("PyObject_Free((PyObject *)self);")
OutRbrace() OutRbrace()
def outputCleanupStructMembers(self): def outputCleanupStructMembers(self):
self.outputFreeIt("self->ob_itself") self.outputFreeIt("self->ob_itself")
def outputFreeIt(self, name): def outputFreeIt(self, name):
Output("/* Cleanup of %s goes here */", name) Output("/* Cleanup of %s goes here */", name)
def outputGetattr(self): def outputGetattr(self):
Output() Output()
Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype) Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype)
OutLbrace() OutLbrace()
self.outputGetattrBody() self.outputGetattrBody()
OutRbrace() OutRbrace()
def outputGetattrBody(self): def outputGetattrBody(self):
self.outputGetattrHook() self.outputGetattrHook()
Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);", Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);",
self.prefix) self.prefix)
def outputGetattrHook(self): def outputGetattrHook(self):
pass pass
def outputSetattr(self): def outputSetattr(self):
Output() Output()
Output("#define %s_setattr NULL", self.prefix) Output("#define %s_setattr NULL", self.prefix)
def outputCompare(self): def outputCompare(self):
Output() Output()
Output("#define %s_compare NULL", self.prefix) Output("#define %s_compare NULL", self.prefix)
def outputRepr(self): def outputRepr(self):
Output() Output()
Output("#define %s_repr NULL", self.prefix) Output("#define %s_repr NULL", self.prefix)
def outputHash(self): def outputHash(self):
Output() Output()
Output("#define %s_hash NULL", self.prefix) Output("#define %s_hash NULL", self.prefix)
def outputTypeObject(self): def outputTypeObject(self):
sf = self.static and "static " sf = self.static and "static "
Output() Output()
Output("%sPyTypeObject %s = {", sf, self.typename) Output("%sPyTypeObject %s = {", sf, self.typename)
IndentLevel() IndentLevel()
Output("PyObject_HEAD_INIT(NULL)") Output("PyObject_HEAD_INIT(NULL)")
Output("0, /*ob_size*/") Output("0, /*ob_size*/")
if self.modulename: if self.modulename:
Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name)
else: else:
Output("\"%s\", /*tp_name*/", self.name) Output("\"%s\", /*tp_name*/", self.name)
Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
Output("0, /*tp_itemsize*/") Output("0, /*tp_itemsize*/")
Output("/* methods */") Output("/* methods */")
Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
Output("0, /*tp_print*/") Output("0, /*tp_print*/")
Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix) Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix)
Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix) Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix)
Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix)
Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix)
Output("(PyNumberMethods *)0, /* tp_as_number */") Output("(PyNumberMethods *)0, /* tp_as_number */")
Output("(PySequenceMethods *)0, /* tp_as_sequence */") Output("(PySequenceMethods *)0, /* tp_as_sequence */")
Output("(PyMappingMethods *)0, /* tp_as_mapping */") Output("(PyMappingMethods *)0, /* tp_as_mapping */")
Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix)
DedentLevel() DedentLevel()
Output("};") Output("};")
def outputTypeObjectInitializer(self): def outputTypeObjectInitializer(self):
Output("""%s.ob_type = &PyType_Type;""", self.typename) Output("""%s.ob_type = &PyType_Type;""", self.typename)
if self.basetype: if self.basetype:
Output("%s.tp_base = %s;", self.typename, self.basetype) Output("%s.tp_base = %s;", self.typename, self.basetype)
Output("if (PyType_Ready(&%s) < 0) return;", self.typename) Output("if (PyType_Ready(&%s) < 0) return;", self.typename)
Output("""Py_INCREF(&%s);""", self.typename) Output("""Py_INCREF(&%s);""", self.typename)
Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename); Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename);
Output("/* Backward-compatible name */") Output("/* Backward-compatible name */")
Output("""Py_INCREF(&%s);""", self.typename); Output("""Py_INCREF(&%s);""", self.typename);
Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename); Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename);
def outputPEP253Hooks(self): def outputPEP253Hooks(self):
pass pass
class PEP252Mixin: class PEP252Mixin:
getsetlist = [] getsetlist = []
def assertions(self): def assertions(self):
# Check that various things aren't overridden. If they are it could # Check that various things aren't overridden. If they are it could
# signify a bgen-client that has been partially converted to PEP252. # signify a bgen-client that has been partially converted to PEP252.
assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func
assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func
assert self.outputGetattrBody == None assert self.outputGetattrBody == None
assert self.outputGetattrHook == None assert self.outputGetattrHook == None
assert self.basechain == "NULL" assert self.basechain == "NULL"
def outputGetattr(self): def outputGetattr(self):
pass pass
outputGetattrBody = None outputGetattrBody = None
outputGetattrHook = None outputGetattrHook = None
def outputSetattr(self): def outputSetattr(self):
pass pass
def outputMethodChain(self): def outputMethodChain(self):
# This is a good place to output the getters and setters # This is a good place to output the getters and setters
self.outputGetSetList() self.outputGetSetList()
def outputHook(self, name): def outputHook(self, name):
methodname = "outputHook_" + name methodname = "outputHook_" + name
if hasattr(self, methodname): if hasattr(self, methodname):
func = getattr(self, methodname) func = getattr(self, methodname)
func() func()
else: else:
Output("0, /*%s*/", name) Output("0, /*%s*/", name)
def outputTypeObject(self): def outputTypeObject(self):
sf = self.static and "static " sf = self.static and "static "
Output() Output()
Output("%sPyTypeObject %s = {", sf, self.typename) Output("%sPyTypeObject %s = {", sf, self.typename)
IndentLevel() IndentLevel()
Output("PyObject_HEAD_INIT(NULL)") Output("PyObject_HEAD_INIT(NULL)")
Output("0, /*ob_size*/") Output("0, /*ob_size*/")
if self.modulename: if self.modulename:
Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name)
else: else:
Output("\"%s\", /*tp_name*/", self.name) Output("\"%s\", /*tp_name*/", self.name)
Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) Output("sizeof(%s), /*tp_basicsize*/", self.objecttype)
Output("0, /*tp_itemsize*/") Output("0, /*tp_itemsize*/")
Output("/* methods */") Output("/* methods */")
Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix)
Output("0, /*tp_print*/") Output("0, /*tp_print*/")
Output("(getattrfunc)0, /*tp_getattr*/") Output("(getattrfunc)0, /*tp_getattr*/")
Output("(setattrfunc)0, /*tp_setattr*/") Output("(setattrfunc)0, /*tp_setattr*/")
Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix)
Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix)
Output("(PyNumberMethods *)0, /* tp_as_number */") Output("(PyNumberMethods *)0, /* tp_as_number */")
Output("(PySequenceMethods *)0, /* tp_as_sequence */") Output("(PySequenceMethods *)0, /* tp_as_sequence */")
Output("(PyMappingMethods *)0, /* tp_as_mapping */") Output("(PyMappingMethods *)0, /* tp_as_mapping */")
Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix)
self.outputHook("tp_call") self.outputHook("tp_call")
Output("0, /*tp_str*/") Output("0, /*tp_str*/")
Output("PyObject_GenericGetAttr, /*tp_getattro*/") Output("PyObject_GenericGetAttr, /*tp_getattro*/")
Output("PyObject_GenericSetAttr, /*tp_setattro */") Output("PyObject_GenericSetAttr, /*tp_setattro */")
self.outputHook("tp_as_buffer") self.outputHook("tp_as_buffer")
Output("%s, /* tp_flags */", self.tp_flags) Output("%s, /* tp_flags */", self.tp_flags)
self.outputHook("tp_doc") self.outputHook("tp_doc")
self.outputHook("tp_traverse") self.outputHook("tp_traverse")
self.outputHook("tp_clear") self.outputHook("tp_clear")
self.outputHook("tp_richcompare") self.outputHook("tp_richcompare")
self.outputHook("tp_weaklistoffset") self.outputHook("tp_weaklistoffset")
self.outputHook("tp_iter") self.outputHook("tp_iter")
self.outputHook("tp_iternext") self.outputHook("tp_iternext")
Output("%s_methods, /* tp_methods */", self.prefix) Output("%s_methods, /* tp_methods */", self.prefix)
self.outputHook("tp_members") self.outputHook("tp_members")
Output("%s_getsetlist, /*tp_getset*/", self.prefix) Output("%s_getsetlist, /*tp_getset*/", self.prefix)
self.outputHook("tp_base") self.outputHook("tp_base")
self.outputHook("tp_dict") self.outputHook("tp_dict")
self.outputHook("tp_descr_get") self.outputHook("tp_descr_get")
self.outputHook("tp_descr_set") self.outputHook("tp_descr_set")
self.outputHook("tp_dictoffset") self.outputHook("tp_dictoffset")
self.outputHook("tp_init") self.outputHook("tp_init")
self.outputHook("tp_alloc") self.outputHook("tp_alloc")
self.outputHook("tp_new") self.outputHook("tp_new")
self.outputHook("tp_free") self.outputHook("tp_free")
DedentLevel() DedentLevel()
Output("};") Output("};")
def outputGetSetList(self): def outputGetSetList(self):
if self.getsetlist: if self.getsetlist:
for name, get, set, doc in self.getsetlist: for name, get, set, doc in self.getsetlist:
if get: if get:
self.outputGetter(name, get) self.outputGetter(name, get)
else: else:
Output("#define %s_get_%s NULL", self.prefix, name) Output("#define %s_get_%s NULL", self.prefix, name)
Output() Output()
if set: if set:
self.outputSetter(name, set) self.outputSetter(name, set)
else: else:
Output("#define %s_set_%s NULL", self.prefix, name) Output("#define %s_set_%s NULL", self.prefix, name)
Output() Output()
Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix) Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix)
IndentLevel() IndentLevel()
for name, get, set, doc in self.getsetlist: for name, get, set, doc in self.getsetlist:
if doc: if doc:
doc = '"' + doc + '"' doc = '"' + doc + '"'
else: else:
doc = "NULL" doc = "NULL"
Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},", Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},",
name, self.prefix, name, self.prefix, name, doc) name, self.prefix, name, self.prefix, name, doc)
Output("{NULL, NULL, NULL, NULL},") Output("{NULL, NULL, NULL, NULL},")
DedentLevel() DedentLevel()
Output("};") Output("};")
else: else:
Output("#define %s_getsetlist NULL", self.prefix) Output("#define %s_getsetlist NULL", self.prefix)
Output() Output()
def outputGetter(self, name, code): def outputGetter(self, name, code):
Output("static PyObject *%s_get_%s(%s *self, void *closure)", Output("static PyObject *%s_get_%s(%s *self, void *closure)",
self.prefix, name, self.objecttype) self.prefix, name, self.objecttype)
OutLbrace() OutLbrace()
Output(code) Output(code)
OutRbrace() OutRbrace()
Output() Output()
def outputSetter(self, name, code): def outputSetter(self, name, code):
Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)", Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)",
self.prefix, name, self.objecttype) self.prefix, name, self.objecttype)
OutLbrace() OutLbrace()
Output(code) Output(code)
Output("return 0;") Output("return 0;")
OutRbrace() OutRbrace()
Output() Output()
class PEP253Mixin(PEP252Mixin): class PEP253Mixin(PEP252Mixin):
tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE" tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"
def outputHook_tp_init(self): def outputHook_tp_init(self):
Output("%s_tp_init, /* tp_init */", self.prefix) Output("%s_tp_init, /* tp_init */", self.prefix)
def outputHook_tp_alloc(self): def outputHook_tp_alloc(self):
Output("%s_tp_alloc, /* tp_alloc */", self.prefix) Output("%s_tp_alloc, /* tp_alloc */", self.prefix)
def outputHook_tp_new(self): def outputHook_tp_new(self):
Output("%s_tp_new, /* tp_new */", self.prefix) Output("%s_tp_new, /* tp_new */", self.prefix)
def outputHook_tp_free(self): def outputHook_tp_free(self):
Output("%s_tp_free, /* tp_free */", self.prefix) Output("%s_tp_free, /* tp_free */", self.prefix)
output_tp_initBody = None output_tp_initBody = None
def output_tp_init(self): def output_tp_init(self):
if self.output_tp_initBody: if self.output_tp_initBody:
Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix) Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix)
OutLbrace() OutLbrace()
self.output_tp_initBody() self.output_tp_initBody()
OutRbrace() OutRbrace()
else: else:
Output("#define %s_tp_init 0", self.prefix) Output("#define %s_tp_init 0", self.prefix)
Output() Output()
output_tp_allocBody = None output_tp_allocBody = None
def output_tp_alloc(self): def output_tp_alloc(self):
if self.output_tp_allocBody: if self.output_tp_allocBody:
Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)", Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)",
self.prefix) self.prefix)
OutLbrace() OutLbrace()
self.output_tp_allocBody() self.output_tp_allocBody()
OutRbrace() OutRbrace()
else: else:
Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix) Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix)
Output() Output()
def output_tp_newBody(self): def output_tp_newBody(self):
Output("PyObject *self;"); Output("PyObject *self;");
Output("%s itself;", self.itselftype); Output("%s itself;", self.itselftype);
Output("char *kw[] = {\"itself\", 0};") Output("char *kw[] = {\"itself\", 0};")
Output() Output()
Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;",
self.prefix); self.prefix);
Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;")
Output("((%s *)self)->ob_itself = itself;", self.objecttype) Output("((%s *)self)->ob_itself = itself;", self.objecttype)
Output("return self;") Output("return self;")
def output_tp_new(self): def output_tp_new(self):
if self.output_tp_newBody: if self.output_tp_newBody:
Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix) Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix)
OutLbrace() OutLbrace()
self.output_tp_newBody() self.output_tp_newBody()
OutRbrace() OutRbrace()
else: else:
Output("#define %s_tp_new PyType_GenericNew", self.prefix) Output("#define %s_tp_new PyType_GenericNew", self.prefix)
Output() Output()
output_tp_freeBody = None output_tp_freeBody = None
def output_tp_free(self): def output_tp_free(self):
if self.output_tp_freeBody: if self.output_tp_freeBody:
Output("static void %s_tp_free(PyObject *self)", self.prefix) Output("static void %s_tp_free(PyObject *self)", self.prefix)
OutLbrace() OutLbrace()
self.output_tp_freeBody() self.output_tp_freeBody()
OutRbrace() OutRbrace()
else: else:
Output("#define %s_tp_free PyObject_Del", self.prefix) Output("#define %s_tp_free PyObject_Del", self.prefix)
Output() Output()
def outputPEP253Hooks(self): def outputPEP253Hooks(self):
self.output_tp_init() self.output_tp_init()
self.output_tp_alloc() self.output_tp_alloc()
self.output_tp_new() self.output_tp_new()
self.output_tp_free() self.output_tp_free()
class GlobalObjectDefinition(ObjectDefinition): class GlobalObjectDefinition(ObjectDefinition):
"""Like ObjectDefinition but exports some parts. """Like ObjectDefinition but exports some parts.
XXX Should also somehow generate a .h file for them. XXX Should also somehow generate a .h file for them.
""" """
def __init__(self, name, prefix = None, itselftype = None): def __init__(self, name, prefix = None, itselftype = None):
ObjectDefinition.__init__(self, name, prefix or name, itselftype or name) ObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
self.static = "" self.static = ""
class ObjectIdentityMixin: class ObjectIdentityMixin:
"""A mixin class for objects that makes the identity of ob_itself """A mixin class for objects that makes the identity of ob_itself
govern comparisons and dictionary lookups. Useful if the C object can govern comparisons and dictionary lookups. Useful if the C object can
be returned by library calls and it is difficult (or impossible) to find be returned by library calls and it is difficult (or impossible) to find
the corresponding Python objects. With this you can create Python object the corresponding Python objects. With this you can create Python object
wrappers on the fly""" wrappers on the fly"""
def outputCompare(self): def outputCompare(self):
Output() Output()
Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype,
self.objecttype) self.objecttype)
OutLbrace() OutLbrace()
Output("unsigned long v, w;") Output("unsigned long v, w;")
Output() Output()
Output("if (!%s_Check((PyObject *)other))", self.prefix) Output("if (!%s_Check((PyObject *)other))", self.prefix)
OutLbrace() OutLbrace()
Output("v=(unsigned long)self;") Output("v=(unsigned long)self;")
Output("w=(unsigned long)other;") Output("w=(unsigned long)other;")
OutRbrace() OutRbrace()
Output("else") Output("else")
OutLbrace() OutLbrace()
Output("v=(unsigned long)self->ob_itself;") Output("v=(unsigned long)self->ob_itself;")
Output("w=(unsigned long)other->ob_itself;") Output("w=(unsigned long)other->ob_itself;")
OutRbrace() OutRbrace()
Output("if( v < w ) return -1;") Output("if( v < w ) return -1;")
Output("if( v > w ) return 1;") Output("if( v > w ) return 1;")
Output("return 0;") Output("return 0;")
OutRbrace() OutRbrace()
def outputHash(self): def outputHash(self):
Output() Output()
Output("static long %s_hash(%s *self)", self.prefix, self.objecttype) Output("static long %s_hash(%s *self)", self.prefix, self.objecttype)
OutLbrace() OutLbrace()
Output("return (long)self->ob_itself;") Output("return (long)self->ob_itself;")
OutRbrace() OutRbrace()

View file

@ -9,211 +9,211 @@ SetOutputFileName() to change the output file.
_NeedClose = 0 _NeedClose = 0
def SetOutputFile(file = None, needclose = 0): def SetOutputFile(file = None, needclose = 0):
"""Call this with an open file object to make it the output file. """Call this with an open file object to make it the output file.
Call it without arguments to close the current file (if necessary) Call it without arguments to close the current file (if necessary)
and reset it to sys.stdout. and reset it to sys.stdout.
If the second argument is true, the new file will be explicitly closed If the second argument is true, the new file will be explicitly closed
on a subsequence call. on a subsequence call.
""" """
global _File, _NeedClose global _File, _NeedClose
if _NeedClose: if _NeedClose:
tmp = _File tmp = _File
_NeedClose = 0 _NeedClose = 0
_File = None _File = None
tmp.close() tmp.close()
if file is None: if file is None:
import sys import sys
file = sys.stdout file = sys.stdout
_File = file _File = file
_NeedClose = file and needclose _NeedClose = file and needclose
def SetOutputFileName(filename = None): def SetOutputFileName(filename = None):
"""Call this with a filename to make it the output file. """Call this with a filename to make it the output file.
Call it without arguments to close the current file (if necessary) Call it without arguments to close the current file (if necessary)
and reset it to sys.stdout. and reset it to sys.stdout.
""" """
SetOutputFile() SetOutputFile()
if filename: if filename:
SetOutputFile(open(filename, 'w'), 1) SetOutputFile(open(filename, 'w'), 1)
SetOutputFile() # Initialize _File SetOutputFile() # Initialize _File
_Level = 0 # Indentation level _Level = 0 # Indentation level
def GetLevel(): def GetLevel():
"""Return the current indentation level.""" """Return the current indentation level."""
return _Level return _Level
def SetLevel(level): def SetLevel(level):
"""Set the current indentation level. """Set the current indentation level.
This does no type or range checking -- use at own risk. This does no type or range checking -- use at own risk.
""" """
global _Level global _Level
_Level = level _Level = level
def Output(format = "", *args): def Output(format = "", *args):
VaOutput(format, args) VaOutput(format, args)
def VaOutput(format, args): def VaOutput(format, args):
"""Call this with a format string and and argument tuple for the format. """Call this with a format string and and argument tuple for the format.
A newline is always added. Each line in the output is indented A newline is always added. Each line in the output is indented
to the proper indentation level -- even if the result of the to the proper indentation level -- even if the result of the
format expansion contains embedded newlines. Exception: lines format expansion contains embedded newlines. Exception: lines
beginning with '#' are not indented -- these are assumed to be beginning with '#' are not indented -- these are assumed to be
C preprprocessor lines. C preprprocessor lines.
""" """
text = format % args text = format % args
if _Level > 0: if _Level > 0:
indent = '\t' * _Level indent = '\t' * _Level
lines = text.split('\n') lines = text.split('\n')
for i in range(len(lines)): for i in range(len(lines)):
if lines[i] and lines[i][0] != '#': if lines[i] and lines[i][0] != '#':
lines[i] = indent + lines[i] lines[i] = indent + lines[i]
text = '\n'.join(lines) text = '\n'.join(lines)
_File.write(text + '\n') _File.write(text + '\n')
def IndentLevel(by = 1): def IndentLevel(by = 1):
"""Increment the indentation level by one. """Increment the indentation level by one.
When called with an argument, adds it to the indentation level. When called with an argument, adds it to the indentation level.
""" """
global _Level global _Level
if _Level+by < 0: if _Level+by < 0:
raise Error, "indentation underflow (internal error)" raise Error, "indentation underflow (internal error)"
_Level = _Level + by _Level = _Level + by
def DedentLevel(by = 1): def DedentLevel(by = 1):
"""Decrement the indentation level by one. """Decrement the indentation level by one.
When called with an argument, subtracts it from the indentation level. When called with an argument, subtracts it from the indentation level.
""" """
IndentLevel(-by) IndentLevel(-by)
def OutIndent(format = "", *args): def OutIndent(format = "", *args):
"""Combine Output() followed by IndentLevel(). """Combine Output() followed by IndentLevel().
If no text is given, acts like lone IndentLevel(). If no text is given, acts like lone IndentLevel().
""" """
if format: VaOutput(format, args) if format: VaOutput(format, args)
IndentLevel() IndentLevel()
def OutDedent(format = "", *args): def OutDedent(format = "", *args):
"""Combine Output() followed by DedentLevel(). """Combine Output() followed by DedentLevel().
If no text is given, acts like loneDedentLevel(). If no text is given, acts like loneDedentLevel().
""" """
if format: VaOutput(format, args) if format: VaOutput(format, args)
DedentLevel() DedentLevel()
def OutLbrace(format = "", *args): def OutLbrace(format = "", *args):
"""Like Output, but add a '{' and increase the indentation level. """Like Output, but add a '{' and increase the indentation level.
If no text is given a lone '{' is output. If no text is given a lone '{' is output.
""" """
if format: if format:
format = format + " {" format = format + " {"
else: else:
format = "{" format = "{"
VaOutput(format, args) VaOutput(format, args)
IndentLevel() IndentLevel()
def OutRbrace(): def OutRbrace():
"""Decrease the indentation level and output a '}' on a line by itself.""" """Decrease the indentation level and output a '}' on a line by itself."""
DedentLevel() DedentLevel()
Output("}") Output("}")
def OutHeader(text, dash): def OutHeader(text, dash):
"""Output a header comment using a given dash character.""" """Output a header comment using a given dash character."""
n = 64 - len(text) n = 64 - len(text)
Output() Output()
Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2)) Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2))
Output() Output()
def OutHeader1(text): def OutHeader1(text):
"""Output a level 1 header comment (uses '=' dashes).""" """Output a level 1 header comment (uses '=' dashes)."""
OutHeader(text, "=") OutHeader(text, "=")
def OutHeader2(text): def OutHeader2(text):
"""Output a level 2 header comment (uses '-' dashes).""" """Output a level 2 header comment (uses '-' dashes)."""
OutHeader(text, "-") OutHeader(text, "-")
def Out(text): def Out(text):
"""Output multiline text that's internally indented. """Output multiline text that's internally indented.
Pass this a multiline character string. The whitespace before the Pass this a multiline character string. The whitespace before the
first nonblank line of the string will be subtracted from all lines. first nonblank line of the string will be subtracted from all lines.
The lines are then output using Output(), but without interpretation The lines are then output using Output(), but without interpretation
of formatting (if you need formatting you can do it before the call). of formatting (if you need formatting you can do it before the call).
Recommended use: Recommended use:
Out(''' Out('''
int main(argc, argv) int main(argc, argv)
int argc; int argc;
char *argv; char *argv;
{ {
printf("Hello, world\\n"); printf("Hello, world\\n");
exit(0); exit(0);
} }
''') ''')
Caveat: the indentation must be consistent -- if you use three tabs Caveat: the indentation must be consistent -- if you use three tabs
in the first line, (up to) three tabs are removed from following lines, in the first line, (up to) three tabs are removed from following lines,
but a line beginning with 24 spaces is not trimmed at all. Don't use but a line beginning with 24 spaces is not trimmed at all. Don't use
this as a feature. this as a feature.
""" """
# (Don't you love using triple quotes *inside* triple quotes? :-) # (Don't you love using triple quotes *inside* triple quotes? :-)
lines = text.split('\n') lines = text.split('\n')
indent = "" indent = ""
for line in lines: for line in lines:
if line.strip(): if line.strip():
for c in line: for c in line:
if not c.isspace(): if not c.isspace():
break break
indent = indent + c indent = indent + c
break break
n = len(indent) n = len(indent)
for line in lines: for line in lines:
if line[:n] == indent: if line[:n] == indent:
line = line[n:] line = line[n:]
else: else:
for c in indent: for c in indent:
if line[:1] <> c: break if line[:1] <> c: break
line = line[1:] line = line[1:]
VaOutput("%s", line) VaOutput("%s", line)
def _test(): def _test():
"""Test program. Run when the module is run as a script.""" """Test program. Run when the module is run as a script."""
OutHeader1("test bgenOutput") OutHeader1("test bgenOutput")
Out(""" Out("""
#include <Python.h> #include <Python.h>
#include <stdio.h> #include <stdio.h>
main(argc, argv) main(argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
int i; int i;
""") """)
IndentLevel() IndentLevel()
Output("""\ Output("""\
/* Here are a few comment lines. /* Here are a few comment lines.
Just to test indenting multiple lines. Just to test indenting multiple lines.
End of the comment lines. */ End of the comment lines. */
""") """)
Output("for (i = 0; i < argc; i++)") Output("for (i = 0; i < argc; i++)")
OutLbrace() OutLbrace()
Output('printf("argv[%%d] = %%s\\n", i, argv[i]);') Output('printf("argv[%%d] = %%s\\n", i, argv[i]);')
OutRbrace() OutRbrace()
Output("exit(0)") Output("exit(0)")
OutRbrace() OutRbrace()
OutHeader2("end test") OutHeader2("end test")
if __name__ == '__main__': if __name__ == '__main__':
_test() _test()

View file

@ -6,54 +6,54 @@ from bgenBuffer import FixedInputBufferType, FixedOutputBufferType
class StackOutputBufferType(FixedOutputBufferType): class StackOutputBufferType(FixedOutputBufferType):
"""Fixed output buffer allocated on the stack -- passed as (buffer, size). """Fixed output buffer allocated on the stack -- passed as (buffer, size).
Instantiate with the buffer size as parameter. Instantiate with the buffer size as parameter.
""" """
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, %s" % (name, self.size) return "%s__out__, %s" % (name, self.size)
class VarStackOutputBufferType(StackOutputBufferType): class VarStackOutputBufferType(StackOutputBufferType):
"""Output buffer allocated on the stack -- passed as (buffer, &size). """Output buffer allocated on the stack -- passed as (buffer, &size).
Instantiate with the buffer size as parameter. Instantiate with the buffer size as parameter.
""" """
def declareSize(self, name): def declareSize(self, name):
Output("int %s__len__ = %s;", name, self.size) Output("int %s__len__ = %s;", name, self.size)
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, &%s__len__" % (name, name) return "%s__out__, &%s__len__" % (name, name)
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s__out__, (int)%s__len__" % (name, name) return "%s__out__, (int)%s__len__" % (name, name)
class VarVarStackOutputBufferType(VarStackOutputBufferType): class VarVarStackOutputBufferType(VarStackOutputBufferType):
"""Output buffer allocated on the stack -- passed as (buffer, size, &size). """Output buffer allocated on the stack -- passed as (buffer, size, &size).
Instantiate with the buffer size as parameter. Instantiate with the buffer size as parameter.
""" """
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, %s__len__, &%s__len__" % (name, name, name) return "%s__out__, %s__len__, &%s__len__" % (name, name, name)
class ReturnVarStackOutputBufferType(VarStackOutputBufferType): class ReturnVarStackOutputBufferType(VarStackOutputBufferType):
"""Output buffer allocated on the stack -- passed as (buffer, size) -> size. """Output buffer allocated on the stack -- passed as (buffer, size) -> size.
Instantiate with the buffer size as parameter. Instantiate with the buffer size as parameter.
The function's return value is the size. The function's return value is the size.
(XXX Should have a way to suppress returning it separately, too.) (XXX Should have a way to suppress returning it separately, too.)
""" """
def passOutput(self, name): def passOutput(self, name):
return "%s__out__, %s__len__" % (name, name) return "%s__out__, %s__len__" % (name, name)
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s__out__, (int)_rv" % name return "%s__out__, (int)_rv" % name

View file

@ -8,57 +8,57 @@ from bgenHeapBuffer import HeapOutputBufferType
class StringBufferMixIn: class StringBufferMixIn:
"""Mix-in class to create various string buffer types. """Mix-in class to create various string buffer types.
Strings are character arrays terminated by a null byte. Strings are character arrays terminated by a null byte.
(For input, this is also covered by stringptr.) (For input, this is also covered by stringptr.)
For output, there are again three variants: For output, there are again three variants:
- Fixed: size is a constant given in the documentation; or - Fixed: size is a constant given in the documentation; or
- Stack: size is passed to the C function but we decide on a size at - Stack: size is passed to the C function but we decide on a size at
code generation time so we can still allocate on the heap); or code generation time so we can still allocate on the heap); or
- Heap: size is passed to the C function and we let the Python caller - Heap: size is passed to the C function and we let the Python caller
pass a size. pass a size.
(Note that this doesn't cover output parameters in which a string (Note that this doesn't cover output parameters in which a string
pointer is returned. These are actually easier (no allocation) but far pointer is returned. These are actually easier (no allocation) but far
less common. I'll write the classes when there is demand.) less common. I'll write the classes when there is demand.)
""" """
def declareSize(self, name): def declareSize(self, name):
pass pass
def getargsFormat(self): def getargsFormat(self):
return "s" return "s"
def getargsArgs(self, name): def getargsArgs(self, name):
return "&%s__in__" % name return "&%s__in__" % name
def mkvalueFormat(self): def mkvalueFormat(self):
return "s" return "s"
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s__out__" % name return "%s__out__" % name
class FixedOutputStringType(StringBufferMixIn, FixedOutputBufferType): class FixedOutputStringType(StringBufferMixIn, FixedOutputBufferType):
"""Null-terminated output string -- passed without size. """Null-terminated output string -- passed without size.
Instantiate with buffer size as parameter. Instantiate with buffer size as parameter.
""" """
class StackOutputStringType(StringBufferMixIn, StackOutputBufferType): class StackOutputStringType(StringBufferMixIn, StackOutputBufferType):
"""Null-terminated output string -- passed as (buffer, size). """Null-terminated output string -- passed as (buffer, size).
Instantiate with buffer size as parameter. Instantiate with buffer size as parameter.
""" """
class HeapOutputStringType(StringBufferMixIn, HeapOutputBufferType): class HeapOutputStringType(StringBufferMixIn, HeapOutputBufferType):
"""Null-terminated output string -- passed as (buffer, size). """Null-terminated output string -- passed as (buffer, size).
Instantiate without parameters. Instantiate without parameters.
Call from Python with buffer size. Call from Python with buffer size.
""" """

View file

@ -6,105 +6,105 @@ from bgenOutput import *
class Type: class Type:
"""Define the various things you can do with a C type. """Define the various things you can do with a C type.
Most methods are intended to be extended or overridden. Most methods are intended to be extended or overridden.
""" """
def __init__(self, typeName, fmt): def __init__(self, typeName, fmt):
"""Call with the C name and getargs format for the type. """Call with the C name and getargs format for the type.
Example: int = Type("int", "i") Example: int = Type("int", "i")
""" """
self.typeName = typeName self.typeName = typeName
self.fmt = fmt self.fmt = fmt
def declare(self, name): def declare(self, name):
"""Declare a variable of the type with a given name. """Declare a variable of the type with a given name.
Example: int.declare('spam') prints "int spam;" Example: int.declare('spam') prints "int spam;"
""" """
Output("%s %s;", self.typeName, name) Output("%s %s;", self.typeName, name)
def getargs(self): def getargs(self):
return self.getargsFormat(), self.getargsArgs() return self.getargsFormat(), self.getargsArgs()
def getargsFormat(self): def getargsFormat(self):
"""Return the format for this type for use with [new]getargs(). """Return the format for this type for use with [new]getargs().
Example: int.getargsFormat() returns the string "i". Example: int.getargsFormat() returns the string "i".
""" """
return self.fmt return self.fmt
def getargsArgs(self, name): def getargsArgs(self, name):
"""Return an argument for use with [new]getargs(). """Return an argument for use with [new]getargs().
Example: int.getargsArgs("spam") returns the string "&spam". Example: int.getargsArgs("spam") returns the string "&spam".
""" """
return "&" + name return "&" + name
def getargsCheck(self, name): def getargsCheck(self, name):
"""Perform any needed post-[new]getargs() checks. """Perform any needed post-[new]getargs() checks.
This is type-dependent; the default does not check for errors. This is type-dependent; the default does not check for errors.
An example would be a check for a maximum string length.""" An example would be a check for a maximum string length."""
def passInput(self, name): def passInput(self, name):
"""Return an argument for passing a variable into a call. """Return an argument for passing a variable into a call.
Example: int.passInput("spam") returns the string "spam". Example: int.passInput("spam") returns the string "spam".
""" """
return name return name
def passOutput(self, name): def passOutput(self, name):
"""Return an argument for returning a variable out of a call. """Return an argument for returning a variable out of a call.
Example: int.passOutput("spam") returns the string "&spam". Example: int.passOutput("spam") returns the string "&spam".
""" """
return "&" + name return "&" + name
def errorCheck(self, name): def errorCheck(self, name):
"""Check for an error returned in the variable. """Check for an error returned in the variable.
This is type-dependent; the default does not check for errors. This is type-dependent; the default does not check for errors.
An example would be a check for a NULL pointer. An example would be a check for a NULL pointer.
If an error is found, the generated routine should If an error is found, the generated routine should
raise an exception and return NULL. raise an exception and return NULL.
XXX There should be a way to add error clean-up code. XXX There should be a way to add error clean-up code.
""" """
Output("/* XXX no err check for %s %s */", self.typeName, name) Output("/* XXX no err check for %s %s */", self.typeName, name)
def mkvalue(self): def mkvalue(self):
return self.mkvalueFormat(), self.mkvalueArgs() return self.mkvalueFormat(), self.mkvalueArgs()
def mkvalueFormat(self): def mkvalueFormat(self):
"""Return the format for this type for use with mkvalue(). """Return the format for this type for use with mkvalue().
This is normally the same as getargsFormat() but it is This is normally the same as getargsFormat() but it is
a separate function to allow future divergence. a separate function to allow future divergence.
""" """
return self.getargsFormat() return self.getargsFormat()
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
"""Return an argument for use with mkvalue(). """Return an argument for use with mkvalue().
Example: int.mkvalueArgs("spam") returns the string "spam". Example: int.mkvalueArgs("spam") returns the string "spam".
""" """
return name return name
def cleanup(self, name): def cleanup(self, name):
"""Clean up if necessary. """Clean up if necessary.
This is normally empty; it may deallocate buffers etc. This is normally empty; it may deallocate buffers etc.
""" """
pass pass
class ByAddressType(Type): class ByAddressType(Type):
"Simple type that is also passed by address for input" "Simple type that is also passed by address for input"
def passInput(self, name): def passInput(self, name):
return "&%s" % name return "&%s" % name
@ -112,25 +112,25 @@ class ByAddressType(Type):
class InputOnlyMixIn: class InputOnlyMixIn:
"Mix-in class to boobytrap passOutput" "Mix-in class to boobytrap passOutput"
def passOutput(self, name): def passOutput(self, name):
raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName
class InputOnlyType(InputOnlyMixIn, Type): class InputOnlyType(InputOnlyMixIn, Type):
"Same as Type, but only usable for input parameters -- passOutput is boobytrapped" "Same as Type, but only usable for input parameters -- passOutput is boobytrapped"
class OutputOnlyMixIn: class OutputOnlyMixIn:
"Mix-in class to boobytrap passInput" "Mix-in class to boobytrap passInput"
def passInput(self, name): def passInput(self, name):
raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName
class OutputOnlyType(OutputOnlyMixIn, Type): class OutputOnlyType(OutputOnlyMixIn, Type):
"Same as Type, but only usable for output parameters -- passInput is boobytrapped" "Same as Type, but only usable for output parameters -- passInput is boobytrapped"
# A modest collection of standard C types. # A modest collection of standard C types.
@ -160,99 +160,99 @@ stringobjectptr = Type("PyStringObject*", "S")
class FakeType(InputOnlyType): class FakeType(InputOnlyType):
"""A type that is not represented in the Python version of the interface. """A type that is not represented in the Python version of the interface.
Instantiate with a value to pass in the call. Instantiate with a value to pass in the call.
""" """
def __init__(self, substitute): def __init__(self, substitute):
self.substitute = substitute self.substitute = substitute
self.typeName = None # Don't show this argument in __doc__ string self.typeName = None # Don't show this argument in __doc__ string
def declare(self, name): def declare(self, name):
pass pass
def getargsFormat(self): def getargsFormat(self):
return "" return ""
def getargsArgs(self, name): def getargsArgs(self, name):
return None return None
def passInput(self, name): def passInput(self, name):
return self.substitute return self.substitute
class OpaqueType(Type): class OpaqueType(Type):
"""A type represented by an opaque object type, always passed by address. """A type represented by an opaque object type, always passed by address.
Instantiate with the type name and the names of the new and convert procs. Instantiate with the type name and the names of the new and convert procs.
If fewer than three arguments are passed, the second argument is used If fewer than three arguments are passed, the second argument is used
to derive the new and convert procs by appending _New and _Convert; it to derive the new and convert procs by appending _New and _Convert; it
defaults to the first argument. defaults to the first argument.
""" """
def __init__(self, name, arg = None, extra = None): def __init__(self, name, arg = None, extra = None):
self.typeName = name self.typeName = name
if extra is None: if extra is None:
# Two arguments (name, usetype) or one (name) # Two arguments (name, usetype) or one (name)
arg = arg or name arg = arg or name
self.new = arg + '_New' self.new = arg + '_New'
self.convert = arg + '_Convert' self.convert = arg + '_Convert'
else: else:
# Three arguments (name, new, convert) # Three arguments (name, new, convert)
self.new = arg self.new = arg
self.convert = extra self.convert = extra
def getargsFormat(self): def getargsFormat(self):
return "O&" return "O&"
def getargsArgs(self, name): def getargsArgs(self, name):
return "%s, &%s" % (self.convert, name) return "%s, &%s" % (self.convert, name)
def passInput(self, name): def passInput(self, name):
return "&%s" % name return "&%s" % name
def mkvalueFormat(self): def mkvalueFormat(self):
return "O&" return "O&"
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s, &%s" % (self.new, name) return "%s, &%s" % (self.new, name)
class OpaqueByValueType(OpaqueType): class OpaqueByValueType(OpaqueType):
"""A type represented by an opaque object type, on input passed BY VALUE. """A type represented by an opaque object type, on input passed BY VALUE.
Instantiate with the type name, and optionally an object type name whose Instantiate with the type name, and optionally an object type name whose
New/Convert functions will be used. New/Convert functions will be used.
""" """
def passInput(self, name): def passInput(self, name):
return name return name
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s, %s" % (self.new, name) return "%s, %s" % (self.new, name)
class OpaqueByValueStructType(OpaqueByValueType): class OpaqueByValueStructType(OpaqueByValueType):
"""Similar to OpaqueByValueType, but we also pass this to mkvalue by """Similar to OpaqueByValueType, but we also pass this to mkvalue by
address, in stead of by value. address, in stead of by value.
""" """
def mkvalueArgs(self, name): def mkvalueArgs(self, name):
return "%s, &%s" % (self.new, name) return "%s, &%s" % (self.new, name)
class OpaqueArrayType(OpaqueByValueType): class OpaqueArrayType(OpaqueByValueType):
"""A type represented by an opaque object type, with ARRAY passing semantics. """A type represented by an opaque object type, with ARRAY passing semantics.
Instantiate with the type name, and optional an object type name whose Instantiate with the type name, and optional an object type name whose
New/Convert functions will be used. New/Convert functions will be used.
""" """
def getargsArgs(self, name): def getargsArgs(self, name):
return "%s, %s" % (self.convert, name) return "%s, %s" % (self.convert, name)
def passOutput(self, name): def passOutput(self, name):
return name return name

View file

@ -17,72 +17,72 @@ ErrorMode = 16+OutMode # this is an error status -- turn it into an exception
class Variable: class Variable:
"""A Variable holds a type, a name, a transfer mode and flags. """A Variable holds a type, a name, a transfer mode and flags.
Most of its methods call the correponding type method with the Most of its methods call the correponding type method with the
variable name. variable name.
""" """
def __init__(self, type, name = None, flags = InMode): def __init__(self, type, name = None, flags = InMode):
"""Call with a type, a name and flags. """Call with a type, a name and flags.
If name is None, it muse be set later. If name is None, it muse be set later.
flags defaults to InMode. flags defaults to InMode.
""" """
self.type = type self.type = type
self.name = name self.name = name
self.flags = flags self.flags = flags
self.mode = flags & ModeMask self.mode = flags & ModeMask
def declare(self): def declare(self):
"""Declare the variable if necessary. """Declare the variable if necessary.
If it is "self", it is not declared. If it is "self", it is not declared.
""" """
if self.flags != SelfMode: if self.flags != SelfMode:
self.type.declare(self.name) self.type.declare(self.name)
def getargsFormat(self): def getargsFormat(self):
"""Call the type's getargsFormatmethod.""" """Call the type's getargsFormatmethod."""
return self.type.getargsFormat() return self.type.getargsFormat()
def getargsArgs(self): def getargsArgs(self):
"""Call the type's getargsArgsmethod.""" """Call the type's getargsArgsmethod."""
return self.type.getargsArgs(self.name) return self.type.getargsArgs(self.name)
def getargsCheck(self): def getargsCheck(self):
return self.type.getargsCheck(self.name) return self.type.getargsCheck(self.name)
def passArgument(self): def passArgument(self):
"""Return the string required to pass the variable as argument. """Return the string required to pass the variable as argument.
For "in" arguments, return the variable name. For "in" arguments, return the variable name.
For "out" and "in out" arguments, For "out" and "in out" arguments,
return its name prefixed with "&". return its name prefixed with "&".
""" """
if self.mode == InMode: if self.mode == InMode:
return self.type.passInput(self.name) return self.type.passInput(self.name)
if self.mode in (OutMode, InOutMode): if self.mode in (OutMode, InOutMode):
return self.type.passOutput(self.name) return self.type.passOutput(self.name)
# XXX Shouldn't get here # XXX Shouldn't get here
return "/*mode?*/" + self.type.passInput(self.name) return "/*mode?*/" + self.type.passInput(self.name)
def errorCheck(self): def errorCheck(self):
"""Check for an error if necessary. """Check for an error if necessary.
This only generates code if the variable's mode is ErrorMode. This only generates code if the variable's mode is ErrorMode.
""" """
if self.flags == ErrorMode: if self.flags == ErrorMode:
self.type.errorCheck(self.name) self.type.errorCheck(self.name)
def mkvalueFormat (self): def mkvalueFormat (self):
"""Call the type's mkvalueFormat method.""" """Call the type's mkvalueFormat method."""
return self.type.mkvalueFormat() return self.type.mkvalueFormat()
def mkvalueArgs(self): def mkvalueArgs(self):
"""Call the type's mkvalueArgs method.""" """Call the type's mkvalueArgs method."""
return self.type.mkvalueArgs(self.name) return self.type.mkvalueArgs(self.name)
def cleanup(self): def cleanup(self):
"""Call the type's cleanup method.""" """Call the type's cleanup method."""
return self.type.cleanup(self.name) return self.type.cleanup(self.name)

View file

@ -52,7 +52,7 @@ FSRef = OpaqueByValueStructType("FSRef", "PyMac_BuildFSRef", "PyMac_GetFSRef")
# OSType and ResType: 4-byte character strings # OSType and ResType: 4-byte character strings
def OSTypeType(typename): def OSTypeType(typename):
return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType") return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType")
OSType = OSTypeType("OSType") OSType = OSTypeType("OSType")
ResType = OSTypeType("ResType") ResType = OSTypeType("ResType")
FourCharCode = OSTypeType("FourCharCode") FourCharCode = OSTypeType("FourCharCode")
@ -104,35 +104,35 @@ OptionalCFURLRef = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj")
# OSErr is special because it is turned into an exception # OSErr is special because it is turned into an exception
# (Could do this with less code using a variant of mkvalue("O&")?) # (Could do this with less code using a variant of mkvalue("O&")?)
class OSErrType(Type): class OSErrType(Type):
def errorCheck(self, name): def errorCheck(self, name):
Output("if (%s != noErr) return PyMac_Error(%s);", name, name) Output("if (%s != noErr) return PyMac_Error(%s);", name, name)
self.used = 1 self.used = 1
OSErr = OSErrType("OSErr", 'h') OSErr = OSErrType("OSErr", 'h')
OSStatus = OSErrType("OSStatus", 'l') OSStatus = OSErrType("OSStatus", 'l')
# Various buffer types # Various buffer types
InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len)
UcharInBuffer = VarInputBufferType('unsigned char', 'long', 'l') # (buf, len) UcharInBuffer = VarInputBufferType('unsigned char', 'long', 'l') # (buf, len)
OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len) OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len)
InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, len) InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, len)
VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len) VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len)
OutBuffer = HeapOutputBufferType('char', 'long', 'l') # (buf, len) OutBuffer = HeapOutputBufferType('char', 'long', 'l') # (buf, len)
VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len) VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len)
VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len) VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len)
# Unicode arguments sometimes have reversed len, buffer (don't understand why Apple did this...) # Unicode arguments sometimes have reversed len, buffer (don't understand why Apple did this...)
class VarUnicodeInputBufferType(VarInputBufferType): class VarUnicodeInputBufferType(VarInputBufferType):
def getargsFormat(self): def getargsFormat(self):
return "u#" return "u#"
class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType): class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType):
pass pass
UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l') UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l')
UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l') UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l')
UniChar_ptr = InputOnlyType("UniCharPtr", "u") UniChar_ptr = InputOnlyType("UniCharPtr", "u")
@ -151,9 +151,9 @@ includestuff = """
/* Macro to test whether a weak-loaded CFM function exists */ /* Macro to test whether a weak-loaded CFM function exists */
#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\\ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\\
PyErr_SetString(PyExc_NotImplementedError, \\ PyErr_SetString(PyExc_NotImplementedError, \\
"Not available in this shared library/OS version"); \\ "Not available in this shared library/OS version"); \\
return NULL; \\ return NULL; \\
}} while(0) }} while(0)
""" """
@ -173,23 +173,23 @@ initstuff = """
# This requires that the OSErr type (defined above) has a non-trivial # This requires that the OSErr type (defined above) has a non-trivial
# errorCheck method. # errorCheck method.
class OSErrMixIn: class OSErrMixIn:
"Mix-in class to treat OSErr/OSStatus return values special" "Mix-in class to treat OSErr/OSStatus return values special"
def makereturnvar(self): def makereturnvar(self):
if self.returntype.__class__ == OSErrType: if self.returntype.__class__ == OSErrType:
return Variable(self.returntype, "_err", ErrorMode) return Variable(self.returntype, "_err", ErrorMode)
else: else:
return Variable(self.returntype, "_rv", OutMode) return Variable(self.returntype, "_rv", OutMode)
class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass
class OSErrMethodGenerator(OSErrMixIn, MethodGenerator): pass class OSErrMethodGenerator(OSErrMixIn, MethodGenerator): pass
class WeakLinkMixIn: class WeakLinkMixIn:
"Mix-in to test the function actually exists (!= NULL) before calling" "Mix-in to test the function actually exists (!= NULL) before calling"
def precheck(self): def precheck(self):
Output('#ifndef %s', self.name) Output('#ifndef %s', self.name)
Output('PyMac_PRECHECK(%s);', self.name) Output('PyMac_PRECHECK(%s);', self.name)
Output('#endif') Output('#endif')
class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass
class WeakLinkMethodGenerator(WeakLinkMixIn, MethodGenerator): pass class WeakLinkMethodGenerator(WeakLinkMixIn, MethodGenerator): pass
@ -197,14 +197,14 @@ class OSErrWeakLinkFunctionGenerator(OSErrMixIn, WeakLinkMixIn, FunctionGenerato
class OSErrWeakLinkMethodGenerator(OSErrMixIn, WeakLinkMixIn, MethodGenerator): pass class OSErrWeakLinkMethodGenerator(OSErrMixIn, WeakLinkMixIn, MethodGenerator): pass
class MacModule(Module): class MacModule(Module):
"Subclass which gets the exception initializer from macglue.c" "Subclass which gets the exception initializer from macglue.c"
def exceptionInitializer(self): def exceptionInitializer(self):
return "PyMac_GetOSErrException()" return "PyMac_GetOSErrException()"
_SetOutputFileName = SetOutputFileName # Save original _SetOutputFileName = SetOutputFileName # Save original
def SetOutputFileName(file = None): def SetOutputFileName(file = None):
"Set the output file name and set its creator&type to CWIE&TEXT" "Set the output file name and set its creator&type to CWIE&TEXT"
_SetOutputFileName(file) _SetOutputFileName(file)
if file: if file:
import MacOS import MacOS
MacOS.SetCreatorAndType(file, 'CWIE', 'TEXT') MacOS.SetCreatorAndType(file, 'CWIE', 'TEXT')

File diff suppressed because it is too large Load diff