Author: Tom Krauss <thomas.p.kra...@gmail.com> Branch: sirtom67/float_complex Changeset: r2904:2e64e82fb960 Date: 2017-03-12 19:26 -0500 http://bitbucket.org/cffi/cffi/changeset/2e64e82fb960/
Log: Support for "double _Complex". Skip the test_c tests for now since libffi returning non-sense. Add complex tests in testing/cffi1/test_recompiler.py diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2035,7 +2035,8 @@ } return PyFloat_FromDouble(value); } - if (cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) { + if ((cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) && + (cd->c_type->ct_size<16)) { double value = read_raw_float_data(cd->c_data, cd->c_type->ct_size); return PyComplex_FromDoubles(value, 0.0); } @@ -4104,6 +4105,16 @@ else goto bad_ffi_type; } + else if (ptypes->flags & CT_PRIMITIVE_COMPLEX) { + // as of March 2017, still no libffi support for complex + // but it fails silently. + if (strcmp(ptypes->name, "float _Complex") == 0) + ffitype = &ffi_type_complex_float; + else if (strcmp(ptypes->name, "double _Complex") == 0) + ffitype = &ffi_type_complex_double; + else + goto bad_ffi_type; + } else { switch (ptypes->size) { case 1: ffitype = &ffi_type_uint8; break; @@ -6594,6 +6605,10 @@ { return a + I*2.0*b; } +static double _Complex _testfunc25(double a, double b) +{ + return a + I*2.0*b; +} static PyObject *b__testfunc(PyObject *self, PyObject *args) { @@ -6628,6 +6643,7 @@ case 22: f = &_testfunc22; break; case 23: f = &_testfunc23; break; case 24: f = &_testfunc24; break; + case 25: f = &_testfunc25; break; default: PyErr_SetNone(PyExc_ValueError); return NULL; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -184,7 +184,7 @@ def test_complex_types(): INF = 1E200 * 1E200 - for name in ["float"]: #, "double"]: + for name in ["float", "double"]: p = new_primitive_type(name + " _Complex") assert bool(cast(p, 0)) assert bool(cast(p, INF)) @@ -1085,6 +1085,7 @@ assert f(3, cast(BSChar, -3), cast(BUChar, 200), cast(BSShort, -5)) == 192 def test_call_function_24(): + py.test.skip("libffi returning nonsense silently") BFloat = new_primitive_type("float") BFloatComplex = new_primitive_type("float _Complex") BFunc3 = new_function_type((BFloat, BFloat), BFloatComplex, False) @@ -1094,6 +1095,18 @@ assert result.real == 1.25 # exact assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact +def test_call_function_25(): + py.test.skip("libffi returning nonsense silently") + BDouble = new_primitive_type("double") + BDoubleComplex = new_primitive_type("double _Complex") + BFunc3 = new_function_type((BDouble, BDouble), BDoubleComplex, False) + f = cast(BFunc3, _testfunc(25)) + result = f(1.25, 5.1) + assert type(result) == complex + assert result.real == 1.25 # exact + assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-10) # inexact + + def test_cannot_call_with_a_autocompleted_struct(): BSChar = new_primitive_type("signed char") BDouble = new_primitive_type("double") diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h --- a/cffi/_cffi_include.h +++ b/cffi/_cffi_include.h @@ -110,6 +110,9 @@ PyInt_FromLong((long)x) : \ PyLong_FromLongLong((long long)x))) +#define _cffi_from_c_float__Complex(x) PyComplex_FromDoubles(crealf(x), cimagf(x)) +#define _cffi_from_c_double__Complex(x) PyComplex_FromDoubles(creal(x), cimag(x)) + #define _cffi_to_c_int(o, type) \ ((type)( \ sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py --- a/testing/cffi1/test_recompiler.py +++ b/testing/cffi1/test_recompiler.py @@ -1994,6 +1994,30 @@ """) assert lib.f1(52).a == 52 +def test_function_returns_float_complex(): + ffi = FFI() + ffi.cdef("float _Complex f1(float a, float b);"); + lib = verify(ffi, "test_function_returns_float_complex", """ + #include <complex.h> + static float _Complex f1 (float a, float b) { return a + I*2.0*b; } + """) + result = lib.f1(1.25, 5.1) + assert type(result) == complex + assert result.real == 1.25 # exact + assert (result.imag != 2*5.1) and (abs(result.imag - 2*5.1) < 1e-5) # inexact + +def test_function_returns_double_complex(): + ffi = FFI() + ffi.cdef("double _Complex f1(double a, double b);"); + lib = verify(ffi, "test_function_returns_double_complex", """ + #include <complex.h> + static double _Complex f1 (double a, double b) { return a + I*2.0*b; } + """) + result = lib.f1(1.25, 5.1) + assert type(result) == complex + assert result.real == 1.25 # exact + assert result.imag == 2*5.1 # exact + def test_typedef_array_dotdotdot(): ffi = FFI() ffi.cdef(""" _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit