[pypy-commit] cffi cffi-1.0: Make "static const int FOO = VALUE; " fully equivalent to "#define FOO VALUE"

arigo noreply at buildbot.pypy.org
Tue May 12 16:14:37 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1992:cbd812009db2
Date: 2015-05-12 15:52 +0200
http://bitbucket.org/cffi/cffi/changeset/cbd812009db2/

Log:	Make "static const int FOO = VALUE;" fully equivalent to "#define
	FOO VALUE"

diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -23,7 +23,7 @@
 _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]")
 _r_words = re.compile(r"\w+|\S")
 _parser_cache = None
-_r_int_literal = re.compile(r"^0?x?[0-9a-f]+[lu]*$", re.IGNORECASE)
+_r_int_literal = re.compile(r"-?0?x?[0-9a-f]+[lu]*$", re.IGNORECASE)
 
 def _get_parser():
     global _parser_cache
@@ -215,26 +215,26 @@
                 "multiple declarations of constant: %s" % (key,))
         self._int_constants[key] = val
 
+    def _add_integer_constant(self, name, int_str):
+        int_str = int_str.lower().rstrip("ul")
+        neg = int_str.startswith('-')
+        if neg:
+            int_str = int_str[1:]
+        # "010" is not valid oct in py3
+        if (int_str.startswith("0") and int_str != '0'
+                and not int_str.startswith("0x")):
+            int_str = "0o" + int_str[1:]
+        pyvalue = int(int_str, 0)
+        if neg:
+            pyvalue = -pyvalue
+        self._add_constants(name, pyvalue)
+        self._declare('macro ' + name, pyvalue)
+
     def _process_macros(self, macros):
         for key, value in macros.items():
             value = value.strip()
-            neg = value.startswith('-')
-            if neg:
-                value = value[1:].strip()
-            match = _r_int_literal.search(value)
-            if match is not None:
-                int_str = match.group(0).lower().rstrip("ul")
-
-                # "010" is not valid oct in py3
-                if (int_str.startswith("0") and
-                        int_str != "0" and
-                        not int_str.startswith("0x")):
-                    int_str = "0o" + int_str[1:]
-
-                pyvalue = int(int_str, 0)
-                if neg: pyvalue = -pyvalue
-                self._add_constants(key, pyvalue)
-                self._declare('macro ' + key, pyvalue)
+            if _r_int_literal.match(value):
+                self._add_integer_constant(key, value)
             elif value == '...':
                 self._declare('macro ' + key, value)
             else:
@@ -270,6 +270,11 @@
                 if tp.is_raw_function:
                     tp = self._get_type_pointer(tp)
                     self._declare('function ' + decl.name, tp)
+                elif (isinstance(tp, model.PrimitiveType) and
+                      tp.is_integer_type() and
+                      hasattr(decl, 'init') and hasattr(decl.init, 'value')
+                      and _r_int_literal.match(decl.init.value)):
+                    self._add_integer_constant(decl.name, decl.init.value)
                 elif self._is_constant_globalvar(node):
                     self._declare('constant ' + decl.name, tp)
                 else:
diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py
--- a/testing/cffi0/test_verify.py
+++ b/testing/cffi0/test_verify.py
@@ -2210,3 +2210,15 @@
     ffi.cdef("#define FOO 123")
     e = py.test.raises(VerificationError, ffi.verify, "#define FOO 124")
     assert str(e.value).endswith("FOO has the real value 124, not 123")
+
+def test_static_const_int_known_value():
+    ffi = FFI()
+    ffi.cdef("static const int FOO = 0x123;")
+    lib = ffi.verify("#define FOO 0x123")
+    assert lib.FOO == 0x123
+
+def test_static_const_int_wrong_value():
+    ffi = FFI()
+    ffi.cdef("static const int FOO = 123;")
+    e = py.test.raises(VerificationError, ffi.verify, "#define FOO 124")
+    assert str(e.value).endswith("FOO has the real value 124, not 123")
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -227,6 +227,14 @@
     assert lib.FOOBAR == -6912
     py.test.raises(AttributeError, "lib.FOOBAR = 2")
 
+def test_check_value_of_static_const():
+    ffi = FFI()
+    ffi.cdef("static const int FOOBAR = 042;")
+    lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)")
+    e = py.test.raises(ffi.error, getattr, lib, 'FOOBAR')
+    assert str(e.value) == (
+       "the C compiler says 'FOOBAR' is equal to -6912, but the cdef disagrees")
+
 def test_constant_nonint():
     ffi = FFI()
     ffi.cdef("static const double FOOBAR;")


More information about the pypy-commit mailing list