Commits

Armin Rigo  committed 9f30a78

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

  • Participants
  • Parent commits 639587a

Comments (0)

Files changed (3)

File c/_cffi_backend.c

     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;
     0,
     0,
 #endif
+    _cffi_to_c_long_double,
 };
 
 /************************************************************/

File cffi/vengine_cpy.py

         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
 
 
     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))
 #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

File testing/test_verify.py

     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',