📄 bgenbacksupport.py
字号:
def checkgenerate(self): return self.virtual def checkreturnvar(self): """Check whether the return value is a reference. If it is we need to declare it in the object in stead of in the method.""" if self.returntype: # Hacking our way ahead. We peek in the typeName, # and to make matters worse we change it to get rid # of the reference and the const. returntypedecl = self.returntype.getArgDeclarations("") if len(returntypedecl) != 1: return None returntypedecl = returntypedecl[0] if "&" in returntypedecl: # It appears to be a reference. Check for "const " if returntypedecl[:6] == "const ": returntypedecl = returntypedecl[6:] while "&" in returntypedecl: returntypedecl = returntypedecl[:-1] returnvarname = self.name + "_rvkeepref" returntypedecl += " " + returnvarname # Hacking gets worse: we create the return # variable in the "usual" way hoping things will "just work" self.rvname = self.name #self.rv = self.makereturnvar() self.return_keepref = True return returntypedecl return None def declarereturnvar(self): if self.rv: return False if not self.returntype: return False self.rv = self.makereturnvar() if self.return_keepref: decl = self.rv.type.getArgDeclarations(self.rvname) assert len(decl) == 1 decl = decl[0] assert "&" in decl if decl[:6] == "const ": decl = decl[6:] while "&" in decl: decl = decl[:-1] Output("%s %s;", decl, self.rvname) for decl in self.rv.type.getAuxDeclarations(self.rvname): Output("%s;", decl) else: self.rv.declare() return True def makereturnvar(self): return Variable(self.returntype, self.rvname, OutMode) 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 generateDeclaration(self): if not self.checkgenerate(): return if self.condition: DedentLevel() Output(self.condition) IndentLevel() Output("%s;", self.getDeclaration()) if self.condition: DedentLevel() Output("#endif") IndentLevel() def getDeclaration(self, qualified=False): if qualified: name = "%s::%s" % (self.classname, self.name) else: name = self.name if self.returntype: namedecl = self.returntype.getArgDeclarations(name) if len(namedecl) != 1: raise RuntimeError, "Illegal return type" namedecl = namedecl[0] else: namedecl = "void %s" % name argdecllist = [] for arg in self.argumentList: argdecllist = argdecllist + arg.getArgDeclarations(fullmodes=True) argdecl = ', '.join(argdecllist) return "%s(%s)%s" % (namedecl, argdecl, self.const) def generate(self): if not self.checkgenerate(): return Output() if self.condition: Output(self.condition) self.functionheader() self.functionbody() self.functiontrailer() if self.condition: Output("#endif") def functionheader(self): Output("%s", self.getDeclaration(qualified=True)) OutLbrace() auxdecllist = [] for arg in self.argumentList: auxdecllist = auxdecllist + arg.getAuxDeclarations() if auxdecllist: for decl in auxdecllist: Output("%s;", decl) Output() def functionbody(self): self.beginGIL() self.declarations() self.precheck() self.callit() self.checkit() self.returnargs() self.endGIL() self.returnvalue() def functiontrailer(self): OutRbrace() def beginGIL(self): #OutLbrace() Output("PyGILState_STATE _GILState = PyGILState_Ensure();") def endGIL(self): Output("PyGILState_Release(_GILState);") #OutRbrace() def returnGIL(self): Output("PyGILState_Release(_GILState);") def declarations(self): anydone = self.declarereturnvar() for arg in self.argumentList: if arg.mode in (InMode, InOutMode): arg.mkvaluePreCheck() initializer = 'Py_BuildValue("%s", %s)' % (arg.mkvalueFormat(), arg.mkvalueArgs()) Output("PyObject *py_%s = %s;", arg.name, initializer) anydone = True if anydone: Output() def precheck(self): # Could acquire Python lock here pass def callit(self): argsformat = self.getargsformat() argsnames = self.getargsnames() if argsnames: argsnames = ', ' + ', '.join(argsnames) else: argsnames = '' Output('PyObject *py_rv = PyObject_CallMethod(py_%s, "%s", "(%s)"%s);', self.classname, self.name, argsformat, argsnames) def checkit(self): Output("if (PyErr_Occurred())") OutLbrace() #self.returnGIL() Output("PySys_WriteStderr(\"Python exception during %s::%s() callback:\\n\");", self.classname, self.name) Output("PyErr_Print();") OutRbrace() Output() def returnargs(self): pyvars = ['py_rv'] if self.rv: self.rv.getargsPreCheck() fmt = self.rv.getargsFormat() args = self.rv.getargsArgs() else: fmt = "" args = "" nargs = 0 for arg in self.argumentList: if arg.mode in (OutMode, InOutMode): arg.getargsPreCheck() fmt = fmt + arg.getargsFormat() thisargs = arg.getargsArgs() if thisargs: nargs += 1 if args: args = args + ", " + thisargs else: args = thisargs if arg.mode in (InMode, InOutMode): pyvars.append('py_%s' % arg.name) if fmt: if nargs > 1: fmt = "(" + fmt + ")" Output('if (py_rv && !PyArg_Parse(py_rv, "%s", %s))', fmt, args) OutLbrace() #self.returnGIL() Output("PySys_WriteStderr(\"Python exception during %s::%s() return:\\n\");", self.classname, self.name) Output("PyErr_Print();") OutRbrace() Output() if self.rv: self.rv.getargsCheck() for arg in self.argumentList: if arg.mode in (OutMode, InOutMode): arg.getargsCheck() for pyvar in pyvars: Output("Py_XDECREF(%s);", pyvar) Output() def returnvalue(self): if self.rv: #self.converttoc(self.rv) if self.return_keepref: fixconst = "" if self.const == ' const': fixconst = 'const_cast<%s *>(this)->' % self.classname Output("%s%s_rvkeepref = %s;", fixconst, self.rv.name, self.rv.name) Output("return %s_rvkeepref;", self.rv.name) else: Output("return %s;", self.rv.name) def getargsformat(self): format = "" for arg in self.argumentList: if arg.mode in (InMode, InOutMode): format = format + "O" return format def getargsnames(self): argnames = [] for arg in self.argumentList: if arg.mode in (InMode, InOutMode): argnames.append("py_%s" % arg.name) return argnames def generateAttributeExistenceTest(self): Output('if (!PyObject_HasAttrString(itself, "%s")) PyErr_Warn(PyExc_Warning, "%s: missing attribute: %s");', self.name, self.classname, self.name)def _test(): m = BackModule("spam") o = BackObjectDefinition("eggs", "eggsbase") m.addobject(o) o.add(BackMethod("ham")) o.add(BackMethod("cheese")) m.generate() if __name__ == '__main__': _test()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -