[pypy-commit] cffi default: Issue #118: improve the detection and error message, jumping
arigo
noreply at buildbot.pypy.org
Sun Nov 10 12:00:40 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1410:c3942c440199
Date: 2013-11-10 12:00 +0100
http://bitbucket.org/cffi/cffi/changeset/c3942c440199/
Log: Issue #118: improve the detection and error message, jumping through
hoops to cover both signed and unsigned cases.
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -646,12 +646,23 @@
prnt('static int %s(PyObject *lib)' % funcname)
prnt('{')
for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
- prnt(' if (%s != %d) {' % (enumerator, enumvalue))
+ if enumvalue < 0:
+ prnt(' if ((%s) >= 0 || (long)(%s) != %dL) {' % (
+ enumerator, enumerator, enumvalue))
+ else:
+ prnt(' if ((%s) < 0 || (unsigned long)(%s) != %dUL) {' % (
+ enumerator, enumerator, enumvalue))
+ prnt(' char buf[64];')
+ prnt(' if ((%s) < 0)' % enumerator)
+ prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % enumerator)
+ prnt(' else')
+ prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' %
+ enumerator)
prnt(' PyErr_Format(_cffi_VerificationError,')
- prnt(' "enum %s: %s has the real value %d, '
- 'not %d",')
- prnt(' "%s", "%s", (int)%s, %d);' % (
- name, enumerator, enumerator, enumvalue))
+ prnt(' "enum %s: %s has the real value %s, '
+ 'not %s",')
+ prnt(' "%s", "%s", buf, "%d");' % (
+ name, enumerator, enumvalue))
prnt(' return -1;')
prnt(' }')
prnt(' return %s;' % self._chained_list_constants[True])
diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py
--- a/cffi/vengine_gen.py
+++ b/cffi/vengine_gen.py
@@ -422,11 +422,22 @@
prnt('int %s(char *out_error)' % funcname)
prnt('{')
for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
- prnt(' if (%s != %d) {' % (enumerator, enumvalue))
+ if enumvalue < 0:
+ prnt(' if ((%s) >= 0 || (long)(%s) != %dL) {' % (
+ enumerator, enumerator, enumvalue))
+ else:
+ prnt(' if ((%s) < 0 || (unsigned long)(%s) != %dUL) {' % (
+ enumerator, enumerator, enumvalue))
+ prnt(' char buf[64];')
+ prnt(' if ((%s) < 0)' % enumerator)
+ prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % enumerator)
+ prnt(' else')
+ prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' %
+ enumerator)
prnt(' snprintf(out_error, 255,'
- '"%s has the real value %d, not %d",')
- prnt(' "%s", (int)%s, %d);' % (
- enumerator, enumerator, enumvalue))
+ ' "%s has the real value %s, not %s",')
+ prnt(' "%s", buf, "%d");' % (
+ enumerator, enumvalue))
prnt(' return -1;')
prnt(' }')
prnt(' return 0;')
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1595,6 +1595,19 @@
## assert ffi.sizeof("enum foo_e") == expected_size
## assert int(ffi.cast("enum foo_e", -1)) == expected_minus1
+def test_enum_bug118():
+ maxulong = 256 ** FFI().sizeof("unsigned long") - 1
+ for c1, c2, c2c in [(0xffffffff, -1, ''),
+ (maxulong, -1, ''),
+ (-1, 0xffffffff, 'U'),
+ (-1, maxulong, 'UL')]:
+ ffi = FFI()
+ ffi.cdef("enum foo_e { AA=%s };" % c1)
+ e = py.test.raises(VerificationError, ffi.verify,
+ "enum foo_e { AA=%s%s };" % (c2, c2c))
+ assert str(e.value) == ('enum foo_e: AA has the real value %d, not %d'
+ % (c2, c1))
+
def test_string_to_voidp_arg():
ffi = FFI()
ffi.cdef("int myfunc(void *);")
More information about the pypy-commit
mailing list