These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524
303 lines
8.9 KiB
Python
303 lines
8.9 KiB
Python
from bgenOutput import *
|
|
from bgenType import *
|
|
from bgenVariable import *
|
|
|
|
|
|
Error = "bgenGenerator.Error"
|
|
|
|
DEBUG=0
|
|
|
|
# Strings to specify argument transfer modes in generator calls
|
|
IN = "in"
|
|
OUT = "out"
|
|
INOUT = IN_OUT = "in-out"
|
|
|
|
|
|
class BaseFunctionGenerator:
|
|
|
|
def __init__(self, name, condition=None, callname=None, modifiers=None):
|
|
if DEBUG: print "<--", name
|
|
self.name = name
|
|
if callname:
|
|
self.callname = callname
|
|
else:
|
|
self.callname = name
|
|
self.prefix = name
|
|
self.objecttype = "PyObject" # Type of _self argument to function
|
|
self.condition = condition
|
|
self.modifiers = modifiers
|
|
|
|
def setprefix(self, prefix):
|
|
self.prefix = prefix
|
|
|
|
def checkgenerate(self):
|
|
return True
|
|
|
|
def generate(self):
|
|
if not self.checkgenerate():
|
|
return
|
|
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 not self.checkgenerate():
|
|
return
|
|
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
|
|
|
|
|
|
class ManualGenerator(BaseFunctionGenerator):
|
|
|
|
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
|
|
|
|
|
|
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 is 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):
|
|
sep = ",\n" + ' '*len("if (!PyArg_ParseTuple(")
|
|
fmt, lst = self.getargsFormatArgs(sep)
|
|
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 getargsFormatArgs(self, sep):
|
|
fmt = ""
|
|
lst = ""
|
|
for arg in self.argumentList:
|
|
if arg.flags == SelfMode:
|
|
continue
|
|
if arg.mode in (InMode, InOutMode):
|
|
arg.getargsPreCheck()
|
|
fmt = fmt + arg.getargsFormat()
|
|
args = arg.getargsArgs()
|
|
if args:
|
|
lst = lst + sep + args
|
|
return fmt, lst
|
|
|
|
def precheck(self):
|
|
pass
|
|
|
|
def beginallowthreads(self):
|
|
pass
|
|
|
|
def endallowthreads(self):
|
|
pass
|
|
|
|
def callit(self):
|
|
args = ""
|
|
s = "%s%s(" % (self.getrvforcallit(), self.callname)
|
|
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
|
|
self.beginallowthreads()
|
|
Output("%s%s(%s);",
|
|
self.getrvforcallit(), self.callname, args)
|
|
self.endallowthreads()
|
|
|
|
def getrvforcallit(self):
|
|
if self.rv:
|
|
return "%s = " % self.rv.name
|
|
else:
|
|
return ""
|
|
|
|
def checkit(self):
|
|
for arg in self.argumentList:
|
|
arg.errorCheck()
|
|
|
|
def returnvalue(self):
|
|
sep = ",\n" + ' '*len("return Py_BuildValue(")
|
|
fmt, lst = self.mkvalueFormatArgs(sep)
|
|
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 mkvalueFormatArgs(self, sep):
|
|
fmt = ""
|
|
lst = ""
|
|
for arg in self.argumentList:
|
|
if not arg: continue
|
|
if arg.flags == ErrorMode: continue
|
|
if arg.mode in (OutMode, InOutMode):
|
|
arg.mkvaluePreCheck()
|
|
fmt = fmt + arg.mkvalueFormat()
|
|
lst = lst + sep + arg.mkvalueArgs()
|
|
return fmt, lst
|
|
|
|
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 _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()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
_test()
|