[pypy-commit] cffi default: merge heads

2019-04-02 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r3254:1af377542a51
Date: 2019-04-02 15:42 +0200
http://bitbucket.org/cffi/cffi/changeset/1af377542a51/

Log:merge heads

diff --git a/cffi/_embedding.h b/cffi/_embedding.h
--- a/cffi/_embedding.h
+++ b/cffi/_embedding.h
@@ -169,8 +169,10 @@
 global_dict = PyDict_New();
 if (global_dict == NULL)
 goto error;
-if (PyDict_SetItemString(global_dict, "__builtins__",
- PyThreadState_GET()->interp->builtins) < 0)
+PyObject *builtins = PyEval_GetBuiltins();
+if (builtins == NULL)
+goto error;
+if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0)
 goto error;
 x = PyEval_EvalCode(
 #if PY_MAJOR_VERSION < 3
@@ -263,23 +265,33 @@
So we use a global variable as a simple spin lock.  This global
variable must be from 'libpythonX.Y.so', not from this
cffi-based extension module, because it must be shared from
-   different cffi-based extension modules.  We choose
+   different cffi-based extension modules.
+
+   In Python < 3.8, we choose
_PyParser_TokenNames[0] as a completely arbitrary pointer value
that is never written to.  The default is to point to the
string "ENDMARKER".  We change it temporarily to point to the
next character in that string.  (Yes, I know it's REALLY
obscure.)
+
+   In Python >= 3.8, this string array is no longer writable, so
+   instead we pick PyCapsuleType.tp_version_tag.  We can't change
+   Python < 3.8 because someone might use a mixture of cffi
+   embedded modules, some of which were compiled before this file
+   changed.
 */
 
 #ifdef WITH_THREAD
+# if PY_VERSION_HEX < 0x0308
 char *volatile *lock = (char *volatile *)_PyParser_TokenNames;
-char *old_value;
+char *old_value, *locked_value;
 
 while (1) {/* spin loop */
 old_value = *lock;
+locked_value = old_value + 1;
 if (old_value[0] == 'E') {
 assert(old_value[1] == 'N');
-if (cffi_compare_and_swap(lock, old_value, old_value + 1))
+if (cffi_compare_and_swap(lock, old_value, locked_value))
 break;
 }
 else {
@@ -290,6 +302,27 @@
this is only run at start-up anyway. */
 }
 }
+# else
+int volatile *lock = (int volatile *)_Type.tp_version_tag;
+int old_value, locked_value;
+assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG));
+
+while (1) {/* spin loop */
+old_value = *lock;
+locked_value = -42;
+if (old_value == 0) {
+if (cffi_compare_and_swap(lock, old_value, locked_value))
+break;
+}
+else {
+assert(old_value == locked_value);
+/* should ideally do a spin loop instruction here, but
+   hard to do it portably and doesn't really matter I
+   think: PyEval_InitThreads() should be very fast, and
+   this is only run at start-up anyway. */
+}
+}
+# endif
 #endif
 
 /* call Py_InitializeEx() */
@@ -306,7 +339,7 @@
 
 #ifdef WITH_THREAD
 /* release the lock */
-while (!cffi_compare_and_swap(lock, old_value + 1, old_value))
+while (!cffi_compare_and_swap(lock, locked_value, old_value))
 ;
 #endif
 
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -817,12 +817,20 @@
 # or positive/negative number
 if isinstance(exprnode, pycparser.c_ast.Constant):
 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)
+if '0' <= s[0] <= '9':
+s = s.rstrip('uUlL')
+try:
+if s.startswith('0'):
+return int(s, 8)
+else:
+return int(s, 10)
+except ValueError:
+if len(s) > 1:
+if s.lower()[0:2] == '0x':
+return int(s, 16)
+elif s.lower()[0:2] == '0b':
+return int(s, 2)
+raise CDefError("invalid constant %r" % (s,))
 elif s[0] == "'" and s[-1] == "'" and (
 len(s) == 3 or (len(s) == 4 and s[1] == "\\")):
 return ord(s[-2])
diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py
--- a/testing/cffi0/test_parsing.py
+++ b/testing/cffi0/test_parsing.py
@@ -466,3 +466,40 @@
 e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}')
 assert str(e.value) == (':1: unexpected : '
 'this construct is valid C but not valid in 
cdef()')
+
+def 

[pypy-commit] cffi default: merge heads

2018-01-11 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r3075:3daecc622902
Date: 2018-01-12 08:40 +0100
http://bitbucket.org/cffi/cffi/changeset/3daecc622902/

Log:merge heads

diff --git a/doc/source/conf.py b/doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -38,7 +38,7 @@
 
 # General information about the project.
 project = u'CFFI'
-copyright = u'2012-2015, Armin Rigo, Maciej Fijalkowski'
+copyright = u'2012-2018, Armin Rigo, Maciej Fijalkowski'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2017-09-16 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r3013:7417b70e5b1a
Date: 2017-09-16 15:43 +0200
http://bitbucket.org/cffi/cffi/changeset/7417b70e5b1a/

Log:merge heads

diff --git a/doc/source/using.rst b/doc/source/using.rst
--- a/doc/source/using.rst
+++ b/doc/source/using.rst
@@ -128,10 +128,37 @@
 
 There is no general equivalent to the ``&`` operator in C (because it
 would not fit nicely in the model, and it does not seem to be needed
-here).  But see `ffi.addressof()`__.
+here).  There is `ffi.addressof()`__, but only for some cases.  You
+cannot take the "address" of a number in Python, for example; similarly,
+you cannot take the address of a CFFI pointer.  If you have this kind
+of C code::
+
+int x, y;
+fetch_size(, );
+
+opaque_t *handle;  // some opaque pointer
+init_stuff();   // initializes the variable 'handle'
+more_stuff(handle);// pass the handle around to more functions
+
+then you need to rewrite it like this, replacing the variables in C
+with what is logically pointers to the variables:
+
+.. code-block:: python
+
+px = ffi.new("int *")
+py = ffi.new("int *")  arr = ffi.new("int[2]")
+lib.fetch_size(px, py)-OR- lib.fetch_size(arr, arr + 1)
+x = px[0]  x = arr[0]
+y = py[0]  y = arr[1]
+
+p_handle = ffi.new("opaque_t **")
+lib.init_stuff(p_handle)   # pass the pointer to the 'handle' pointer
+handle = p_handle[0]   # now we can read 'handle' out of 'p_handle'
+lib.more_stuff(handle)
 
 .. __: ref.html#ffi-addressof
 
+
 Any operation that would in C return a pointer or array or struct type
 gives you a fresh cdata object.  Unlike the "original" one, these fresh
 cdata objects don't have ownership: they are merely references to
@@ -208,7 +235,7 @@
 string stored in the source array (adding surrogates if necessary).
 See the `Unicode character types`__ section for more details.
 
-__: ref.html#unichar
+.. __: ref.html#unichar
 
 Note that unlike Python lists or tuples, but like C, you *cannot* index in
 a C array from the end using negative numbers.
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -11,7 +11,7 @@
   when used as ``charN_t *`` or ``charN_t[]`` they represent a unicode
   string.  The difference with ``wchar_t`` is that they have a known,
   fixed size.  They should work at all places that used to work with
-  ``wchar_t`` (please report an issue if I missing something).  Note
+  ``wchar_t`` (please report an issue if I missed something).  Note
   that with ``set_source()``, you need to make sure that these types are
   actually defined by the C source you provide (if used in ``cdef()``).
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2016-08-22 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r2746:3ce478433f9b
Date: 2016-08-22 17:40 +0200
http://bitbucket.org/cffi/cffi/changeset/3ce478433f9b/

Log:merge heads

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3042,13 +3042,14 @@
 static PyObject *
 convert_struct_to_owning_object(char *data, CTypeDescrObject *ct)
 {
+/* also accepts unions, for the API mode */
 CDataObject *cd;
 Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
 Py_ssize_t datasize = ct->ct_size;
 
-if ((ct->ct_flags & (CT_STRUCT|CT_IS_OPAQUE)) != CT_STRUCT) {
+if (datasize < 0) {
 PyErr_SetString(PyExc_TypeError,
-"return type is not a struct or is opaque");
+"return type is an opaque structure or union");
 return NULL;
 }
 cd = allocate_owning_object(dataoffset + datasize, ct);
@@ -4623,6 +4624,8 @@
 ct = ct->ct_itemdescr;
 }
 ffifield = fb_fill_type(fb, ct, 0);
+if (PyErr_Occurred())
+return NULL;
 if (elements != NULL) {
 for (j=0; j

[pypy-commit] cffi default: merge heads

2016-04-24 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r2685:381f8b0c2ee0
Date: 2016-04-24 13:46 +0200
http://bitbucket.org/cffi/cffi/changeset/381f8b0c2ee0/

Log:merge heads

diff --git a/AUTHORS b/AUTHORS
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,3 +1,8 @@
 This package has been mostly done by Armin Rigo with help from
 Maciej Fijakowski. The idea is heavily based (although not directly
 copied) from LuaJIT ffi by Mike Pall.
+
+
+Other contributors:
+
+  Google Inc.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -6065,6 +6065,17 @@
  _Type, , ))
 return NULL;
 
+if (destructor == Py_None) {
+   if (!PyObject_TypeCheck(origobj, _Type)) {
+   PyErr_SetString(PyExc_TypeError,
+   "Can remove destructor only on a object "
+   "previously returned by ffi.gc()");
+   return NULL;
+   }
+   Py_CLEAR(((CDataObject_gcp *)origobj)->destructor);
+   Py_RETURN_NONE;
+}
+
 cd = allocate_gcp_object(origobj, origobj->c_type, destructor);
 return (PyObject *)cd;
 }
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -397,20 +397,7 @@
 data.  Later, when this new cdata object is garbage-collected,
 'destructor(old_cdata_object)' will be called.
 """
-try:
-gcp = self._backend.gcp
-except AttributeError:
-pass
-else:
-return gcp(cdata, destructor)
-#
-with self._lock:
-try:
-gc_weakrefs = self.gc_weakrefs
-except AttributeError:
-from .gc_weakref import GcWeakrefs
-gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
-return gc_weakrefs.build(cdata, destructor)
+return self._backend.gcp(cdata, destructor)
 
 def _get_cached_btype(self, type):
 assert self._lock.acquire(False) is False
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -993,6 +993,31 @@
 assert onerror is None   # XXX not implemented
 return BType(source, error)
 
+def gcp(self, cdata, destructor):
+BType = self.typeof(cdata)
+
+if destructor is None:
+if not (hasattr(BType, '_gcp_type') and
+BType._gcp_type is BType):
+raise TypeError("Can remove destructor only on a object "
+"previously returned by ffi.gc()")
+cdata._destructor = None
+return None
+
+try:
+gcp_type = BType._gcp_type
+except AttributeError:
+class CTypesDataGcp(BType):
+__slots__ = ['_orig', '_destructor']
+def __del__(self):
+if self._destructor is not None:
+self._destructor(self._orig)
+gcp_type = BType._gcp_type = CTypesDataGcp
+new_cdata = self.cast(gcp_type, cdata)
+new_cdata._orig = cdata
+new_cdata._destructor = destructor
+return new_cdata
+
 typeof = type
 
 def getcname(self, BType, replace_with):
diff --git a/cffi/gc_weakref.py b/cffi/gc_weakref.py
deleted file mode 100644
--- a/cffi/gc_weakref.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from weakref import ref
-
-
-class GcWeakrefs(object):
-def __init__(self, ffi):
-self.ffi = ffi
-self.data = {}
-
-def build(self, cdata, destructor):
-# make a new cdata of the same type as the original one
-new_cdata = self.ffi.cast(self.ffi._backend.typeof(cdata), cdata)
-#
-def remove(key):
-# careful, this function is not protected by any lock
-old_key = self.data.pop(index)
-assert old_key is key
-destructor(cdata)
-#
-key = ref(new_cdata, remove)
-index = object()
-self.data[index] = key
-return new_cdata
diff --git a/doc/source/ref.rst b/doc/source/ref.rst
--- a/doc/source/ref.rst
+++ b/doc/source/ref.rst
@@ -318,6 +318,11 @@
 which means the destructor is called as soon as *this* exact returned
 object is garbage-collected.
 
+**ffi.gc(ptr, None)**: removes the ownership on a object returned by a
+regular call to ``ffi.gc``, and no destructor will be called when it
+is garbage-collected.  The object is modified in-place, and the
+function returns ``None``.
+
 Note that this should be avoided for large memory allocations or
 for limited resources.  This is particularly true on PyPy: its GC does
 not know how much memory or how many resources the returned ``ptr``
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -3,6 +3,13 @@
 ==
 
 
+v1.next
+===
+
+* ``ffi.gc(p, None)`` removes the destructor on an object previously
+ 

[pypy-commit] cffi default: merge heads

2016-02-19 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r2642:d2a90d323791
Date: 2016-02-19 10:38 +0100
http://bitbucket.org/cffi/cffi/changeset/d2a90d323791/

Log:merge heads

diff --git a/testing/cffi0/test_zintegration.py 
b/testing/cffi0/test_zintegration.py
--- a/testing/cffi0/test_zintegration.py
+++ b/testing/cffi0/test_zintegration.py
@@ -11,7 +11,7 @@
 def create_venv(name):
 tmpdir = udir.join(name)
 try:
-subprocess.check_call(['virtualenv', '--distribute',
+subprocess.check_call(['virtualenv', '--never-download',
'-p', os.path.abspath(sys.executable),
str(tmpdir)])
 except OSError as e:
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Merge heads

2014-12-17 Thread rguillebert
Author: Romain Guillebert romain...@gmail.com
Branch: 
Changeset: r1592:9267d5f13672
Date: 2014-12-17 18:04 +0100
http://bitbucket.org/cffi/cffi/changeset/9267d5f13672/

Log:Merge heads

diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -1,10 +1,3 @@
 
 
-Next steps
---
-
-verify() handles typedef ... some_integer_type, but this creates
-an opaque type that works like a struct (so we can't get the value
-out of it).
-
-accept and kill static inline in the cdefs
+Add other required types from stdint.h
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4765,7 +4765,7 @@
 CFieldObject *cf;
 Py_ssize_t offset;
 
-if (!PyArg_ParseTuple(args, O!O:typeof,
+if (!PyArg_ParseTuple(args, O!O:typeoffsetof,
   CTypeDescr_Type, ct, fieldname))
 return NULL;
 
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -208,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
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -235,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):
@@ -274,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))
@@ -835,12 +836,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)\
@@ -851,7 +855,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])
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -16,7 +16,8 @@
 class Verifier(object):
 
 def __init__(self, ffi, preamble, tmpdir=None, modulename=None,
- ext_package=None, tag='', force_generic_engine=False, 
flags=None, **kwds):
+ ext_package=None, tag='', force_generic_engine=False,
+ source_extension='.c', flags=None, **kwds):
 self.ffi = ffi
 self.preamble = preamble
 if not modulename:
@@ -44,7 +45,7 @@
   k1, k2)
 suffix 

[pypy-commit] cffi default: merge heads

2014-02-27 Thread antocuni
Author: Antonio Cuni anto.c...@gmail.com
Branch: 
Changeset: r1464:3b6e66b91886
Date: 2014-02-27 11:08 +0100
http://bitbucket.org/cffi/cffi/changeset/3b6e66b91886/

Log:merge heads

diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1429,8 +1429,10 @@
 p = newp(BStructPtr, [12])
 assert p.a1 == 12
 e = py.test.raises(TypeError, newp, BStructPtr, [None])
-assert (an integer is required in str(e.value) or
-unsupported operand type for int(): 'NoneType' in str(e.value)) #PyPy
+msg = str(e.value)
+assert (an integer is required in msg or  # CPython
+unsupported operand type for int(): 'NoneType' in msg or  # old 
PyPys
+expected integer, got NoneType object in msg) # newer PyPys
 py.test.raises(TypeError, 'p.a1 = def')
 if sys.version_info  (3,):
 BEnum2 = new_enum_type(unicode(foo), (unicode('abc'),), (5,), BInt)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2014-01-07 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r1449:9941a90948dc
Date: 2014-01-07 09:57 +0100
http://bitbucket.org/cffi/cffi/changeset/9941a90948dc/

Log:merge heads

diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -81,29 +81,29 @@
 'long':   'i',
 'long long':  'i',
 'signed char':'i',
-'unsigned char':  'u',
-'unsigned short': 'u',
-'unsigned int':   'u',
-'unsigned long':  'u',
-'unsigned long long': 'u',
+'unsigned char':  'i',
+'unsigned short': 'i',
+'unsigned int':   'i',
+'unsigned long':  'i',
+'unsigned long long': 'i',
 'float':  'f',
 'double': 'f',
 'long double':'f',
-'_Bool':  'u',
+'_Bool':  'i',
 # the following types are not primitive in the C sense
 'wchar_t':'c',
 'int8_t': 'i',
-'uint8_t':'u',
+'uint8_t':'i',
 'int16_t':'i',
-'uint16_t':   'u',
+'uint16_t':   'i',
 'int32_t':'i',
-'uint32_t':   'u',
+'uint32_t':   'i',
 'int64_t':'i',
-'uint64_t':   'u',
+'uint64_t':   'i',
 'intptr_t':   'i',
-'uintptr_t':  'u',
+'uintptr_t':  'i',
 'ptrdiff_t':  'i',
-'size_t': 'u',
+'size_t': 'i',
 'ssize_t':'i',
 }
 
@@ -114,12 +114,8 @@
 
 def is_char_type(self):
 return self.ALL_PRIMITIVE_TYPES[self.name] == 'c'
-def is_signed_type(self):
+def is_integer_type(self):
 return self.ALL_PRIMITIVE_TYPES[self.name] == 'i'
-def is_unsigned_type(self):
-return self.ALL_PRIMITIVE_TYPES[self.name] == 'u'
-def is_integer_type(self):
-return self.ALL_PRIMITIVE_TYPES[self.name] in 'iu'
 def is_float_type(self):
 return self.ALL_PRIMITIVE_TYPES[self.name] == 'f'
 
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -214,10 +214,7 @@
 extraarg = ''
 if isinstance(tp, model.PrimitiveType):
 if tp.is_integer_type() and tp.name != '_Bool':
-if tp.is_signed_type():
-converter = '_cffi_to_c_SIGNED'
-else:
-converter = '_cffi_to_c_UNSIGNED'
+converter = '_cffi_to_c_int'
 extraarg = ', %s' % tp.name
 else:
 converter = '_cffi_to_c_%s' % (tp.name.replace(' ', '_'),)
@@ -270,10 +267,7 @@
 def _convert_expr_from_c(self, tp, var, context):
 if isinstance(tp, model.PrimitiveType):
 if tp.is_integer_type():
-if tp.is_signed_type():
-return '_cffi_from_c_SIGNED(%s, %s)' % (var, tp.name)
-else:
-return '_cffi_from_c_UNSIGNED(%s, %s)' % (var, tp.name)
+return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
 elif tp.name != 'long double':
 return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
 else:
@@ -801,25 +795,23 @@
 #define _cffi_to_c_double PyFloat_AsDouble
 #define _cffi_to_c_float PyFloat_AsDouble
 
-#define _cffi_from_c_SIGNED(x, type) \
-(sizeof(type) = sizeof(long) ? PyInt_FromLong(x) :  \
-PyLong_FromLongLong(x))
-#define _cffi_from_c_UNSIGNED(x, type)   \
-(sizeof(type)  sizeof(long) ? PyInt_FromLong(x) :   \
- sizeof(type) == sizeof(long) ? PyLong_FromUnsignedLong(x) : \
-PyLong_FromUnsignedLongLong(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)))
 
-#define _cffi_to_c_SIGNED(o, type)   \
-(sizeof(type) == 1 ? _cffi_to_c_i8(o) :  \
- sizeof(type) == 2 ? _cffi_to_c_i16(o) : \
- sizeof(type) == 4 ? _cffi_to_c_i32(o) : \
- sizeof(type) == 8 ? _cffi_to_c_i64(o) : \
- (Py_FatalError(unsupported 

[pypy-commit] cffi default: merge heads

2013-06-19 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r1274:52dcd2ee1de1
Date: 2013-06-19 10:17 +0200
http://bitbucket.org/cffi/cffi/changeset/52dcd2ee1de1/

Log:merge heads

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3421,6 +3421,7 @@
 }
 
 #define SF_MSVC_BITFIELDS 1
+#define SF_GCC_ARM_BITFIELDS 2
 
 static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args)
 {
@@ -3435,7 +3436,11 @@
 #ifdef MS_WIN32
 int sflags = SF_MSVC_BITFIELDS;
 #else
+# ifdef __arm__
+int sflags = SF_GCC_ARM_BITFIELDS;
+# else
 int sflags = 0;
+# endif
 #endif
 
 if (!PyArg_ParseTuple(args, O!O!|Onii:complete_struct_or_union,
@@ -3499,8 +3504,7 @@
 goto error;
 
 do_align = 1;
-#ifndef __arm__
-if (fbitsize = 0) {
+if (!(sflags  SF_GCC_ARM_BITFIELDS)  fbitsize = 0) {
 if (!(sflags  SF_MSVC_BITFIELDS)) {
 /* GCC: anonymous bitfields (of any size) don't cause 
alignment */
 do_align = PyText_GetSize(fname)  0;
@@ -3510,7 +3514,6 @@
 do_align = fbitsize  0;
 }
 }
-#endif
 if (alignment  falign  do_align)
 alignment = falign;
 
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -2780,10 +2780,10 @@
('b1', BInt, 9),
('b2', BUInt, 7),
('c', BChar, -1)], -1, -1, -1, flag)
-if flag == 0:   # gcc
+if flag % 2 == 0:   # gcc and gcc ARM
 assert typeoffsetof(BStruct, 'c') == (BChar, 3)
 assert sizeof(BStruct) == 4
-else:   # msvc
+else:   # msvc
 assert typeoffsetof(BStruct, 'c') == (BChar, 8)
 assert sizeof(BStruct) == 12
 assert alignof(BStruct) == 4
@@ -2796,7 +2796,10 @@
 if flag == 0:   # gcc
 assert sizeof(BStruct) == 5
 assert alignof(BStruct) == 1
-else:   # msvc
+elif flag == 1: # msvc
+assert sizeof(BStruct) == 6
+assert alignof(BStruct) == 2
+else:   # gcc ARM
 assert sizeof(BStruct) == 6
 assert alignof(BStruct) == 2
 #
@@ -2808,10 +2811,15 @@
 if flag == 0:   # gcc
 assert typeoffsetof(BStruct, 'c') == (BChar, 4)
 assert sizeof(BStruct) == 5
-else:   # msvc
+assert alignof(BStruct) == 1
+elif flag == 1:  # msvc
 assert typeoffsetof(BStruct, 'c') == (BChar, 1)
 assert sizeof(BStruct) == 2
-assert alignof(BStruct) == 1
+assert alignof(BStruct) == 1
+else:# gcc ARM
+assert typeoffsetof(BStruct, 'c') == (BChar, 4)
+assert sizeof(BStruct) == 8
+assert alignof(BStruct) == 4
 
 
 def test_bitfield_as_gcc():
@@ -2820,6 +2828,9 @@
 def test_bitfield_as_msvc():
 _test_bitfield_details(flag=1)
 
+def test_bitfield_as_arm_gcc():
+_test_bitfield_details(flag=2)
+
 
 def test_version():
 # this test is here mostly for PyPy
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2013-04-02 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r1221:e43094a16966
Date: 2013-04-02 19:21 +0200
http://bitbucket.org/cffi/cffi/changeset/e43094a16966/

Log:merge heads

diff --git a/AUTHORS b/AUTHORS
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
 This package has been mostly done by Armin Rigo with help from
-Maciej Fija#322;kowski.
\ No newline at end of file
+Maciej Fija#322;kowski. The idea is heavily based (although not directly
+copied) from LuaJIT ffi by Mike Pall.
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2013-03-31 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r1218:c15983a2607b
Date: 2013-03-31 19:15 +0200
http://bitbucket.org/cffi/cffi/changeset/c15983a2607b/

Log:merge heads

diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -1094,7 +1094,7 @@
 assert content.startswith(b'\x64\x00\x00\x00\x65\x00\x00\x00')
 b[4] = b'\x45'
 else:
-assert content.startswith('\x00\x00\x00\x64\x00\x00\x00\x65')
+assert content.startswith(b'\x00\x00\x00\x64\x00\x00\x00\x65')
 b[7] = b'\x45'
 assert len(content) == 4 * 10
 assert a[1] == 0x45
diff --git a/testing/test_function.py b/testing/test_function.py
--- a/testing/test_function.py
+++ b/testing/test_function.py
@@ -173,7 +173,7 @@
 res = fd.getvalue()
 if sys.platform == 'win32':
 NIL = b
-elif sys.platform.startswith('linux'):
+elif sys.platform.startswith(('linux', 'gnu')):
 NIL = b(nil)
 else:
 NIL = b0x0# OS/X at least
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2013-03-04 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r1182:a9b47162788d
Date: 2013-03-04 15:40 +0100
http://bitbucket.org/cffi/cffi/changeset/a9b47162788d/

Log:merge heads

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -937,7 +937,9 @@
 **pointer** to such a struct is fine).  If you pass a struct (not a
 **pointer** to a struct), the struct type cannot have been declared with
 ``...;`` and completed with ``verify()``; you need to declare it
-completely in ``cdef()``.
+completely in ``cdef()``.  You can work around these limitations by
+writing a C function with a simpler signature in the code passed to
+``ffi.verify()``, which calls the real C function.
 
 Aside from these limitations, functions and callbacks can return structs.
 
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2013-01-02 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r1113:ef0728d36e2b
Date: 2013-01-02 22:42 +0100
http://bitbucket.org/cffi/cffi/changeset/ef0728d36e2b/

Log:merge heads

diff --git a/testing/test_zintegration.py b/testing/test_zintegration.py
--- a/testing/test_zintegration.py
+++ b/testing/test_zintegration.py
@@ -6,7 +6,8 @@
 def create_venv(name):
 tmpdir = udir.join(name)
 try:
-subprocess.check_call(['virtualenv', '-p', sys.executable,
+subprocess.check_call(['virtualenv', '--distribute',
+   '-p', sys.executable,
str(tmpdir)])
 except OSError, e:
 py.test.skip(Cannot execute virtualenv: %s % (e,))
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2012-10-09 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r991:ec097c369113
Date: 2012-10-09 11:20 +0200
http://bitbucket.org/cffi/cffi/changeset/ec097c369113/

Log:merge heads

diff --git a/demo/_curses.py b/demo/_curses.py
--- a/demo/_curses.py
+++ b/demo/_curses.py
@@ -22,6 +22,11 @@
 
 int setupterm(char *term, int fildes, int *errret);
 
+int tigetflag(char *);
+int tigetnum(char *);
+char *tigetstr(char *);
+char *tparm (char *, ...);
+
 int cbreak(void);
 int nocbreak(void);
 int echo(void);
@@ -205,8 +210,17 @@
 
 initscr = Window
 
+_setupterm_called = False
 
-def setupterm(term=ffi.NULL, fd=-1):
+
+def _ensure_setupterm_called():
+if not _setupterm_called:
+raise error(must call (at least) setupterm() first)
+
+
+def setupterm(term=None, fd=-1):
+if term is None:
+term = ffi.NULL
 if fd  0:
 import sys
 fd = sys.stdout.fileno()
@@ -219,6 +233,33 @@
 else:
 s = setupterm: unknown error %d % err[0]
 raise error(s)
+global _setupterm_called
+_setupterm_called = True
+
+
+def tigetflag(capname):
+_ensure_setupterm_called()
+return lib.tigetflag(capname)
+
+
+def tigetnum(capname):
+_ensure_setupterm_called()
+return lib.tigetnum(capname)
+
+
+def tigetstr(capname):
+_ensure_setupterm_called()
+out = lib.tigetstr(capname)
+if out == ffi.NULL:
+return None
+return ffi.string(out)
+
+
+def tparm(name, *args):
+_ensure_setupterm_called()
+cargs = [ffi.cast(long, arg) for arg in args]
+return ffi.string(lib.tparm(name, *cargs))
+
 
 def color_pair(n):
 return n  8
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2012-08-23 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r886:4208a40e9af3
Date: 2012-08-23 17:47 +0200
http://bitbucket.org/cffi/cffi/changeset/4208a40e9af3/

Log:merge heads

diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -396,6 +396,10 @@
 tp.fldnames = tuple(fldnames)
 tp.fldtypes = tuple(fldtypes)
 tp.fldbitsize = tuple(fldbitsize)
+if fldbitsize != [-1] * len(fldbitsize):
+if isinstance(tp, model.StructType) and tp.partial:
+raise NotImplementedError(%s: using both bitfields and '...;'
+  % (tp,))
 return tp
 
 def _make_partial(self, tp):
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -386,7 +386,8 @@
 prnt('  static Py_ssize_t nums[] = {')
 prnt('sizeof(%s),' % cname)
 prnt('offsetof(struct _cffi_aligncheck, y),')
-for fname, _, _ in tp.enumfields():
+for fname, _, fbitsize in tp.enumfields():
+assert fbitsize  0
 prnt('offsetof(%s, %s),' % (cname, fname))
 prnt('sizeof(((%s *)0)-%s),' % (cname, fname))
 prnt('-1')
@@ -399,7 +400,9 @@
 'sizeof(%s) != %d' % (cname, ffi.sizeof(BStruct)),
 'offsetof(struct _cffi_aligncheck, y) != %d' % (
 ffi.alignof(BStruct),)]
-for fname, ftype, _ in tp.enumfields():
+for fname, ftype, fbitsize in tp.enumfields():
+if fbitsize = 0:
+continue# xxx ignore fbitsize for now
 BField = ffi._get_cached_btype(ftype)
 conditions += [
 'offsetof(%s, %s) != %d' % (
diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py
--- a/cffi/vengine_gen.py
+++ b/cffi/vengine_gen.py
@@ -208,7 +208,8 @@
 prnt('  static ssize_t nums[] = {')
 prnt('1, sizeof(%s),' % cname)
 prnt('offsetof(struct _cffi_aligncheck, y),')
-for fname in tp.fldnames:
+for fname, fbitsize in zip(tp.fldnames, tp.fldbitsize):
+assert fbitsize  0
 prnt('offsetof(%s, %s),' % (cname, fname))
 prnt('sizeof(((%s *)0)-%s),' % (cname, fname))
 prnt('-1')
@@ -221,7 +222,10 @@
 'sizeof(%s) != %d' % (cname, ffi.sizeof(BStruct)),
 'offsetof(struct _cffi_aligncheck, y) != %d' % (
 ffi.alignof(BStruct),)]
-for fname, ftype in zip(tp.fldnames, tp.fldtypes):
+for fname, ftype, fbitsize in zip(tp.fldnames, tp.fldtypes,
+  tp.fldbitsize):
+if fbitsize = 0:
+continue# xxx ignore fbitsize for now
 BField = ffi._get_cached_btype(ftype)
 conditions += [
 'offsetof(%s, %s) != %d' % (
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -387,6 +387,20 @@
 s = ffi.new(struct foo_s *)
 assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
 
+def test_struct_with_bitfield_exact():
+ffi = FFI()
+ffi.cdef(struct foo_s { int a:2, b:3; };)
+ffi.verify(struct foo_s { int a:2, b:3; };)
+s = ffi.new(struct foo_s *)
+s.b = 3
+py.test.raises(OverflowError, s.b = 4)
+assert s.b == 3
+
+def test_unsupported_struct_with_bitfield_ellipsis():
+ffi = FFI()
+py.test.raises(NotImplementedError, ffi.cdef,
+   struct foo_s { int a:2, b:3; ...; };)
+
 def test_global_constants():
 ffi = FFI()
 # use 'static const int', as generally documented, although in this
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2012-08-18 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r862:da964df4e6c7
Date: 2012-08-18 12:03 +0200
http://bitbucket.org/cffi/cffi/changeset/da964df4e6c7/

Log:merge heads

diff --git a/cffi/ffiplatform.py b/cffi/ffiplatform.py
--- a/cffi/ffiplatform.py
+++ b/cffi/ffiplatform.py
@@ -11,9 +11,11 @@
 
 
 
-def get_extension(srcfilename, modname, **kwds):
+def get_extension(srcfilename, modname, sources=(), **kwds):
 from distutils.core import Extension
-return Extension(name=modname, sources=[srcfilename], **kwds)
+allsources = [srcfilename]
+allsources.extend(sources)
+return Extension(name=modname, sources=allsources, **kwds)
 
 def compile(tmpdir, ext):
 Compile a C extension module using distutils.
diff --git a/testing/test_zdistutils.py b/testing/test_zdistutils.py
--- a/testing/test_zdistutils.py
+++ b/testing/test_zdistutils.py
@@ -157,6 +157,24 @@
 v.get_extension()
 assert os.path.exists(v.sourcefilename)
 
+def test_extension_object_extra_sources(self):
+ffi = FFI()
+ffi.cdef(double test1eoes(double x);)
+extra_source = str(udir.join('extension_extra_sources.c'))
+with open(extra_source, 'w') as f:
+f.write('double test1eoes(double x) { return x * 6.0; }\n')
+csrc = '''/*9*/
+double test1eoes(double x);   /* or #include extra_sources.h */
+'''
+lib = ffi.verify(csrc, sources=[extra_source],
+ force_generic_engine=self.generic)
+assert lib.test1eoes(7.0) == 42.0
+v = ffi.verifier
+ext = v.get_extension()
+assert 'distutils.extension.Extension' in str(ext.__class__)
+assert ext.sources == [v.sourcefilename, extra_source]
+assert ext.name == v.get_module_name()
+
 
 class TestDistUtilsCPython(DistUtilsTest):
 generic = False
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: merge heads

2012-07-08 Thread arigo
Author: Armin Rigo ar...@tunes.org
Branch: 
Changeset: r596:f35564e0f15b
Date: 2012-07-08 10:35 +0200
http://bitbucket.org/cffi/cffi/changeset/f35564e0f15b/

Log:merge heads

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -4,6 +4,8 @@
 .*.swp
 testing/__pycache__
 demo/__pycache__
+__pycache__
+_cffi_backend.so
 doc/build
 build
 dist
___
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit