diff options
author | Armin Rigo <arigo@tunes.org> | 2012-07-28 22:38:07 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2012-07-28 22:38:07 +0200 |
commit | ad729259d4fc96fc68215056c5f5ed9cad44a794 (patch) | |
tree | 0957a882902708ce617800d3568b60a81c9e81fb /cffi/verifier.py | |
parent | 55c5e2e47f961face24f6e5bb1d1849a9dd1a35c (diff) | |
parent | 443dd327d32cf1322889693f84cf43fdc18a7324 (diff) | |
download | cffi-ad729259d4fc96fc68215056c5f5ed9cad44a794.tar.gz |
hg merge default
Diffstat (limited to 'cffi/verifier.py')
-rw-r--r-- | cffi/verifier.py | 582 |
1 files changed, 143 insertions, 439 deletions
diff --git a/cffi/verifier.py b/cffi/verifier.py index 0661cd9..2e775ae 100644 --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -16,7 +16,7 @@ class Verifier(object): self.preamble = preamble self.kwds = kwds # - key = '\x00'.join(['1', sys.version[:3], __version__, preamble] + + key = '\x00'.join(['2', sys.version[:3], __version__, preamble] + ffi._cdefsources) k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff).lstrip('0').rstrip('L') k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff).lstrip('0').rstrip('L') @@ -81,26 +81,11 @@ class Verifier(object): if f is not None: f.close() self.modulefilename = filename - self._collect_types() self._status = 'module' def _prnt(self, what=''): print >> self._f, what - def _gettypenum(self, type): - # a KeyError here is a bug. please report it! :-) - return self._typesdict[type] - - def _collect_types(self): - self._typesdict = {} - self._generate("collecttype") - - def _do_collect_type(self, tp): - if (not isinstance(tp, model.PrimitiveType) and - tp not in self._typesdict): - num = len(self._typesdict) - self._typesdict[tp] = num - def _write_source(self, file=None): must_close = (file is None) if must_close: @@ -116,64 +101,15 @@ class Verifier(object): self._status = 'source' def _write_source_to_f(self): - self._collect_types() - # - # The new module will have a _cffi_setup() function that receives - # objects from the ffi world, and that calls some setup code in - # the module. This setup code is split in several independent - # functions, e.g. one per constant. The functions are "chained" - # by ending in a tail call to each other. - # - # This is further split in two chained lists, depending on if we - # can do it at import-time or if we must wait for _cffi_setup() to - # provide us with the <ctype> objects. This is needed because we - # need the values of the enum constants in order to build the - # <ctype 'enum'> that we may have to pass to _cffi_setup(). - # - # The following two 'chained_list_constants' items contains - # the head of these two chained lists, as a string that gives the - # call to do, if any. - self._chained_list_constants = ['0', '0'] - # prnt = self._prnt - # first paste some standard set of lines that are mostly '#define' + # first paste some standard set of lines that are mostly '#include' prnt(cffimod_header) - prnt() # then paste the C source given by the user, verbatim. prnt(self.preamble) - prnt() # # call generate_cpy_xxx_decl(), for every xxx found from # ffi._parser._declarations. This generates all the functions. self._generate("decl") - # - # implement the function _cffi_setup_custom() as calling the - # head of the chained list. - self._generate_setup_custom() - prnt() - # - # produce the method table, including the entries for the - # generated Python->C function wrappers, which are done - # by generate_cpy_function_method(). - prnt('static PyMethodDef _cffi_methods[] = {') - self._generate("method") - prnt(' {"_cffi_setup", _cffi_setup, METH_VARARGS},') - prnt(' {NULL, NULL} /* Sentinel */') - prnt('};') - prnt() - # - # standard init. - modname = self.get_module_name() - prnt('PyMODINIT_FUNC') - prnt('init%s(void)' % modname) - prnt('{') - prnt(' PyObject *lib;') - prnt(' lib = Py_InitModule("%s", _cffi_methods);' % modname) - prnt(' if (lib == NULL || %s < 0)' % ( - self._chained_list_constants[False],)) - prnt(' return;') - prnt(' _cffi_init();') - prnt('}') def _compile_module(self): # compile this C source @@ -190,13 +126,9 @@ class Verifier(object): def _load_library(self): # XXX review all usages of 'self' here! - # import it as a new extension module - try: - module = imp.load_dynamic(self.get_module_name(), - self.modulefilename) - except ImportError, e: - error = "importing %r: %s" % (self.modulefilename, e) - raise ffiplatform.VerificationError(error) + # import it with the CFFI backend + backend = self.ffi._backend + module = backend.load_library(self.modulefilename) # # call loading_cpy_struct() to get the struct layout inferred by # the C compiler @@ -204,10 +136,10 @@ class Verifier(object): # # the C code will need the <ctype> objects. Collect them in # order in a list. - revmapping = dict([(value, key) - for (key, value) in self._typesdict.items()]) - lst = [revmapping[i] for i in range(len(revmapping))] - lst = map(self.ffi._get_cached_btype, lst) + #revmapping = dict([(value, key) + # for (key, value) in self._typesdict.items()]) + #lst = [revmapping[i] for i in range(len(revmapping))] + #lst = map(self.ffi._get_cached_btype, lst) # # build the FFILibrary class and instance and call _cffi_setup(). # this will set up some fields like '_cffi_types', and only then @@ -215,9 +147,9 @@ class Verifier(object): # build (notably) the constant objects, as <cdata> if they are # pointers, and store them as attributes on the 'library' object. class FFILibrary(object): - pass + _cffi_module = module library = FFILibrary() - module._cffi_setup(lst, ffiplatform.VerificationError, library) + #module._cffi_setup(lst, ffiplatform.VerificationError, library) # # finally, call the loaded_cpy_xxx() functions. This will perform # the final adjustments, like copying the Python->C wrapper @@ -250,171 +182,85 @@ class Verifier(object): pass # ---------- - - def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): - extraarg = '' - if isinstance(tp, model.PrimitiveType): - converter = '_cffi_to_c_%s' % (tp.name.replace(' ', '_'),) - errvalue = '-1' - # - elif isinstance(tp, model.PointerType): - if (isinstance(tp.totype, model.PrimitiveType) and - tp.totype.name == 'char'): - converter = '_cffi_to_c_char_p' - else: - converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') - extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) - errvalue = 'NULL' - # - elif isinstance(tp, (model.StructOrUnion, model.EnumType)): - # a struct (not a struct pointer) as a function argument - self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' - % (tovar, self._gettypenum(tp), fromvar)) - self._prnt(' %s;' % errcode) - return - # - elif isinstance(tp, model.FunctionPtrType): - converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') - extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) - errvalue = 'NULL' - # - else: - raise NotImplementedError(tp) - # - self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) - self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( - tovar, tp.get_c_name(''), errvalue)) - self._prnt(' %s;' % errcode) - - def _convert_expr_from_c(self, tp, var): - if isinstance(tp, model.PrimitiveType): - return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var) - elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): - return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( - var, self._gettypenum(tp)) - elif isinstance(tp, model.ArrayType): - return '_cffi_from_c_deref((char *)%s, _cffi_type(%d))' % ( - var, self._gettypenum(tp)) - elif isinstance(tp, model.StructType): - return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( - var, self._gettypenum(tp)) - elif isinstance(tp, model.EnumType): - return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( - var, self._gettypenum(tp)) - else: - raise NotImplementedError(tp) - - # ---------- # typedefs: generates no code so far - _generate_cpy_typedef_collecttype = _generate_nothing _generate_cpy_typedef_decl = _generate_nothing - _generate_cpy_typedef_method = _generate_nothing _loading_cpy_typedef = _loaded_noop _loaded_cpy_typedef = _loaded_noop # ---------- # function declarations - def _generate_cpy_function_collecttype(self, tp, name): - assert isinstance(tp, model.FunctionPtrType) - if tp.ellipsis: - self._do_collect_type(tp) - else: - for type in tp.args: - self._do_collect_type(type) - self._do_collect_type(tp.result) - def _generate_cpy_function_decl(self, tp, name): assert isinstance(tp, model.FunctionPtrType) if tp.ellipsis: # cannot support vararg functions better than this: check for its # exact type (including the fixed arguments), and build it as a - # constant function pointer (no CPython wrapper) + # constant function pointer (no _cffi_f_%s wrapper) self._generate_cpy_const(False, name, tp) return prnt = self._prnt numargs = len(tp.args) - if numargs == 0: - argname = 'no_arg' - elif numargs == 1: - argname = 'arg0' - else: - argname = 'args' - prnt('static PyObject *') - prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + argnames = [] + for i, type in enumerate(tp.args): + indirection = '' + if isinstance(type, model.StructOrUnion): + indirection = '*' + argnames.append('%sx%d' % (indirection, i)) + arglist = [type.get_c_name(' %s' % arg) + for type, arg in zip(tp.args, argnames)] + arglist = ', '.join(arglist) or 'void' + funcdecl = ' _cffi_f_%s(%s)' % (name, arglist) + prnt(tp.result.get_c_name(funcdecl)) prnt('{') # - for i, type in enumerate(tp.args): - prnt(' %s;' % type.get_c_name(' x%d' % i)) if not isinstance(tp.result, model.VoidType): - result_code = 'result = ' - prnt(' %s;' % tp.result.get_c_name(' result')) + result_code = 'return ' else: result_code = '' - # - if len(tp.args) > 1: - rng = range(len(tp.args)) - for i in rng: - prnt(' PyObject *arg%d;' % i) - prnt() - prnt(' if (!PyArg_ParseTuple(args, "%s:%s", %s))' % ( - 'O' * numargs, name, ', '.join(['&arg%d' % i for i in rng]))) - prnt(' return NULL;') - prnt() - # - for i, type in enumerate(tp.args): - self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, - 'return NULL') - prnt() - # - prnt(' _cffi_restore_errno();') - prnt(' { %s%s(%s); }' % ( - result_code, name, - ', '.join(['x%d' % i for i in range(len(tp.args))]))) - prnt(' _cffi_save_errno();') - prnt() - # - if result_code: - prnt(' return %s;' % - self._convert_expr_from_c(tp.result, 'result')) - else: - prnt(' Py_INCREF(Py_None);') - prnt(' return Py_None;') + prnt(' %s%s(%s);' % (result_code, name, ', '.join(argnames))) prnt('}') prnt() - def _generate_cpy_function_method(self, tp, name): - if tp.ellipsis: - return - numargs = len(tp.args) - if numargs == 0: - meth = 'METH_NOARGS' - elif numargs == 1: - meth = 'METH_O' - else: - meth = 'METH_VARARGS' - self._prnt(' {"%s", _cffi_f_%s, %s},' % (name, name, meth)) - _loading_cpy_function = _loaded_noop def _loaded_cpy_function(self, tp, name, module, library): + assert isinstance(tp, model.FunctionPtrType) if tp.ellipsis: - return - setattr(library, name, getattr(module, name)) + newfunction = self._load_constant(False, tp, name, module) + else: + indirections = [] + if any(isinstance(type, model.StructOrUnion) for type in tp.args): + indirect_args = [] + for i, type in enumerate(tp.args): + if isinstance(type, model.StructOrUnion): + type = model.PointerType(type) + indirections.append((i, type)) + indirect_args.append(type) + tp = model.FunctionPtrType(tuple(indirect_args), + tp.result, tp.ellipsis) + BFunc = self.ffi._get_cached_btype(tp) + wrappername = '_cffi_f_%s' % name + newfunction = module.load_function(BFunc, wrappername) + for i, type in indirections: + newfunction = self._make_struct_wrapper(newfunction, i, type) + setattr(library, name, newfunction) + + def _make_struct_wrapper(self, oldfunc, i, tp): + backend = self.ffi._backend + BType = self.ffi._get_cached_btype(tp) + def newfunc(*args): + args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:] + return oldfunc(*args) + return newfunc # ---------- # named structs - _generate_cpy_struct_collecttype = _generate_nothing - def _generate_cpy_struct_decl(self, tp, name): assert name == tp.name self._generate_struct_or_union_decl(tp, 'struct', name) - def _generate_cpy_struct_method(self, tp, name): - self._generate_struct_or_union_method(tp, 'struct', name) - def _loading_cpy_struct(self, tp, name, module): self._loading_struct_or_union(tp, 'struct', name, module) @@ -446,20 +292,19 @@ class Verifier(object): prnt(' { %s = &p->%s; (void)tmp; }' % ( ftype.get_c_name('(*tmp)'), fname)) prnt('}') - prnt('static PyObject *') - prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,)) + prnt('ssize_t %s(ssize_t i)' % (layoutfuncname,)) prnt('{') prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) if tp.partial: - prnt(' static Py_ssize_t nums[] = {') - prnt(' sizeof(%s),' % cname) + prnt(' static ssize_t nums[] = {') + prnt(' 1, sizeof(%s),' % cname) prnt(' offsetof(struct _cffi_aligncheck, y),') for fname in tp.fldnames: prnt(' offsetof(%s, %s),' % (cname, fname)) prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) prnt(' -1') prnt(' };') - prnt(' return _cffi_get_struct_layout(nums);') + prnt(' return nums[i];') else: ffi = self.ffi BStruct = ffi._get_cached_btype(tp) @@ -478,43 +323,42 @@ class Verifier(object): for i in range(1, len(conditions)-1): prnt(' %s ||' % conditions[i]) prnt(' %s) {' % conditions[-1]) - prnt(' Py_INCREF(Py_False);') - prnt(' return Py_False;') + prnt(' return -1;') prnt(' }') prnt(' else {') - prnt(' Py_INCREF(Py_True);') - prnt(' return Py_True;') + prnt(' return 0;') prnt(' }') prnt(' /* the next line is not executed, but compiled */') prnt(' %s(0);' % (checkfuncname,)) prnt('}') prnt() - def _generate_struct_or_union_method(self, tp, prefix, name): - if tp.fldnames is None: - return # nothing to do with opaque structs - layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) - self._prnt(' {"%s", %s, METH_NOARGS},' % (layoutfuncname, - layoutfuncname)) - def _loading_struct_or_union(self, tp, prefix, name, module): if tp.fldnames is None: return # nothing to do with opaque structs layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) cname = ('%s %s' % (prefix, name)).strip() # - function = getattr(module, layoutfuncname) - layout = function() - if layout is False: + BFunc = self.ffi.typeof("ssize_t(*)(ssize_t)") + function = module.load_function(BFunc, layoutfuncname) + layout = function(0) + if layout < 0: raise ffiplatform.VerificationError( "incompatible layout for %s" % cname) - elif layout is True: + elif layout == 0: assert not tp.partial else: - totalsize = layout[0] - totalalignment = layout[1] - fieldofs = layout[2::2] - fieldsize = layout[3::2] + totalsize = function(1) + totalalignment = function(2) + fieldofs = [] + fieldsize = [] + num = 3 + while True: + x = function(num) + if x < 0: break + fieldofs.append(x) + fieldsize.append(function(num+1)) + num += 2 assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment @@ -527,14 +371,9 @@ class Verifier(object): # 'anonymous' declarations. These are produced for anonymous structs # or unions; the 'name' is obtained by a typedef. - _generate_cpy_anonymous_collecttype = _generate_nothing - def _generate_cpy_anonymous_decl(self, tp, name): self._generate_struct_or_union_decl(tp, '', name) - def _generate_cpy_anonymous_method(self, tp, name): - self._generate_struct_or_union_method(tp, '', name) - def _loading_cpy_anonymous(self, tp, name, module): self._loading_struct_or_union(tp, '', name, module) @@ -544,58 +383,54 @@ class Verifier(object): # ---------- # constants, likely declared with '#define' - def _generate_cpy_const(self, is_int, name, tp=None, category='const', - vartp=None, delayed=True): + def _generate_cpy_const(self, is_int, name, tp=None, category='const'): prnt = self._prnt funcname = '_cffi_%s_%s' % (category, name) - prnt('static int %s(PyObject *lib)' % funcname) - prnt('{') - prnt(' PyObject *o;') - prnt(' int res;') - if not is_int: - prnt(' %s;' % (vartp or tp).get_c_name(' i')) - else: + if is_int: assert category == 'const' - # - if not is_int: + prnt('int %s(long long *out_value)' % funcname) + prnt('{') + prnt(' *out_value = (long long)(%s);' % (name,)) + prnt(' return (%s) <= 0;' % (name,)) + prnt('}') + else: + assert tp is not None + prnt(tp.get_c_name(' %s(void)' % funcname),) + prnt('{') if category == 'var': - realexpr = '&' + name + ampersand = '&' else: - realexpr = name - prnt(' i = (%s);' % (realexpr,)) - prnt(' o = %s;' % (self._convert_expr_from_c(tp, 'i'),)) - assert delayed - else: - prnt(' if (LONG_MIN <= (%s) && (%s) <= LONG_MAX)' % (name, name)) - prnt(' o = PyInt_FromLong((long)(%s));' % (name,)) - prnt(' else if ((%s) <= 0)' % (name,)) - prnt(' o = PyLong_FromLongLong((long long)(%s));' % (name,)) - prnt(' else') - prnt(' o = PyLong_FromUnsignedLongLong(' - '(unsigned long long)(%s));' % (name,)) - prnt(' if (o == NULL)') - prnt(' return -1;') - prnt(' res = PyObject_SetAttrString(lib, "%s", o);' % name) - prnt(' Py_DECREF(o);') - prnt(' if (res < 0)') - prnt(' return -1;') - prnt(' return %s;' % self._chained_list_constants[delayed]) - self._chained_list_constants[delayed] = funcname + '(lib)' - prnt('}') + ampersand = '' + prnt(' return (%s%s);' % (ampersand, name)) + prnt('}') prnt() - def _generate_cpy_constant_collecttype(self, tp, name): - is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() - if not is_int: - self._do_collect_type(tp) - def _generate_cpy_constant_decl(self, tp, name): is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() self._generate_cpy_const(is_int, name, tp) - _generate_cpy_constant_method = _generate_nothing _loading_cpy_constant = _loaded_noop - _loaded_cpy_constant = _loaded_noop + + def _load_constant(self, is_int, tp, name, module): + funcname = '_cffi_const_%s' % name + if is_int: + BFunc = self.ffi.typeof("int(*)(long long*)") + function = module.load_function(BFunc, funcname) + p = self.ffi.new("long long*") + negative = function(p) + value = int(p[0]) + if value < 0 and not negative: + value += (1 << (8*self.ffi.sizeof("long long"))) + else: + BFunc = self.ffi.typeof(tp.get_c_name('(*)(void)')) + function = module.load_function(BFunc, funcname) + value = function() + return value + + def _loaded_cpy_constant(self, tp, name, module, library): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + value = self._load_constant(is_int, tp, name, module) + setattr(library, name, value) # ---------- # enums @@ -603,37 +438,40 @@ class Verifier(object): def _generate_cpy_enum_decl(self, tp, name): if tp.partial: for enumerator in tp.enumerators: - self._generate_cpy_const(True, enumerator, delayed=False) + self._generate_cpy_const(True, enumerator) return # funcname = '_cffi_enum_%s' % name prnt = self._prnt - prnt('static int %s(PyObject *lib)' % funcname) + prnt('int %s(char *out_error)' % funcname) prnt('{') for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): prnt(' if (%s != %d) {' % (enumerator, enumvalue)) - prnt(' PyErr_Format(_cffi_VerificationError,') - prnt(' "in enum %s: %s has the real value %d, ' - 'not %d",') - prnt(' "%s", "%s", (int)%s, %d);' % ( + prnt(' snprintf(out_error, 255, "in enum %s: ' + '%s has the real value %d, not %d",') + prnt(' "%s", "%s", (int)%s, %d);' % ( name, enumerator, enumerator, enumvalue)) prnt(' return -1;') prnt(' }') - prnt(' return %s;' % self._chained_list_constants[True]) - self._chained_list_constants[True] = funcname + '(lib)' + prnt(' return 0;') prnt('}') prnt() - _generate_cpy_enum_collecttype = _generate_nothing - _generate_cpy_enum_method = _generate_nothing _loading_cpy_enum = _loaded_noop def _loading_cpy_enum(self, tp, name, module): if tp.partial: - enumvalues = [getattr(module, enumerator) + enumvalues = [self._load_constant(True, tp, enumerator, module) for enumerator in tp.enumerators] tp.enumvalues = tuple(enumvalues) tp.partial = False + else: + BFunc = self.ffi.typeof("int(*)(char*)") + funcname = '_cffi_enum_%s' % name + function = module.load_function(BFunc, funcname) + p = self.ffi.new("char[]", 256) + if function(p) < 0: + raise ffiplatform.VerificationError(str(p)) def _loaded_cpy_enum(self, tp, name, module, library): for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): @@ -646,185 +484,51 @@ class Verifier(object): assert tp == '...' self._generate_cpy_const(True, name) - _generate_cpy_macro_collecttype = _generate_nothing - _generate_cpy_macro_method = _generate_nothing _loading_cpy_macro = _loaded_noop - _loaded_cpy_macro = _loaded_noop + + def _loaded_cpy_macro(self, tp, name, module, library): + value = self._load_constant(True, tp, name, module) + setattr(library, name, value) # ---------- # global variables - def _generate_cpy_variable_collecttype(self, tp, name): - if isinstance(tp, model.ArrayType): - self._do_collect_type(tp) - else: - tp_ptr = model.PointerType(tp) - self._do_collect_type(tp_ptr) - def _generate_cpy_variable_decl(self, tp, name): if isinstance(tp, model.ArrayType): tp_ptr = model.PointerType(tp.item) - self._generate_cpy_const(False, name, tp, vartp=tp_ptr) + self._generate_cpy_const(False, name, tp_ptr) else: tp_ptr = model.PointerType(tp) self._generate_cpy_const(False, name, tp_ptr, category='var') - _generate_cpy_variable_method = _generate_nothing _loading_cpy_variable = _loaded_noop def _loaded_cpy_variable(self, tp, name, module, library): if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the - return # sense that "a=..." is forbidden + # sense that "a=..." is forbidden + tp_ptr = model.PointerType(tp.item) + value = self._load_constant(False, tp_ptr, name, module) + setattr(library, name, value) + return # remove ptr=<cdata 'int *'> from the library instance, and replace # it by a property on the class, which reads/writes into ptr[0]. - ptr = getattr(library, name) - delattr(library, name) + funcname = '_cffi_var_%s' % name + BFunc = self.ffi.typeof(tp.get_c_name('*(*)(void)')) + function = module.load_function(BFunc, funcname) + ptr = function() def getter(library): return ptr[0] def setter(library, value): ptr[0] = value setattr(library.__class__, name, property(getter, setter)) - # ---------- - - def _generate_setup_custom(self): - prnt = self._prnt - prnt('static PyObject *_cffi_setup_custom(PyObject *lib)') - prnt('{') - prnt(' if (%s < 0)' % self._chained_list_constants[True]) - prnt(' return NULL;') - prnt(' Py_INCREF(Py_None);') - prnt(' return Py_None;') - prnt('}') - cffimod_header = r''' -#include <Python.h> +#include <stdio.h> #include <stddef.h> - -#define _cffi_from_c_double PyFloat_FromDouble -#define _cffi_from_c_float PyFloat_FromDouble -#define _cffi_from_c_signed_char PyInt_FromLong -#define _cffi_from_c_short PyInt_FromLong -#define _cffi_from_c_int PyInt_FromLong -#define _cffi_from_c_long PyInt_FromLong -#define _cffi_from_c_unsigned_char PyInt_FromLong -#define _cffi_from_c_unsigned_short PyInt_FromLong -#define _cffi_from_c_unsigned_long PyLong_FromUnsignedLong -#define _cffi_from_c_unsigned_long_long PyLong_FromUnsignedLongLong - -#if SIZEOF_INT < SIZEOF_LONG -# define _cffi_from_c_unsigned_int PyInt_FromLong -#else -# define _cffi_from_c_unsigned_int PyLong_FromUnsignedLong -#endif - -#if SIZEOF_LONG < SIZEOF_LONG_LONG -# define _cffi_from_c_long_long PyLong_FromLongLong -#else -# define _cffi_from_c_long_long PyInt_FromLong -#endif - -#define _cffi_to_c_long PyInt_AsLong -#define _cffi_to_c_double PyFloat_AsDouble -#define _cffi_to_c_float PyFloat_AsDouble - -#define _cffi_to_c_char_p \ - ((char *(*)(PyObject *))_cffi_exports[0]) -#define _cffi_to_c_signed_char \ - ((signed char(*)(PyObject *))_cffi_exports[1]) -#define _cffi_to_c_unsigned_char \ - ((unsigned char(*)(PyObject *))_cffi_exports[2]) -#define _cffi_to_c_short \ - ((short(*)(PyObject *))_cffi_exports[3]) -#define _cffi_to_c_unsigned_short \ - ((unsigned short(*)(PyObject *))_cffi_exports[4]) - -#if SIZEOF_INT < SIZEOF_LONG -# define _cffi_to_c_int \ - ((int(*)(PyObject *))_cffi_exports[5]) -# define _cffi_to_c_unsigned_int \ - ((unsigned int(*)(PyObject *))_cffi_exports[6]) -#else -# define _cffi_to_c_int _cffi_to_c_long -# define _cffi_to_c_unsigned_int _cffi_to_c_unsigned_long -#endif - -#define _cffi_to_c_unsigned_long \ - ((unsigned long(*)(PyObject *))_cffi_exports[7]) -#define _cffi_to_c_unsigned_long_long \ - ((unsigned long long(*)(PyObject *))_cffi_exports[8]) -#define _cffi_to_c_char \ - ((char(*)(PyObject *))_cffi_exports[9]) -#define _cffi_from_c_pointer \ - ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[10]) -#define _cffi_to_c_pointer \ - ((char *(*)(PyObject *, CTypeDescrObject *))_cffi_exports[11]) -#define _cffi_get_struct_layout \ - ((PyObject *(*)(Py_ssize_t[]))_cffi_exports[12]) -#define _cffi_restore_errno \ - ((void(*)(void))_cffi_exports[13]) -#define _cffi_save_errno \ - ((void(*)(void))_cffi_exports[14]) -#define _cffi_from_c_char \ - ((PyObject *(*)(char))_cffi_exports[15]) -#define _cffi_from_c_deref \ - ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16]) -#define _cffi_to_c \ - ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17]) -#define _cffi_from_c_struct \ - ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18]) -#define _cffi_to_c_wchar_t \ - ((wchar_t(*)(PyObject *))_cffi_exports[19]) -#define _cffi_from_c_wchar_t \ - ((PyObject *(*)(wchar_t))_cffi_exports[20]) -#define _CFFI_NUM_EXPORTS 21 - -#if SIZEOF_LONG < SIZEOF_LONG_LONG -# define _cffi_to_c_long_long PyLong_AsLongLong -#else -# define _cffi_to_c_long_long _cffi_to_c_long -#endif - -typedef struct _ctypedescr CTypeDescrObject; - -static void *_cffi_exports[_CFFI_NUM_EXPORTS]; -static PyObject *_cffi_types, *_cffi_VerificationError; - -static PyObject *_cffi_setup_custom(PyObject *lib); /* forward */ - -static PyObject *_cffi_setup(PyObject *self, PyObject *args) -{ - PyObject *library; - if (!PyArg_ParseTuple(args, "OOO", &_cffi_types, &_cffi_VerificationError, - &library)) - return NULL; - Py_INCREF(_cffi_types); - Py_INCREF(_cffi_VerificationError); - return _cffi_setup_custom(library); -} - -static void _cffi_init(void) -{ - PyObject *module = PyImport_ImportModule("_cffi_backend"); - PyObject *c_api_object; - - if (module == NULL) - return; - - c_api_object = PyObject_GetAttrString(module, "_C_API"); - if (c_api_object == NULL) - return; - if (!PyCObject_Check(c_api_object)) { - PyErr_SetNone(PyExc_ImportError); - return; - } - memcpy(_cffi_exports, PyCObject_AsVoidPtr(c_api_object), - _CFFI_NUM_EXPORTS * sizeof(void *)); -} - -#define _cffi_type(num) ((CTypeDescrObject *)PyList_GET_ITEM(_cffi_types, num)) - -/**********/ +#include <stdint.h> +#include <stdarg.h> +#include <errno.h> +#include <sys/types.h> /* XXX for ssize_t */ ''' # ____________________________________________________________ |