[pypy-commit] cffi reusable-enum-values: ffi.include update _int_constant and prevent duplicated const decl
mozbugbox
noreply at buildbot.pypy.org
Wed Apr 2 09:26:20 CEST 2014
Author: mozbugbox <mozbugbox at yahoo.com.au>
Branch: reusable-enum-values
Changeset: r1488:f31f43f81992
Date: 2014-04-02 11:45 +0800
http://bitbucket.org/cffi/cffi/changeset/f31f43f81992/
Log: ffi.include update _int_constant and prevent duplicated const decl
Duplicated declaration of constants even in enum name is not valid.
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -542,6 +542,10 @@
if enum.value is not None:
nextenumvalue = self._parse_constant(enum.value)
enumvalues.append(nextenumvalue)
+ if enum.name in self._int_constants:
+ raise api.FFIError(
+ "multiple declarations of constant %s" % (enum.name,))
+
self._int_constants[enum.name] = nextenumvalue
nextenumvalue += 1
enumvalues = tuple(enumvalues)
@@ -556,3 +560,9 @@
kind = name.split(' ', 1)[0]
if kind in ('typedef', 'struct', 'union', 'enum'):
self._declare(name, tp)
+ for k, v in other._int_constants.items():
+ if k not in self._int_constants:
+ self._int_constants[k] = v
+ else:
+ raise api.FFIError(
+ "multiple declarations of constant %s" % (k,))
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -865,25 +865,25 @@
def test_enum(self):
ffi = FFI(backend=self.Backend())
- ffi.cdef("enum foo { A, B, CC, D };")
- assert ffi.string(ffi.cast("enum foo", 0)) == "A"
- assert ffi.string(ffi.cast("enum foo", 2)) == "CC"
- assert ffi.string(ffi.cast("enum foo", 3)) == "D"
+ ffi.cdef("enum foo { A0, B0, CC0, D0 };")
+ assert ffi.string(ffi.cast("enum foo", 0)) == "A0"
+ assert ffi.string(ffi.cast("enum foo", 2)) == "CC0"
+ assert ffi.string(ffi.cast("enum foo", 3)) == "D0"
assert ffi.string(ffi.cast("enum foo", 4)) == "4"
- ffi.cdef("enum bar { A, B=-2, CC, D, E };")
- assert ffi.string(ffi.cast("enum bar", 0)) == "A"
- assert ffi.string(ffi.cast("enum bar", -2)) == "B"
- assert ffi.string(ffi.cast("enum bar", -1)) == "CC"
- assert ffi.string(ffi.cast("enum bar", 1)) == "E"
+ ffi.cdef("enum bar { A1, B1=-2, CC1, D1, E1 };")
+ assert ffi.string(ffi.cast("enum bar", 0)) == "A1"
+ assert ffi.string(ffi.cast("enum bar", -2)) == "B1"
+ assert ffi.string(ffi.cast("enum bar", -1)) == "CC1"
+ assert ffi.string(ffi.cast("enum bar", 1)) == "E1"
assert ffi.cast("enum bar", -2) != ffi.cast("enum bar", -2)
assert ffi.cast("enum foo", 0) != ffi.cast("enum bar", 0)
assert ffi.cast("enum bar", 0) != ffi.cast("int", 0)
- assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC>"
+ assert repr(ffi.cast("enum bar", -1)) == "<cdata 'enum bar' -1: CC1>"
assert repr(ffi.cast("enum foo", -1)) == ( # enums are unsigned, if
"<cdata 'enum foo' 4294967295>") # they contain no neg value
- ffi.cdef("enum baz { A=0x1000, B=0x2000 };")
- assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A"
- assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B"
+ ffi.cdef("enum baz { A2=0x1000, B2=0x2000 };")
+ assert ffi.string(ffi.cast("enum baz", 0x1000)) == "A2"
+ assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B2"
def test_enum_in_struct(self):
ffi = FFI(backend=self.Backend())
@@ -1324,12 +1324,13 @@
def test_enum_refer_previous_enum_value(self):
ffi = FFI(backend=self.Backend())
- ffi.cdef("enum e { AA, BB=2, CC=4, DD=BB, EE, FF=CC };")
+ ffi.cdef("enum e { AA, BB=2, CC=4, DD=BB, EE, FF=CC, GG=FF };")
assert ffi.string(ffi.cast("enum e", 2)) == "BB"
assert ffi.string(ffi.cast("enum e", 3)) == "EE"
assert ffi.sizeof("char[DD]") == 2
assert ffi.sizeof("char[EE]") == 3
assert ffi.sizeof("char[FF]") == 4
+ assert ffi.sizeof("char[GG]") == 4
def test_nested_anonymous_struct(self):
ffi = FFI(backend=self.Backend())
@@ -1552,6 +1553,7 @@
ffi2.include(ffi1)
p = ffi2.cast("enum foo", 1)
assert ffi2.string(p) == "FB"
+ assert ffi2.sizeof("char[FC]") == 2
def test_include_typedef_2(self):
backend = self.Backend()
More information about the pypy-commit
mailing list