[pypy-commit] cffi default: Fix issue16: anonymous enums.
arigo
noreply at buildbot.pypy.org
Fri Jul 27 17:04:20 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r724:18972b4e0db3
Date: 2012-07-27 17:04 +0200
http://bitbucket.org/cffi/cffi/changeset/18972b4e0db3/
Log: Fix issue16: anonymous enums.
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -817,6 +817,7 @@
return CTypesFunctionPtr
def new_enum_type(self, name, enumerators, enumvalues):
+ assert isinstance(name, str)
mapping = dict(zip(enumerators, enumvalues))
reverse_mapping = dict(reversed(zip(enumvalues, enumerators)))
CTypesInt = self.ffi._get_cached_btype(model.PrimitiveType('int'))
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -383,11 +383,27 @@
"not immediately constant expression")
def _get_enum_type(self, type):
+ # See _get_struct_or_union_type() for the reason of the
+ # complicated logic here. This is still a simplified version,
+ # assuming that it's ok to assume the more complicated cases
+ # don't occur...
+ try:
+ return self._structnode2type[type]
+ except KeyError:
+ pass
name = type.name
+ if name is None:
+ self._anonymous_counter += 1
+ explicit_name = '$%d' % self._anonymous_counter
+ key = None
+ else:
+ explicit_name = name
+ key = 'enum %s' % (name,)
+ tp = self._declarations.get(key, None)
+ if tp is not None:
+ return tp
+ #
decls = type.values
- key = 'enum %s' % (name,)
- if key in self._declarations:
- return self._declarations[key]
if decls is not None:
enumerators = [enum.name for enum in decls.enumerators]
partial = False
@@ -403,11 +419,13 @@
enumvalues.append(nextenumvalue)
nextenumvalue += 1
enumvalues = tuple(enumvalues)
- tp = model.EnumType(name, enumerators, enumvalues)
+ tp = model.EnumType(explicit_name, enumerators, enumvalues)
tp.partial = partial
- self._declare(key, tp)
+ if key is not None:
+ self._declare(key, tp)
else: # opaque enum
enumerators = ()
enumvalues = ()
- tp = model.EnumType(name, (), ())
+ tp = model.EnumType(explicit_name, (), ())
+ self._structnode2type[type] = tp
return tp
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -1179,3 +1179,11 @@
assert ffi1.typeof("enum foo") is not ffi2.typeof("enum foo")
# sanity check: twice 'ffi1'
assert ffi1.typeof("struct foo*") is ffi1.typeof("struct foo *")
+
+ def test_anonymous_enum(self):
+ ffi = FFI(backend=self.Backend())
+ ffi.cdef("typedef enum { Value0 = 0 } e, *pe;\n"
+ "typedef enum { Value1 = 1 } e1;")
+ assert ffi.getctype("e*") == 'enum $1 *'
+ assert ffi.getctype("pe") == 'enum $1 *'
+ assert ffi.getctype("e1*") == 'enum $2 *'
More information about the pypy-commit
mailing list