[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