[pypy-commit] cffi default: Issue #193: if we use a struct between the first cdef() where it is
arigo
noreply at buildbot.pypy.org
Wed May 20 14:31:40 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r2062:2dfaf4b4f0aa
Date: 2015-05-20 14:32 +0200
http://bitbucket.org/cffi/cffi/changeset/2dfaf4b4f0aa/
Log: Issue #193: if we use a struct between the first cdef() where it is
declared and another cdef() where its fields are defined, then the
definition was ignored.
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -109,6 +109,11 @@
if override:
for cache in self._function_caches:
cache.clear()
+ finishlist = self._parser._recomplete
+ if finishlist:
+ self._parser._recomplete = []
+ for tp in finishlist:
+ tp.finish_backend_type(self, finishlist)
def dlopen(self, name, flags=0):
"""Load and return a dynamic library identified by 'name'.
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -101,6 +101,7 @@
self._override = False
self._packed = False
self._int_constants = {}
+ self._recomplete = []
def _parse(self, csource):
csource, macros = _preprocess(csource)
@@ -555,6 +556,9 @@
raise NotImplementedError("%s: using both bitfields and '...;'"
% (tp,))
tp.packed = self._packed
+ if tp.completed: # must be re-completed: it is not opaque any more
+ tp.completed = 0
+ self._recomplete.append(tp)
return tp
def _make_partial(self, tp, nested):
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -293,7 +293,7 @@
class StructOrUnion(StructOrUnionOrEnum):
fixedlayout = None
- completed = False
+ completed = 0
partial = False
packed = False
@@ -351,12 +351,13 @@
"for '%s'" % (self.name,))
return
BType = ffi._cached_btypes[self]
- if self.fldtypes is None:
- return # not completing it: it's an opaque struct
#
self.completed = 1
#
- if self.fixedlayout is None:
+ if self.fldtypes is None:
+ pass # not completing it: it's an opaque struct
+ #
+ elif self.fixedlayout is None:
fldtypes = [tp.get_cached_btype(ffi, finishlist)
for tp in self.fldtypes]
lst = list(zip(self.fldnames, fldtypes, self.fldbitsize))
diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py
--- a/testing/cffi0/backend_tests.py
+++ b/testing/cffi0/backend_tests.py
@@ -1703,3 +1703,13 @@
assert lib.DOT_HEX == 0x100
assert lib.DOT_HEX2 == 0x10
assert lib.DOT_UL == 1000
+
+ def test_opaque_struct_becomes_nonopaque(self):
+ # Issue #193: if we use a struct between the first cdef() where it is
+ # declared and another cdef() where its fields are defined, then the
+ # definition was ignored.
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("struct foo_s;")
+ py.test.raises(TypeError, ffi.new, "struct foo_s *")
+ ffi.cdef("struct foo_s { int x; };")
+ ffi.new("struct foo_s *")
More information about the pypy-commit
mailing list