Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit