update Linux i686
This commit is contained in:
parent
7f55398eed
commit
89ee84c73e
1390 changed files with 4932 additions and 433509 deletions
|
|
@ -4,5 +4,5 @@ __all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError',
|
|||
from .api import FFI, CDefError, FFIError
|
||||
from .ffiplatform import VerificationError, VerificationMissing
|
||||
|
||||
__version__ = "0.8.2"
|
||||
__version_info__ = (0, 8, 2)
|
||||
__version__ = "0.8.6"
|
||||
__version_info__ = (0, 8, 6)
|
||||
|
|
|
|||
|
|
@ -55,8 +55,7 @@ class FFI(object):
|
|||
# _cffi_backend.so compiled.
|
||||
import _cffi_backend as backend
|
||||
from . import __version__
|
||||
assert (backend.__version__ == __version__ or
|
||||
backend.__version__ == __version__[:3])
|
||||
assert backend.__version__ == __version__
|
||||
# (If you insist you can also try to pass the option
|
||||
# 'backend=backend_ctypes.CTypesBackend()', but don't
|
||||
# rely on it! It's probably not going to work well.)
|
||||
|
|
@ -443,6 +442,10 @@ def _make_ffi_library(ffi, libname, flags):
|
|||
for enumname, enumval in zip(tp.enumerators, tp.enumvalues):
|
||||
if enumname not in library.__dict__:
|
||||
library.__dict__[enumname] = enumval
|
||||
for key, val in ffi._parser._int_constants.items():
|
||||
if key not in library.__dict__:
|
||||
library.__dict__[key] = val
|
||||
|
||||
copied_enums.append(True)
|
||||
if name in library.__dict__:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$")
|
|||
_r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]")
|
||||
_r_words = re.compile(r"\w+|\S")
|
||||
_parser_cache = None
|
||||
_r_int_literal = re.compile(r"^0?x?[0-9a-f]+u?l?$", re.IGNORECASE)
|
||||
|
||||
def _get_parser():
|
||||
global _parser_cache
|
||||
|
|
@ -99,6 +100,7 @@ class Parser(object):
|
|||
self._structnode2type = weakref.WeakKeyDictionary()
|
||||
self._override = False
|
||||
self._packed = False
|
||||
self._int_constants = {}
|
||||
|
||||
def _parse(self, csource):
|
||||
csource, macros = _preprocess(csource)
|
||||
|
|
@ -128,9 +130,10 @@ class Parser(object):
|
|||
finally:
|
||||
if lock is not None:
|
||||
lock.release()
|
||||
return ast, macros
|
||||
# csource will be used to find buggy source text
|
||||
return ast, macros, csource
|
||||
|
||||
def convert_pycparser_error(self, e, csource):
|
||||
def _convert_pycparser_error(self, e, csource):
|
||||
# xxx look for ":NUM:" at the start of str(e) and try to interpret
|
||||
# it as a line number
|
||||
line = None
|
||||
|
|
@ -142,6 +145,12 @@ class Parser(object):
|
|||
csourcelines = csource.splitlines()
|
||||
if 1 <= linenum <= len(csourcelines):
|
||||
line = csourcelines[linenum-1]
|
||||
return line
|
||||
|
||||
def convert_pycparser_error(self, e, csource):
|
||||
line = self._convert_pycparser_error(e, csource)
|
||||
|
||||
msg = str(e)
|
||||
if line:
|
||||
msg = 'cannot parse "%s"\n%s' % (line.strip(), msg)
|
||||
else:
|
||||
|
|
@ -160,14 +169,9 @@ class Parser(object):
|
|||
self._packed = prev_packed
|
||||
|
||||
def _internal_parse(self, csource):
|
||||
ast, macros = self._parse(csource)
|
||||
ast, macros, csource = self._parse(csource)
|
||||
# add the macros
|
||||
for key, value in macros.items():
|
||||
value = value.strip()
|
||||
if value != '...':
|
||||
raise api.CDefError('only supports the syntax "#define '
|
||||
'%s ..." for now (literally)' % key)
|
||||
self._declare('macro ' + key, value)
|
||||
self._process_macros(macros)
|
||||
# find the first "__dotdotdot__" and use that as a separator
|
||||
# between the repeated typedefs and the real csource
|
||||
iterator = iter(ast.ext)
|
||||
|
|
@ -175,27 +179,61 @@ class Parser(object):
|
|||
if decl.name == '__dotdotdot__':
|
||||
break
|
||||
#
|
||||
for decl in iterator:
|
||||
if isinstance(decl, pycparser.c_ast.Decl):
|
||||
self._parse_decl(decl)
|
||||
elif isinstance(decl, pycparser.c_ast.Typedef):
|
||||
if not decl.name:
|
||||
raise api.CDefError("typedef does not declare any name",
|
||||
decl)
|
||||
if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType)
|
||||
and decl.type.type.names == ['__dotdotdot__']):
|
||||
realtype = model.unknown_type(decl.name)
|
||||
elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and
|
||||
isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and
|
||||
isinstance(decl.type.type.type,
|
||||
pycparser.c_ast.IdentifierType) and
|
||||
decl.type.type.type.names == ['__dotdotdot__']):
|
||||
realtype = model.unknown_ptr_type(decl.name)
|
||||
try:
|
||||
for decl in iterator:
|
||||
if isinstance(decl, pycparser.c_ast.Decl):
|
||||
self._parse_decl(decl)
|
||||
elif isinstance(decl, pycparser.c_ast.Typedef):
|
||||
if not decl.name:
|
||||
raise api.CDefError("typedef does not declare any name",
|
||||
decl)
|
||||
if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType)
|
||||
and decl.type.type.names == ['__dotdotdot__']):
|
||||
realtype = model.unknown_type(decl.name)
|
||||
elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and
|
||||
isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and
|
||||
isinstance(decl.type.type.type,
|
||||
pycparser.c_ast.IdentifierType) and
|
||||
decl.type.type.type.names == ['__dotdotdot__']):
|
||||
realtype = model.unknown_ptr_type(decl.name)
|
||||
else:
|
||||
realtype = self._get_type(decl.type, name=decl.name)
|
||||
self._declare('typedef ' + decl.name, realtype)
|
||||
else:
|
||||
realtype = self._get_type(decl.type, name=decl.name)
|
||||
self._declare('typedef ' + decl.name, realtype)
|
||||
raise api.CDefError("unrecognized construct", decl)
|
||||
except api.FFIError as e:
|
||||
msg = self._convert_pycparser_error(e, csource)
|
||||
if msg:
|
||||
e.args = (e.args[0] + "\n *** Err: %s" % msg,)
|
||||
raise
|
||||
|
||||
def _add_constants(self, key, val):
|
||||
if key in self._int_constants:
|
||||
raise api.FFIError(
|
||||
"multiple declarations of constant: %s" % (key,))
|
||||
self._int_constants[key] = val
|
||||
|
||||
def _process_macros(self, macros):
|
||||
for key, value in macros.items():
|
||||
value = value.strip()
|
||||
match = _r_int_literal.search(value)
|
||||
if match is not None:
|
||||
int_str = match.group(0).lower().rstrip("ul")
|
||||
|
||||
# "010" is not valid oct in py3
|
||||
if (int_str.startswith("0") and
|
||||
int_str != "0" and
|
||||
not int_str.startswith("0x")):
|
||||
int_str = "0o" + int_str[1:]
|
||||
|
||||
pyvalue = int(int_str, 0)
|
||||
self._add_constants(key, pyvalue)
|
||||
elif value == '...':
|
||||
self._declare('macro ' + key, value)
|
||||
else:
|
||||
raise api.CDefError("unrecognized construct", decl)
|
||||
raise api.CDefError('only supports the syntax "#define '
|
||||
'%s ..." (literally) or "#define '
|
||||
'%s 0x1FF" for now' % (key, key))
|
||||
|
||||
def _parse_decl(self, decl):
|
||||
node = decl.type
|
||||
|
|
@ -227,7 +265,7 @@ class Parser(object):
|
|||
self._declare('variable ' + decl.name, tp)
|
||||
|
||||
def parse_type(self, cdecl):
|
||||
ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)
|
||||
ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2]
|
||||
assert not macros
|
||||
exprnode = ast.ext[-1].type.args.params[0]
|
||||
if isinstance(exprnode, pycparser.c_ast.ID):
|
||||
|
|
@ -306,7 +344,8 @@ class Parser(object):
|
|||
if ident == 'void':
|
||||
return model.void_type
|
||||
if ident == '__dotdotdot__':
|
||||
raise api.FFIError('bad usage of "..."')
|
||||
raise api.FFIError(':%d: bad usage of "..."' %
|
||||
typenode.coord.line)
|
||||
return resolve_common_type(ident)
|
||||
#
|
||||
if isinstance(type, pycparser.c_ast.Struct):
|
||||
|
|
@ -333,7 +372,8 @@ class Parser(object):
|
|||
return self._get_struct_union_enum_type('union', typenode, name,
|
||||
nested=True)
|
||||
#
|
||||
raise api.FFIError("bad or unsupported type declaration")
|
||||
raise api.FFIError(":%d: bad or unsupported type declaration" %
|
||||
typenode.coord.line)
|
||||
|
||||
def _parse_function_type(self, typenode, funcname=None):
|
||||
params = list(getattr(typenode.args, 'params', []))
|
||||
|
|
@ -499,6 +539,10 @@ class Parser(object):
|
|||
if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and
|
||||
exprnode.op == '-'):
|
||||
return -self._parse_constant(exprnode.expr)
|
||||
# load previously defined int constant
|
||||
if (isinstance(exprnode, pycparser.c_ast.ID) and
|
||||
exprnode.name in self._int_constants):
|
||||
return self._int_constants[exprnode.name]
|
||||
#
|
||||
if partial_length_ok:
|
||||
if (isinstance(exprnode, pycparser.c_ast.ID) and
|
||||
|
|
@ -506,8 +550,8 @@ class Parser(object):
|
|||
self._partial_length = True
|
||||
return '...'
|
||||
#
|
||||
raise api.FFIError("unsupported expression: expected a "
|
||||
"simple numeric constant")
|
||||
raise api.FFIError(":%d: unsupported expression: expected a "
|
||||
"simple numeric constant" % exprnode.coord.line)
|
||||
|
||||
def _build_enum_type(self, explicit_name, decls):
|
||||
if decls is not None:
|
||||
|
|
@ -522,6 +566,7 @@ class Parser(object):
|
|||
if enum.value is not None:
|
||||
nextenumvalue = self._parse_constant(enum.value)
|
||||
enumvalues.append(nextenumvalue)
|
||||
self._add_constants(enum.name, nextenumvalue)
|
||||
nextenumvalue += 1
|
||||
enumvalues = tuple(enumvalues)
|
||||
tp = model.EnumType(explicit_name, enumerators, enumvalues)
|
||||
|
|
@ -535,3 +580,5 @@ class Parser(object):
|
|||
kind = name.split(' ', 1)[0]
|
||||
if kind in ('typedef', 'struct', 'union', 'enum'):
|
||||
self._declare(name, tp)
|
||||
for k, v in other._int_constants.items():
|
||||
self._add_constants(k, v)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ def _build(tmpdir, ext):
|
|||
import distutils.errors
|
||||
#
|
||||
dist = Distribution({'ext_modules': [ext]})
|
||||
dist.parse_config_files()
|
||||
options = dist.get_option_dict('build_ext')
|
||||
options['force'] = ('ffiplatform', True)
|
||||
options['build_lib'] = ('ffiplatform', tmpdir)
|
||||
|
|
|
|||
|
|
@ -89,43 +89,54 @@ class VCPythonEngine(object):
|
|||
# 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(' {"_cffi_setup", _cffi_setup, METH_VARARGS, NULL},')
|
||||
prnt(' {NULL, NULL, 0, NULL} /* Sentinel */')
|
||||
prnt('};')
|
||||
prnt()
|
||||
#
|
||||
# standard init.
|
||||
modname = self.verifier.get_module_name()
|
||||
if sys.version_info >= (3,):
|
||||
prnt('static struct PyModuleDef _cffi_module_def = {')
|
||||
prnt(' PyModuleDef_HEAD_INIT,')
|
||||
prnt(' "%s",' % modname)
|
||||
prnt(' NULL,')
|
||||
prnt(' -1,')
|
||||
prnt(' _cffi_methods,')
|
||||
prnt(' NULL, NULL, NULL, NULL')
|
||||
prnt('};')
|
||||
prnt()
|
||||
initname = 'PyInit_%s' % modname
|
||||
createmod = 'PyModule_Create(&_cffi_module_def)'
|
||||
errorcase = 'return NULL'
|
||||
finalreturn = 'return lib'
|
||||
else:
|
||||
initname = 'init%s' % modname
|
||||
createmod = 'Py_InitModule("%s", _cffi_methods)' % modname
|
||||
errorcase = 'return'
|
||||
finalreturn = 'return'
|
||||
constants = self._chained_list_constants[False]
|
||||
prnt('#if PY_MAJOR_VERSION >= 3')
|
||||
prnt()
|
||||
prnt('static struct PyModuleDef _cffi_module_def = {')
|
||||
prnt(' PyModuleDef_HEAD_INIT,')
|
||||
prnt(' "%s",' % modname)
|
||||
prnt(' NULL,')
|
||||
prnt(' -1,')
|
||||
prnt(' _cffi_methods,')
|
||||
prnt(' NULL, NULL, NULL, NULL')
|
||||
prnt('};')
|
||||
prnt()
|
||||
prnt('PyMODINIT_FUNC')
|
||||
prnt('%s(void)' % initname)
|
||||
prnt('PyInit_%s(void)' % modname)
|
||||
prnt('{')
|
||||
prnt(' PyObject *lib;')
|
||||
prnt(' lib = %s;' % createmod)
|
||||
prnt(' if (lib == NULL || %s < 0)' % (
|
||||
self._chained_list_constants[False],))
|
||||
prnt(' %s;' % errorcase)
|
||||
prnt(' _cffi_init();')
|
||||
prnt(' %s;' % finalreturn)
|
||||
prnt(' lib = PyModule_Create(&_cffi_module_def);')
|
||||
prnt(' if (lib == NULL)')
|
||||
prnt(' return NULL;')
|
||||
prnt(' if (%s < 0 || _cffi_init() < 0) {' % (constants,))
|
||||
prnt(' Py_DECREF(lib);')
|
||||
prnt(' return NULL;')
|
||||
prnt(' }')
|
||||
prnt(' return lib;')
|
||||
prnt('}')
|
||||
prnt()
|
||||
prnt('#else')
|
||||
prnt()
|
||||
prnt('PyMODINIT_FUNC')
|
||||
prnt('init%s(void)' % modname)
|
||||
prnt('{')
|
||||
prnt(' PyObject *lib;')
|
||||
prnt(' lib = Py_InitModule("%s", _cffi_methods);' % modname)
|
||||
prnt(' if (lib == NULL)')
|
||||
prnt(' return;')
|
||||
prnt(' if (%s < 0 || _cffi_init() < 0)' % (constants,))
|
||||
prnt(' return;')
|
||||
prnt(' return;')
|
||||
prnt('}')
|
||||
prnt()
|
||||
prnt('#endif')
|
||||
|
||||
def load_library(self):
|
||||
# XXX review all usages of 'self' here!
|
||||
|
|
@ -394,7 +405,7 @@ class VCPythonEngine(object):
|
|||
meth = 'METH_O'
|
||||
else:
|
||||
meth = 'METH_VARARGS'
|
||||
self._prnt(' {"%s", _cffi_f_%s, %s},' % (name, name, meth))
|
||||
self._prnt(' {"%s", _cffi_f_%s, %s, NULL},' % (name, name, meth))
|
||||
|
||||
_loading_cpy_function = _loaded_noop
|
||||
|
||||
|
|
@ -481,8 +492,8 @@ class VCPythonEngine(object):
|
|||
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))
|
||||
self._prnt(' {"%s", %s, METH_NOARGS, NULL},' % (layoutfuncname,
|
||||
layoutfuncname))
|
||||
|
||||
def _loading_struct_or_union(self, tp, prefix, name, module):
|
||||
if tp.fldnames is None:
|
||||
|
|
@ -589,13 +600,7 @@ class VCPythonEngine(object):
|
|||
'variable type'),))
|
||||
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(' o = _cffi_from_c_int_const(%s);' % name)
|
||||
prnt(' if (o == NULL)')
|
||||
prnt(' return -1;')
|
||||
if size_too:
|
||||
|
|
@ -632,13 +637,18 @@ class VCPythonEngine(object):
|
|||
# ----------
|
||||
# enums
|
||||
|
||||
def _enum_funcname(self, prefix, name):
|
||||
# "$enum_$1" => "___D_enum____D_1"
|
||||
name = name.replace('$', '___D_')
|
||||
return '_cffi_e_%s_%s' % (prefix, name)
|
||||
|
||||
def _generate_cpy_enum_decl(self, tp, name, prefix='enum'):
|
||||
if tp.partial:
|
||||
for enumerator in tp.enumerators:
|
||||
self._generate_cpy_const(True, enumerator, delayed=False)
|
||||
return
|
||||
#
|
||||
funcname = '_cffi_e_%s_%s' % (prefix, name)
|
||||
funcname = self._enum_funcname(prefix, name)
|
||||
prnt = self._prnt
|
||||
prnt('static int %s(PyObject *lib)' % funcname)
|
||||
prnt('{')
|
||||
|
|
@ -760,17 +770,30 @@ cffimod_header = r'''
|
|||
#include <Python.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef MS_WIN32
|
||||
#include <malloc.h> /* for alloca() */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned char _Bool;
|
||||
/* this block of #ifs should be kept exactly identical between
|
||||
c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
|
||||
#if defined(_MSC_VER)
|
||||
# include <malloc.h> /* for alloca() */
|
||||
# if _MSC_VER < 1600 /* MSVC < 2010 */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# if _MSC_VER < 1800 /* MSVC < 2013 */
|
||||
typedef unsigned char _Bool;
|
||||
# endif
|
||||
#else
|
||||
# include <stdint.h>
|
||||
# if (defined (__SVR4) && defined (__sun)) || defined(_AIX)
|
||||
# include <alloca.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
|
|
@ -795,6 +818,15 @@ typedef unsigned char _Bool;
|
|||
#define _cffi_to_c_double PyFloat_AsDouble
|
||||
#define _cffi_to_c_float PyFloat_AsDouble
|
||||
|
||||
#define _cffi_from_c_int_const(x) \
|
||||
(((x) > 0) ? \
|
||||
((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \
|
||||
PyInt_FromLong((long)(x)) : \
|
||||
PyLong_FromUnsignedLongLong((unsigned long long)(x)) : \
|
||||
((long long)(x) >= (long long)LONG_MIN) ? \
|
||||
PyInt_FromLong((long)(x)) : \
|
||||
PyLong_FromLongLong((long long)(x)))
|
||||
|
||||
#define _cffi_from_c_int(x, type) \
|
||||
(((type)-1) > 0 ? /* unsigned */ \
|
||||
(sizeof(type) < sizeof(long) ? PyInt_FromLong(x) : \
|
||||
|
|
@ -804,14 +836,14 @@ typedef unsigned char _Bool;
|
|||
PyLong_FromLongLong(x)))
|
||||
|
||||
#define _cffi_to_c_int(o, type) \
|
||||
(sizeof(type) == 1 ? (((type)-1) > 0 ? _cffi_to_c_u8(o) \
|
||||
: _cffi_to_c_i8(o)) : \
|
||||
sizeof(type) == 2 ? (((type)-1) > 0 ? _cffi_to_c_u16(o) \
|
||||
: _cffi_to_c_i16(o)) : \
|
||||
sizeof(type) == 4 ? (((type)-1) > 0 ? _cffi_to_c_u32(o) \
|
||||
: _cffi_to_c_i32(o)) : \
|
||||
sizeof(type) == 8 ? (((type)-1) > 0 ? _cffi_to_c_u64(o) \
|
||||
: _cffi_to_c_i64(o)) : \
|
||||
(sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \
|
||||
: (type)_cffi_to_c_i8(o)) : \
|
||||
sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \
|
||||
: (type)_cffi_to_c_i16(o)) : \
|
||||
sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \
|
||||
: (type)_cffi_to_c_i32(o)) : \
|
||||
sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \
|
||||
: (type)_cffi_to_c_i64(o)) : \
|
||||
(Py_FatalError("unsupported size for type " #type), 0))
|
||||
|
||||
#define _cffi_to_c_i8 \
|
||||
|
|
@ -885,25 +917,32 @@ static PyObject *_cffi_setup(PyObject *self, PyObject *args)
|
|||
return PyBool_FromLong(was_alive);
|
||||
}
|
||||
|
||||
static void _cffi_init(void)
|
||||
static int _cffi_init(void)
|
||||
{
|
||||
PyObject *module = PyImport_ImportModule("_cffi_backend");
|
||||
PyObject *c_api_object;
|
||||
PyObject *module, *c_api_object = NULL;
|
||||
|
||||
module = PyImport_ImportModule("_cffi_backend");
|
||||
if (module == NULL)
|
||||
return;
|
||||
goto failure;
|
||||
|
||||
c_api_object = PyObject_GetAttrString(module, "_C_API");
|
||||
if (c_api_object == NULL)
|
||||
return;
|
||||
goto failure;
|
||||
if (!PyCapsule_CheckExact(c_api_object)) {
|
||||
Py_DECREF(c_api_object);
|
||||
PyErr_SetNone(PyExc_ImportError);
|
||||
return;
|
||||
goto failure;
|
||||
}
|
||||
memcpy(_cffi_exports, PyCapsule_GetPointer(c_api_object, "cffi"),
|
||||
_CFFI_NUM_EXPORTS * sizeof(void *));
|
||||
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(c_api_object);
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
Py_XDECREF(module);
|
||||
Py_XDECREF(c_api_object);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define _cffi_type(num) ((CTypeDescrObject *)PyList_GET_ITEM(_cffi_types, num))
|
||||
|
|
|
|||
|
|
@ -249,10 +249,10 @@ class VGenericEngine(object):
|
|||
prnt(' /* %s */' % str(e)) # cannot verify it, ignore
|
||||
prnt('}')
|
||||
self.export_symbols.append(layoutfuncname)
|
||||
prnt('ssize_t %s(ssize_t i)' % (layoutfuncname,))
|
||||
prnt('intptr_t %s(intptr_t i)' % (layoutfuncname,))
|
||||
prnt('{')
|
||||
prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname)
|
||||
prnt(' static ssize_t nums[] = {')
|
||||
prnt(' static intptr_t nums[] = {')
|
||||
prnt(' sizeof(%s),' % cname)
|
||||
prnt(' offsetof(struct _cffi_aligncheck, y),')
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
|
|
@ -276,7 +276,7 @@ class VGenericEngine(object):
|
|||
return # nothing to do with opaque structs
|
||||
layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
|
||||
#
|
||||
BFunc = self.ffi._typeof_locked("ssize_t(*)(ssize_t)")[0]
|
||||
BFunc = self.ffi._typeof_locked("intptr_t(*)(intptr_t)")[0]
|
||||
function = module.load_function(BFunc, layoutfuncname)
|
||||
layout = []
|
||||
num = 0
|
||||
|
|
@ -410,13 +410,18 @@ class VGenericEngine(object):
|
|||
# ----------
|
||||
# enums
|
||||
|
||||
def _enum_funcname(self, prefix, name):
|
||||
# "$enum_$1" => "___D_enum____D_1"
|
||||
name = name.replace('$', '___D_')
|
||||
return '_cffi_e_%s_%s' % (prefix, name)
|
||||
|
||||
def _generate_gen_enum_decl(self, tp, name, prefix='enum'):
|
||||
if tp.partial:
|
||||
for enumerator in tp.enumerators:
|
||||
self._generate_gen_const(True, enumerator)
|
||||
return
|
||||
#
|
||||
funcname = '_cffi_e_%s_%s' % (prefix, name)
|
||||
funcname = self._enum_funcname(prefix, name)
|
||||
self.export_symbols.append(funcname)
|
||||
prnt = self._prnt
|
||||
prnt('int %s(char *out_error)' % funcname)
|
||||
|
|
@ -430,14 +435,14 @@ class VGenericEngine(object):
|
|||
enumerator, enumerator, enumvalue))
|
||||
prnt(' char buf[64];')
|
||||
prnt(' if ((%s) < 0)' % enumerator)
|
||||
prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % enumerator)
|
||||
prnt(' sprintf(buf, "%%ld", (long)(%s));' % enumerator)
|
||||
prnt(' else')
|
||||
prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' %
|
||||
prnt(' sprintf(buf, "%%lu", (unsigned long)(%s));' %
|
||||
enumerator)
|
||||
prnt(' snprintf(out_error, 255,'
|
||||
prnt(' sprintf(out_error,'
|
||||
' "%s has the real value %s, not %s",')
|
||||
prnt(' "%s", buf, "%d");' % (
|
||||
enumerator, enumvalue))
|
||||
enumerator[:100], enumvalue))
|
||||
prnt(' return -1;')
|
||||
prnt(' }')
|
||||
prnt(' return 0;')
|
||||
|
|
@ -453,7 +458,7 @@ class VGenericEngine(object):
|
|||
else:
|
||||
BType = self.ffi._typeof_locked("char[]")[0]
|
||||
BFunc = self.ffi._typeof_locked("int(*)(char*)")[0]
|
||||
funcname = '_cffi_e_%s_%s' % (prefix, name)
|
||||
funcname = self._enum_funcname(prefix, name)
|
||||
function = module.load_function(BFunc, funcname)
|
||||
p = self.ffi.new(BType, 256)
|
||||
if function(p) < 0:
|
||||
|
|
@ -547,20 +552,29 @@ cffimod_header = r'''
|
|||
#include <errno.h>
|
||||
#include <sys/types.h> /* XXX for ssize_t on some platforms */
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <Windows.h>
|
||||
# define snprintf _snprintf
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef SSIZE_T ssize_t;
|
||||
typedef unsigned char _Bool;
|
||||
#else
|
||||
/* this block of #ifs should be kept exactly identical between
|
||||
c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
|
||||
#if defined(_MSC_VER)
|
||||
# include <malloc.h> /* for alloca() */
|
||||
# if _MSC_VER < 1600 /* MSVC < 2010 */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# if _MSC_VER < 1800 /* MSVC < 2013 */
|
||||
typedef unsigned char _Bool;
|
||||
# endif
|
||||
#else
|
||||
# include <stdint.h>
|
||||
# if (defined (__SVR4) && defined (__sun)) || defined(_AIX)
|
||||
# include <alloca.h>
|
||||
# endif
|
||||
#endif
|
||||
'''
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue