summaryrefslogtreecommitdiffstats
path: root/Tools/bgen
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>2003-01-19 21:53:57 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>2003-01-19 21:53:57 (GMT)
commit2cf08ab4c2ef9743b35e61414c978555e2c6815d (patch)
treea366fb5e447728555fac03e5eb6f209fa371e490 /Tools/bgen
parent28256f276e1d61d54301b874958fc78c26117c9e (diff)
downloadcpython-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.py360
-rw-r--r--Tools/bgen/bgen/bgenGenerator.py468
-rw-r--r--Tools/bgen/bgen/bgenGeneratorGroup.py58
-rw-r--r--Tools/bgen/bgen/bgenHeapBuffer.py134
-rw-r--r--Tools/bgen/bgen/bgenModule.py168
-rw-r--r--Tools/bgen/bgen/bgenObjectDefinition.py948
-rw-r--r--Tools/bgen/bgen/bgenOutput.py326
-rw-r--r--Tools/bgen/bgen/bgenStackBuffer.py56
-rw-r--r--Tools/bgen/bgen/bgenStringBuffer.py78
-rw-r--r--Tools/bgen/bgen/bgenType.py282
-rw-r--r--Tools/bgen/bgen/bgenVariable.py138
-rw-r--r--Tools/bgen/bgen/macsupport.py76
-rw-r--r--Tools/bgen/bgen/scantools.py1244
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()