def build_ctype(self, name, decl): which = decl.getitem(String(u"type")) if isinstance(which, String) and which.string == u"cfunc": restype = decl.getitem(String(u'restype')) argtypes_list = decl.getitem(String(u'argtypes')) if not isinstance(argtypes_list, List): raise Error(u"incorrect function record") restype = self.lookup_type(restype) argtypes = [] for argtype in argtypes_list.contents: argtypes.append(self.lookup_type(argtype)) return ffi.CFunc(restype, argtypes) if isinstance(which, String) and which.string == u"union": if decl in self.cycle_catch: return self.cycle_catch[decl] fields = decl.getitem(String(u"fields")) self.cycle_catch[decl] = ctype = ffi.Union(None, name) ctype.declare(self.parse_fields(name, fields)) return ctype if isinstance(which, String) and which.string == u"struct": if decl in self.cycle_catch: return self.cycle_catch[decl] fields = decl.getitem(String(u"fields")) self.cycle_catch[decl] = ctype = ffi.Struct(None, name) ctype.declare(self.parse_fields(name, fields)) return ctype if isinstance(which, String) and which.string == u"opaque": return ffi.Struct(None, name) if isinstance(which, String) and which.string == u"array": ctype = self.lookup_type(decl.getitem(String(u'ctype'))) length = decl.getitem(String(u"length")) if length is null: return ffi.Array(ctype) elif isinstance(length, Integer): return ffi.Array(ctype, length.value) else: raise Error(name + u": incorrect length value: %s" % length.repr()) if isinstance(which, String) and which.string == u"pointer": to = self.lookup_type(decl.getitem(String(u'to'))) return ffi.Pointer(to) raise Error(name + u": no ctype builder for " + which.repr())
def lookup_type(self, name): if isinstance(name, String): if name.string in self.typecache: return self.typecache[name.string] if name.string.endswith(u'*'): ctype = ffi.Pointer(self.lookup_type(String(name.string[:-1]))) self.typecache[name.string] = ctype return ctype if self.types.contains(name): decl = self.types.getitem(name) ctype = self.build_ctype(name.string, decl) self.typecache[name.string] = ctype return ctype if name.string in ffi.systemv.types: return ffi.systemv.types[name.string] if name.string == u'void': return null raise Error(name.repr() + u" not in API") else: return self.build_ctype(u"<unnamed>", name)
def lookup_type(self, name): if isinstance(name, String): if name.string in self.typecache: return self.typecache[name.string] if name.string.endswith(u'*'): ctype = ffi.Pointer(self.lookup_type(String(name.string[:-1]))) self.typecache[name.string] = ctype return ctype if self.types.contains(name): decl = self.types.getitem(name) ctype = self.build_ctype(name.string, decl) self.typecache[name.string] = ctype return ctype if name.string in ffi.systemv.types: return ffi.systemv.types[name.string] if name.string == u'void': return null if u"." in name.string and self.dependencies is not None: namespace, name = name.string.split(u".", 1) return self.dependencies.getitem(String(namespace)).getattr(name) raise unwind(LKeyError(self, name)) else: return self.build_ctype(u"<unnamed>", name)
def build_ctype_raw(self, name, decl): which = decl.getitem(String(u"type")) if isinstance(which, String) and which.string == u"cfunc": restype = decl.getitem(String(u'restype')) argtypes_list = decl.getitem(String(u'argtypes')) if not isinstance(argtypes_list, List): raise OldError(u"incorrect function record") restype = self.lookup_type(restype) argtypes = [] for argtype in argtypes_list.contents: argtypes.append(self.lookup_type(argtype)) return ffi.CFunc(restype, argtypes) if isinstance(which, String) and which.string == u"union": if decl in self.cycle_catch: return self.cycle_catch[decl] fields = decl.getitem(String(u"fields")) self.cycle_catch[decl] = ctype = ffi.Union(None, name) ctype.declare(self.parse_fields(name, fields)) return ctype if isinstance(which, String) and which.string == u"struct": if decl in self.cycle_catch: return self.cycle_catch[decl] fields = decl.getitem(String(u"fields")) self.cycle_catch[decl] = ctype = ffi.Struct(None, name) ctype.declare(self.parse_fields(name, fields)) return ctype if isinstance(which, String) and which.string == u"opaque": return ffi.Struct(None, name) if isinstance(which, String) and which.string == u"array": ctype = self.lookup_type(decl.getitem(String(u'ctype'))) length = decl.getitem(String(u"length")) if length is null: return ffi.Array(ctype) elif isinstance(length, Integer): return ffi.Array(ctype, length.value) else: raise OldError(name + u": incorrect length value: %s" % length.repr()) if isinstance(which, String) and which.string == u"pointer": to_obj = decl.getitem(String(u'to')) # A little hack to name common opaque pointers. if isinstance(to_obj, Dict): to = self.build_ctype(name, to_obj) else: to = self.lookup_type(to_obj) return ffi.Pointer(to) if isinstance(which, String) and which.string == u"enum": ctype = self.lookup_type(decl.getitem(String(u'ctype'))) constants = decl.getitem(String(u"constants")) if not isinstance(constants, Dict): raise unwind( LTypeError(name + u": expected constant table to be dictionary")) table = {} for name_, const in constants.data.iteritems(): if not isinstance(name_, String): raise unwind( LTypeError( name + u": expected constants table key to be string")) if not isinstance(const, Integer): raise unwind( LTypeError( name + u": expected constants table value to be integer")) table[name_.string] = const.value return ffi.Bitmask(ffi.to_type(ctype), table, multichoice=False) if isinstance(which, String) and which.string == u"bitmask": ctype = self.lookup_type(decl.getitem(String(u'ctype'))) constants = decl.getitem(String(u"constants")) if not isinstance(constants, Dict): raise unwind( LTypeError(name + u": expected constant table to be dictionary")) table = {} for name_, const in constants.data.iteritems(): if not isinstance(name_, String): raise unwind( LTypeError( name + u": expected constants table key to be string")) if not isinstance(const, Integer): raise unwind( LTypeError( name + u": expected constants table value to be integer")) table[name_.string] = const.value return ffi.Bitmask(ffi.to_type(ctype), table, multichoice=True) raise OldError(name + u": no ctype builder for " + which.repr())