[pypy-commit] cffi default: A test and fix about 'long double' with vengine_cpy.

arigo noreply at buildbot.pypy.org
Sun Aug 12 21:45:16 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r830:9f30a78877b0
Date: 2012-08-12 21:45 +0200
http://bitbucket.org/cffi/cffi/changeset/9f30a78877b0/

Log:	A test and fix about 'long double' with vengine_cpy.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -4339,6 +4339,15 @@
     return result;
 }
 
+static long double _cffi_to_c_long_double(PyObject *obj)
+{
+    if (CData_Check(obj) &&
+            (((CDataObject *)obj)->c_type->ct_flags & CT_IS_LONGDOUBLE))
+        return read_raw_longdouble_data(((CDataObject *)obj)->c_data);
+    else
+        return PyFloat_AsDouble(obj);
+}
+
 static PyObject *_cffi_get_struct_layout(Py_ssize_t nums[])
 {
     PyObject *result;
@@ -4403,6 +4412,7 @@
     0,
     0,
 #endif
+    _cffi_to_c_long_double,
 };
 
 /************************************************************/
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -25,8 +25,9 @@
         return self._typesdict[type]
 
     def _do_collect_type(self, tp):
-        if (not isinstance(tp, model.PrimitiveType) and
-                tp not in self._typesdict):
+        if ((not isinstance(tp, model.PrimitiveType)
+             or tp.name == 'long double')
+                and tp not in self._typesdict):
             num = len(self._typesdict)
             self._typesdict[tp] = num
 
@@ -210,7 +211,11 @@
 
     def _convert_expr_from_c(self, tp, var):
         if isinstance(tp, model.PrimitiveType):
-            return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
+            if tp.name != 'long double':
+                return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
+            else:
+                return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % (
+                    var, self._gettypenum(tp))
         elif isinstance(tp, (model.PointerType, model.FunctionPtrType)):
             return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
                 var, self._gettypenum(tp))
@@ -722,10 +727,12 @@
 #define _cffi_from_c_struct                                              \
     ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18])
 #define _cffi_to_c_wchar_t                                               \
-                 ((wchar_t(*)(PyObject *))_cffi_exports[19])
+    ((wchar_t(*)(PyObject *))_cffi_exports[19])
 #define _cffi_from_c_wchar_t                                             \
     ((PyObject *(*)(wchar_t))_cffi_exports[20])
-#define _CFFI_NUM_EXPORTS 21
+#define _cffi_to_c_long_double                                           \
+    ((long double(*)(PyObject *))_cffi_exports[21])
+#define _CFFI_NUM_EXPORTS 22
 
 #if SIZEOF_LONG < SIZEOF_LONG_LONG
 #  define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -89,6 +89,17 @@
     lib = ffi.verify("#include <string.h>")
     assert lib.strlen(b"hello") == 5
 
+def test_longdouble():
+    ffi = FFI()
+    ffi.cdef("long double sinl(long double x);")
+    lib = ffi.verify('#include <math.h>')
+    for input in [1.23,
+                  ffi.cast("double", 1.23),
+                  ffi.cast("long double", 1.23)]:
+        x = lib.sinl(input)
+        assert repr(x).startswith("<cdata 'long double'")
+        assert (float(x) - math.sin(1.23)) < 1E-10
+
 
 all_integer_types = ['short', 'int', 'long', 'long long',
                      'signed char', 'unsigned char',


More information about the pypy-commit mailing list