Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r75270:3db26c31b597
Date: 2015-01-09 11:45 +0100
http://bitbucket.org/pypy/pypy/changeset/3db26c31b597/

Log:    Run pypy/tool/import_cffi.py

diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -6,3 +6,8 @@
 
 __version__ = "0.8.6"
 __version_info__ = (0, 8, 6)
+
+# The verifier module file names are based on the CRC32 of a string that
+# contains the following version number.  It may be older than __version__
+# if nothing is clearly incompatible.
+__version_verifier_modules__ = "0.8.6"
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -69,6 +69,7 @@
         self._function_caches = []
         self._libraries = []
         self._cdefsources = []
+        self._windows_unicode = None
         if hasattr(backend, 'set_ffi'):
             backend.set_ffi(self)
         for name in backend.__dict__:
@@ -77,6 +78,7 @@
         #
         with self._lock:
             self.BVoidP = self._get_cached_btype(model.voidp_type)
+            self.BCharA = self._get_cached_btype(model.char_array_type)
         if isinstance(backend, types.ModuleType):
             # _cffi_backend: attach these constants to the class
             if not hasattr(FFI, 'NULL'):
@@ -191,11 +193,12 @@
 
     def offsetof(self, cdecl, fieldname):
         """Return the offset of the named field inside the given
-        structure, which must be given as a C type name.
+        structure, which must be given as a C type name.  The field
+        may be 'x.y.z' in case of nested structures.
         """
         if isinstance(cdecl, basestring):
             cdecl = self._typeof(cdecl)
-        return self._backend.typeoffsetof(cdecl, fieldname)[1]
+        return self._typeoffsetof(cdecl, fieldname)[1]
 
     def new(self, cdecl, init=None):
         """Allocate an instance according to the specified C type and
@@ -264,6 +267,16 @@
         """
         return self._backend.buffer(cdata, size)
 
+    def from_buffer(self, python_buffer):
+        """Return a <cdata 'char[]'> that points to the data of the
+        given Python object, which must support the buffer interface.
+        Note that this is not meant to be used on the built-in types str,
+        unicode, or bytearray (you can build 'char[]' arrays explicitly)
+        but only on objects containing large quantities of raw data
+        in some other format, like 'array.array' or numpy arrays.
+        """
+        return self._backend.from_buffer(self.BCharA, python_buffer)
+
     def callback(self, cdecl, python_callable=None, error=None):
         """Return a callback object or a decorator making such a
         callback object.  'cdecl' must name a C function pointer type.
@@ -335,9 +348,23 @@
         which requires binary compatibility in the signatures.
         """
         from .verifier import Verifier, _caller_dir_pycache
+        #
+        # If set_unicode(True) was called, insert the UNICODE and
+        # _UNICODE macro declarations
+        if self._windows_unicode:
+            self._apply_windows_unicode(kwargs)
+        #
+        # Set the tmpdir here, and not in Verifier.__init__: it picks
+        # up the caller's directory, which we want to be the caller of
+        # ffi.verify(), as opposed to the caller of Veritier().
         tmpdir = tmpdir or _caller_dir_pycache()
+        #
+        # Make a Verifier() and use it to load the library.
         self.verifier = Verifier(self, source, tmpdir, **kwargs)
         lib = self.verifier.load_library()
+        #
+        # Save the loaded library for keep-alive purposes, even
+        # if the caller doesn't keep it alive itself (it should).
         self._libraries.append(lib)
         return lib
 
@@ -359,12 +386,22 @@
     def addressof(self, cdata, field=None):
         """Return the address of a <cdata 'struct-or-union'>.
         If 'field' is specified, return the address of this field.
+        The field may be 'x.y.z' in case of nested structures.
         """
         ctype = self._backend.typeof(cdata)
-        ctype, offset = self._backend.typeoffsetof(ctype, field)
+        ctype, offset = self._typeoffsetof(ctype, field)
         ctypeptr = self._pointer_to(ctype)
         return self._backend.rawaddressof(ctypeptr, cdata, offset)
 
+    def _typeoffsetof(self, ctype, field):
+        if field is not None and '.' in field:
+            offset = 0
+            for field1 in field.split('.'):
+                ctype, offset1 = self._backend.typeoffsetof(ctype, field1)
+                offset += offset1
+            return ctype, offset
+        return self._backend.typeoffsetof(ctype, field)
+
     def include(self, ffi_to_include):
         """Includes the typedefs, structs, unions and enums defined
         in another FFI instance.  Usage is similar to a #include in C,
@@ -387,6 +424,44 @@
     def from_handle(self, x):
         return self._backend.from_handle(x)
 
+    def set_unicode(self, enabled_flag):
+        """Windows: if 'enabled_flag' is True, enable the UNICODE and
+        _UNICODE defines in C, and declare the types like TCHAR and LPTCSTR
+        to be (pointers to) wchar_t.  If 'enabled_flag' is False,
+        declare these types to be (pointers to) plain 8-bit characters.
+        This is mostly for backward compatibility; you usually want True.
+        """
+        if self._windows_unicode is not None:
+            raise ValueError("set_unicode() can only be called once")
+        enabled_flag = bool(enabled_flag)
+        if enabled_flag:
+            self.cdef("typedef wchar_t TBYTE;"
+                      "typedef wchar_t TCHAR;"
+                      "typedef const wchar_t *LPCTSTR;"
+                      "typedef const wchar_t *PCTSTR;"
+                      "typedef wchar_t *LPTSTR;"
+                      "typedef wchar_t *PTSTR;"
+                      "typedef TBYTE *PTBYTE;"
+                      "typedef TCHAR *PTCHAR;")
+        else:
+            self.cdef("typedef char TBYTE;"
+                      "typedef char TCHAR;"
+                      "typedef const char *LPCTSTR;"
+                      "typedef const char *PCTSTR;"
+                      "typedef char *LPTSTR;"
+                      "typedef char *PTSTR;"
+                      "typedef TBYTE *PTBYTE;"
+                      "typedef TCHAR *PTCHAR;")
+        self._windows_unicode = enabled_flag
+
+    def _apply_windows_unicode(self, kwds):
+        defmacros = kwds.get('define_macros', ())
+        if not isinstance(defmacros, (list, tuple)):
+            raise TypeError("'define_macros' must be a list or tuple")
+        defmacros = list(defmacros) + [('UNICODE', '1'),
+                                       ('_UNICODE', '1')]
+        kwds['define_macros'] = defmacros
+
 
 def _load_backend_lib(backend, name, flags):
     if name is None:
diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py
--- a/lib_pypy/cffi/commontypes.py
+++ b/lib_pypy/cffi/commontypes.py
@@ -29,6 +29,9 @@
                 result = model.PointerType(resolve_common_type(result[:-2]))
         elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
             result = model.PrimitiveType(result)
+        elif result == 'set-unicode-needed':
+            raise api.FFIError("The Windows type %r is only available after "
+                               "you call ffi.set_unicode()" % (commontype,))
         else:
             if commontype == result:
                 raise api.FFIError("Unsupported type: %r.  Please file a bug "
@@ -86,8 +89,6 @@
         "ULONGLONG": "unsigned long long",
         "WCHAR": "wchar_t",
         "SHORT": "short",
-        "TBYTE": "WCHAR",
-        "TCHAR": "WCHAR",
         "UCHAR": "unsigned char",
         "UINT": "unsigned int",
         "UINT8": "unsigned char",
@@ -157,14 +158,12 @@
 
         "LPCVOID": model.const_voidp_type,
         "LPCWSTR": "const WCHAR *",
-        "LPCTSTR": "LPCWSTR",
         "LPDWORD": "DWORD *",
         "LPHANDLE": "HANDLE *",
         "LPINT": "int *",
         "LPLONG": "long *",
         "LPSTR": "CHAR *",
         "LPWSTR": "WCHAR *",
-        "LPTSTR": "LPWSTR",
         "LPVOID": model.voidp_type,
         "LPWORD": "WORD *",
         "LRESULT": "LONG_PTR",
@@ -173,7 +172,6 @@
         "PBYTE": "BYTE *",
         "PCHAR": "CHAR *",
         "PCSTR": "const CHAR *",
-        "PCTSTR": "LPCWSTR",
         "PCWSTR": "const WCHAR *",
         "PDWORD": "DWORD *",
         "PDWORDLONG": "DWORDLONG *",
@@ -200,9 +198,6 @@
         "PSIZE_T": "SIZE_T *",
         "PSSIZE_T": "SSIZE_T *",
         "PSTR": "CHAR *",
-        "PTBYTE": "TBYTE *",
-        "PTCHAR": "TCHAR *",
-        "PTSTR": "LPWSTR",
         "PUCHAR": "UCHAR *",
         "PUHALF_PTR": "UHALF_PTR *",
         "PUINT": "UINT *",
@@ -240,6 +235,15 @@
         "USN": "LONGLONG",
         "VOID": model.void_type,
         "WPARAM": "UINT_PTR",
+
+        "TBYTE": "set-unicode-needed",
+        "TCHAR": "set-unicode-needed",
+        "LPCTSTR": "set-unicode-needed",
+        "PCTSTR": "set-unicode-needed",
+        "LPTSTR": "set-unicode-needed",
+        "PTSTR": "set-unicode-needed",
+        "PTBYTE": "set-unicode-needed",
+        "PTCHAR;": "set-unicode-needed",
         })
     return result
 
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -1,4 +1,3 @@
-
 from . import api, model
 from .commontypes import COMMON_TYPES, resolve_common_type
 try:
@@ -209,6 +208,8 @@
 
     def _add_constants(self, key, val):
         if key in self._int_constants:
+            if self._int_constants[key] == val:
+                return     # ignore identical double declarations
             raise api.FFIError(
                 "multiple declarations of constant: %s" % (key,))
         self._int_constants[key] = val
@@ -460,6 +461,8 @@
             elif kind == 'union':
                 tp = model.UnionType(explicit_name, None, None, None)
             elif kind == 'enum':
+                if explicit_name == '__dotdotdot__':
+                    raise CDefError("Enums cannot be declared with ...")
                 tp = self._build_enum_type(explicit_name, type.values)
             else:
                 raise AssertionError("kind = %r" % (kind,))
@@ -532,9 +535,24 @@
 
     def _parse_constant(self, exprnode, partial_length_ok=False):
         # for now, limited to expressions that are an immediate number
-        # or negative number
+        # or positive/negative number
         if isinstance(exprnode, pycparser.c_ast.Constant):
-            return int(exprnode.value, 0)
+            s = exprnode.value
+            if s.startswith('0'):
+                if s.startswith('0x') or s.startswith('0X'):
+                    return int(s, 16)
+                return int(s, 8)
+            elif '1' <= s[0] <= '9':
+                return int(s, 10)
+            elif s[0] == "'" and s[-1] == "'" and (
+                    len(s) == 3 or (len(s) == 4 and s[1] == "\\")):
+                return ord(s[-2])
+            else:
+                raise api.CDefError("invalid constant %r" % (s,))
+        #
+        if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and
+                exprnode.op == '+'):
+            return self._parse_constant(exprnode.expr)
         #
         if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and
                 exprnode.op == '-'):
diff --git a/lib_pypy/cffi/ffiplatform.py b/lib_pypy/cffi/ffiplatform.py
--- a/lib_pypy/cffi/ffiplatform.py
+++ b/lib_pypy/cffi/ffiplatform.py
@@ -11,6 +11,9 @@
     """
 
 
+LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs',
+                      'extra_objects', 'depends']
+
 def get_extension(srcfilename, modname, sources=(), **kwds):
     from distutils.core import Extension
     allsources = [srcfilename]
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -235,6 +235,8 @@
         BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist)
         return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length)
 
+char_array_type = ArrayType(PrimitiveType('char'), None)
+
 
 class StructOrUnionOrEnum(BaseTypeByIdentity):
     _attrs_ = ('name',)
@@ -478,7 +480,7 @@
     try:
         res = getattr(ffi._backend, funcname)(*args)
     except NotImplementedError as e:
-        raise NotImplementedError("%r: %s" % (srctype, e))
+        raise NotImplementedError("%s: %r: %s" % (funcname, srctype, e))
     # note that setdefault() on WeakValueDictionary is not atomic
     # and contains a rare bug (http://bugs.python.org/issue19542);
     # we have to use a lock and do it ourselves
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
+++ b/lib_pypy/cffi/vengine_cpy.py
@@ -65,7 +65,7 @@
         # 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']
+        self._chained_list_constants = ['((void)lib,0)', '((void)lib,0)']
         #
         prnt = self._prnt
         # first paste some standard set of lines that are mostly '#define'
@@ -138,15 +138,22 @@
         prnt()
         prnt('#endif')
 
-    def load_library(self):
+    def load_library(self, flags=None):
         # XXX review all usages of 'self' here!
         # import it as a new extension module
+        if hasattr(sys, "getdlopenflags"):
+            previous_flags = sys.getdlopenflags()
         try:
+            if hasattr(sys, "setdlopenflags") and flags is not None:
+                sys.setdlopenflags(flags)
             module = imp.load_dynamic(self.verifier.get_module_name(),
                                       self.verifier.modulefilename)
         except ImportError as e:
             error = "importing %r: %s" % (self.verifier.modulefilename, e)
             raise ffiplatform.VerificationError(error)
+        finally:
+            if hasattr(sys, "setdlopenflags"):
+                sys.setdlopenflags(previous_flags)
         #
         # call loading_cpy_struct() to get the struct layout inferred by
         # the C compiler
@@ -228,7 +235,8 @@
                 converter = '_cffi_to_c_int'
                 extraarg = ', %s' % tp.name
             else:
-                converter = '_cffi_to_c_%s' % (tp.name.replace(' ', '_'),)
+                converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''),
+                                                   tp.name.replace(' ', '_'))
             errvalue = '-1'
         #
         elif isinstance(tp, model.PointerType):
@@ -267,8 +275,8 @@
         self._prnt('  if (datasize != 0) {')
         self._prnt('    if (datasize < 0)')
         self._prnt('      %s;' % errcode)
-        self._prnt('    %s = alloca(datasize);' % (tovar,))
-        self._prnt('    memset((void *)%s, 0, datasize);' % (tovar,))
+        self._prnt('    %s = alloca((size_t)datasize);' % (tovar,))
+        self._prnt('    memset((void *)%s, 0, (size_t)datasize);' % (tovar,))
         self._prnt('    if (_cffi_convert_array_from_object('
                    '(char *)%s, _cffi_type(%d), %s) < 0)' % (
             tovar, self._gettypenum(tp), fromvar))
@@ -336,7 +344,7 @@
         prnt = self._prnt
         numargs = len(tp.args)
         if numargs == 0:
-            argname = 'no_arg'
+            argname = 'noarg'
         elif numargs == 1:
             argname = 'arg0'
         else:
@@ -386,6 +394,9 @@
         prnt('  Py_END_ALLOW_THREADS')
         prnt()
         #
+        prnt('  (void)self; /* unused */')
+        if numargs == 0:
+            prnt('  (void)noarg; /* unused */')
         if result_code:
             prnt('  return %s;' %
                  self._convert_expr_from_c(tp.result, 'result', 'result type'))
@@ -452,6 +463,7 @@
         prnt('static void %s(%s *p)' % (checkfuncname, cname))
         prnt('{')
         prnt('  /* only to generate compile-time warnings or errors */')
+        prnt('  (void)p;')
         for fname, ftype, fbitsize in tp.enumfields():
             if (isinstance(ftype, model.PrimitiveType)
                 and ftype.is_integer_type()) or fbitsize >= 0:
@@ -482,6 +494,8 @@
                 prnt('    sizeof(((%s *)0)->%s),' % (cname, fname))
         prnt('    -1')
         prnt('  };')
+        prnt('  (void)self; /* unused */')
+        prnt('  (void)noarg; /* unused */')
         prnt('  return _cffi_get_struct_layout(nums);')
         prnt('  /* the next line is not executed, but compiled */')
         prnt('  %s(0);' % (checkfuncname,))
@@ -653,14 +667,14 @@
         prnt('static int %s(PyObject *lib)' % funcname)
         prnt('{')
         for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
-            if enumvalue < 0:
-                prnt('  if ((%s) >= 0 || (long)(%s) != %dL) {' % (
+            if enumvalue <= 0:
+                prnt('  if ((%s) > 0 || (long)(%s) != %dL) {' % (
                     enumerator, enumerator, enumvalue))
             else:
-                prnt('  if ((%s) < 0 || (unsigned long)(%s) != %dUL) {' % (
+                prnt('  if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % (
                     enumerator, enumerator, enumvalue))
             prnt('    char buf[64];')
-            prnt('    if ((%s) < 0)' % enumerator)
+            prnt('    if ((%s) <= 0)' % enumerator)
             prnt('        snprintf(buf, 63, "%%ld", (long)(%s));' % enumerator)
             prnt('    else')
             prnt('        snprintf(buf, 63, "%%lu", (unsigned long)(%s));' %
@@ -783,6 +797,24 @@
    typedef unsigned __int16 uint16_t;
    typedef unsigned __int32 uint32_t;
    typedef unsigned __int64 uint64_t;
+   typedef __int8 int_least8_t;
+   typedef __int16 int_least16_t;
+   typedef __int32 int_least32_t;
+   typedef __int64 int_least64_t;
+   typedef unsigned __int8 uint_least8_t;
+   typedef unsigned __int16 uint_least16_t;
+   typedef unsigned __int32 uint_least32_t;
+   typedef unsigned __int64 uint_least64_t;
+   typedef __int8 int_fast8_t;
+   typedef __int16 int_fast16_t;
+   typedef __int32 int_fast32_t;
+   typedef __int64 int_fast64_t;
+   typedef unsigned __int8 uint_fast8_t;
+   typedef unsigned __int16 uint_fast16_t;
+   typedef unsigned __int32 uint_fast32_t;
+   typedef unsigned __int64 uint_fast64_t;
+   typedef __int64 intmax_t;
+   typedef unsigned __int64 uintmax_t;
 # else
 #  include <stdint.h>
 # endif
@@ -828,12 +860,15 @@
             PyLong_FromLongLong((long long)(x)))
 
 #define _cffi_from_c_int(x, type)                                        \
-    (((type)-1) > 0 ?   /* unsigned */                                   \
-        (sizeof(type) < sizeof(long) ? PyInt_FromLong(x) :               \
-         sizeof(type) == sizeof(long) ? PyLong_FromUnsignedLong(x) :     \
-                                        PyLong_FromUnsignedLongLong(x))  \
-      : (sizeof(type) <= sizeof(long) ? PyInt_FromLong(x) :              \
-                                        PyLong_FromLongLong(x)))
+    (((type)-1) > 0 ? /* unsigned */                                     \
+        (sizeof(type) < sizeof(long) ?                                   \
+            PyInt_FromLong((long)x) :                                    \
+         sizeof(type) == sizeof(long) ?                                  \
+            PyLong_FromUnsignedLong((unsigned long)x) :                  \
+            PyLong_FromUnsignedLongLong((unsigned long long)x)) :        \
+        (sizeof(type) <= sizeof(long) ?                                  \
+            PyInt_FromLong((long)x) :                                    \
+            PyLong_FromLongLong((long long)x)))
 
 #define _cffi_to_c_int(o, type)                                          \
     (sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o)        \
@@ -844,7 +879,7 @@
                                          : (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))
+     (Py_FatalError("unsupported size for type " #type), (type)0))
 
 #define _cffi_to_c_i8                                                    \
                  ((int(*)(PyObject *))_cffi_exports[1])
@@ -907,6 +942,7 @@
 {
     PyObject *library;
     int was_alive = (_cffi_types != NULL);
+    (void)self; /* unused */
     if (!PyArg_ParseTuple(args, "OOO", &_cffi_types, &_cffi_VerificationError,
                                        &library))
         return NULL;
diff --git a/lib_pypy/cffi/vengine_gen.py b/lib_pypy/cffi/vengine_gen.py
--- a/lib_pypy/cffi/vengine_gen.py
+++ b/lib_pypy/cffi/vengine_gen.py
@@ -58,12 +58,12 @@
             modname = self.verifier.get_module_name()
             prnt("void %s%s(void) { }\n" % (prefix, modname))
 
-    def load_library(self):
+    def load_library(self, flags=0):
         # import it with the CFFI backend
         backend = self.ffi._backend
         # needs to make a path that contains '/', on Posix
         filename = os.path.join(os.curdir, self.verifier.modulefilename)
-        module = backend.load_library(filename)
+        module = backend.load_library(filename, flags)
         #
         # call loading_gen_struct() to get the struct layout inferred by
         # the C compiler
@@ -235,6 +235,7 @@
         prnt('static void %s(%s *p)' % (checkfuncname, cname))
         prnt('{')
         prnt('  /* only to generate compile-time warnings or errors */')
+        prnt('  (void)p;')
         for fname, ftype, fbitsize in tp.enumfields():
             if (isinstance(ftype, model.PrimitiveType)
                 and ftype.is_integer_type()) or fbitsize >= 0:
@@ -427,14 +428,14 @@
         prnt('int %s(char *out_error)' % funcname)
         prnt('{')
         for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
-            if enumvalue < 0:
-                prnt('  if ((%s) >= 0 || (long)(%s) != %dL) {' % (
+            if enumvalue <= 0:
+                prnt('  if ((%s) > 0 || (long)(%s) != %dL) {' % (
                     enumerator, enumerator, enumvalue))
             else:
-                prnt('  if ((%s) < 0 || (unsigned long)(%s) != %dUL) {' % (
+                prnt('  if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % (
                     enumerator, enumerator, enumvalue))
             prnt('    char buf[64];')
-            prnt('    if ((%s) < 0)' % enumerator)
+            prnt('    if ((%s) <= 0)' % enumerator)
             prnt('        sprintf(buf, "%%ld", (long)(%s));' % enumerator)
             prnt('    else')
             prnt('        sprintf(buf, "%%lu", (unsigned long)(%s));' %
@@ -565,6 +566,24 @@
    typedef unsigned __int16 uint16_t;
    typedef unsigned __int32 uint32_t;
    typedef unsigned __int64 uint64_t;
+   typedef __int8 int_least8_t;
+   typedef __int16 int_least16_t;
+   typedef __int32 int_least32_t;
+   typedef __int64 int_least64_t;
+   typedef unsigned __int8 uint_least8_t;
+   typedef unsigned __int16 uint_least16_t;
+   typedef unsigned __int32 uint_least32_t;
+   typedef unsigned __int64 uint_least64_t;
+   typedef __int8 int_fast8_t;
+   typedef __int16 int_fast16_t;
+   typedef __int32 int_fast32_t;
+   typedef __int64 int_fast64_t;
+   typedef unsigned __int8 uint_fast8_t;
+   typedef unsigned __int16 uint_fast16_t;
+   typedef unsigned __int32 uint_fast32_t;
+   typedef unsigned __int64 uint_fast64_t;
+   typedef __int64 intmax_t;
+   typedef unsigned __int64 uintmax_t;
 # else
 #  include <stdint.h>
 # endif
diff --git a/lib_pypy/cffi/verifier.py b/lib_pypy/cffi/verifier.py
--- a/lib_pypy/cffi/verifier.py
+++ b/lib_pypy/cffi/verifier.py
@@ -1,12 +1,23 @@
-import sys, os, binascii, imp, shutil
-from . import __version__
+import sys, os, binascii, shutil
+from . import __version_verifier_modules__
 from . import ffiplatform
 
+if sys.version_info >= (3, 3):
+    import importlib.machinery
+    def _extension_suffixes():
+        return importlib.machinery.EXTENSION_SUFFIXES[:]
+else:
+    import imp
+    def _extension_suffixes():
+        return [suffix for suffix, _, type in imp.get_suffixes()
+                if type == imp.C_EXTENSION]
+
 
 class Verifier(object):
 
     def __init__(self, ffi, preamble, tmpdir=None, modulename=None,
-                 ext_package=None, tag='', force_generic_engine=False, **kwds):
+                 ext_package=None, tag='', force_generic_engine=False,
+                 source_extension='.c', flags=None, relative_to=None, **kwds):
         self.ffi = ffi
         self.preamble = preamble
         if not modulename:
@@ -14,14 +25,15 @@
         vengine_class = _locate_engine_class(ffi, force_generic_engine)
         self._vengine = vengine_class(self)
         self._vengine.patch_extension_kwds(kwds)
-        self.kwds = kwds
+        self.flags = flags
+        self.kwds = self.make_relative_to(kwds, relative_to)
         #
         if modulename:
             if tag:
                 raise TypeError("can't specify both 'modulename' and 'tag'")
         else:
-            key = '\x00'.join([sys.version[:3], __version__, preamble,
-                               flattened_kwds] +
+            key = '\x00'.join([sys.version[:3], __version_verifier_modules__,
+                               preamble, flattened_kwds] +
                               ffi._cdefsources)
             if sys.version_info >= (3,):
                 key = key.encode('utf-8')
@@ -33,7 +45,7 @@
                                               k1, k2)
         suffix = _get_so_suffixes()[0]
         self.tmpdir = tmpdir or _caller_dir_pycache()
-        self.sourcefilename = os.path.join(self.tmpdir, modulename + '.c')
+        self.sourcefilename = os.path.join(self.tmpdir, modulename + 
source_extension)
         self.modulefilename = os.path.join(self.tmpdir, modulename + suffix)
         self.ext_package = ext_package
         self._has_source = False
@@ -97,6 +109,20 @@
     def generates_python_module(self):
         return self._vengine._gen_python_module
 
+    def make_relative_to(self, kwds, relative_to):
+        if relative_to and os.path.dirname(relative_to):
+            dirname = os.path.dirname(relative_to)
+            kwds = kwds.copy()
+            for key in ffiplatform.LIST_OF_FILE_NAMES:
+                if key in kwds:
+                    lst = kwds[key]
+                    if not isinstance(lst, (list, tuple)):
+                        raise TypeError("keyword '%s' should be a list or 
tuple"
+                                        % (key,))
+                    lst = [os.path.join(dirname, fn) for fn in lst]
+                    kwds[key] = lst
+        return kwds
+
     # ----------
 
     def _locate_module(self):
@@ -148,7 +174,10 @@
 
     def _load_library(self):
         assert self._has_module
-        return self._vengine.load_library()
+        if self.flags is not None:
+            return self._vengine.load_library(self.flags)
+        else:
+            return self._vengine.load_library()
 
 # ____________________________________________________________
 
@@ -181,6 +210,9 @@
 def _caller_dir_pycache():
     if _TMPDIR:
         return _TMPDIR
+    result = os.environ.get('CFFI_TMPDIR')
+    if result:
+        return result
     filename = sys._getframe(2).f_code.co_filename
     return os.path.abspath(os.path.join(os.path.dirname(filename),
                            '__pycache__'))
@@ -222,11 +254,7 @@
             pass
 
 def _get_so_suffixes():
-    suffixes = []
-    for suffix, mode, type in imp.get_suffixes():
-        if type == imp.C_EXTENSION:
-            suffixes.append(suffix)
-
+    suffixes = _extension_suffixes()
     if not suffixes:
         # bah, no C_EXTENSION available.  Occurs on pypy without cpyext
         if sys.platform == 'win32':
diff --git a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py 
b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/backend_tests.py
@@ -2,7 +2,7 @@
 import py
 import platform
 import sys, ctypes
-from cffi import FFI, CDefError
+from cffi import FFI, CDefError, FFIError
 from pypy.module.test_lib_pypy.cffi_tests.support import *
 
 SIZE_OF_INT   = ctypes.sizeof(ctypes.c_int)
@@ -917,6 +917,16 @@
         assert int(invalid_value) == 2
         assert ffi.string(invalid_value) == "2"
 
+    def test_enum_char_hex_oct(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef(r"enum foo{A='!', B='\'', C=0x10, D=010, E=- 0x10, F=-010};")
+        assert ffi.string(ffi.cast("enum foo", ord('!'))) == "A"
+        assert ffi.string(ffi.cast("enum foo", ord("'"))) == "B"
+        assert ffi.string(ffi.cast("enum foo", 16)) == "C"
+        assert ffi.string(ffi.cast("enum foo", 8)) == "D"
+        assert ffi.string(ffi.cast("enum foo", -16)) == "E"
+        assert ffi.string(ffi.cast("enum foo", -8)) == "F"
+
     def test_array_of_struct(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int a, b; };")
@@ -950,6 +960,15 @@
         assert ffi.offsetof("struct foo", "b") == 4
         assert ffi.offsetof("struct foo", "c") == 8
 
+    def test_offsetof_nested(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("struct foo { int a, b, c; };"
+                 "struct bar { struct foo d, e; };")
+        assert ffi.offsetof("struct bar", "e") == 12
+        assert ffi.offsetof("struct bar", "e.a") == 12
+        assert ffi.offsetof("struct bar", "e.b") == 16
+        assert ffi.offsetof("struct bar", "e.c") == 20
+
     def test_alignof(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { char a; short b; char c; };")
@@ -1496,6 +1515,16 @@
         assert a == ffi.addressof(p, 'y')
         assert a != ffi.addressof(p, 'x')
 
+    def test_addressof_field_nested(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("struct foo_s { int x, y; };"
+                 "struct bar_s { struct foo_s a, b; };")
+        p = ffi.new("struct bar_s *")
+        a = ffi.addressof(p[0], 'b.y')
+        assert int(ffi.cast("uintptr_t", a)) == (
+            int(ffi.cast("uintptr_t", p)) +
+            ffi.sizeof("struct foo_s") + ffi.sizeof("int"))
+
     def test_addressof_anonymous_struct(self):
         ffi = FFI()
         ffi.cdef("typedef struct { int x; } foo_t;")
@@ -1565,6 +1594,12 @@
         p = ffi2.new("foo_p", [142])
         assert p.x == 142
 
+    def test_ignore_multiple_declarations_of_constant(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("#define FOO 42")
+        ffi.cdef("#define FOO 42")
+        py.test.raises(FFIError, ffi.cdef, "#define FOO 43")
+
     def test_struct_packed(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct nonpacked { char a; int b; };")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_cdata.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_cdata.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_cdata.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_cdata.py
@@ -20,6 +20,8 @@
         return FakeType("void")
     def new_pointer_type(self, x):
         return FakeType('ptr-to-%r' % (x,))
+    def new_array_type(self, x, y):
+        return FakeType('array-from-%r-len-%r' % (x, y))
     def cast(self, x, y):
         return 'casted!'
     def _get_types(self):
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
@@ -20,8 +20,8 @@
         ffi.cdef("struct foo_s { int a,b,c,d,e; int x:1; };")
         e = py.test.raises(NotImplementedError, ffi.callback,
                            "struct foo_s foo(void)", lambda: 42)
-        assert str(e.value) == ("<struct foo_s(*)(void)>: "
-            "cannot pass as argument or return value a struct with bit fields")
+        assert str(e.value) == ("struct foo_s(*)(): "
+            "callback with unsupported argument or return type or with '...'")
 
     def test_inspecttype(self):
         ffi = FFI(backend=self.Backend())
@@ -123,7 +123,7 @@
         self.check("int a:2; short b:15; char c:2; char y;", 5, 4, 8)
         self.check("int a:2; char b:1; char c:1; char y;", 1, 4, 4)
 
-    @pytest.mark.skipif("platform.machine().startswith('arm')")
+    @pytest.mark.skipif("platform.machine().startswith(('arm', 'aarch64'))")
     def test_bitfield_anonymous_no_align(self):
         L = FFI().alignof("long long")
         self.check("char y; int :1;", 0, 1, 2)
@@ -136,7 +136,8 @@
         self.check("char x; long long z:57; char y;", L + 8, L, L + 8 + L)
         self.check("char x; long long  :57; char y;", L + 8, 1, L + 9)
 
-    @pytest.mark.skipif("not platform.machine().startswith('arm')")
+    @pytest.mark.skipif(
+        "not platform.machine().startswith(('arm', 'aarch64'))")
     def test_bitfield_anonymous_align_arm(self):
         L = FFI().alignof("long long")
         self.check("char y; int :1;", 0, 4, 4)
@@ -149,7 +150,7 @@
         self.check("char x; long long z:57; char y;", L + 8, L, L + 8 + L)
         self.check("char x; long long  :57; char y;", L + 8, L, L + 8 + L)
 
-    @pytest.mark.skipif("platform.machine().startswith('arm')")
+    @pytest.mark.skipif("platform.machine().startswith(('arm', 'aarch64'))")
     def test_bitfield_zero(self):
         L = FFI().alignof("long long")
         self.check("char y; int :0;", 0, 1, 4)
@@ -160,7 +161,8 @@
         self.check("char x; int :0; short b:1; char y;", 5, 2, 6)
         self.check("int a:1; int :0; int b:1; char y;", 5, 4, 8)
 
-    @pytest.mark.skipif("not platform.machine().startswith('arm')")
+    @pytest.mark.skipif(
+        "not platform.machine().startswith(('arm', 'aarch64'))")
     def test_bitfield_zero_arm(self):
         L = FFI().alignof("long long")
         self.check("char y; int :0;", 0, 4, 4)
@@ -212,3 +214,12 @@
         code, message = ffi.getwinerror(-1)
         assert code == 2
         assert message == "The system cannot find the file specified"
+
+    def test_from_buffer(self):
+        import array
+        ffi = FFI()
+        a = array.array('H', [10000, 20000, 30000])
+        c = ffi.from_buffer(a)
+        assert ffi.typeof(c) is ffi.typeof("char[]")
+        ffi.cast("unsigned short *", c)[1] += 500
+        assert list(a) == [10000, 20500, 30000]
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_parsing.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_parsing.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_parsing.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_parsing.py
@@ -289,3 +289,14 @@
         decl = ast.children()[0][1]
         node = decl.type
         assert p._is_constant_globalvar(node) == expected_output
+
+def test_enum():
+    ffi = FFI()
+    ffi.cdef("""
+        enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1};
+        """)
+    C = ffi.dlopen(None)
+    assert C.POS == 1
+    assert C.TWO == 2
+    assert C.NIL == 0
+    assert C.NEG == -1
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
@@ -1,7 +1,7 @@
 # Generated by pypy/tool/import_cffi.py
 import py, re
 import sys, os, math, weakref
-from cffi import FFI, VerificationError, VerificationMissing, model
+from cffi import FFI, VerificationError, VerificationMissing, model, FFIError
 from pypy.module.test_lib_pypy.cffi_tests.support import *
 
 
@@ -15,12 +15,13 @@
 else:
     if (sys.platform == 'darwin' and
           [int(x) for x in os.uname()[2].split('.')] >= [11, 0, 0]):
+        # assume a standard clang or gcc
+        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion']
         # special things for clang
-        extra_compile_args = [
-            '-Werror', '-Qunused-arguments', '-Wno-error=shorten-64-to-32']
+        extra_compile_args.append('-Qunused-arguments')
     else:
         # assume a standard gcc
-        extra_compile_args = ['-Werror']
+        extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion']
 
     class FFI(FFI):
         def verify(self, *args, **kwds):
@@ -90,11 +91,48 @@
     lib = ffi.verify('#include <math.h>', libraries=lib_m)
     assert lib.sin(1.23) == math.sin(1.23)
 
+def _Wconversion(cdef, source, **kargs):
+    if sys.platform == 'win32':
+        py.test.skip("needs GCC or Clang")
+    ffi = FFI()
+    ffi.cdef(cdef)
+    py.test.raises(VerificationError, ffi.verify, source, **kargs)
+    extra_compile_args_orig = extra_compile_args[:]
+    extra_compile_args.remove('-Wconversion')
+    try:
+        lib = ffi.verify(source, **kargs)
+    finally:
+        extra_compile_args[:] = extra_compile_args_orig
+    return lib
+
+def test_Wconversion_unsigned():
+    _Wconversion("unsigned foo(void);",
+                 "int foo(void) { return -1;}")
+
+def test_Wconversion_integer():
+    _Wconversion("short foo(void);",
+                 "long long foo(void) { return 1<<sizeof(short);}")
+
+def test_Wconversion_floating():
+    lib = _Wconversion("float sin(double);",
+                       "#include <math.h>", libraries=lib_m)
+    res = lib.sin(1.23)
+    assert res != math.sin(1.23)     # not exact, because of double->float
+    assert abs(res - math.sin(1.23)) < 1E-5
+
+def test_Wconversion_float2int():
+    _Wconversion("int sinf(float);",
+                 "#include <math.h>", libraries=lib_m)
+
+def test_Wconversion_double2int():
+    _Wconversion("int sin(double);",
+                 "#include <math.h>", libraries=lib_m)
+
 def test_rounding_1():
     ffi = FFI()
-    ffi.cdef("float sin(double x);")
+    ffi.cdef("double sinf(float x);")
     lib = ffi.verify('#include <math.h>', libraries=lib_m)
-    res = lib.sin(1.23)
+    res = lib.sinf(1.23)
     assert res != math.sin(1.23)     # not exact, because of double->float
     assert abs(res - math.sin(1.23)) < 1E-5
 
@@ -113,14 +151,21 @@
     assert lib.strlen(b"hi there!") == 9
 
 def test_strlen_approximate():
-    ffi = FFI()
-    ffi.cdef("int strlen(char *s);")
-    lib = ffi.verify("#include <string.h>")
+    lib = _Wconversion("int strlen(char *s);",
+                       "#include <string.h>")
     assert lib.strlen(b"hi there!") == 9
 
+def test_return_approximate():
+    for typename in ['short', 'int', 'long', 'long long']:
+        ffi = FFI()
+        ffi.cdef("%s foo(signed char x);" % typename)
+        lib = ffi.verify("signed char foo(signed char x) { return x;}")
+        assert lib.foo(-128) == -128
+        assert lib.foo(+127) == +127
+
 def test_strlen_array_of_char():
     ffi = FFI()
-    ffi.cdef("int strlen(char[]);")
+    ffi.cdef("size_t strlen(char[]);")
     lib = ffi.verify("#include <string.h>")
     assert lib.strlen(b"hello") == 5
 
@@ -209,8 +254,8 @@
     ffi = FFI()
     ffi.cdef('\n'.join(["%s foo_%s(%s);" % (tp, tp.replace(' ', '_'), tp)
                        for tp in typenames]))
-    lib = ffi.verify('\n'.join(["%s foo_%s(%s x) { return x+1; }" %
-                                (tp, tp.replace(' ', '_'), tp)
+    lib = ffi.verify('\n'.join(["%s foo_%s(%s x) { return (%s)(x+1); }" %
+                                (tp, tp.replace(' ', '_'), tp, tp)
                                 for tp in typenames]))
     for typename in typenames:
         foo = getattr(lib, 'foo_%s' % typename.replace(' ', '_'))
@@ -316,7 +361,7 @@
 def test_char_type():
     ffi = FFI()
     ffi.cdef("char foo(char);")
-    lib = ffi.verify("char foo(char x) { return x+1; }")
+    lib = ffi.verify("char foo(char x) { return ++x; }")
     assert lib.foo(b"A") == b"B"
     py.test.raises(TypeError, lib.foo, b"bar")
     py.test.raises(TypeError, lib.foo, "bar")
@@ -386,7 +431,7 @@
     ffi = FFI()
     ffi.cdef("typedef struct foo_s foo_t; int bar(foo_t *);")
     lib = ffi.verify("typedef struct foo_s foo_t;\n"
-                     "int bar(foo_t *f) { return 42; }\n")
+                     "int bar(foo_t *f) { (void)f; return 42; }\n")
     assert lib.bar(ffi.NULL) == 42
 
 def test_ffi_full_struct():
@@ -897,7 +942,7 @@
         static int foo(token_t *tk) {
             if (!tk)
                 return -42;
-            *tk += 1.601;
+            *tk += 1.601f;
             return (int)*tk;
         }
         #define TOKEN_SIZE sizeof(token_t)
@@ -992,7 +1037,7 @@
             long a;
         };
         int foo(struct foo_s s) {
-            return s.a - (int)s.b;
+            return (int)s.a - (int)s.b;
         }
     """)
     s = ffi.new("struct foo_s *", [100, 1])
@@ -1009,7 +1054,7 @@
             long a;
         };
         int foo1(struct foo_s s) {
-            return s.a - (int)s.b;
+            return (int)s.a - (int)s.b;
         }
         int (*foo)(struct foo_s s) = &foo1;
     """)
@@ -1068,7 +1113,7 @@
 def test_array_as_argument():
     ffi = FFI()
     ffi.cdef("""
-        int strlen(char string[]);
+        size_t strlen(char string[]);
     """)
     ffi.verify("#include <string.h>")
 
@@ -1080,7 +1125,7 @@
     """)
     lib = ffi.verify("""
         enum foo_e { AA, CC, BB };
-        int foo_func(enum foo_e e) { return e; }
+        int foo_func(enum foo_e e) { return (int)e; }
     """)
     assert lib.foo_func(lib.BB) == 2
     py.test.raises(TypeError, lib.foo_func, "BB")
@@ -1093,7 +1138,7 @@
     """)
     lib = ffi.verify("""
         enum foo_e { AA, CC, BB };
-        enum foo_e foo_func(int x) { return x; }
+        enum foo_e foo_func(int x) { return (enum foo_e)x; }
     """)
     assert lib.foo_func(lib.BB) == lib.BB == 2
 
@@ -1128,6 +1173,19 @@
     assert lib.AA == 0
     assert lib.BB == 2
 
+def test_typedef_enum_as_argument():
+    ffi = FFI()
+    ffi.cdef("""
+        typedef enum { AA, BB, ... } foo_t;
+        int foo_func(foo_t);
+    """)
+    lib = ffi.verify("""
+        typedef enum { AA, CC, BB } foo_t;
+        int foo_func(foo_t e) { return (int)e; }
+    """)
+    assert lib.foo_func(lib.BB) == lib.BB == 2
+    py.test.raises(TypeError, lib.foo_func, "BB")
+
 def test_typedef_enum_as_function_result():
     ffi = FFI()
     ffi.cdef("""
@@ -1136,7 +1194,7 @@
     """)
     lib = ffi.verify("""
         typedef enum { AA, CC, BB } foo_t;
-        foo_t foo_func(int x) { return x; }
+        foo_t foo_func(int x) { return (foo_t)x; }
     """)
     assert lib.foo_func(lib.BB) == lib.BB == 2
 
@@ -1292,7 +1350,7 @@
     """)
 
 def test_tmpdir():
-    import tempfile, os, shutil
+    import tempfile, os
     from pypy.module.test_lib_pypy.cffi_tests.udir import udir
     tmpdir = tempfile.mkdtemp(dir=str(udir))
     ffi = FFI()
@@ -1301,6 +1359,20 @@
     assert os.listdir(tmpdir)
     assert lib.foo(100) == 142
 
+def test_relative_to():
+    import tempfile, os
+    from pypy.module.test_lib_pypy.cffi_tests.udir import udir
+    tmpdir = tempfile.mkdtemp(dir=str(udir))
+    ffi = FFI()
+    ffi.cdef("int foo(int);")
+    f = open(os.path.join(tmpdir, 'foo.h'), 'w')
+    print >> f, "int foo(int a) { return a + 42; }"
+    f.close()
+    lib = ffi.verify('#include "foo.h"',
+                     include_dirs=['.'],
+                     relative_to=os.path.join(tmpdir, 'x'))
+    assert lib.foo(100) == 142
+
 def test_bug1():
     ffi = FFI()
     ffi.cdef("""
@@ -1677,7 +1749,7 @@
         static int c_callback(int how_many, ...) {
             va_list ap;
             /* collect the "..." arguments into the values[] array */
-            int i, *values = alloca(how_many * sizeof(int));
+            int i, *values = alloca((size_t)how_many * sizeof(int));
             va_start(ap, how_many);
             for (i=0; i<how_many; i++)
                 values[i] = va_arg(ap, int);
@@ -1718,7 +1790,7 @@
     ffi.cdef("char sum3chars(char *);")
     lib = ffi.verify("""
         char sum3chars(char *f) {
-            return f[0] + f[1] + f[2];
+            return (char)(f[0] + f[1] + f[2]);
         }
     """)
     assert lib.sum3chars((b'\x10', b'\x20', b'\x30')) == b'\x60'
@@ -1753,7 +1825,7 @@
 def test_typeof_function():
     ffi = FFI()
     ffi.cdef("int foo(int, char);")
-    lib = ffi.verify("int foo(int x, char y) { return 42; }")
+    lib = ffi.verify("int foo(int x, char y) { (void)x; (void)y; return 42; }")
     ctype = ffi.typeof(lib.foo)
     assert len(ctype.args) == 2
     assert ctype.result == ffi.typeof("int")
@@ -1818,6 +1890,7 @@
     long tf_bl(signed char x, long c);
     unsigned long tf_bL(signed char x, unsigned long c);
     long long tf_bq(signed char x, long long c);
+    unsigned long long tf_bQ(signed char x, unsigned long long c);
     float tf_bf(signed char x, float c);
     double tf_bd(signed char x, double c);
     long double tf_bD(signed char x, long double c);
@@ -1835,20 +1908,35 @@
     double dvalue;
     long double Dvalue;
 
-    #define S(letter)  xvalue = x; letter##value = c; return rvalue;
+    typedef signed char b_t;
+    typedef unsigned char B_t;
+    typedef short h_t;
+    typedef unsigned short H_t;
+    typedef int i_t;
+    typedef unsigned int I_t;
+    typedef long l_t;
+    typedef unsigned long L_t;
+    typedef long long q_t;
+    typedef unsigned long long Q_t;
+    typedef float f_t;
+    typedef double d_t;
+    typedef long double D_t;
+    #define S(letter)  xvalue = (int)x; letter##value = (letter##_t)c;
+    #define R(letter)  return (letter##_t)rvalue;
 
-    signed char tf_bb(signed char x, signed char c) { S(i) }
-    unsigned char tf_bB(signed char x, unsigned char c) { S(i) }
-    short tf_bh(signed char x, short c) { S(i) }
-    unsigned short tf_bH(signed char x, unsigned short c) { S(i) }
-    int tf_bi(signed char x, int c) { S(i) }
-    unsigned int tf_bI(signed char x, unsigned int c) { S(i) }
-    long tf_bl(signed char x, long c) { S(i) }
-    unsigned long tf_bL(signed char x, unsigned long c) { S(i) }
-    long long tf_bq(signed char x, long long c) { S(i) }
-    float tf_bf(signed char x, float c) { S(f) }
-    double tf_bd(signed char x, double c) { S(d) }
-    long double tf_bD(signed char x, long double c) { S(D) }
+    signed char tf_bb(signed char x, signed char c) { S(i) R(b) }
+    unsigned char tf_bB(signed char x, unsigned char c) { S(i) R(B) }
+    short tf_bh(signed char x, short c) { S(i) R(h) }
+    unsigned short tf_bH(signed char x, unsigned short c) { S(i) R(H) }
+    int tf_bi(signed char x, int c) { S(i) R(i) }
+    unsigned int tf_bI(signed char x, unsigned int c) { S(i) R(I) }
+    long tf_bl(signed char x, long c) { S(i) R(l) }
+    unsigned long tf_bL(signed char x, unsigned long c) { S(i) R(L) }
+    long long tf_bq(signed char x, long long c) { S(i) R(q) }
+    unsigned long long tf_bQ(signed char x, unsigned long long c) { S(i) R(Q) }
+    float tf_bf(signed char x, float c) { S(f) R(f) }
+    double tf_bd(signed char x, double c) { S(d) R(d) }
+    long double tf_bD(signed char x, long double c) { S(D) R(D) }
     """)
     lib.rvalue = 0x7182838485868788
     for kind, cname in [('b', 'signed char'),
@@ -1860,6 +1948,7 @@
                         ('l', 'long'),
                         ('L', 'unsigned long'),
                         ('q', 'long long'),
+                        ('Q', 'unsigned long long'),
                         ('f', 'float'),
                         ('d', 'double'),
                         ('D', 'long double')]:
@@ -1963,3 +2052,77 @@
             n = (1 << 29) + i
             lib.SetLastError(n)
             assert ffi.getwinerror()[0] == n
+
+def test_verify_dlopen_flags():
+    ffi1 = FFI()
+    ffi1.cdef("int foo;")
+
+    lib1 = ffi1.verify("int foo;", flags=ffi1.RTLD_GLOBAL | ffi1.RTLD_LAZY)
+    lib2 = get_second_lib()
+
+    lib1.foo = 42
+
+    assert lib2.foo == 42
+
+def get_second_lib():
+    # Hack, using modulename makes the test fail
+    ffi2 = FFI()
+    ffi2.cdef("int foo;")
+    lib2 = ffi2.verify("int foo;", flags=ffi2.RTLD_GLOBAL | ffi2.RTLD_LAZY)
+    return lib2
+
+def test_consider_not_implemented_function_type():
+    ffi = FFI()
+    ffi.cdef("typedef union { int a; float b; } Data;"
+             "typedef struct { int a:2; } MyStr;"
+             "typedef void (*foofunc_t)(Data);"
+             "typedef MyStr (*barfunc_t)(void);")
+    fooptr = ffi.cast("foofunc_t", 123)
+    barptr = ffi.cast("barfunc_t", 123)
+    # assert did not crash so far
+    e = py.test.raises(NotImplementedError, fooptr, ffi.new("Data *"))
+    assert str(e.value) == (
+        "ctype 'Data' not supported as argument or return value")
+    e = py.test.raises(NotImplementedError, barptr)
+    assert str(e.value) == (
+        "ctype 'MyStr' not supported as argument or return value "
+        "(it is a struct with bit fields)")
+
+def test_verify_extra_arguments():
+    ffi = FFI()
+    ffi.cdef("#define ABA ...")
+    lib = ffi.verify("", define_macros=[('ABA', '42')])
+    assert lib.ABA == 42
+
+def test_implicit_unicode_on_windows():
+    if sys.platform != 'win32':
+        py.test.skip("win32-only test")
+    ffi = FFI()
+    e = py.test.raises(FFIError, ffi.cdef, "int foo(LPTSTR);")
+    assert str(e.value) == ("The Windows type 'LPTSTR' is only available after"
+                            " you call ffi.set_unicode()")
+    for with_unicode in [True, False]:
+        ffi = FFI()
+        ffi.set_unicode(with_unicode)
+        ffi.cdef("""
+            DWORD GetModuleFileName(HMODULE hModule, LPTSTR lpFilename,
+                                    DWORD nSize);
+        """)
+        lib = ffi.verify("""
+            #include <windows.h>
+        """, libraries=['Kernel32'])
+        outbuf = ffi.new("TCHAR[]", 200)
+        n = lib.GetModuleFileName(ffi.NULL, outbuf, 500)
+        assert 0 < n < 500
+        for i in range(n):
+            print repr(outbuf[i])
+            assert ord(outbuf[i]) != 0
+        assert ord(outbuf[n]) == 0
+        assert ord(outbuf[0]) < 128     # should be a letter, or '\'
+
+def test_use_local_dir():
+    ffi = FFI()
+    lib = ffi.verify("", modulename="test_use_local_dir")
+    this_dir = os.path.dirname(__file__)
+    pycache_files = os.listdir(os.path.join(this_dir, '__pycache__'))
+    assert any('test_use_local_dir' in s for s in pycache_files)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_zdistutils.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_zdistutils.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_zdistutils.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_zdistutils.py
@@ -18,7 +18,7 @@
 
     def teardown_class(self):
         if udir.isdir():
-            udir.remove()
+            udir.remove(ignore_errors=True)
 
     def test_locate_engine_class(self):
         cls = _locate_engine_class(FFI(), self.generic)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_zintegration.py
@@ -76,7 +76,7 @@
 class TestZIntegration(object):
     def teardown_class(self):
         if udir.isdir():
-            udir.remove()
+            udir.remove(ignore_errors=True)
 
     def test_infrastructure(self):
         run_setup_and_program('infrastructure', '''
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to