[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