diff options
author | Jack Jansen <jack.jansen@cwi.nl> | 2003-01-19 21:53:57 (GMT) |
---|---|---|
committer | Jack Jansen <jack.jansen@cwi.nl> | 2003-01-19 21:53:57 (GMT) |
commit | 2cf08ab4c2ef9743b35e61414c978555e2c6815d (patch) | |
tree | a366fb5e447728555fac03e5eb6f209fa371e490 /Tools/bgen | |
parent | 28256f276e1d61d54301b874958fc78c26117c9e (diff) | |
download | cpython-2cf08ab4c2ef9743b35e61414c978555e2c6815d.zip cpython-2cf08ab4c2ef9743b35e61414c978555e2c6815d.tar.gz cpython-2cf08ab4c2ef9743b35e61414c978555e2c6815d.tar.bz2 |
Sigh, due to sloppiness on my part bgen has become pretty mixed up wrt. tabs
and spaces. Detabbed the lot.
Diffstat (limited to 'Tools/bgen')
-rw-r--r-- | Tools/bgen/bgen/bgenBuffer.py | 360 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenGenerator.py | 468 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenGeneratorGroup.py | 58 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenHeapBuffer.py | 134 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenModule.py | 168 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenObjectDefinition.py | 948 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenOutput.py | 326 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenStackBuffer.py | 56 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenStringBuffer.py | 78 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenType.py | 282 | ||||
-rw-r--r-- | Tools/bgen/bgen/bgenVariable.py | 138 | ||||
-rw-r--r-- | Tools/bgen/bgen/macsupport.py | 76 | ||||
-rw-r--r-- | Tools/bgen/bgen/scantools.py | 1244 |
13 files changed, 2168 insertions, 2168 deletions
diff --git a/Tools/bgen/bgen/bgenBuffer.py b/Tools/bgen/bgen/bgenBuffer.py index ee4a128..4b888d7 100644 --- a/Tools/bgen/bgen/bgenBuffer.py +++ b/Tools/bgen/bgen/bgenBuffer.py @@ -12,14 +12,14 @@ from bgenOutput import * # Map common types to their format characters type2format = { - 'long': 'l', - 'int': 'i', - 'short': 'h', - 'char': 'b', - 'unsigned long': 'l', - 'unsigned int': 'i', - 'unsigned short': 'h', - 'unsigned char': 'b', + 'long': 'l', + 'int': 'i', + 'short': 'h', + 'char': 'b', + 'unsigned long': 'l', + 'unsigned int': 'i', + 'unsigned short': 'h', + 'unsigned char': 'b', } @@ -27,238 +27,238 @@ type2format = { class FixedInputOutputBufferType(InputOnlyType): - - """Fixed buffer -- passed as (inbuffer, outbuffer).""" - - def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None): - self.typeName = "Buffer" - self.size = str(size) - self.datatype = datatype - self.sizetype = sizetype - self.sizeformat = sizeformat or type2format[sizetype] - self.label_needed = 0 - - def declare(self, name): - self.declareBuffer(name) - self.declareSize(name) - - def declareBuffer(self, name): - self.declareInputBuffer(name) - self.declareOutputBuffer(name) - - def declareInputBuffer(self, name): - Output("%s *%s__in__;", self.datatype, name) - - def declareOutputBuffer(self, name): - Output("%s %s__out__[%s];", self.datatype, name, self.size) - - def declareSize(self, name): - Output("%s %s__len__;", self.sizetype, name) - Output("int %s__in_len__;", name) - - def getargsFormat(self): - return "s#" - - def getargsArgs(self, name): - return "&%s__in__, &%s__in_len__" % (name, name) - - def getargsCheck(self, name): - Output("if (%s__in_len__ != %s)", name, self.size) - OutLbrace() - Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");', - self.size) - Output("goto %s__error__;", name) - self.label_needed = 1 - OutRbrace() - self.transferSize(name) - - def transferSize(self, name): - Output("%s__len__ = %s__in_len__;", name, name) - - def passOutput(self, name): - return "%s__in__, %s__out__" % (name, name) - - def mkvalueFormat(self): - return "s#" - - def mkvalueArgs(self, name): - return "%s__out__, (int)%s" % (name, self.size) - - def cleanup(self, name): - if self.label_needed: - DedentLevel() - Output(" %s__error__: ;", name) - IndentLevel() + + """Fixed buffer -- passed as (inbuffer, outbuffer).""" + + def __init__(self, size, datatype = 'char', sizetype = 'int', sizeformat = None): + self.typeName = "Buffer" + self.size = str(size) + self.datatype = datatype + self.sizetype = sizetype + self.sizeformat = sizeformat or type2format[sizetype] + self.label_needed = 0 + + def declare(self, name): + self.declareBuffer(name) + self.declareSize(name) + + def declareBuffer(self, name): + self.declareInputBuffer(name) + self.declareOutputBuffer(name) + + def declareInputBuffer(self, name): + Output("%s *%s__in__;", self.datatype, name) + + def declareOutputBuffer(self, name): + Output("%s %s__out__[%s];", self.datatype, name, self.size) + + def declareSize(self, name): + Output("%s %s__len__;", self.sizetype, name) + Output("int %s__in_len__;", name) + + def getargsFormat(self): + return "s#" + + def getargsArgs(self, name): + return "&%s__in__, &%s__in_len__" % (name, name) + + def getargsCheck(self, name): + Output("if (%s__in_len__ != %s)", name, self.size) + OutLbrace() + Output('PyErr_SetString(PyExc_TypeError, "buffer length should be %s");', + self.size) + Output("goto %s__error__;", name) + self.label_needed = 1 + OutRbrace() + self.transferSize(name) + + def transferSize(self, name): + Output("%s__len__ = %s__in_len__;", name, name) + + def passOutput(self, name): + return "%s__in__, %s__out__" % (name, name) + + def mkvalueFormat(self): + return "s#" + + def mkvalueArgs(self, name): + return "%s__out__, (int)%s" % (name, self.size) + + def cleanup(self, name): + if self.label_needed: + DedentLevel() + Output(" %s__error__: ;", name) + IndentLevel() class FixedCombinedInputOutputBufferType(FixedInputOutputBufferType): - - """Like fixed buffer -- but same parameter is input and output.""" - - def passOutput(self, name): - return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \ - (self.datatype, name, name, self.size) + + """Like fixed buffer -- but same parameter is input and output.""" + + def passOutput(self, name): + return "(%s *)memcpy(%s__out__, %s__in__, %s)" % \ + (self.datatype, name, name, self.size) class InputOnlyBufferMixIn(InputOnlyMixIn): - def declareOutputBuffer(self, name): - pass + def declareOutputBuffer(self, name): + pass class OutputOnlyBufferMixIn(OutputOnlyMixIn): - def declareInputBuffer(self, name): - pass + def declareInputBuffer(self, name): + pass class OptionalInputBufferMixIn: - - """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""" - - def getargsFormat(self): - return "z#" + + """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""" + + def getargsFormat(self): + return "z#" 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): - return "%s__in__" % name + def passInput(self, name): + return "%s__in__" % name class OptionalFixedInputBufferType(OptionalInputBufferMixIn, FixedInputBufferType): - pass + pass 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): - return "%s__out__" % name + def passOutput(self, name): + return "%s__out__" % name class VarInputBufferType(FixedInputBufferType): - """Variable size input buffer -- passed as (buffer, size). - - Instantiate without size parameter. - """ - - def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): - FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) - - def getargsCheck(self, name): - Output("%s__len__ = %s__in_len__;", name, name) - - def passInput(self, name): - return "%s__in__, %s__len__" % (name, name) - + """Variable size input buffer -- passed as (buffer, size). + + Instantiate without size parameter. + """ + + def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): + FixedInputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) + + def getargsCheck(self, name): + Output("%s__len__ = %s__in_len__;", name, name) + + def passInput(self, name): + return "%s__in__, %s__len__" % (name, name) + class ReverseInputBufferMixin: - """ Mixin for input buffers that are passed as (size, buffer) """ - - def passInput(self, name): - return "%s__len__, %s__in__" % (name, name) - + """ Mixin for input buffers that are passed as (size, buffer) """ + + def passInput(self, name): + return "%s__len__, %s__in__" % (name, name) + class OptionalVarInputBufferType(OptionalInputBufferMixIn, VarInputBufferType): - pass - + pass + # ----- PART 2: Structure buffers ----- class StructInputOutputBufferType(FixedInputOutputBufferType): - - """Structure buffer -- passed as a structure pointer. - - Instantiate with the struct type as parameter. - """ - - def __init__(self, type): - FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type) - self.typeName = self.type = type - - def declareInputBuffer(self, name): - Output("%s *%s__in__;", self.type, name) - - def declareSize(self, name): - Output("int %s__in_len__;", name) - - def declareOutputBuffer(self, name): - Output("%s %s__out__;", self.type, name) - - def getargsArgs(self, name): - return "(char **)&%s__in__, &%s__in_len__" % (name, name) - - def transferSize(self, name): - pass - - def passInput(self, name): - return "%s__in__" % name - - def passOutput(self, name): - return "%s__in__, &%s__out__" % (name, name) - - def mkvalueArgs(self, name): - return "(char *)&%s__out__, (int)%s" % (name, self.size) + + """Structure buffer -- passed as a structure pointer. + + Instantiate with the struct type as parameter. + """ + + def __init__(self, type): + FixedInputOutputBufferType.__init__(self, "sizeof(%s)" % type) + self.typeName = self.type = type + + def declareInputBuffer(self, name): + Output("%s *%s__in__;", self.type, name) + + def declareSize(self, name): + Output("int %s__in_len__;", name) + + def declareOutputBuffer(self, name): + Output("%s %s__out__;", self.type, name) + + def getargsArgs(self, name): + return "(char **)&%s__in__, &%s__in_len__" % (name, name) + + def transferSize(self, name): + pass + + def passInput(self, name): + return "%s__in__" % name + + def passOutput(self, name): + return "%s__in__, &%s__out__" % (name, name) + + def mkvalueArgs(self, name): + return "(char *)&%s__out__, (int)%s" % (name, self.size) class StructCombinedInputOutputBufferType(StructInputOutputBufferType): - """Like structure buffer -- but same parameter is input and output.""" - - def passOutput(self, name): - return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \ - (self.type, name, name, self.size) + """Like structure buffer -- but same parameter is input and output.""" + + def passOutput(self, name): + return "(%s *)memcpy((char *)%s__out__, (char *)%s__in__, %s)" % \ + (self.type, name, name, self.size) 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): - """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): - return "*%s__in__" % name + def passInput(self, name): + return "*%s__in__" % name 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. - """ - - def declareSize(self, name): - pass + Instantiate with the struct type as parameter. + """ + + def declareSize(self, name): + pass - def passOutput(self, name): - return "&%s__out__" % name + def passOutput(self, name): + return "&%s__out__" % name 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. - """ - - def declareSize(self, name): - pass + Instantiate with the struct type as parameter. + """ + + def declareSize(self, name): + pass - def passOutput(self, name): - return "%s__out__" % name + def passOutput(self, name): + return "%s__out__" % name diff --git a/Tools/bgen/bgen/bgenGenerator.py b/Tools/bgen/bgen/bgenGenerator.py index 1c19388..f3cdfce 100644 --- a/Tools/bgen/bgen/bgenGenerator.py +++ b/Tools/bgen/bgen/bgenGenerator.py @@ -15,260 +15,260 @@ INOUT = IN_OUT = "in-out" class BaseFunctionGenerator: - def __init__(self, name, condition=None): - if DEBUG: print "<--", name - self.name = name - self.prefix = name - self.objecttype = "PyObject" # Type of _self argument to function - self.condition = condition - - def setprefix(self, prefix): - self.prefix = prefix - - def generate(self): - if DEBUG: print "-->", self.name - if self.condition: - Output() - Output(self.condition) - self.functionheader() - self.functionbody() - self.functiontrailer() - if self.condition: - Output("#endif") - - def functionheader(self): - Output() - Output("static PyObject *%s_%s(%s *_self, PyObject *_args)", - self.prefix, self.name, self.objecttype) - OutLbrace() - Output("PyObject *_res = NULL;") - - def functionbody(self): - Output("/* XXX To be provided */") - - def functiontrailer(self): - OutRbrace() - - def reference(self, name = None): - if name is None: - name = self.name - docstring = self.docstring() - if self.condition: - Output() - Output(self.condition) - Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name) - Output(" PyDoc_STR(%s)},", stringify(docstring)) - if self.condition: - Output("#endif") - - def docstring(self): - return None - - def __cmp__(self, other): - if not hasattr(other, 'name'): - return cmp(id(self), id(other)) - return cmp(self.name, other.name) + def __init__(self, name, condition=None): + if DEBUG: print "<--", name + self.name = name + self.prefix = name + self.objecttype = "PyObject" # Type of _self argument to function + self.condition = condition + + def setprefix(self, prefix): + self.prefix = prefix + + def generate(self): + if DEBUG: print "-->", self.name + if self.condition: + Output() + Output(self.condition) + self.functionheader() + self.functionbody() + self.functiontrailer() + if self.condition: + Output("#endif") + + def functionheader(self): + Output() + Output("static PyObject *%s_%s(%s *_self, PyObject *_args)", + self.prefix, self.name, self.objecttype) + OutLbrace() + Output("PyObject *_res = NULL;") + + def functionbody(self): + Output("/* XXX To be provided */") + + def functiontrailer(self): + OutRbrace() + + def reference(self, name = None): + if name is None: + name = self.name + docstring = self.docstring() + if self.condition: + Output() + Output(self.condition) + Output("{\"%s\", (PyCFunction)%s_%s, 1,", name, self.prefix, self.name) + Output(" PyDoc_STR(%s)},", stringify(docstring)) + if self.condition: + Output("#endif") + + def docstring(self): + return None + + def __cmp__(self, other): + if not hasattr(other, 'name'): + return cmp(id(self), id(other)) + return cmp(self.name, other.name) _stringify_map = {'\n': '\\n', '\t': '\\t', '\r': '\\r', '\b': '\\b', '\e': '\\e', '\a': '\\a', '\f': '\\f', '"': '\\"'} def stringify(str): - if str is None: return "NULL" - res = '"' - map = _stringify_map - for c in str: - if map.has_key(c): res = res + map[c] - elif ' ' <= c <= '~': res = res + c - else: res = res + '\\%03o' % ord(c) - res = res + '"' - return res + if str is None: return "NULL" + res = '"' + map = _stringify_map + for c in str: + if map.has_key(c): res = res + map[c] + elif ' ' <= c <= '~': res = res + c + else: res = res + '\\%03o' % ord(c) + res = res + '"' + return res class ManualGenerator(BaseFunctionGenerator): - def __init__(self, name, body, condition=None): - BaseFunctionGenerator.__init__(self, name, condition=condition) - self.body = body + def __init__(self, name, body, condition=None): + BaseFunctionGenerator.__init__(self, name, condition=condition) + self.body = body - def functionbody(self): - Output("%s", self.body) - - def setselftype(self, selftype, itselftype): - self.objecttype = selftype - self.itselftype = itselftype + def functionbody(self): + Output("%s", self.body) + + def setselftype(self, selftype, itselftype): + self.objecttype = selftype + self.itselftype = itselftype class FunctionGenerator(BaseFunctionGenerator): - def __init__(self, returntype, name, *argumentList, **conditionlist): - BaseFunctionGenerator.__init__(self, name, **conditionlist) - self.returntype = returntype - self.argumentList = [] - self.setreturnvar() - self.parseArgumentList(argumentList) - self.prefix = "XXX" # Will be changed by setprefix() call - self.itselftype = None # Type of _self->ob_itself, if defined - - def setreturnvar(self): - if self.returntype: - self.rv = self.makereturnvar() - self.argumentList.append(self.rv) - else: - self.rv = None - - def makereturnvar(self): - return Variable(self.returntype, "_rv", OutMode) - - def setselftype(self, selftype, itselftype): - self.objecttype = selftype - self.itselftype = itselftype - - def parseArgumentList(self, argumentList): - iarg = 0 - for type, name, mode in argumentList: - iarg = iarg + 1 - if name is None: name = "_arg%d" % iarg - arg = Variable(type, name, mode) - self.argumentList.append(arg) - - def docstring(self): - input = [] - output = [] - for arg in self.argumentList: - if arg.flags == ErrorMode or arg.flags == SelfMode: - continue - if arg.type == None: - str = 'void' - else: - if hasattr(arg.type, 'typeName'): - typeName = arg.type.typeName - if typeName is None: # Suppressed type - continue - else: - typeName = "?" - print "Nameless type", arg.type - - str = typeName + ' ' + arg.name - if arg.mode in (InMode, InOutMode): - input.append(str) - if arg.mode in (InOutMode, OutMode): - output.append(str) - if not input: - instr = "()" - else: - instr = "(%s)" % ", ".join(input) - if not output or output == ["void"]: - outstr = "None" - else: - outstr = "(%s)" % ", ".join(output) - return instr + " -> " + outstr - - def functionbody(self): - self.declarations() - self.precheck() - self.getargs() - self.callit() - self.checkit() - self.returnvalue() - - def declarations(self): - for arg in self.argumentList: - arg.declare() - - def getargs(self): - fmt = "" - lst = "" - sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(") - for arg in self.argumentList: - if arg.flags == SelfMode: - continue - if arg.mode in (InMode, InOutMode): - fmt = fmt + arg.getargsFormat() - args = arg.getargsArgs() - if args: - lst = lst + sep + args - Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst) - IndentLevel() - Output("return NULL;") - DedentLevel() - for arg in self.argumentList: - if arg.flags == SelfMode: - continue - if arg.mode in (InMode, InOutMode): - arg.getargsCheck() - - def precheck(self): - pass - - def callit(self): - args = "" - if self.rv: - s = "%s = %s(" % (self.rv.name, self.name) - else: - s = "%s(" % self.name - sep = ",\n" + ' '*len(s) - for arg in self.argumentList: - if arg is self.rv: - continue - s = arg.passArgument() - if args: s = sep + s - args = args + s - if self.rv: - Output("%s = %s(%s);", - self.rv.name, self.name, args) - else: - Output("%s(%s);", self.name, args) - - def checkit(self): - for arg in self.argumentList: - arg.errorCheck() - - def returnvalue(self): - fmt = "" - lst = "" - sep = ",\n" + ' '*len("return Py_BuildValue(") - for arg in self.argumentList: - if not arg: continue - if arg.flags == ErrorMode: continue - if arg.mode in (OutMode, InOutMode): - fmt = fmt + arg.mkvalueFormat() - lst = lst + sep + arg.mkvalueArgs() - if fmt == "": - Output("Py_INCREF(Py_None);") - Output("_res = Py_None;"); - else: - Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst) - tmp = self.argumentList[:] - tmp.reverse() - for arg in tmp: - if not arg: continue - arg.cleanup() - Output("return _res;") + def __init__(self, returntype, name, *argumentList, **conditionlist): + BaseFunctionGenerator.__init__(self, name, **conditionlist) + self.returntype = returntype + self.argumentList = [] + self.setreturnvar() + self.parseArgumentList(argumentList) + self.prefix = "XXX" # Will be changed by setprefix() call + self.itselftype = None # Type of _self->ob_itself, if defined + + def setreturnvar(self): + if self.returntype: + self.rv = self.makereturnvar() + self.argumentList.append(self.rv) + else: + self.rv = None + + def makereturnvar(self): + return Variable(self.returntype, "_rv", OutMode) + + def setselftype(self, selftype, itselftype): + self.objecttype = selftype + self.itselftype = itselftype + + def parseArgumentList(self, argumentList): + iarg = 0 + for type, name, mode in argumentList: + iarg = iarg + 1 + if name is None: name = "_arg%d" % iarg + arg = Variable(type, name, mode) + self.argumentList.append(arg) + + def docstring(self): + input = [] + output = [] + for arg in self.argumentList: + if arg.flags == ErrorMode or arg.flags == SelfMode: + continue + if arg.type == None: + str = 'void' + else: + if hasattr(arg.type, 'typeName'): + typeName = arg.type.typeName + if typeName is None: # Suppressed type + continue + else: + typeName = "?" + print "Nameless type", arg.type + + str = typeName + ' ' + arg.name + if arg.mode in (InMode, InOutMode): + input.append(str) + if arg.mode in (InOutMode, OutMode): + output.append(str) + if not input: + instr = "()" + else: + instr = "(%s)" % ", ".join(input) + if not output or output == ["void"]: + outstr = "None" + else: + outstr = "(%s)" % ", ".join(output) + return instr + " -> " + outstr + + def functionbody(self): + self.declarations() + self.precheck() + self.getargs() + self.callit() + self.checkit() + self.returnvalue() + + def declarations(self): + for arg in self.argumentList: + arg.declare() + + def getargs(self): + fmt = "" + lst = "" + sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(") + for arg in self.argumentList: + if arg.flags == SelfMode: + continue + if arg.mode in (InMode, InOutMode): + fmt = fmt + arg.getargsFormat() + args = arg.getargsArgs() + if args: + lst = lst + sep + args + Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst) + IndentLevel() + Output("return NULL;") + DedentLevel() + for arg in self.argumentList: + if arg.flags == SelfMode: + continue + if arg.mode in (InMode, InOutMode): + arg.getargsCheck() + + def precheck(self): + pass + + def callit(self): + args = "" + if self.rv: + s = "%s = %s(" % (self.rv.name, self.name) + else: + s = "%s(" % self.name + sep = ",\n" + ' '*len(s) + for arg in self.argumentList: + if arg is self.rv: + continue + s = arg.passArgument() + if args: s = sep + s + args = args + s + if self.rv: + Output("%s = %s(%s);", + self.rv.name, self.name, args) + else: + Output("%s(%s);", self.name, args) + + def checkit(self): + for arg in self.argumentList: + arg.errorCheck() + + def returnvalue(self): + fmt = "" + lst = "" + sep = ",\n" + ' '*len("return Py_BuildValue(") + for arg in self.argumentList: + if not arg: continue + if arg.flags == ErrorMode: continue + if arg.mode in (OutMode, InOutMode): + fmt = fmt + arg.mkvalueFormat() + lst = lst + sep + arg.mkvalueArgs() + if fmt == "": + Output("Py_INCREF(Py_None);") + Output("_res = Py_None;"); + else: + Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst) + tmp = self.argumentList[:] + tmp.reverse() + for arg in tmp: + if not arg: continue + arg.cleanup() + Output("return _res;") class MethodGenerator(FunctionGenerator): - def parseArgumentList(self, args): - a0, args = args[0], args[1:] - t0, n0, m0 = a0 - if m0 != InMode: - raise ValueError, "method's 'self' must be 'InMode'" - self.itself = Variable(t0, "_self->ob_itself", SelfMode) - self.argumentList.append(self.itself) - FunctionGenerator.parseArgumentList(self, args) + def parseArgumentList(self, args): + a0, args = args[0], args[1:] + t0, n0, m0 = a0 + if m0 != InMode: + raise ValueError, "method's 'self' must be 'InMode'" + self.itself = Variable(t0, "_self->ob_itself", SelfMode) + self.argumentList.append(self.itself) + FunctionGenerator.parseArgumentList(self, args) def _test(): - void = None - eggs = FunctionGenerator(void, "eggs", - (stringptr, 'cmd', InMode), - (int, 'x', InMode), - (double, 'y', InOutMode), - (int, 'status', ErrorMode), - ) - eggs.setprefix("spam") - print "/* START */" - eggs.generate() + void = None + eggs = FunctionGenerator(void, "eggs", + (stringptr, 'cmd', InMode), + (int, 'x', InMode), + (double, 'y', InOutMode), + (int, 'status', ErrorMode), + ) + eggs.setprefix("spam") + print "/* START */" + eggs.generate() if __name__ == "__main__": - _test() + _test() diff --git a/Tools/bgen/bgen/bgenGeneratorGroup.py b/Tools/bgen/bgen/bgenGeneratorGroup.py index 784bf69..d82ab53 100644 --- a/Tools/bgen/bgen/bgenGeneratorGroup.py +++ b/Tools/bgen/bgen/bgenGeneratorGroup.py @@ -2,39 +2,39 @@ from bgenOutput import * class GeneratorGroup: - def __init__(self, prefix): - self.prefix = prefix - self.generators = [] + def __init__(self, prefix): + self.prefix = prefix + self.generators = [] - def add(self, g, dupcheck=0): - if dupcheck: - if g in self.generators: - print 'DUP', g.name - return - g.setprefix(self.prefix) - self.generators.append(g) + def add(self, g, dupcheck=0): + if dupcheck: + if g in self.generators: + print 'DUP', g.name + return + g.setprefix(self.prefix) + self.generators.append(g) - def generate(self): - for g in self.generators: - g.generate() - Output() - Output("static PyMethodDef %s_methods[] = {", self.prefix) - IndentLevel() - for g in self.generators: - g.reference() - Output("{NULL, NULL, 0}") - DedentLevel() - Output("};") + def generate(self): + for g in self.generators: + g.generate() + Output() + Output("static PyMethodDef %s_methods[] = {", self.prefix) + IndentLevel() + for g in self.generators: + g.reference() + Output("{NULL, NULL, 0}") + DedentLevel() + Output("};") def _test(): - void = None - from bgenGenerator import FunctionGenerator - group = GeneratorGroup("spam") - eggs = FunctionGenerator(void, "eggs") - group.add(eggs) - print "/* START */" - group.generate() + void = None + from bgenGenerator import FunctionGenerator + group = GeneratorGroup("spam") + eggs = FunctionGenerator(void, "eggs") + group.add(eggs) + print "/* START */" + group.generate() if __name__ == "__main__": - _test() + _test() diff --git a/Tools/bgen/bgen/bgenHeapBuffer.py b/Tools/bgen/bgen/bgenHeapBuffer.py index 1b16d55..9bfc5a1 100644 --- a/Tools/bgen/bgen/bgenHeapBuffer.py +++ b/Tools/bgen/bgen/bgenHeapBuffer.py @@ -7,105 +7,105 @@ from bgenBuffer import 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. - Call from Python with input buffer. - """ + Instantiate without parameters. + Call from Python with input buffer. + """ - def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): - FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) + def __init__(self, datatype = 'char', sizetype = 'int', sizeformat = None): + FixedInputOutputBufferType.__init__(self, "0", datatype, sizetype, sizeformat) - def declareOutputBuffer(self, name): - Output("%s *%s__out__;", self.datatype, name) + def declareOutputBuffer(self, name): + Output("%s *%s__out__;", self.datatype, name) - def getargsCheck(self, name): - Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name) - OutLbrace() - Output('PyErr_NoMemory();') - Output("goto %s__error__;", name) - self.label_needed = 1 - OutRbrace() - Output("%s__len__ = %s__in_len__;", name, name) + def getargsCheck(self, name): + Output("if ((%s__out__ = malloc(%s__in_len__)) == NULL)", name, name) + OutLbrace() + Output('PyErr_NoMemory();') + Output("goto %s__error__;", name) + self.label_needed = 1 + OutRbrace() + Output("%s__len__ = %s__in_len__;", name, name) - def passOutput(self, name): - return "%s__in__, %s__out__, (%s)%s__len__" % \ - (name, name, self.sizetype, name) + def passOutput(self, name): + return "%s__in__, %s__out__, (%s)%s__len__" % \ + (name, name, self.sizetype, name) - def mkvalueArgs(self, name): - return "%s__out__, (int)%s__len__" % (name, name) + def mkvalueArgs(self, name): + return "%s__out__, (int)%s__len__" % (name, name) - def cleanup(self, name): - Output("free(%s__out__);", name) - FixedInputOutputBufferType.cleanup(self, name) + def cleanup(self, name): + Output("free(%s__out__);", name) + FixedInputOutputBufferType.cleanup(self, name) class VarHeapInputOutputBufferType(HeapInputOutputBufferType): - """same as base class, but passed as (inbuffer, outbuffer, &size)""" - - def passOutput(self, name): - return "%s__in__, %s__out__, &%s__len__" % (name, name, name) + """same as base class, but passed as (inbuffer, outbuffer, &size)""" + + def passOutput(self, name): + return "%s__in__, %s__out__, &%s__len__" % (name, name, name) class HeapCombinedInputOutputBufferType(HeapInputOutputBufferType): - """same as base class, but passed as (inoutbuffer, size)""" - - def passOutput(self, name): - return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \ - (self.datatype, name, name, name) + """same as base class, but passed as (inoutbuffer, size)""" + + def passOutput(self, name): + return "(%s *)memcpy(%s__out__, %s__in__, %s__len__)" % \ + (self.datatype, name, name, name) class VarHeapCombinedInputOutputBufferType(HeapInputOutputBufferType): - """same as base class, but passed as (inoutbuffer, &size)""" - - def passOutput(self, name): - return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \ - (self.datatype, name, name, name) + """same as base class, but passed as (inoutbuffer, &size)""" + + def passOutput(self, name): + return "(%s *)memcpy(%s__out__, %s__in__, &%s__len__)" % \ + (self.datatype, name, name, name) class HeapOutputBufferType(OutputOnlyMixIn, HeapInputOutputBufferType): - """Output buffer allocated on the heap -- passed as (buffer, size). - - Instantiate without parameters. - Call from Python with buffer size. - """ - - def declareInputBuffer(self, name): - pass - - def getargsFormat(self): - return "i" - - def getargsArgs(self, name): - return "&%s__in_len__" % name - - def passOutput(self, name): - return "%s__out__, %s__len__" % (name, name) + """Output buffer allocated on the heap -- passed as (buffer, size). + + Instantiate without parameters. + Call from Python with buffer size. + """ + + def declareInputBuffer(self, name): + pass + + def getargsFormat(self): + return "i" + + def getargsArgs(self, name): + return "&%s__in_len__" % name + + def passOutput(self, name): + return "%s__out__, %s__len__" % (name, name) 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. - Call from Python with buffer size. - """ + Instantiate without parameters. + Call from Python with buffer size. + """ - def passOutput(self, name): - return "%s__out__, &%s__len__" % (name, name) + def passOutput(self, name): + return "%s__out__, &%s__len__" % (name, name) 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. - Call from Python with buffer size. - """ + Instantiate without parameters. + Call from Python with buffer size. + """ - def passOutput(self, name): - return "%s__out__, %s__len__, &%s__len__" % (name, name, name) + def passOutput(self, name): + return "%s__out__, %s__len__, &%s__len__" % (name, name, name) diff --git a/Tools/bgen/bgen/bgenModule.py b/Tools/bgen/bgen/bgenModule.py index 1a182a7..3e26b16 100644 --- a/Tools/bgen/bgen/bgenModule.py +++ b/Tools/bgen/bgen/bgenModule.py @@ -3,92 +3,92 @@ from bgenGeneratorGroup import GeneratorGroup class Module(GeneratorGroup): - def __init__(self, name, prefix = None, - includestuff = None, - finalstuff = None, - initstuff = None, - variablestuff = None, - longname = None): - GeneratorGroup.__init__(self, prefix or name) - self.name = name - if longname: - self.longname = longname - else: - self.longname = name - self.includestuff = includestuff - self.initstuff = initstuff - self.finalstuff = finalstuff - self.variablestuff = variablestuff - self.typeobjects = [] - - def addobject(self, od): - self.generators.append(od) - self.typeobjects.append(od) - od.setmodulename(self.longname) - - def generate(self): - OutHeader1("Module " + self.name) - Output("#include \"Python.h\"") - Output() - - if self.includestuff: - Output() - Output("%s", self.includestuff) - - self.declareModuleVariables() - - GeneratorGroup.generate(self) - - if self.finalstuff: - Output() - Output("%s", self.finalstuff) - - Output() - Output("void init%s(void)", self.name) - OutLbrace() - Output("PyObject *m;") - Output("PyObject *d;") - Output() - - if self.initstuff: - Output("%s", self.initstuff) - Output() - - Output("m = Py_InitModule(\"%s\", %s_methods);", - self.name, self.prefix) - Output("d = PyModule_GetDict(m);") - self.createModuleVariables() - OutRbrace() - OutHeader1("End module " + self.name) - - def declareModuleVariables(self): - self.errorname = self.prefix + "_Error" - Output("static PyObject *%s;", self.errorname) - - def createModuleVariables(self): - Output("""%s = %s;""", self.errorname, self.exceptionInitializer()) - Output("""if (%s == NULL ||""", self.errorname) - Output(""" PyDict_SetItemString(d, "Error", %s) != 0)""", - self.errorname) - IndentLevel() - Output("""return;""") - DedentLevel() - for tp in self.typeobjects: - tp.outputTypeObjectInitializer() - if self.variablestuff: - Output("%s", self.variablestuff) - Output() - - def exceptionInitializer(self): - return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name + def __init__(self, name, prefix = None, + includestuff = None, + finalstuff = None, + initstuff = None, + variablestuff = None, + longname = None): + GeneratorGroup.__init__(self, prefix or name) + self.name = name + if longname: + self.longname = longname + else: + self.longname = name + self.includestuff = includestuff + self.initstuff = initstuff + self.finalstuff = finalstuff + self.variablestuff = variablestuff + self.typeobjects = [] + + def addobject(self, od): + self.generators.append(od) + self.typeobjects.append(od) + od.setmodulename(self.longname) + + def generate(self): + OutHeader1("Module " + self.name) + Output("#include \"Python.h\"") + Output() + + if self.includestuff: + Output() + Output("%s", self.includestuff) + + self.declareModuleVariables() + + GeneratorGroup.generate(self) + + if self.finalstuff: + Output() + Output("%s", self.finalstuff) + + Output() + Output("void init%s(void)", self.name) + OutLbrace() + Output("PyObject *m;") + Output("PyObject *d;") + Output() + + if self.initstuff: + Output("%s", self.initstuff) + Output() + + Output("m = Py_InitModule(\"%s\", %s_methods);", + self.name, self.prefix) + Output("d = PyModule_GetDict(m);") + self.createModuleVariables() + OutRbrace() + OutHeader1("End module " + self.name) + + def declareModuleVariables(self): + self.errorname = self.prefix + "_Error" + Output("static PyObject *%s;", self.errorname) + + def createModuleVariables(self): + Output("""%s = %s;""", self.errorname, self.exceptionInitializer()) + Output("""if (%s == NULL ||""", self.errorname) + Output(""" PyDict_SetItemString(d, "Error", %s) != 0)""", + self.errorname) + IndentLevel() + Output("""return;""") + DedentLevel() + for tp in self.typeobjects: + tp.outputTypeObjectInitializer() + if self.variablestuff: + Output("%s", self.variablestuff) + Output() + + def exceptionInitializer(self): + return """PyErr_NewException("%s.Error", NULL, NULL)""" % self.name def _test(): - from bgenGenerator import FunctionGenerator - m = Module("spam", "", "#include <stdio.h>") - g = FunctionGenerator(None, "bacon") - m.add(g) - m.generate() + from bgenGenerator import FunctionGenerator + m = Module("spam", "", "#include <stdio.h>") + g = FunctionGenerator(None, "bacon") + m.add(g) + m.generate() if __name__ == "__main__": - _test() + _test() diff --git a/Tools/bgen/bgen/bgenObjectDefinition.py b/Tools/bgen/bgen/bgenObjectDefinition.py index 986b407..40435ad 100644 --- a/Tools/bgen/bgen/bgenObjectDefinition.py +++ b/Tools/bgen/bgen/bgenObjectDefinition.py @@ -2,485 +2,485 @@ from bgenOutput import * from bgenGeneratorGroup import GeneratorGroup class ObjectDefinition(GeneratorGroup): - "Spit out code that together defines a new Python object type" - basechain = "NULL" - tp_flags = "Py_TPFLAGS_DEFAULT" - basetype = None - - def __init__(self, name, prefix, itselftype): - """ObjectDefinition constructor. May be extended, but do not override. - - - name: the object's official name, e.g. 'SndChannel'. - - 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'. - - XXX For official Python data types, rules for the 'Py' prefix are a problem. - """ - - GeneratorGroup.__init__(self, prefix or name) - self.name = name - self.itselftype = itselftype - self.objecttype = name + 'Object' - self.typename = name + '_Type' - 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.modulename = None - if hasattr(self, "assertions"): - self.assertions() - - def add(self, g, dupcheck=0): - g.setselftype(self.objecttype, self.itselftype) - GeneratorGroup.add(self, g, dupcheck) - - def reference(self): - # In case we are referenced from a module - pass - - def setmodulename(self, name): - self.modulename = name - - def generate(self): - # XXX This should use long strings and %(varname)s substitution! - - OutHeader2("Object type " + self.name) - - sf = self.static and "static " - Output("%sPyTypeObject %s;", sf, self.typename) - Output() - Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", - self.prefix, self.typename, self.typename) - Output() - Output("typedef struct %s {", self.objecttype) - IndentLevel() - Output("PyObject_HEAD") - self.outputStructMembers() - DedentLevel() - Output("} %s;", self.objecttype) - - self.outputNew() - - self.outputConvert() - - self.outputDealloc() - - GeneratorGroup.generate(self) - - Output() - self.outputMethodChain() - - self.outputGetattr() - - self.outputSetattr() - - self.outputCompare() - - self.outputRepr() - - self.outputHash() - - self.outputPEP253Hooks() - - self.outputTypeObject() - - OutHeader2("End object type " + self.name) - - def outputMethodChain(self): - Output("%sPyMethodChain %s_chain = { %s_methods, %s };", - self.static, self.prefix, self.prefix, self.basechain) - - def outputStructMembers(self): - Output("%s ob_itself;", self.itselftype) - - def outputNew(self): - Output() - Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix, - self.itselftype, self.argref) - OutLbrace() - Output("%s *it;", self.objecttype) - self.outputCheckNewArg() - Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) - Output("if (it == NULL) return NULL;") - if self.basetype: - Output("/* XXXX Should we tp_init or tp_new our basetype? */") - self.outputInitStructMembers() - Output("return (PyObject *)it;") - OutRbrace() - - def outputInitStructMembers(self): - Output("it->ob_itself = %sitself;", self.argref) - - def outputCheckNewArg(self): - "Override this method to apply additional checks/conversions" - - def outputConvert(self): - Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, - self.itselftype) - OutLbrace() - self.outputCheckConvertArg() - Output("if (!%s_Check(v))", self.prefix) - OutLbrace() - Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name) - Output("return 0;") - OutRbrace() - Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype) - Output("return 1;") - OutRbrace() - - def outputCheckConvertArg(self): - "Override this method to apply additional conversions" - - def outputDealloc(self): - Output() - Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype) - OutLbrace() - self.outputCleanupStructMembers() - if self.basetype: - Output("%s.tp_dealloc(self)", self.basetype) - elif hasattr(self, 'output_tp_free'): - # This is a new-style object with tp_free slot - Output("self->ob_type->tp_free((PyObject *)self);") - else: - Output("PyObject_Free((PyObject *)self);") - OutRbrace() - - def outputCleanupStructMembers(self): - self.outputFreeIt("self->ob_itself") - - def outputFreeIt(self, name): - Output("/* Cleanup of %s goes here */", name) - - def outputGetattr(self): - Output() - Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype) - OutLbrace() - self.outputGetattrBody() - OutRbrace() - - def outputGetattrBody(self): - self.outputGetattrHook() - Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);", - self.prefix) - - def outputGetattrHook(self): - pass - - def outputSetattr(self): - Output() - Output("#define %s_setattr NULL", self.prefix) - - def outputCompare(self): - Output() - Output("#define %s_compare NULL", self.prefix) - - def outputRepr(self): - Output() - Output("#define %s_repr NULL", self.prefix) - - def outputHash(self): - Output() - Output("#define %s_hash NULL", self.prefix) - - def outputTypeObject(self): - sf = self.static and "static " - Output() - Output("%sPyTypeObject %s = {", sf, self.typename) - IndentLevel() - Output("PyObject_HEAD_INIT(NULL)") - Output("0, /*ob_size*/") - if self.modulename: - Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) - else: - Output("\"%s\", /*tp_name*/", self.name) - Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) - Output("0, /*tp_itemsize*/") - Output("/* methods */") - Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) - Output("0, /*tp_print*/") - Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix) - Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix) - Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) - Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) - Output("(PyNumberMethods *)0, /* tp_as_number */") - Output("(PySequenceMethods *)0, /* tp_as_sequence */") - Output("(PyMappingMethods *)0, /* tp_as_mapping */") - Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) - DedentLevel() - Output("};") - - def outputTypeObjectInitializer(self): - Output("""%s.ob_type = &PyType_Type;""", self.typename) - if self.basetype: - Output("%s.tp_base = %s;", self.typename, self.basetype) - Output("if (PyType_Ready(&%s) < 0) return;", self.typename) - Output("""Py_INCREF(&%s);""", self.typename) - Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename); - Output("/* Backward-compatible name */") - Output("""Py_INCREF(&%s);""", self.typename); - Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename); - - def outputPEP253Hooks(self): - pass - + "Spit out code that together defines a new Python object type" + basechain = "NULL" + tp_flags = "Py_TPFLAGS_DEFAULT" + basetype = None + + def __init__(self, name, prefix, itselftype): + """ObjectDefinition constructor. May be extended, but do not override. + + - name: the object's official name, e.g. 'SndChannel'. + - 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'. + + XXX For official Python data types, rules for the 'Py' prefix are a problem. + """ + + GeneratorGroup.__init__(self, prefix or name) + self.name = name + self.itselftype = itselftype + self.objecttype = name + 'Object' + self.typename = name + '_Type' + 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.modulename = None + if hasattr(self, "assertions"): + self.assertions() + + def add(self, g, dupcheck=0): + g.setselftype(self.objecttype, self.itselftype) + GeneratorGroup.add(self, g, dupcheck) + + def reference(self): + # In case we are referenced from a module + pass + + def setmodulename(self, name): + self.modulename = name + + def generate(self): + # XXX This should use long strings and %(varname)s substitution! + + OutHeader2("Object type " + self.name) + + sf = self.static and "static " + Output("%sPyTypeObject %s;", sf, self.typename) + Output() + Output("#define %s_Check(x) ((x)->ob_type == &%s || PyObject_TypeCheck((x), &%s))", + self.prefix, self.typename, self.typename) + Output() + Output("typedef struct %s {", self.objecttype) + IndentLevel() + Output("PyObject_HEAD") + self.outputStructMembers() + DedentLevel() + Output("} %s;", self.objecttype) + + self.outputNew() + + self.outputConvert() + + self.outputDealloc() + + GeneratorGroup.generate(self) + + Output() + self.outputMethodChain() + + self.outputGetattr() + + self.outputSetattr() + + self.outputCompare() + + self.outputRepr() + + self.outputHash() + + self.outputPEP253Hooks() + + self.outputTypeObject() + + OutHeader2("End object type " + self.name) + + def outputMethodChain(self): + Output("%sPyMethodChain %s_chain = { %s_methods, %s };", + self.static, self.prefix, self.prefix, self.basechain) + + def outputStructMembers(self): + Output("%s ob_itself;", self.itselftype) + + def outputNew(self): + Output() + Output("%sPyObject *%s_New(%s %sitself)", self.static, self.prefix, + self.itselftype, self.argref) + OutLbrace() + Output("%s *it;", self.objecttype) + self.outputCheckNewArg() + Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename) + Output("if (it == NULL) return NULL;") + if self.basetype: + Output("/* XXXX Should we tp_init or tp_new our basetype? */") + self.outputInitStructMembers() + Output("return (PyObject *)it;") + OutRbrace() + + def outputInitStructMembers(self): + Output("it->ob_itself = %sitself;", self.argref) + + def outputCheckNewArg(self): + "Override this method to apply additional checks/conversions" + + def outputConvert(self): + Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, + self.itselftype) + OutLbrace() + self.outputCheckConvertArg() + Output("if (!%s_Check(v))", self.prefix) + OutLbrace() + Output('PyErr_SetString(PyExc_TypeError, "%s required");', self.name) + Output("return 0;") + OutRbrace() + Output("*p_itself = ((%s *)v)->ob_itself;", self.objecttype) + Output("return 1;") + OutRbrace() + + def outputCheckConvertArg(self): + "Override this method to apply additional conversions" + + def outputDealloc(self): + Output() + Output("static void %s_dealloc(%s *self)", self.prefix, self.objecttype) + OutLbrace() + self.outputCleanupStructMembers() + if self.basetype: + Output("%s.tp_dealloc(self)", self.basetype) + elif hasattr(self, 'output_tp_free'): + # This is a new-style object with tp_free slot + Output("self->ob_type->tp_free((PyObject *)self);") + else: + Output("PyObject_Free((PyObject *)self);") + OutRbrace() + + def outputCleanupStructMembers(self): + self.outputFreeIt("self->ob_itself") + + def outputFreeIt(self, name): + Output("/* Cleanup of %s goes here */", name) + + def outputGetattr(self): + Output() + Output("static PyObject *%s_getattr(%s *self, char *name)", self.prefix, self.objecttype) + OutLbrace() + self.outputGetattrBody() + OutRbrace() + + def outputGetattrBody(self): + self.outputGetattrHook() + Output("return Py_FindMethodInChain(&%s_chain, (PyObject *)self, name);", + self.prefix) + + def outputGetattrHook(self): + pass + + def outputSetattr(self): + Output() + Output("#define %s_setattr NULL", self.prefix) + + def outputCompare(self): + Output() + Output("#define %s_compare NULL", self.prefix) + + def outputRepr(self): + Output() + Output("#define %s_repr NULL", self.prefix) + + def outputHash(self): + Output() + Output("#define %s_hash NULL", self.prefix) + + def outputTypeObject(self): + sf = self.static and "static " + Output() + Output("%sPyTypeObject %s = {", sf, self.typename) + IndentLevel() + Output("PyObject_HEAD_INIT(NULL)") + Output("0, /*ob_size*/") + if self.modulename: + Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) + else: + Output("\"%s\", /*tp_name*/", self.name) + Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) + Output("0, /*tp_itemsize*/") + Output("/* methods */") + Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) + Output("0, /*tp_print*/") + Output("(getattrfunc) %s_getattr, /*tp_getattr*/", self.prefix) + Output("(setattrfunc) %s_setattr, /*tp_setattr*/", self.prefix) + Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) + Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) + Output("(PyNumberMethods *)0, /* tp_as_number */") + Output("(PySequenceMethods *)0, /* tp_as_sequence */") + Output("(PyMappingMethods *)0, /* tp_as_mapping */") + Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) + DedentLevel() + Output("};") + + def outputTypeObjectInitializer(self): + Output("""%s.ob_type = &PyType_Type;""", self.typename) + if self.basetype: + Output("%s.tp_base = %s;", self.typename, self.basetype) + Output("if (PyType_Ready(&%s) < 0) return;", self.typename) + Output("""Py_INCREF(&%s);""", self.typename) + Output("PyModule_AddObject(m, \"%s\", (PyObject *)&%s);", self.name, self.typename); + Output("/* Backward-compatible name */") + Output("""Py_INCREF(&%s);""", self.typename); + Output("PyModule_AddObject(m, \"%sType\", (PyObject *)&%s);", self.name, self.typename); + + def outputPEP253Hooks(self): + pass + class PEP252Mixin: - getsetlist = [] - - def assertions(self): - # Check that various things aren't overridden. If they are it could - # signify a bgen-client that has been partially converted to PEP252. - assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func - assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func - assert self.outputGetattrBody == None - assert self.outputGetattrHook == None - assert self.basechain == "NULL" - - def outputGetattr(self): - pass - - outputGetattrBody = None - - outputGetattrHook = None - - def outputSetattr(self): - pass - - def outputMethodChain(self): - # This is a good place to output the getters and setters - self.outputGetSetList() - - def outputHook(self, name): - methodname = "outputHook_" + name - if hasattr(self, methodname): - func = getattr(self, methodname) - func() - else: - Output("0, /*%s*/", name) - - def outputTypeObject(self): - sf = self.static and "static " - Output() - Output("%sPyTypeObject %s = {", sf, self.typename) - IndentLevel() - Output("PyObject_HEAD_INIT(NULL)") - Output("0, /*ob_size*/") - if self.modulename: - Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) - else: - Output("\"%s\", /*tp_name*/", self.name) - Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) - Output("0, /*tp_itemsize*/") - - Output("/* methods */") - Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) - Output("0, /*tp_print*/") - Output("(getattrfunc)0, /*tp_getattr*/") - Output("(setattrfunc)0, /*tp_setattr*/") - Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) - Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) - - Output("(PyNumberMethods *)0, /* tp_as_number */") - Output("(PySequenceMethods *)0, /* tp_as_sequence */") - Output("(PyMappingMethods *)0, /* tp_as_mapping */") - - Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) - self.outputHook("tp_call") - Output("0, /*tp_str*/") - Output("PyObject_GenericGetAttr, /*tp_getattro*/") - Output("PyObject_GenericSetAttr, /*tp_setattro */") - - self.outputHook("tp_as_buffer") - Output("%s, /* tp_flags */", self.tp_flags) - self.outputHook("tp_doc") - self.outputHook("tp_traverse") - self.outputHook("tp_clear") - self.outputHook("tp_richcompare") - self.outputHook("tp_weaklistoffset") - self.outputHook("tp_iter") - self.outputHook("tp_iternext") - Output("%s_methods, /* tp_methods */", self.prefix) - self.outputHook("tp_members") - Output("%s_getsetlist, /*tp_getset*/", self.prefix) - self.outputHook("tp_base") - self.outputHook("tp_dict") - self.outputHook("tp_descr_get") - self.outputHook("tp_descr_set") - self.outputHook("tp_dictoffset") - self.outputHook("tp_init") - self.outputHook("tp_alloc") - self.outputHook("tp_new") - self.outputHook("tp_free") - DedentLevel() - Output("};") - - def outputGetSetList(self): - if self.getsetlist: - for name, get, set, doc in self.getsetlist: - if get: - self.outputGetter(name, get) - else: - Output("#define %s_get_%s NULL", self.prefix, name) - Output() - if set: - self.outputSetter(name, set) - else: - Output("#define %s_set_%s NULL", self.prefix, name) - Output() - - Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix) - IndentLevel() - for name, get, set, doc in self.getsetlist: - if doc: - doc = '"' + doc + '"' - else: - doc = "NULL" - Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},", - name, self.prefix, name, self.prefix, name, doc) - Output("{NULL, NULL, NULL, NULL},") - DedentLevel() - Output("};") - else: - Output("#define %s_getsetlist NULL", self.prefix) - Output() - - def outputGetter(self, name, code): - Output("static PyObject *%s_get_%s(%s *self, void *closure)", - self.prefix, name, self.objecttype) - OutLbrace() - Output(code) - OutRbrace() - Output() - - def outputSetter(self, name, code): - Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)", - self.prefix, name, self.objecttype) - OutLbrace() - Output(code) - Output("return 0;") - OutRbrace() - Output() - + getsetlist = [] + + def assertions(self): + # Check that various things aren't overridden. If they are it could + # signify a bgen-client that has been partially converted to PEP252. + assert self.outputGetattr.im_func == PEP252Mixin.outputGetattr.im_func + assert self.outputSetattr.im_func == PEP252Mixin.outputSetattr.im_func + assert self.outputGetattrBody == None + assert self.outputGetattrHook == None + assert self.basechain == "NULL" + + def outputGetattr(self): + pass + + outputGetattrBody = None + + outputGetattrHook = None + + def outputSetattr(self): + pass + + def outputMethodChain(self): + # This is a good place to output the getters and setters + self.outputGetSetList() + + def outputHook(self, name): + methodname = "outputHook_" + name + if hasattr(self, methodname): + func = getattr(self, methodname) + func() + else: + Output("0, /*%s*/", name) + + def outputTypeObject(self): + sf = self.static and "static " + Output() + Output("%sPyTypeObject %s = {", sf, self.typename) + IndentLevel() + Output("PyObject_HEAD_INIT(NULL)") + Output("0, /*ob_size*/") + if self.modulename: + Output("\"%s.%s\", /*tp_name*/", self.modulename, self.name) + else: + Output("\"%s\", /*tp_name*/", self.name) + Output("sizeof(%s), /*tp_basicsize*/", self.objecttype) + Output("0, /*tp_itemsize*/") + + Output("/* methods */") + Output("(destructor) %s_dealloc, /*tp_dealloc*/", self.prefix) + Output("0, /*tp_print*/") + Output("(getattrfunc)0, /*tp_getattr*/") + Output("(setattrfunc)0, /*tp_setattr*/") + Output("(cmpfunc) %s_compare, /*tp_compare*/", self.prefix) + Output("(reprfunc) %s_repr, /*tp_repr*/", self.prefix) + + Output("(PyNumberMethods *)0, /* tp_as_number */") + Output("(PySequenceMethods *)0, /* tp_as_sequence */") + Output("(PyMappingMethods *)0, /* tp_as_mapping */") + + Output("(hashfunc) %s_hash, /*tp_hash*/", self.prefix) + self.outputHook("tp_call") + Output("0, /*tp_str*/") + Output("PyObject_GenericGetAttr, /*tp_getattro*/") + Output("PyObject_GenericSetAttr, /*tp_setattro */") + + self.outputHook("tp_as_buffer") + Output("%s, /* tp_flags */", self.tp_flags) + self.outputHook("tp_doc") + self.outputHook("tp_traverse") + self.outputHook("tp_clear") + self.outputHook("tp_richcompare") + self.outputHook("tp_weaklistoffset") + self.outputHook("tp_iter") + self.outputHook("tp_iternext") + Output("%s_methods, /* tp_methods */", self.prefix) + self.outputHook("tp_members") + Output("%s_getsetlist, /*tp_getset*/", self.prefix) + self.outputHook("tp_base") + self.outputHook("tp_dict") + self.outputHook("tp_descr_get") + self.outputHook("tp_descr_set") + self.outputHook("tp_dictoffset") + self.outputHook("tp_init") + self.outputHook("tp_alloc") + self.outputHook("tp_new") + self.outputHook("tp_free") + DedentLevel() + Output("};") + + def outputGetSetList(self): + if self.getsetlist: + for name, get, set, doc in self.getsetlist: + if get: + self.outputGetter(name, get) + else: + Output("#define %s_get_%s NULL", self.prefix, name) + Output() + if set: + self.outputSetter(name, set) + else: + Output("#define %s_set_%s NULL", self.prefix, name) + Output() + + Output("static PyGetSetDef %s_getsetlist[] = {", self.prefix) + IndentLevel() + for name, get, set, doc in self.getsetlist: + if doc: + doc = '"' + doc + '"' + else: + doc = "NULL" + Output("{\"%s\", (getter)%s_get_%s, (setter)%s_set_%s, %s},", + name, self.prefix, name, self.prefix, name, doc) + Output("{NULL, NULL, NULL, NULL},") + DedentLevel() + Output("};") + else: + Output("#define %s_getsetlist NULL", self.prefix) + Output() + + def outputGetter(self, name, code): + Output("static PyObject *%s_get_%s(%s *self, void *closure)", + self.prefix, name, self.objecttype) + OutLbrace() + Output(code) + OutRbrace() + Output() + + def outputSetter(self, name, code): + Output("static int %s_set_%s(%s *self, PyObject *v, void *closure)", + self.prefix, name, self.objecttype) + OutLbrace() + Output(code) + Output("return 0;") + OutRbrace() + Output() + class PEP253Mixin(PEP252Mixin): - tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE" - - def outputHook_tp_init(self): - Output("%s_tp_init, /* tp_init */", self.prefix) - - def outputHook_tp_alloc(self): - Output("%s_tp_alloc, /* tp_alloc */", self.prefix) - - def outputHook_tp_new(self): - Output("%s_tp_new, /* tp_new */", self.prefix) - - def outputHook_tp_free(self): - Output("%s_tp_free, /* tp_free */", self.prefix) - - output_tp_initBody = None - - def output_tp_init(self): - if self.output_tp_initBody: - Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix) - OutLbrace() - self.output_tp_initBody() - OutRbrace() - else: - Output("#define %s_tp_init 0", self.prefix) - Output() - - output_tp_allocBody = None - - def output_tp_alloc(self): - if self.output_tp_allocBody: - Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)", - self.prefix) - OutLbrace() - self.output_tp_allocBody() - OutRbrace() - else: - Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix) - Output() - - def output_tp_newBody(self): - Output("PyObject *self;"); - Output("%s itself;", self.itselftype); - Output("char *kw[] = {\"itself\", 0};") - Output() - Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", - self.prefix); - Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") - Output("((%s *)self)->ob_itself = itself;", self.objecttype) - Output("return self;") - - def output_tp_new(self): - if self.output_tp_newBody: - Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix) - OutLbrace() - self.output_tp_newBody() - OutRbrace() - else: - Output("#define %s_tp_new PyType_GenericNew", self.prefix) - Output() - - output_tp_freeBody = None - - def output_tp_free(self): - if self.output_tp_freeBody: - Output("static void %s_tp_free(PyObject *self)", self.prefix) - OutLbrace() - self.output_tp_freeBody() - OutRbrace() - else: - Output("#define %s_tp_free PyObject_Del", self.prefix) - Output() - - def outputPEP253Hooks(self): - self.output_tp_init() - self.output_tp_alloc() - self.output_tp_new() - self.output_tp_free() + tp_flags = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE" + + def outputHook_tp_init(self): + Output("%s_tp_init, /* tp_init */", self.prefix) + + def outputHook_tp_alloc(self): + Output("%s_tp_alloc, /* tp_alloc */", self.prefix) + + def outputHook_tp_new(self): + Output("%s_tp_new, /* tp_new */", self.prefix) + + def outputHook_tp_free(self): + Output("%s_tp_free, /* tp_free */", self.prefix) + + output_tp_initBody = None + + def output_tp_init(self): + if self.output_tp_initBody: + Output("static int %s_tp_init(PyObject *self, PyObject *args, PyObject *kwds)", self.prefix) + OutLbrace() + self.output_tp_initBody() + OutRbrace() + else: + Output("#define %s_tp_init 0", self.prefix) + Output() + + output_tp_allocBody = None + + def output_tp_alloc(self): + if self.output_tp_allocBody: + Output("static PyObject *%s_tp_alloc(PyTypeObject *type, int nitems)", + self.prefix) + OutLbrace() + self.output_tp_allocBody() + OutRbrace() + else: + Output("#define %s_tp_alloc PyType_GenericAlloc", self.prefix) + Output() + + def output_tp_newBody(self): + Output("PyObject *self;"); + Output("%s itself;", self.itselftype); + Output("char *kw[] = {\"itself\", 0};") + Output() + Output("if (!PyArg_ParseTupleAndKeywords(args, kwds, \"O&\", kw, %s_Convert, &itself)) return NULL;", + self.prefix); + Output("if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;") + Output("((%s *)self)->ob_itself = itself;", self.objecttype) + Output("return self;") + + def output_tp_new(self): + if self.output_tp_newBody: + Output("static PyObject *%s_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)", self.prefix) + OutLbrace() + self.output_tp_newBody() + OutRbrace() + else: + Output("#define %s_tp_new PyType_GenericNew", self.prefix) + Output() + + output_tp_freeBody = None + + def output_tp_free(self): + if self.output_tp_freeBody: + Output("static void %s_tp_free(PyObject *self)", self.prefix) + OutLbrace() + self.output_tp_freeBody() + OutRbrace() + else: + Output("#define %s_tp_free PyObject_Del", self.prefix) + Output() + + def outputPEP253Hooks(self): + self.output_tp_init() + self.output_tp_alloc() + self.output_tp_new() + self.output_tp_free() class GlobalObjectDefinition(ObjectDefinition): - """Like ObjectDefinition but exports some parts. - - XXX Should also somehow generate a .h file for them. - """ + """Like ObjectDefinition but exports some parts. + + XXX Should also somehow generate a .h file for them. + """ - def __init__(self, name, prefix = None, itselftype = None): - ObjectDefinition.__init__(self, name, prefix or name, itselftype or name) - self.static = "" + def __init__(self, name, prefix = None, itselftype = None): + ObjectDefinition.__init__(self, name, prefix or name, itselftype or name) + self.static = "" class ObjectIdentityMixin: - """A mixin class for objects that makes the identity of ob_itself - govern comparisons and dictionary lookups. Useful if the C object can - be returned by library calls and it is difficult (or impossible) to find - the corresponding Python objects. With this you can create Python object - wrappers on the fly""" - - def outputCompare(self): - Output() - Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, - self.objecttype) - OutLbrace() - Output("unsigned long v, w;") - Output() - Output("if (!%s_Check((PyObject *)other))", self.prefix) - OutLbrace() - Output("v=(unsigned long)self;") - Output("w=(unsigned long)other;") - OutRbrace() - Output("else") - OutLbrace() - Output("v=(unsigned long)self->ob_itself;") - Output("w=(unsigned long)other->ob_itself;") - OutRbrace() - Output("if( v < w ) return -1;") - Output("if( v > w ) return 1;") - Output("return 0;") - OutRbrace() - - def outputHash(self): - Output() - Output("static long %s_hash(%s *self)", self.prefix, self.objecttype) - OutLbrace() - Output("return (long)self->ob_itself;") - OutRbrace() - + """A mixin class for objects that makes the identity of ob_itself + govern comparisons and dictionary lookups. Useful if the C object can + be returned by library calls and it is difficult (or impossible) to find + the corresponding Python objects. With this you can create Python object + wrappers on the fly""" + + def outputCompare(self): + Output() + Output("static int %s_compare(%s *self, %s *other)", self.prefix, self.objecttype, + self.objecttype) + OutLbrace() + Output("unsigned long v, w;") + Output() + Output("if (!%s_Check((PyObject *)other))", self.prefix) + OutLbrace() + Output("v=(unsigned long)self;") + Output("w=(unsigned long)other;") + OutRbrace() + Output("else") + OutLbrace() + Output("v=(unsigned long)self->ob_itself;") + Output("w=(unsigned long)other->ob_itself;") + OutRbrace() + Output("if( v < w ) return -1;") + Output("if( v > w ) return 1;") + Output("return 0;") + OutRbrace() + + def outputHash(self): + Output() + Output("static long %s_hash(%s *self)", self.prefix, self.objecttype) + OutLbrace() + Output("return (long)self->ob_itself;") + OutRbrace() + diff --git a/Tools/bgen/bgen/bgenOutput.py b/Tools/bgen/bgen/bgenOutput.py index c7e560c..7ba5de3 100644 --- a/Tools/bgen/bgen/bgenOutput.py +++ b/Tools/bgen/bgen/bgenOutput.py @@ -9,211 +9,211 @@ SetOutputFileName() to change the output file. _NeedClose = 0 def SetOutputFile(file = None, needclose = 0): - """Call this with an open file object to make it the output file. - - Call it without arguments to close the current file (if necessary) - and reset it to sys.stdout. - If the second argument is true, the new file will be explicitly closed - on a subsequence call. - """ - global _File, _NeedClose - if _NeedClose: - tmp = _File - _NeedClose = 0 - _File = None - tmp.close() - if file is None: - import sys - file = sys.stdout - _File = file - _NeedClose = file and needclose + """Call this with an open file object to make it the output file. + + Call it without arguments to close the current file (if necessary) + and reset it to sys.stdout. + If the second argument is true, the new file will be explicitly closed + on a subsequence call. + """ + global _File, _NeedClose + if _NeedClose: + tmp = _File + _NeedClose = 0 + _File = None + tmp.close() + if file is None: + import sys + file = sys.stdout + _File = file + _NeedClose = file and needclose def SetOutputFileName(filename = None): - """Call this with a filename to make it the output file. - - Call it without arguments to close the current file (if necessary) - and reset it to sys.stdout. - """ - SetOutputFile() - if filename: - SetOutputFile(open(filename, 'w'), 1) + """Call this with a filename to make it the output file. + + Call it without arguments to close the current file (if necessary) + and reset it to sys.stdout. + """ + SetOutputFile() + if filename: + SetOutputFile(open(filename, 'w'), 1) -SetOutputFile() # Initialize _File +SetOutputFile() # Initialize _File -_Level = 0 # Indentation level +_Level = 0 # Indentation level def GetLevel(): - """Return the current indentation level.""" - return _Level + """Return the current indentation level.""" + return _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. - """ - global _Level - _Level = level + This does no type or range checking -- use at own risk. + """ + global _Level + _Level = level def Output(format = "", *args): - VaOutput(format, args) + VaOutput(format, args) def VaOutput(format, args): - """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 - to the proper indentation level -- even if the result of the - format expansion contains embedded newlines. Exception: lines - beginning with '#' are not indented -- these are assumed to be - C preprprocessor lines. - """ - text = format % args - if _Level > 0: - indent = '\t' * _Level - lines = text.split('\n') - for i in range(len(lines)): - if lines[i] and lines[i][0] != '#': - lines[i] = indent + lines[i] - text = '\n'.join(lines) - _File.write(text + '\n') + """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 + to the proper indentation level -- even if the result of the + format expansion contains embedded newlines. Exception: lines + beginning with '#' are not indented -- these are assumed to be + C preprprocessor lines. + """ + text = format % args + if _Level > 0: + indent = '\t' * _Level + lines = text.split('\n') + for i in range(len(lines)): + if lines[i] and lines[i][0] != '#': + lines[i] = indent + lines[i] + text = '\n'.join(lines) + _File.write(text + '\n') 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. - """ - global _Level - if _Level+by < 0: - raise Error, "indentation underflow (internal error)" - _Level = _Level + by + When called with an argument, adds it to the indentation level. + """ + global _Level + if _Level+by < 0: + raise Error, "indentation underflow (internal error)" + _Level = _Level + by 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. - """ - IndentLevel(-by) + When called with an argument, subtracts it from the indentation level. + """ + IndentLevel(-by) def OutIndent(format = "", *args): - """Combine Output() followed by IndentLevel(). - - If no text is given, acts like lone IndentLevel(). - """ - if format: VaOutput(format, args) - IndentLevel() + """Combine Output() followed by IndentLevel(). + + If no text is given, acts like lone IndentLevel(). + """ + if format: VaOutput(format, args) + IndentLevel() def OutDedent(format = "", *args): - """Combine Output() followed by DedentLevel(). - - If no text is given, acts like loneDedentLevel(). - """ - if format: VaOutput(format, args) - DedentLevel() + """Combine Output() followed by DedentLevel(). + + If no text is given, acts like loneDedentLevel(). + """ + if format: VaOutput(format, args) + DedentLevel() def OutLbrace(format = "", *args): - """Like Output, but add a '{' and increase the indentation level. - - If no text is given a lone '{' is output. - """ - if format: - format = format + " {" - else: - format = "{" - VaOutput(format, args) - IndentLevel() + """Like Output, but add a '{' and increase the indentation level. + + If no text is given a lone '{' is output. + """ + if format: + format = format + " {" + else: + format = "{" + VaOutput(format, args) + IndentLevel() def OutRbrace(): - """Decrease the indentation level and output a '}' on a line by itself.""" - DedentLevel() - Output("}") + """Decrease the indentation level and output a '}' on a line by itself.""" + DedentLevel() + Output("}") def OutHeader(text, dash): - """Output a header comment using a given dash character.""" - n = 64 - len(text) - Output() - Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2)) - Output() + """Output a header comment using a given dash character.""" + n = 64 - len(text) + Output() + Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2)) + Output() def OutHeader1(text): - """Output a level 1 header comment (uses '=' dashes).""" - OutHeader(text, "=") + """Output a level 1 header comment (uses '=' dashes).""" + OutHeader(text, "=") def OutHeader2(text): - """Output a level 2 header comment (uses '-' dashes).""" - OutHeader(text, "-") + """Output a level 2 header comment (uses '-' dashes).""" + OutHeader(text, "-") def Out(text): - """Output multiline text that's internally indented. - - Pass this a multiline character string. The whitespace before the - first nonblank line of the string will be subtracted from all lines. - The lines are then output using Output(), but without interpretation - of formatting (if you need formatting you can do it before the call). - Recommended use: - - Out(''' - int main(argc, argv) - int argc; - char *argv; - { - printf("Hello, world\\n"); - exit(0); - } - ''') - - Caveat: the indentation must be consistent -- if you use three tabs - 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 - this as a feature. - """ - # (Don't you love using triple quotes *inside* triple quotes? :-) - - lines = text.split('\n') - indent = "" - for line in lines: - if line.strip(): - for c in line: - if not c.isspace(): - break - indent = indent + c - break - n = len(indent) - for line in lines: - if line[:n] == indent: - line = line[n:] - else: - for c in indent: - if line[:1] <> c: break - line = line[1:] - VaOutput("%s", line) + """Output multiline text that's internally indented. + + Pass this a multiline character string. The whitespace before the + first nonblank line of the string will be subtracted from all lines. + The lines are then output using Output(), but without interpretation + of formatting (if you need formatting you can do it before the call). + Recommended use: + + Out(''' + int main(argc, argv) + int argc; + char *argv; + { + printf("Hello, world\\n"); + exit(0); + } + ''') + + Caveat: the indentation must be consistent -- if you use three tabs + 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 + this as a feature. + """ + # (Don't you love using triple quotes *inside* triple quotes? :-) + + lines = text.split('\n') + indent = "" + for line in lines: + if line.strip(): + for c in line: + if not c.isspace(): + break + indent = indent + c + break + n = len(indent) + for line in lines: + if line[:n] == indent: + line = line[n:] + else: + for c in indent: + if line[:1] <> c: break + line = line[1:] + VaOutput("%s", line) def _test(): - """Test program. Run when the module is run as a script.""" - OutHeader1("test bgenOutput") - Out(""" - #include <Python.h> - #include <stdio.h> - - main(argc, argv) - int argc; - char **argv; - { - int i; - """) - IndentLevel() - Output("""\ + """Test program. Run when the module is run as a script.""" + OutHeader1("test bgenOutput") + Out(""" + #include <Python.h> + #include <stdio.h> + + main(argc, argv) + int argc; + char **argv; + { + int i; + """) + IndentLevel() + Output("""\ /* Here are a few comment lines. Just to test indenting multiple lines. End of the comment lines. */ """) - Output("for (i = 0; i < argc; i++)") - OutLbrace() - Output('printf("argv[%%d] = %%s\\n", i, argv[i]);') - OutRbrace() - Output("exit(0)") - OutRbrace() - OutHeader2("end test") + Output("for (i = 0; i < argc; i++)") + OutLbrace() + Output('printf("argv[%%d] = %%s\\n", i, argv[i]);') + OutRbrace() + Output("exit(0)") + OutRbrace() + OutHeader2("end test") if __name__ == '__main__': - _test() + _test() diff --git a/Tools/bgen/bgen/bgenStackBuffer.py b/Tools/bgen/bgen/bgenStackBuffer.py index 1b6350a..9669607 100644 --- a/Tools/bgen/bgen/bgenStackBuffer.py +++ b/Tools/bgen/bgen/bgenStackBuffer.py @@ -6,54 +6,54 @@ from bgenBuffer import FixedInputBufferType, 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): - return "%s__out__, %s" % (name, self.size) + def passOutput(self, name): + return "%s__out__, %s" % (name, self.size) 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): - Output("int %s__len__ = %s;", name, self.size) + def declareSize(self, name): + Output("int %s__len__ = %s;", name, self.size) - def passOutput(self, name): - return "%s__out__, &%s__len__" % (name, name) + def passOutput(self, name): + return "%s__out__, &%s__len__" % (name, name) - def mkvalueArgs(self, name): - return "%s__out__, (int)%s__len__" % (name, name) + def mkvalueArgs(self, name): + return "%s__out__, (int)%s__len__" % (name, name) 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): - return "%s__out__, %s__len__, &%s__len__" % (name, name, name) + def passOutput(self, name): + return "%s__out__, %s__len__, &%s__len__" % (name, name, name) 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. - The function's return value is the size. - (XXX Should have a way to suppress returning it separately, too.) - """ + Instantiate with the buffer size as parameter. + The function's return value is the size. + (XXX Should have a way to suppress returning it separately, too.) + """ - def passOutput(self, name): - return "%s__out__, %s__len__" % (name, name) + def passOutput(self, name): + return "%s__out__, %s__len__" % (name, name) - def mkvalueArgs(self, name): - return "%s__out__, (int)_rv" % name + def mkvalueArgs(self, name): + return "%s__out__, (int)_rv" % name diff --git a/Tools/bgen/bgen/bgenStringBuffer.py b/Tools/bgen/bgen/bgenStringBuffer.py index 7d9c77e..39c8cf9 100644 --- a/Tools/bgen/bgen/bgenStringBuffer.py +++ b/Tools/bgen/bgen/bgenStringBuffer.py @@ -8,57 +8,57 @@ from bgenHeapBuffer import HeapOutputBufferType class StringBufferMixIn: - """Mix-in class to create various string buffer types. - - Strings are character arrays terminated by a null byte. - (For input, this is also covered by stringptr.) - For output, there are again three variants: - - 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 - 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 - pass a size. - (Note that this doesn't cover output parameters in which a string - pointer is returned. These are actually easier (no allocation) but far - less common. I'll write the classes when there is demand.) - """ - - def declareSize(self, name): - pass - - def getargsFormat(self): - return "s" - - def getargsArgs(self, name): - return "&%s__in__" % name - - def mkvalueFormat(self): - return "s" - - def mkvalueArgs(self, name): - return "%s__out__" % name + """Mix-in class to create various string buffer types. + + Strings are character arrays terminated by a null byte. + (For input, this is also covered by stringptr.) + For output, there are again three variants: + - 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 + 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 + pass a size. + (Note that this doesn't cover output parameters in which a string + pointer is returned. These are actually easier (no allocation) but far + less common. I'll write the classes when there is demand.) + """ + + def declareSize(self, name): + pass + + def getargsFormat(self): + return "s" + + def getargsArgs(self, name): + return "&%s__in__" % name + + def mkvalueFormat(self): + return "s" + + def mkvalueArgs(self, name): + return "%s__out__" % name 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): - """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): - """Null-terminated output string -- passed as (buffer, size). + """Null-terminated output string -- passed as (buffer, size). - Instantiate without parameters. - Call from Python with buffer size. - """ + Instantiate without parameters. + Call from Python with buffer size. + """ diff --git a/Tools/bgen/bgen/bgenType.py b/Tools/bgen/bgen/bgenType.py index 51f5844..8ac3ac3 100644 --- a/Tools/bgen/bgen/bgenType.py +++ b/Tools/bgen/bgen/bgenType.py @@ -6,105 +6,105 @@ from bgenOutput import * 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): - """Call with the C name and getargs format for the type. + def __init__(self, typeName, fmt): + """Call with the C name and getargs format for the type. - Example: int = Type("int", "i") - """ - self.typeName = typeName - self.fmt = fmt + Example: int = Type("int", "i") + """ + self.typeName = typeName + self.fmt = fmt - def declare(self, name): - """Declare a variable of the type with a given name. + def declare(self, name): + """Declare a variable of the type with a given name. - Example: int.declare('spam') prints "int spam;" - """ - Output("%s %s;", self.typeName, name) + Example: int.declare('spam') prints "int spam;" + """ + Output("%s %s;", self.typeName, name) - def getargs(self): - return self.getargsFormat(), self.getargsArgs() + def getargs(self): + return self.getargsFormat(), self.getargsArgs() - def getargsFormat(self): - """Return the format for this type for use with [new]getargs(). + def getargsFormat(self): + """Return the format for this type for use with [new]getargs(). - Example: int.getargsFormat() returns the string "i". - """ - return self.fmt + Example: int.getargsFormat() returns the string "i". + """ + return self.fmt - def getargsArgs(self, name): - """Return an argument for use with [new]getargs(). + def getargsArgs(self, name): + """Return an argument for use with [new]getargs(). - Example: int.getargsArgs("spam") returns the string "&spam". - """ - return "&" + name + Example: int.getargsArgs("spam") returns the string "&spam". + """ + return "&" + name - def getargsCheck(self, name): - """Perform any needed post-[new]getargs() checks. + def getargsCheck(self, name): + """Perform any needed post-[new]getargs() checks. - This is type-dependent; the default does not check for errors. - An example would be a check for a maximum string length.""" + This is type-dependent; the default does not check for errors. + An example would be a check for a maximum string length.""" - def passInput(self, name): - """Return an argument for passing a variable into a call. + def passInput(self, name): + """Return an argument for passing a variable into a call. - Example: int.passInput("spam") returns the string "spam". - """ - return name + Example: int.passInput("spam") returns the string "spam". + """ + return name - def passOutput(self, name): - """Return an argument for returning a variable out of a call. + def passOutput(self, name): + """Return an argument for returning a variable out of a call. - Example: int.passOutput("spam") returns the string "&spam". - """ - return "&" + name + Example: int.passOutput("spam") returns the string "&spam". + """ + return "&" + name - def errorCheck(self, name): - """Check for an error returned in the variable. + def errorCheck(self, name): + """Check for an error returned in the variable. - This is type-dependent; the default does not check for errors. - An example would be a check for a NULL pointer. - If an error is found, the generated routine should - raise an exception and return NULL. + This is type-dependent; the default does not check for errors. + An example would be a check for a NULL pointer. + If an error is found, the generated routine should + raise an exception and return NULL. - XXX There should be a way to add error clean-up code. - """ - Output("/* XXX no err check for %s %s */", self.typeName, name) + XXX There should be a way to add error clean-up code. + """ + Output("/* XXX no err check for %s %s */", self.typeName, name) - def mkvalue(self): - return self.mkvalueFormat(), self.mkvalueArgs() + def mkvalue(self): + return self.mkvalueFormat(), self.mkvalueArgs() - def mkvalueFormat(self): - """Return the format for this type for use with mkvalue(). + def mkvalueFormat(self): + """Return the format for this type for use with mkvalue(). - This is normally the same as getargsFormat() but it is - a separate function to allow future divergence. - """ - return self.getargsFormat() + This is normally the same as getargsFormat() but it is + a separate function to allow future divergence. + """ + return self.getargsFormat() - def mkvalueArgs(self, name): - """Return an argument for use with mkvalue(). + def mkvalueArgs(self, name): + """Return an argument for use with mkvalue(). - Example: int.mkvalueArgs("spam") returns the string "spam". - """ - return name + Example: int.mkvalueArgs("spam") returns the string "spam". + """ + return name - def cleanup(self, name): - """Clean up if necessary. + def cleanup(self, name): + """Clean up if necessary. - This is normally empty; it may deallocate buffers etc. - """ - pass + This is normally empty; it may deallocate buffers etc. + """ + pass 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): - return "&%s" % name + def passInput(self, name): + return "&%s" % name @@ -112,25 +112,25 @@ class ByAddressType(Type): class InputOnlyMixIn: - "Mix-in class to boobytrap passOutput" + "Mix-in class to boobytrap passOutput" - def passOutput(self, name): - raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName + def passOutput(self, name): + raise RuntimeError, "Type '%s' can only be used for input parameters" % self.typeName 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: - "Mix-in class to boobytrap passInput" + "Mix-in class to boobytrap passInput" - def passInput(self, name): - raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName + def passInput(self, name): + raise RuntimeError, "Type '%s' can only be used for output parameters" % self.typeName 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. @@ -160,99 +160,99 @@ stringobjectptr = Type("PyStringObject*", "S") 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): - self.substitute = substitute - self.typeName = None # Don't show this argument in __doc__ string + def __init__(self, substitute): + self.substitute = substitute + self.typeName = None # Don't show this argument in __doc__ string - def declare(self, name): - pass + def declare(self, name): + pass - def getargsFormat(self): - return "" + def getargsFormat(self): + return "" - def getargsArgs(self, name): - return None + def getargsArgs(self, name): + return None - def passInput(self, name): - return self.substitute + def passInput(self, name): + return self.substitute 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. - 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 - defaults to the first argument. - """ + 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 + to derive the new and convert procs by appending _New and _Convert; it + defaults to the first argument. + """ - def __init__(self, name, arg = None, extra = None): - self.typeName = name - if extra is None: - # Two arguments (name, usetype) or one (name) - arg = arg or name - self.new = arg + '_New' - self.convert = arg + '_Convert' - else: - # Three arguments (name, new, convert) - self.new = arg - self.convert = extra + def __init__(self, name, arg = None, extra = None): + self.typeName = name + if extra is None: + # Two arguments (name, usetype) or one (name) + arg = arg or name + self.new = arg + '_New' + self.convert = arg + '_Convert' + else: + # Three arguments (name, new, convert) + self.new = arg + self.convert = extra - def getargsFormat(self): - return "O&" + def getargsFormat(self): + return "O&" - def getargsArgs(self, name): - return "%s, &%s" % (self.convert, name) + def getargsArgs(self, name): + return "%s, &%s" % (self.convert, name) - def passInput(self, name): - return "&%s" % name + def passInput(self, name): + return "&%s" % name - def mkvalueFormat(self): - return "O&" + def mkvalueFormat(self): + return "O&" - def mkvalueArgs(self, name): - return "%s, &%s" % (self.new, name) + def mkvalueArgs(self, name): + return "%s, &%s" % (self.new, name) 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 - New/Convert functions will be used. - """ + Instantiate with the type name, and optionally an object type name whose + New/Convert functions will be used. + """ - def passInput(self, name): - return name + def passInput(self, name): + return name - def mkvalueArgs(self, name): - return "%s, %s" % (self.new, name) - + def mkvalueArgs(self, name): + return "%s, %s" % (self.new, name) + class OpaqueByValueStructType(OpaqueByValueType): - """Similar to OpaqueByValueType, but we also pass this to mkvalue by - address, in stead of by value. - """ + """Similar to OpaqueByValueType, but we also pass this to mkvalue by + address, in stead of by value. + """ - def mkvalueArgs(self, name): - return "%s, &%s" % (self.new, name) + def mkvalueArgs(self, name): + return "%s, &%s" % (self.new, name) 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 - New/Convert functions will be used. - """ + Instantiate with the type name, and optional an object type name whose + New/Convert functions will be used. + """ - def getargsArgs(self, name): - return "%s, %s" % (self.convert, name) + def getargsArgs(self, name): + return "%s, %s" % (self.convert, name) - def passOutput(self, name): - return name + def passOutput(self, name): + return name diff --git a/Tools/bgen/bgen/bgenVariable.py b/Tools/bgen/bgen/bgenVariable.py index 310cc8f..7b947ab 100644 --- a/Tools/bgen/bgen/bgenVariable.py +++ b/Tools/bgen/bgen/bgenVariable.py @@ -17,72 +17,72 @@ ErrorMode = 16+OutMode # this is an error status -- turn it into an exception class Variable: - """A Variable holds a type, a name, a transfer mode and flags. - - Most of its methods call the correponding type method with the - variable name. - """ - - def __init__(self, type, name = None, flags = InMode): - """Call with a type, a name and flags. - - If name is None, it muse be set later. - flags defaults to InMode. - """ - self.type = type - self.name = name - self.flags = flags - self.mode = flags & ModeMask - - def declare(self): - """Declare the variable if necessary. - - If it is "self", it is not declared. - """ - if self.flags != SelfMode: - self.type.declare(self.name) - - def getargsFormat(self): - """Call the type's getargsFormatmethod.""" - return self.type.getargsFormat() - - def getargsArgs(self): - """Call the type's getargsArgsmethod.""" - return self.type.getargsArgs(self.name) - - def getargsCheck(self): - return self.type.getargsCheck(self.name) - - def passArgument(self): - """Return the string required to pass the variable as argument. - - For "in" arguments, return the variable name. - For "out" and "in out" arguments, - return its name prefixed with "&". - """ - if self.mode == InMode: - return self.type.passInput(self.name) - if self.mode in (OutMode, InOutMode): - return self.type.passOutput(self.name) - # XXX Shouldn't get here - return "/*mode?*/" + self.type.passInput(self.name) - - def errorCheck(self): - """Check for an error if necessary. - - This only generates code if the variable's mode is ErrorMode. - """ - if self.flags == ErrorMode: - self.type.errorCheck(self.name) - - def mkvalueFormat (self): - """Call the type's mkvalueFormat method.""" - return self.type.mkvalueFormat() - - def mkvalueArgs(self): - """Call the type's mkvalueArgs method.""" - return self.type.mkvalueArgs(self.name) - - def cleanup(self): - """Call the type's cleanup method.""" - return self.type.cleanup(self.name) + """A Variable holds a type, a name, a transfer mode and flags. + + Most of its methods call the correponding type method with the + variable name. + """ + + def __init__(self, type, name = None, flags = InMode): + """Call with a type, a name and flags. + + If name is None, it muse be set later. + flags defaults to InMode. + """ + self.type = type + self.name = name + self.flags = flags + self.mode = flags & ModeMask + + def declare(self): + """Declare the variable if necessary. + + If it is "self", it is not declared. + """ + if self.flags != SelfMode: + self.type.declare(self.name) + + def getargsFormat(self): + """Call the type's getargsFormatmethod.""" + return self.type.getargsFormat() + + def getargsArgs(self): + """Call the type's getargsArgsmethod.""" + return self.type.getargsArgs(self.name) + + def getargsCheck(self): + return self.type.getargsCheck(self.name) + + def passArgument(self): + """Return the string required to pass the variable as argument. + + For "in" arguments, return the variable name. + For "out" and "in out" arguments, + return its name prefixed with "&". + """ + if self.mode == InMode: + return self.type.passInput(self.name) + if self.mode in (OutMode, InOutMode): + return self.type.passOutput(self.name) + # XXX Shouldn't get here + return "/*mode?*/" + self.type.passInput(self.name) + + def errorCheck(self): + """Check for an error if necessary. + + This only generates code if the variable's mode is ErrorMode. + """ + if self.flags == ErrorMode: + self.type.errorCheck(self.name) + + def mkvalueFormat (self): + """Call the type's mkvalueFormat method.""" + return self.type.mkvalueFormat() + + def mkvalueArgs(self): + """Call the type's mkvalueArgs method.""" + return self.type.mkvalueArgs(self.name) + + def cleanup(self): + """Call the type's cleanup method.""" + return self.type.cleanup(self.name) diff --git a/Tools/bgen/bgen/macsupport.py b/Tools/bgen/bgen/macsupport.py index 049354a..b4885ad 100644 --- a/Tools/bgen/bgen/macsupport.py +++ b/Tools/bgen/bgen/macsupport.py @@ -52,7 +52,7 @@ FSRef = OpaqueByValueStructType("FSRef", "PyMac_BuildFSRef", "PyMac_GetFSRef") # OSType and ResType: 4-byte character strings def OSTypeType(typename): - return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType") + return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType") OSType = OSTypeType("OSType") ResType = OSTypeType("ResType") FourCharCode = OSTypeType("FourCharCode") @@ -104,35 +104,35 @@ OptionalCFURLRef = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj") # OSErr is special because it is turned into an exception # (Could do this with less code using a variant of mkvalue("O&")?) class OSErrType(Type): - def errorCheck(self, name): - Output("if (%s != noErr) return PyMac_Error(%s);", name, name) - self.used = 1 + def errorCheck(self, name): + Output("if (%s != noErr) return PyMac_Error(%s);", name, name) + self.used = 1 OSErr = OSErrType("OSErr", 'h') OSStatus = OSErrType("OSStatus", 'l') # Various buffer types -InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) -UcharInBuffer = VarInputBufferType('unsigned char', 'long', 'l') # (buf, len) -OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len) +InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) +UcharInBuffer = VarInputBufferType('unsigned 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) -OutBuffer = HeapOutputBufferType('char', 'long', 'l') # (buf, len) -VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len) +OutBuffer = HeapOutputBufferType('char', 'long', 'l') # (buf, len) +VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len) VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len) # Unicode arguments sometimes have reversed len, buffer (don't understand why Apple did this...) class VarUnicodeInputBufferType(VarInputBufferType): - def getargsFormat(self): - return "u#" - + def getargsFormat(self): + return "u#" + class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType): - pass - + pass + UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l') UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l') UniChar_ptr = InputOnlyType("UniCharPtr", "u") @@ -151,9 +151,9 @@ includestuff = """ /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\\ - PyErr_SetString(PyExc_NotImplementedError, \\ - "Not available in this shared library/OS version"); \\ - return NULL; \\ + PyErr_SetString(PyExc_NotImplementedError, \\ + "Not available in this shared library/OS version"); \\ + return NULL; \\ }} while(0) """ @@ -173,23 +173,23 @@ initstuff = """ # This requires that the OSErr type (defined above) has a non-trivial # errorCheck method. class OSErrMixIn: - "Mix-in class to treat OSErr/OSStatus return values special" - def makereturnvar(self): - if self.returntype.__class__ == OSErrType: - return Variable(self.returntype, "_err", ErrorMode) - else: - return Variable(self.returntype, "_rv", OutMode) + "Mix-in class to treat OSErr/OSStatus return values special" + def makereturnvar(self): + if self.returntype.__class__ == OSErrType: + return Variable(self.returntype, "_err", ErrorMode) + else: + return Variable(self.returntype, "_rv", OutMode) class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass class OSErrMethodGenerator(OSErrMixIn, MethodGenerator): pass class WeakLinkMixIn: - "Mix-in to test the function actually exists (!= NULL) before calling" - - def precheck(self): - Output('#ifndef %s', self.name) - Output('PyMac_PRECHECK(%s);', self.name) - Output('#endif') + "Mix-in to test the function actually exists (!= NULL) before calling" + + def precheck(self): + Output('#ifndef %s', self.name) + Output('PyMac_PRECHECK(%s);', self.name) + Output('#endif') class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass class WeakLinkMethodGenerator(WeakLinkMixIn, MethodGenerator): pass @@ -197,14 +197,14 @@ class OSErrWeakLinkFunctionGenerator(OSErrMixIn, WeakLinkMixIn, FunctionGenerato class OSErrWeakLinkMethodGenerator(OSErrMixIn, WeakLinkMixIn, MethodGenerator): pass class MacModule(Module): - "Subclass which gets the exception initializer from macglue.c" - def exceptionInitializer(self): - return "PyMac_GetOSErrException()" + "Subclass which gets the exception initializer from macglue.c" + def exceptionInitializer(self): + return "PyMac_GetOSErrException()" _SetOutputFileName = SetOutputFileName # Save original def SetOutputFileName(file = None): - "Set the output file name and set its creator&type to CWIE&TEXT" - _SetOutputFileName(file) - if file: - import MacOS - MacOS.SetCreatorAndType(file, 'CWIE', 'TEXT') + "Set the output file name and set its creator&type to CWIE&TEXT" + _SetOutputFileName(file) + if file: + import MacOS + MacOS.SetCreatorAndType(file, 'CWIE', 'TEXT') diff --git a/Tools/bgen/bgen/scantools.py b/Tools/bgen/bgen/scantools.py index 61c2f37..b9b6854 100644 --- a/Tools/bgen/bgen/scantools.py +++ b/Tools/bgen/bgen/scantools.py @@ -20,650 +20,650 @@ import os import fnmatch from types import * try: - import MacOS + import MacOS except ImportError: - MacOS = None + MacOS = None try: - from bgenlocations import CREATOR, INCLUDEDIR + from bgenlocations import CREATOR, INCLUDEDIR except ImportError: - CREATOR = None - INCLUDEDIR = os.curdir + CREATOR = None + INCLUDEDIR = os.curdir Error = "scantools.Error" class Scanner: - # Set to 1 in subclass to debug your scanner patterns. - debug = 0 - - def __init__(self, input = None, output = None, defsoutput = None): - self.initsilent() - self.initblacklists() - self.initrepairinstructions() - self.initpaths() - self.initfiles() - self.initpatterns() - self.compilepatterns() - self.initosspecifics() - self.initusedtypes() - if output: - self.setoutput(output, defsoutput) - if input: - self.setinput(input) - - def initusedtypes(self): - self.usedtypes = {} - - def typeused(self, type, mode): - if not self.usedtypes.has_key(type): - self.usedtypes[type] = {} - self.usedtypes[type][mode] = None - - def reportusedtypes(self): - types = self.usedtypes.keys() - types.sort() - for type in types: - modes = self.usedtypes[type].keys() - modes.sort() - self.report("%s %s", type, " ".join(modes)) - - def gentypetest(self, file): - fp = open(file, "w") - fp.write("types=[\n") - types = self.usedtypes.keys() - types.sort() - for type in types: - fp.write("\t'%s',\n"%type) - fp.write("]\n") - fp.write("""missing=0 + # Set to 1 in subclass to debug your scanner patterns. + debug = 0 + + def __init__(self, input = None, output = None, defsoutput = None): + self.initsilent() + self.initblacklists() + self.initrepairinstructions() + self.initpaths() + self.initfiles() + self.initpatterns() + self.compilepatterns() + self.initosspecifics() + self.initusedtypes() + if output: + self.setoutput(output, defsoutput) + if input: + self.setinput(input) + + def initusedtypes(self): + self.usedtypes = {} + + def typeused(self, type, mode): + if not self.usedtypes.has_key(type): + self.usedtypes[type] = {} + self.usedtypes[type][mode] = None + + def reportusedtypes(self): + types = self.usedtypes.keys() + types.sort() + for type in types: + modes = self.usedtypes[type].keys() + modes.sort() + self.report("%s %s", type, " ".join(modes)) + + def gentypetest(self, file): + fp = open(file, "w") + fp.write("types=[\n") + types = self.usedtypes.keys() + types.sort() + for type in types: + fp.write("\t'%s',\n"%type) + fp.write("]\n") + fp.write("""missing=0 for t in types: - try: - tt = eval(t) - except NameError: - print "** Missing type:", t - missing = 1 + try: + tt = eval(t) + except NameError: + print "** Missing type:", t + missing = 1 if missing: raise "Missing Types" """) - fp.close() - - def initsilent(self): - self.silent = 1 - - def error(self, format, *args): - if self.silent >= 0: - print format%args - - def report(self, format, *args): - if not self.silent: - print format%args - - def writeinitialdefs(self): - pass - - def initblacklists(self): - self.blacklistnames = self.makeblacklistnames() - self.blacklisttypes = ["unknown", "-"] + self.makeblacklisttypes() - self.greydictnames = self.greylist2dict(self.makegreylist()) - - def greylist2dict(self, list): - rv = {} - for define, namelist in list: - for name in namelist: - rv[name] = define - return rv - - def makeblacklistnames(self): - return [] - - def makeblacklisttypes(self): - return [] - - def makegreylist(self): - return [] - - def initrepairinstructions(self): - self.repairinstructions = self.makerepairinstructions() - self.inherentpointertypes = self.makeinherentpointertypes() - - def makerepairinstructions(self): - """Parse the repair file into repair instructions. - - The file format is simple: - 1) use \ to split a long logical line in multiple physical lines - 2) everything after the first # on a line is ignored (as comment) - 3) empty lines are ignored - 4) remaining lines must have exactly 3 colon-separated fields: - functionpattern : argumentspattern : argumentsreplacement - 5) all patterns use shell style pattern matching - 6) an empty functionpattern means the same as * - 7) the other two fields are each comma-separated lists of triples - 8) a triple is a space-separated list of 1-3 words - 9) a triple with less than 3 words is padded at the end with "*" words - 10) when used as a pattern, a triple matches the type, name, and mode - of an argument, respectively - 11) when used as a replacement, the words of a triple specify - replacements for the corresponding words of the argument, - with "*" as a word by itself meaning leave the original word - (no other uses of "*" is allowed) - 12) the replacement need not have the same number of triples - as the pattern - """ - f = self.openrepairfile() - if not f: return [] - print "Reading repair file", `f.name`, "..." - list = [] - lineno = 0 - while 1: - line = f.readline() - if not line: break - lineno = lineno + 1 - startlineno = lineno - while line[-2:] == '\\\n': - line = line[:-2] + ' ' + f.readline() - lineno = lineno + 1 - i = line.find('#') - if i >= 0: line = line[:i] - words = [s.strip() for s in line.split(':')] - if words == ['']: continue - if len(words) <> 3: - print "Line", startlineno, - print ": bad line (not 3 colon-separated fields)" - print `line` - continue - [fpat, pat, rep] = words - if not fpat: fpat = "*" - if not pat: - print "Line", startlineno, - print "Empty pattern" - print `line` - continue - patparts = [s.strip() for s in pat.split(',')] - repparts = [s.strip() for s in rep.split(',')] - patterns = [] - for p in patparts: - if not p: - print "Line", startlineno, - print "Empty pattern part" - print `line` - continue - pattern = p.split() - if len(pattern) > 3: - print "Line", startlineno, - print "Pattern part has > 3 words" - print `line` - pattern = pattern[:3] - else: - while len(pattern) < 3: - pattern.append("*") - patterns.append(pattern) - replacements = [] - for p in repparts: - if not p: - print "Line", startlineno, - print "Empty replacement part" - print `line` - continue - replacement = p.split() - if len(replacement) > 3: - print "Line", startlineno, - print "Pattern part has > 3 words" - print `line` - replacement = replacement[:3] - else: - while len(replacement) < 3: - replacement.append("*") - replacements.append(replacement) - list.append((fpat, patterns, replacements)) - return list - - def makeinherentpointertypes(self): - return [] - - def openrepairfile(self, filename = "REPAIR"): - try: - return open(filename, "rU") - except IOError, msg: - print `filename`, ":", msg - print "Cannot open repair file -- assume no repair needed" - return None - - def initfiles(self): - self.specmine = 0 - self.defsmine = 0 - self.scanmine = 0 - self.specfile = sys.stdout - self.defsfile = None - self.scanfile = sys.stdin - self.lineno = 0 - self.line = "" - - def initpaths(self): - self.includepath = [os.curdir, INCLUDEDIR] - - def initpatterns(self): - self.head_pat = r"^EXTERN_API[^_]" - self.tail_pat = r"[;={}]" - self.type_pat = r"EXTERN_API" + \ - r"[ \t\n]*\([ \t\n]*" + \ - r"(?P<type>[a-zA-Z0-9_* \t]*[a-zA-Z0-9_*])" + \ - r"[ \t\n]*\)[ \t\n]*" - self.name_pat = r"(?P<name>[a-zA-Z0-9_]+)[ \t\n]*" - self.args_pat = r"\((?P<args>([^\(;=\)]+|\([^\(;=\)]*\))*)\)" - self.whole_pat = self.type_pat + self.name_pat + self.args_pat - self.sym_pat = r"^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \ - r"[ \t]*(?P<defn>[-0-9_a-zA-Z'\"\(][^\t\n,;}]*),?" - self.asplit_pat = r"^(?P<type>.*[^a-zA-Z0-9_])(?P<name>[a-zA-Z0-9_]+)(?P<array>\[\])?$" - self.comment1_pat = r"(?P<rest>.*)//.*" - # note that the next pattern only removes comments that are wholly within one line - self.comment2_pat = r"(?P<rest1>.*)/\*.*\*/(?P<rest2>.*)" - - def compilepatterns(self): - for name in dir(self): - if name[-4:] == "_pat": - pat = getattr(self, name) - prog = re.compile(pat) - setattr(self, name[:-4], prog) - - def initosspecifics(self): - if MacOS and CREATOR: - self.filetype = 'TEXT' - self.filecreator = CREATOR - else: - self.filetype = self.filecreator = None - - def setfiletype(self, filename): - if MacOS and (self.filecreator or self.filetype): - creator, type = MacOS.GetCreatorAndType(filename) - if self.filecreator: creator = self.filecreator - if self.filetype: type = self.filetype - MacOS.SetCreatorAndType(filename, creator, type) - - def close(self): - self.closefiles() - - def closefiles(self): - self.closespec() - self.closedefs() - self.closescan() - - def closespec(self): - tmp = self.specmine and self.specfile - self.specfile = None - if tmp: tmp.close() - - def closedefs(self): - tmp = self.defsmine and self.defsfile - self.defsfile = None - if tmp: tmp.close() - - def closescan(self): - tmp = self.scanmine and self.scanfile - self.scanfile = None - if tmp: tmp.close() - - def setoutput(self, spec, defs = None): - self.closespec() - self.closedefs() - if spec: - if type(spec) == StringType: - file = self.openoutput(spec) - mine = 1 - else: - file = spec - mine = 0 - self.specfile = file - self.specmine = mine - if defs: - if type(defs) == StringType: - file = self.openoutput(defs) - mine = 1 - else: - file = defs - mine = 0 - self.defsfile = file - self.defsmine = mine - - def openoutput(self, filename): - try: - file = open(filename, 'w') - except IOError, arg: - raise IOError, (filename, arg) - self.setfiletype(filename) - return file - - def setinput(self, scan = sys.stdin): - if not type(scan) in (TupleType, ListType): - scan = [scan] - self.allscaninputs = scan - self._nextinput() - - def _nextinput(self): - if not self.allscaninputs: - return 0 - scan = self.allscaninputs[0] - self.allscaninputs = self.allscaninputs[1:] - self.closescan() - if scan: - if type(scan) == StringType: - file = self.openinput(scan) - mine = 1 - else: - file = scan - mine = 0 - self.scanfile = file - self.scanmine = mine - self.lineno = 0 - return 1 - - def openinput(self, filename): - if not os.path.isabs(filename): - for dir in self.includepath: - fullname = os.path.join(dir, filename) - #self.report("trying full name %s", `fullname`) - try: - return open(fullname, 'rU') - except IOError: - pass - # If not on the path, or absolute, try default open() - try: - return open(filename, 'rU') - except IOError, arg: - raise IOError, (arg, filename) - - def getline(self): - if not self.scanfile: - raise Error, "input file not set" - self.line = self.scanfile.readline() - if not self.line: - if self._nextinput(): - return self.getline() - raise EOFError - self.lineno = self.lineno + 1 - return self.line - - def scan(self): - if not self.scanfile: - self.error("No input file has been specified") - return - inputname = self.scanfile.name - self.report("scanfile = %s", `inputname`) - if not self.specfile: - self.report("(No interface specifications will be written)") - else: - self.report("specfile = %s", `self.specfile.name`) - self.specfile.write("# Generated from %s\n\n" % `inputname`) - if not self.defsfile: - self.report("(No symbol definitions will be written)") - else: - self.report("defsfile = %s", `self.defsfile.name`) - self.defsfile.write("# Generated from %s\n\n" % `os.path.split(inputname)[1]`) - self.writeinitialdefs() - self.alreadydone = [] - try: - while 1: - try: line = self.getline() - except EOFError: break - if self.debug: - self.report("LINE: %s" % `line`) - match = self.comment1.match(line) - if match: - line = match.group('rest') - if self.debug: - self.report("\tafter comment1: %s" % `line`) - match = self.comment2.match(line) - while match: - line = match.group('rest1')+match.group('rest2') - if self.debug: - self.report("\tafter comment2: %s" % `line`) - match = self.comment2.match(line) - if self.defsfile: - match = self.sym.match(line) - if match: - if self.debug: - self.report("\tmatches sym.") - self.dosymdef(match) - continue - match = self.head.match(line) - if match: - if self.debug: - self.report("\tmatches head.") - self.dofuncspec() - continue - except EOFError: - self.error("Uncaught EOF error") - self.reportusedtypes() - - def dosymdef(self, match): - name, defn = match.group('name', 'defn') - defn = escape8bit(defn) - if self.debug: - self.report("\tsym: name=%s, defn=%s" % (`name`, `defn`)) - if not name in self.blacklistnames: - self.defsfile.write("%s = %s\n" % (name, defn)) - else: - self.defsfile.write("# %s = %s\n" % (name, defn)) - # XXXX No way to handle greylisted names - - def dofuncspec(self): - raw = self.line - while not self.tail.search(raw): - line = self.getline() - if self.debug: - self.report("* CONTINUATION LINE: %s" % `line`) - match = self.comment1.match(line) - if match: - line = match.group('rest') - if self.debug: - self.report("\tafter comment1: %s" % `line`) - match = self.comment2.match(line) - while match: - line = match.group('rest1')+match.group('rest2') - if self.debug: - self.report("\tafter comment1: %s" % `line`) - match = self.comment2.match(line) - raw = raw + line - if self.debug: - self.report("* WHOLE LINE: %s" % `raw`) - self.processrawspec(raw) - - def processrawspec(self, raw): - match = self.whole.search(raw) - if not match: - self.report("Bad raw spec: %s", `raw`) - if self.debug: - if not self.type.search(raw): - self.report("(Type already doesn't match)") - else: - self.report("(but type matched)") - return - type, name, args = match.group('type', 'name', 'args') - type = re.sub("\*", " ptr", type) - type = re.sub("[ \t]+", "_", type) - if name in self.alreadydone: - self.report("Name has already been defined: %s", `name`) - return - self.report("==> %s %s <==", type, name) - if self.blacklisted(type, name): - self.report("*** %s %s blacklisted", type, name) - return - returnlist = [(type, name, 'ReturnMode')] - returnlist = self.repairarglist(name, returnlist) - [(type, name, returnmode)] = returnlist - arglist = self.extractarglist(args) - arglist = self.repairarglist(name, arglist) - if self.unmanageable(type, name, arglist): - ##for arg in arglist: - ## self.report(" %s", `arg`) - self.report("*** %s %s unmanageable", type, name) - return - self.alreadydone.append(name) - self.generate(type, name, arglist) - - def extractarglist(self, args): - args = args.strip() - if not args or args == "void": - return [] - parts = [s.strip() for s in args.split(",")] - arglist = [] - for part in parts: - arg = self.extractarg(part) - arglist.append(arg) - return arglist - - def extractarg(self, part): - mode = "InMode" - part = part.strip() - match = self.asplit.match(part) - if not match: - self.error("Indecipherable argument: %s", `part`) - return ("unknown", part, mode) - type, name, array = match.group('type', 'name', 'array') - if array: - # array matches an optional [] after the argument name - type = type + " ptr " - type = re.sub("\*", " ptr ", type) - type = type.strip() - type = re.sub("[ \t]+", "_", type) - return self.modifyarg(type, name, mode) - - def modifyarg(self, type, name, mode): - if type[:6] == "const_": - type = type[6:] - elif type[-4:] == "_ptr": - type = type[:-4] - mode = "OutMode" - elif type in self.inherentpointertypes: - mode = "OutMode" - if type[-4:] == "_far": - type = type[:-4] - return type, name, mode - - def repairarglist(self, functionname, arglist): - arglist = arglist[:] - i = 0 - while i < len(arglist): - for item in self.repairinstructions: - if len(item) == 2: - pattern, replacement = item - functionpat = "*" - else: - functionpat, pattern, replacement = item - if not fnmatch.fnmatchcase(functionname, functionpat): - continue - n = len(pattern) - if i+n > len(arglist): continue - current = arglist[i:i+n] - for j in range(n): - if not self.matcharg(pattern[j], current[j]): - break - else: # All items of the pattern match - new = self.substituteargs( - pattern, replacement, current) - if new is not None: - arglist[i:i+n] = new - i = i+len(new) # No recursive substitutions - break - else: # No patterns match - i = i+1 - return arglist - - def matcharg(self, patarg, arg): - return len(filter(None, map(fnmatch.fnmatchcase, arg, patarg))) == 3 - - def substituteargs(self, pattern, replacement, old): - new = [] - for k in range(len(replacement)): - item = replacement[k] - newitem = [item[0], item[1], item[2]] - for i in range(3): - if item[i] == '*': - newitem[i] = old[k][i] - elif item[i][:1] == '$': - index = int(item[i][1:]) - 1 - newitem[i] = old[index][i] - new.append(tuple(newitem)) - ##self.report("old: %s", `old`) - ##self.report("new: %s", `new`) - return new - - def generate(self, type, name, arglist): - self.typeused(type, 'return') - classname, listname = self.destination(type, name, arglist) - if not self.specfile: return - self.specfile.write("f = %s(%s, %s,\n" % (classname, type, `name`)) - for atype, aname, amode in arglist: - self.typeused(atype, amode) - self.specfile.write(" (%s, %s, %s),\n" % - (atype, `aname`, amode)) - if self.greydictnames.has_key(name): - self.specfile.write(" condition=%s,\n"%`self.greydictnames[name]`) - self.specfile.write(")\n") - self.specfile.write("%s.append(f)\n\n" % listname) - - def destination(self, type, name, arglist): - return "FunctionGenerator", "functions" - - def blacklisted(self, type, name): - if type in self.blacklisttypes: - ##self.report("return type %s is blacklisted", type) - return 1 - if name in self.blacklistnames: - ##self.report("function name %s is blacklisted", name) - return 1 - return 0 - - def unmanageable(self, type, name, arglist): - for atype, aname, amode in arglist: - if atype in self.blacklisttypes: - self.report("argument type %s is blacklisted", atype) - return 1 - return 0 + fp.close() + + def initsilent(self): + self.silent = 1 + + def error(self, format, *args): + if self.silent >= 0: + print format%args + + def report(self, format, *args): + if not self.silent: + print format%args + + def writeinitialdefs(self): + pass + + def initblacklists(self): + self.blacklistnames = self.makeblacklistnames() + self.blacklisttypes = ["unknown", "-"] + self.makeblacklisttypes() + self.greydictnames = self.greylist2dict(self.makegreylist()) + + def greylist2dict(self, list): + rv = {} + for define, namelist in list: + for name in namelist: + rv[name] = define + return rv + + def makeblacklistnames(self): + return [] + + def makeblacklisttypes(self): + return [] + + def makegreylist(self): + return [] + + def initrepairinstructions(self): + self.repairinstructions = self.makerepairinstructions() + self.inherentpointertypes = self.makeinherentpointertypes() + + def makerepairinstructions(self): + """Parse the repair file into repair instructions. + + The file format is simple: + 1) use \ to split a long logical line in multiple physical lines + 2) everything after the first # on a line is ignored (as comment) + 3) empty lines are ignored + 4) remaining lines must have exactly 3 colon-separated fields: + functionpattern : argumentspattern : argumentsreplacement + 5) all patterns use shell style pattern matching + 6) an empty functionpattern means the same as * + 7) the other two fields are each comma-separated lists of triples + 8) a triple is a space-separated list of 1-3 words + 9) a triple with less than 3 words is padded at the end with "*" words + 10) when used as a pattern, a triple matches the type, name, and mode + of an argument, respectively + 11) when used as a replacement, the words of a triple specify + replacements for the corresponding words of the argument, + with "*" as a word by itself meaning leave the original word + (no other uses of "*" is allowed) + 12) the replacement need not have the same number of triples + as the pattern + """ + f = self.openrepairfile() + if not f: return [] + print "Reading repair file", `f.name`, "..." + list = [] + lineno = 0 + while 1: + line = f.readline() + if not line: break + lineno = lineno + 1 + startlineno = lineno + while line[-2:] == '\\\n': + line = line[:-2] + ' ' + f.readline() + lineno = lineno + 1 + i = line.find('#') + if i >= 0: line = line[:i] + words = [s.strip() for s in line.split(':')] + if words == ['']: continue + if len(words) <> 3: + print "Line", startlineno, + print ": bad line (not 3 colon-separated fields)" + print `line` + continue + [fpat, pat, rep] = words + if not fpat: fpat = "*" + if not pat: + print "Line", startlineno, + print "Empty pattern" + print `line` + continue + patparts = [s.strip() for s in pat.split(',')] + repparts = [s.strip() for s in rep.split(',')] + patterns = [] + for p in patparts: + if not p: + print "Line", startlineno, + print "Empty pattern part" + print `line` + continue + pattern = p.split() + if len(pattern) > 3: + print "Line", startlineno, + print "Pattern part has > 3 words" + print `line` + pattern = pattern[:3] + else: + while len(pattern) < 3: + pattern.append("*") + patterns.append(pattern) + replacements = [] + for p in repparts: + if not p: + print "Line", startlineno, + print "Empty replacement part" + print `line` + continue + replacement = p.split() + if len(replacement) > 3: + print "Line", startlineno, + print "Pattern part has > 3 words" + print `line` + replacement = replacement[:3] + else: + while len(replacement) < 3: + replacement.append("*") + replacements.append(replacement) + list.append((fpat, patterns, replacements)) + return list + + def makeinherentpointertypes(self): + return [] + + def openrepairfile(self, filename = "REPAIR"): + try: + return open(filename, "rU") + except IOError, msg: + print `filename`, ":", msg + print "Cannot open repair file -- assume no repair needed" + return None + + def initfiles(self): + self.specmine = 0 + self.defsmine = 0 + self.scanmine = 0 + self.specfile = sys.stdout + self.defsfile = None + self.scanfile = sys.stdin + self.lineno = 0 + self.line = "" + + def initpaths(self): + self.includepath = [os.curdir, INCLUDEDIR] + + def initpatterns(self): + self.head_pat = r"^EXTERN_API[^_]" + self.tail_pat = r"[;={}]" + self.type_pat = r"EXTERN_API" + \ + r"[ \t\n]*\([ \t\n]*" + \ + r"(?P<type>[a-zA-Z0-9_* \t]*[a-zA-Z0-9_*])" + \ + r"[ \t\n]*\)[ \t\n]*" + self.name_pat = r"(?P<name>[a-zA-Z0-9_]+)[ \t\n]*" + self.args_pat = r"\((?P<args>([^\(;=\)]+|\([^\(;=\)]*\))*)\)" + self.whole_pat = self.type_pat + self.name_pat + self.args_pat + self.sym_pat = r"^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \ + r"[ \t]*(?P<defn>[-0-9_a-zA-Z'\"\(][^\t\n,;}]*),?" + self.asplit_pat = r"^(?P<type>.*[^a-zA-Z0-9_])(?P<name>[a-zA-Z0-9_]+)(?P<array>\[\])?$" + self.comment1_pat = r"(?P<rest>.*)//.*" + # note that the next pattern only removes comments that are wholly within one line + self.comment2_pat = r"(?P<rest1>.*)/\*.*\*/(?P<rest2>.*)" + + def compilepatterns(self): + for name in dir(self): + if name[-4:] == "_pat": + pat = getattr(self, name) + prog = re.compile(pat) + setattr(self, name[:-4], prog) + + def initosspecifics(self): + if MacOS and CREATOR: + self.filetype = 'TEXT' + self.filecreator = CREATOR + else: + self.filetype = self.filecreator = None + + def setfiletype(self, filename): + if MacOS and (self.filecreator or self.filetype): + creator, type = MacOS.GetCreatorAndType(filename) + if self.filecreator: creator = self.filecreator + if self.filetype: type = self.filetype + MacOS.SetCreatorAndType(filename, creator, type) + + def close(self): + self.closefiles() + + def closefiles(self): + self.closespec() + self.closedefs() + self.closescan() + + def closespec(self): + tmp = self.specmine and self.specfile + self.specfile = None + if tmp: tmp.close() + + def closedefs(self): + tmp = self.defsmine and self.defsfile + self.defsfile = None + if tmp: tmp.close() + + def closescan(self): + tmp = self.scanmine and self.scanfile + self.scanfile = None + if tmp: tmp.close() + + def setoutput(self, spec, defs = None): + self.closespec() + self.closedefs() + if spec: + if type(spec) == StringType: + file = self.openoutput(spec) + mine = 1 + else: + file = spec + mine = 0 + self.specfile = file + self.specmine = mine + if defs: + if type(defs) == StringType: + file = self.openoutput(defs) + mine = 1 + else: + file = defs + mine = 0 + self.defsfile = file + self.defsmine = mine + + def openoutput(self, filename): + try: + file = open(filename, 'w') + except IOError, arg: + raise IOError, (filename, arg) + self.setfiletype(filename) + return file + + def setinput(self, scan = sys.stdin): + if not type(scan) in (TupleType, ListType): + scan = [scan] + self.allscaninputs = scan + self._nextinput() + + def _nextinput(self): + if not self.allscaninputs: + return 0 + scan = self.allscaninputs[0] + self.allscaninputs = self.allscaninputs[1:] + self.closescan() + if scan: + if type(scan) == StringType: + file = self.openinput(scan) + mine = 1 + else: + file = scan + mine = 0 + self.scanfile = file + self.scanmine = mine + self.lineno = 0 + return 1 + + def openinput(self, filename): + if not os.path.isabs(filename): + for dir in self.includepath: + fullname = os.path.join(dir, filename) + #self.report("trying full name %s", `fullname`) + try: + return open(fullname, 'rU') + except IOError: + pass + # If not on the path, or absolute, try default open() + try: + return open(filename, 'rU') + except IOError, arg: + raise IOError, (arg, filename) + + def getline(self): + if not self.scanfile: + raise Error, "input file not set" + self.line = self.scanfile.readline() + if not self.line: + if self._nextinput(): + return self.getline() + raise EOFError + self.lineno = self.lineno + 1 + return self.line + + def scan(self): + if not self.scanfile: + self.error("No input file has been specified") + return + inputname = self.scanfile.name + self.report("scanfile = %s", `inputname`) + if not self.specfile: + self.report("(No interface specifications will be written)") + else: + self.report("specfile = %s", `self.specfile.name`) + self.specfile.write("# Generated from %s\n\n" % `inputname`) + if not self.defsfile: + self.report("(No symbol definitions will be written)") + else: + self.report("defsfile = %s", `self.defsfile.name`) + self.defsfile.write("# Generated from %s\n\n" % `os.path.split(inputname)[1]`) + self.writeinitialdefs() + self.alreadydone = [] + try: + while 1: + try: line = self.getline() + except EOFError: break + if self.debug: + self.report("LINE: %s" % `line`) + match = self.comment1.match(line) + if match: + line = match.group('rest') + if self.debug: + self.report("\tafter comment1: %s" % `line`) + match = self.comment2.match(line) + while match: + line = match.group('rest1')+match.group('rest2') + if self.debug: + self.report("\tafter comment2: %s" % `line`) + match = self.comment2.match(line) + if self.defsfile: + match = self.sym.match(line) + if match: + if self.debug: + self.report("\tmatches sym.") + self.dosymdef(match) + continue + match = self.head.match(line) + if match: + if self.debug: + self.report("\tmatches head.") + self.dofuncspec() + continue + except EOFError: + self.error("Uncaught EOF error") + self.reportusedtypes() + + def dosymdef(self, match): + name, defn = match.group('name', 'defn') + defn = escape8bit(defn) + if self.debug: + self.report("\tsym: name=%s, defn=%s" % (`name`, `defn`)) + if not name in self.blacklistnames: + self.defsfile.write("%s = %s\n" % (name, defn)) + else: + self.defsfile.write("# %s = %s\n" % (name, defn)) + # XXXX No way to handle greylisted names + + def dofuncspec(self): + raw = self.line + while not self.tail.search(raw): + line = self.getline() + if self.debug: + self.report("* CONTINUATION LINE: %s" % `line`) + match = self.comment1.match(line) + if match: + line = match.group('rest') + if self.debug: + self.report("\tafter comment1: %s" % `line`) + match = self.comment2.match(line) + while match: + line = match.group('rest1')+match.group('rest2') + if self.debug: + self.report("\tafter comment1: %s" % `line`) + match = self.comment2.match(line) + raw = raw + line + if self.debug: + self.report("* WHOLE LINE: %s" % `raw`) + self.processrawspec(raw) + + def processrawspec(self, raw): + match = self.whole.search(raw) + if not match: + self.report("Bad raw spec: %s", `raw`) + if self.debug: + if not self.type.search(raw): + self.report("(Type already doesn't match)") + else: + self.report("(but type matched)") + return + type, name, args = match.group('type', 'name', 'args') + type = re.sub("\*", " ptr", type) + type = re.sub("[ \t]+", "_", type) + if name in self.alreadydone: + self.report("Name has already been defined: %s", `name`) + return + self.report("==> %s %s <==", type, name) + if self.blacklisted(type, name): + self.report("*** %s %s blacklisted", type, name) + return + returnlist = [(type, name, 'ReturnMode')] + returnlist = self.repairarglist(name, returnlist) + [(type, name, returnmode)] = returnlist + arglist = self.extractarglist(args) + arglist = self.repairarglist(name, arglist) + if self.unmanageable(type, name, arglist): + ##for arg in arglist: + ## self.report(" %s", `arg`) + self.report("*** %s %s unmanageable", type, name) + return + self.alreadydone.append(name) + self.generate(type, name, arglist) + + def extractarglist(self, args): + args = args.strip() + if not args or args == "void": + return [] + parts = [s.strip() for s in args.split(",")] + arglist = [] + for part in parts: + arg = self.extractarg(part) + arglist.append(arg) + return arglist + + def extractarg(self, part): + mode = "InMode" + part = part.strip() + match = self.asplit.match(part) + if not match: + self.error("Indecipherable argument: %s", `part`) + return ("unknown", part, mode) + type, name, array = match.group('type', 'name', 'array') + if array: + # array matches an optional [] after the argument name + type = type + " ptr " + type = re.sub("\*", " ptr ", type) + type = type.strip() + type = re.sub("[ \t]+", "_", type) + return self.modifyarg(type, name, mode) + + def modifyarg(self, type, name, mode): + if type[:6] == "const_": + type = type[6:] + elif type[-4:] == "_ptr": + type = type[:-4] + mode = "OutMode" + elif type in self.inherentpointertypes: + mode = "OutMode" + if type[-4:] == "_far": + type = type[:-4] + return type, name, mode + + def repairarglist(self, functionname, arglist): + arglist = arglist[:] + i = 0 + while i < len(arglist): + for item in self.repairinstructions: + if len(item) == 2: + pattern, replacement = item + functionpat = "*" + else: + functionpat, pattern, replacement = item + if not fnmatch.fnmatchcase(functionname, functionpat): + continue + n = len(pattern) + if i+n > len(arglist): continue + current = arglist[i:i+n] + for j in range(n): + if not self.matcharg(pattern[j], current[j]): + break + else: # All items of the pattern match + new = self.substituteargs( + pattern, replacement, current) + if new is not None: + arglist[i:i+n] = new + i = i+len(new) # No recursive substitutions + break + else: # No patterns match + i = i+1 + return arglist + + def matcharg(self, patarg, arg): + return len(filter(None, map(fnmatch.fnmatchcase, arg, patarg))) == 3 + + def substituteargs(self, pattern, replacement, old): + new = [] + for k in range(len(replacement)): + item = replacement[k] + newitem = [item[0], item[1], item[2]] + for i in range(3): + if item[i] == '*': + newitem[i] = old[k][i] + elif item[i][:1] == '$': + index = int(item[i][1:]) - 1 + newitem[i] = old[index][i] + new.append(tuple(newitem)) + ##self.report("old: %s", `old`) + ##self.report("new: %s", `new`) + return new + + def generate(self, type, name, arglist): + self.typeused(type, 'return') + classname, listname = self.destination(type, name, arglist) + if not self.specfile: return + self.specfile.write("f = %s(%s, %s,\n" % (classname, type, `name`)) + for atype, aname, amode in arglist: + self.typeused(atype, amode) + self.specfile.write(" (%s, %s, %s),\n" % + (atype, `aname`, amode)) + if self.greydictnames.has_key(name): + self.specfile.write(" condition=%s,\n"%`self.greydictnames[name]`) + self.specfile.write(")\n") + self.specfile.write("%s.append(f)\n\n" % listname) + + def destination(self, type, name, arglist): + return "FunctionGenerator", "functions" + + def blacklisted(self, type, name): + if type in self.blacklisttypes: + ##self.report("return type %s is blacklisted", type) + return 1 + if name in self.blacklistnames: + ##self.report("function name %s is blacklisted", name) + return 1 + return 0 + + def unmanageable(self, type, name, arglist): + for atype, aname, amode in arglist: + if atype in self.blacklisttypes: + self.report("argument type %s is blacklisted", atype) + return 1 + return 0 class Scanner_PreUH3(Scanner): - """Scanner for Universal Headers before release 3""" - def initpatterns(self): - Scanner.initpatterns(self) - self.head_pat = "^extern pascal[ \t]+" # XXX Mac specific! - self.type_pat = "pascal[ \t\n]+(?P<type>[a-zA-Z0-9_ \t]*[a-zA-Z0-9_])[ \t\n]+" - self.whole_pat = self.type_pat + self.name_pat + self.args_pat - self.sym_pat = "^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \ - "[ \t]*(?P<defn>[-0-9'\"][^\t\n,;}]*),?" + """Scanner for Universal Headers before release 3""" + def initpatterns(self): + Scanner.initpatterns(self) + self.head_pat = "^extern pascal[ \t]+" # XXX Mac specific! + self.type_pat = "pascal[ \t\n]+(?P<type>[a-zA-Z0-9_ \t]*[a-zA-Z0-9_])[ \t\n]+" + self.whole_pat = self.type_pat + self.name_pat + self.args_pat + self.sym_pat = "^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \ + "[ \t]*(?P<defn>[-0-9'\"][^\t\n,;}]*),?" class Scanner_OSX(Scanner): - """Scanner for modern (post UH3.3) Universal Headers """ - def initpatterns(self): - Scanner.initpatterns(self) - self.head_pat = "^EXTERN_API(_C)?" - self.type_pat = "EXTERN_API(_C)?" + \ - "[ \t\n]*\([ \t\n]*" + \ - "(?P<type>[a-zA-Z0-9_* \t]*[a-zA-Z0-9_*])" + \ - "[ \t\n]*\)[ \t\n]*" - self.whole_pat = self.type_pat + self.name_pat + self.args_pat - self.sym_pat = "^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \ - "[ \t]*(?P<defn>[-0-9_a-zA-Z'\"\(][^\t\n,;}]*),?" + """Scanner for modern (post UH3.3) Universal Headers """ + def initpatterns(self): + Scanner.initpatterns(self) + self.head_pat = "^EXTERN_API(_C)?" + self.type_pat = "EXTERN_API(_C)?" + \ + "[ \t\n]*\([ \t\n]*" + \ + "(?P<type>[a-zA-Z0-9_* \t]*[a-zA-Z0-9_*])" + \ + "[ \t\n]*\)[ \t\n]*" + self.whole_pat = self.type_pat + self.name_pat + self.args_pat + self.sym_pat = "^[ \t]*(?P<name>[a-zA-Z0-9_]+)[ \t]*=" + \ + "[ \t]*(?P<defn>[-0-9_a-zA-Z'\"\(][^\t\n,;}]*),?" _8bit = re.compile(r"[\200-\377]") def escape8bit(s): - if _8bit.search(s) is not None: - out = [] - for c in s: - o = ord(c) - if o >= 128: - out.append("\\" + hex(o)[1:]) - else: - out.append(c) - s = "".join(out) - return s + if _8bit.search(s) is not None: + out = [] + for c in s: + o = ord(c) + if o >= 128: + out.append("\\" + hex(o)[1:]) + else: + out.append(c) + s = "".join(out) + return s def test(): - input = "D:Development:THINK C:Mac #includes:Apple #includes:AppleEvents.h" - output = "@aespecs.py" - defsoutput = "@aedefs.py" - s = Scanner(input, output, defsoutput) - s.scan() + input = "D:Development:THINK C:Mac #includes:Apple #includes:AppleEvents.h" + output = "@aespecs.py" + defsoutput = "@aedefs.py" + s = Scanner(input, output, defsoutput) + s.scan() if __name__ == '__main__': - test() + test() |