Author: Armin Rigo <ar...@tunes.org> Branch: cpy-extension Changeset: r317:68c0d7f1febd Date: 2012-06-14 09:54 +0200 http://bitbucket.org/cffi/cffi/changeset/68c0d7f1febd/
Log: Ignore the declared type for global int constants. diff --git a/cffi/model.py b/cffi/model.py --- a/cffi/model.py +++ b/cffi/model.py @@ -48,9 +48,14 @@ def get_c_name(self, replace_with=''): return self.name + replace_with + def is_char_type(self): + return self.name == 'char' + def is_signed_type(self): + return self.is_integer_type() and not self.is_unsigned_type() + def is_unsigned_type(self): + return self.name.startswith('unsigned ') def is_integer_type(self): - return not self.is_float_type() - + return not self.is_float_type() and not self.is_char_type() def is_float_type(self): return self.name in ('double', 'float') diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -313,19 +313,29 @@ # constants, likely declared with '#define' def generate_cpy_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() prnt = self.prnt my_func_name = '_cffi_const_%s' % name prnt('static int %s(PyObject *dct)' % my_func_name) prnt('{') - prnt(' %s;' % tp.get_c_name(' i')) + if not is_int: + prnt(' %s;' % tp.get_c_name(' i')) prnt(' PyObject *o;') prnt(' int res;') if self.chained_list_constants is not None: prnt(' if (%s(dct) < 0)' % self.chained_list_constants) prnt(' return -1;') self.chained_list_constants = my_func_name - prnt(' i = (%s);' % (name,)) - prnt(' o = %s;' % (self.convert_expr_from_c(tp, 'i'),)) + if not is_int: + prnt(' i = (%s);' % (name,)) + prnt(' o = %s;' % (self.convert_expr_from_c(tp, 'i'),)) + else: + prnt(' if ((%s) == (long)(%s))' % (name, name)) + prnt(' o = PyInt_FromLong((long)(%s));' % (name,)) + prnt(' else if ((%s) == (long long)(%s))' % (name, name)) + prnt(' o = PyLong_FromLongLong((long long)(%s));' % (name,)) + prnt(' else') + prnt(' o = PyLong_FromUnsignedLongLong(%s);' % (name,)) prnt(' if (o == NULL)') prnt(' return -1;') prnt(' res = PyDict_SetItemString(dct, "%s", o);' % name) diff --git a/testing/test_verify.py b/testing/test_verify.py --- a/testing/test_verify.py +++ b/testing/test_verify.py @@ -1,6 +1,6 @@ import py import math -from cffi import FFI, VerificationError, VerificationMissing +from cffi import FFI, VerificationError, VerificationMissing, model def test_missing_function(): @@ -49,8 +49,19 @@ 'unsigned long', 'unsigned long long'] all_signed_integer_types = [_typename for _typename in all_integer_types if not _typename.startswith('unsigned ')] +all_unsigned_integer_types = [_typename for _typename in all_integer_types + if _typename.startswith('unsigned ')] all_float_types = ['float', 'double'] +def test_primitive_category(): + for typename in all_integer_types + all_float_types + ['char']: + tp = model.PrimitiveType(typename) + assert tp.is_char_type() == (typename == 'char') + assert tp.is_signed_type() == (typename in all_signed_integer_types) + assert tp.is_unsigned_type()== (typename in all_unsigned_integer_types) + assert tp.is_integer_type() == (typename in all_integer_types) + assert tp.is_float_type() == (typename in all_float_types) + def test_all_integer_and_float_types(): for typename in all_integer_types + all_float_types: ffi = FFI() @@ -238,3 +249,19 @@ assert lib.AA == 42 assert lib.BB == -43 assert lib.CC == 44 + +def test_global_const_int_size(): + # integer constants: ignore the declared type, always just use the value + for value in [-2**80, -2**40, -2**20, -2**10, -2**5, -1, + 2**5, 2**10, 2**20, 2**40, 2**80]: + ffi = FFI() + if value == int(ffi.cast("long long", value)): + vstr = '%dLL' % value + elif value == int(ffi.cast("unsigned long long", value)): + vstr = '%dULL' % value + else: + continue + ffi.cdef("static const unsigned short AA;") + lib = ffi.verify("#define AA %s\n" % vstr) + assert lib.AA == value + assert type(lib.AA) is type(int(lib.AA)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit