diff options
| author | mozbugbox <mozbugbox@yahoo.com.au> | 2014-04-02 11:45:29 +0800 |
|---|---|---|
| committer | mozbugbox <mozbugbox@yahoo.com.au> | 2014-04-02 11:45:29 +0800 |
| commit | 58f87aa85b0381e91c6b1d8b194b3a71f1f0a14a (patch) | |
| tree | ec0ad40f33de4d19aa91722766331e6a5da2f4ae | |
| parent | c8f68e82fd06d667e36389ee1c8e9b3fdfbe49d2 (diff) | |
| download | cffi-reusable-enum-values.tar.gz | |
ffi.include update _int_constant and prevent duplicated const declreusable-enum-values
Duplicated declaration of constants even in enum name is not
valid.
| -rw-r--r-- | cffi/cparser.py | 10 | ||||
| -rw-r--r-- | testing/backend_tests.py | 30 |
2 files changed, 26 insertions, 14 deletions
diff --git a/cffi/cparser.py b/cffi/cparser.py index 8ad87db..0456b05 100644 --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -542,6 +542,10 @@ class Parser(object): 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 @@ class Parser(object): 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 index ce5381e..e7da1ef 100644 --- a/testing/backend_tests.py +++ b/testing/backend_tests.py @@ -865,25 +865,25 @@ class BackendTests: 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 @@ class BackendTests: 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 @@ class BackendTests: 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() |
