Author: Armin Rigo <ar...@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 *);") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit