Author: Tom Krauss <[email protected]>
Branch: sirtom67/float_complex
Changeset: r2921:8e77b23da941
Date: 2017-03-27 08:27 -0500
http://bitbucket.org/cffi/cffi/changeset/8e77b23da941/
Log: tests pass. Had to #include <complex.h> - might want to make that
optional
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2964,9 +2964,20 @@
if (cd->c_type->ct_flags & CT_PRIMITIVE_COMPLEX) {
Py_complex value = read_raw_complex_data(cd->c_data,
cd->c_type->ct_size);
PyObject *op = PyComplex_FromCComplex(value);
- PyComplexObject *opc = (PyComplexObject *) op;
return op;
}
+ // floats can also be converted to complex
+ if (cd->c_type->ct_flags & CT_PRIMITIVE_FLOAT) {
+ Py_complex value;
+ if (!(cd->c_type->ct_flags & CT_IS_LONGDOUBLE)) {
+ value.real = read_raw_float_data(cd->c_data, cd->c_type->ct_size);
+ }
+ else {
+ value.real = (double)read_raw_longdouble_data(cd->c_data);
+ }
+ value.imag = 0.0;
+ return PyComplex_FromCComplex(value);
+ }
PyErr_Format(PyExc_TypeError, "complex() not supported on cdata '%s'",
cd->c_type->ct_name);
return NULL;
diff --git a/c/parse_c_type.c b/c/parse_c_type.c
--- a/c/parse_c_type.c
+++ b/c/parse_c_type.c
@@ -797,7 +797,6 @@
int parse_c_type_from(struct _cffi_parse_info_s *info, size_t *output_index,
const char *input)
{
- printf("parse_c_type_from\n");
int result;
token_t token;
diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h
--- a/cffi/_cffi_include.h
+++ b/cffi/_cffi_include.h
@@ -16,6 +16,7 @@
#endif
#include <Python.h>
+#include <complex.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -99,6 +100,29 @@
#define _cffi_to_c_double PyFloat_AsDouble
#define _cffi_to_c_float PyFloat_AsDouble
+#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))
+
+/* inefficient - converts twice! */
+#define _cffi_to_c_float__Complex(op) \
+ ( ((float)(PyComplex_AsCComplex(op).real)) + \
+ I*((float)(PyComplex_AsCComplex(op).imag)) )
+/* not safe!
+//#define _cffi_to_c_float__Complex(op) \
+// ( ((float)((PyComplexObject *)(op))->cval.real) + \
+// I*((float)((PyComplexObject *)(op))->cval.imag) )
+*/
+
+/* inefficient - converts twice! */
+#define _cffi_to_c_double__Complex(op) \
+ ( (PyComplex_AsCComplex(op).real) + \
+ I*(PyComplex_AsCComplex(op).imag) )
+/* not safe!
+//#define _cffi_to_c_double__Complex(op) \
+// ( (((PyComplexObject *)(op))->cval.real) + \
+// I*(((PyComplexObject *)(op))->cval.imag) )
+*/
+
#define _cffi_from_c_int(x, type) \
(((type)-1) > 0 ? /* unsigned */ \
(sizeof(type) < sizeof(long) ? \
@@ -110,9 +134,6 @@
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/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -806,6 +806,7 @@
cffimod_header = r'''
#include <Python.h>
#include <stddef.h>
+#include <complex.h>
/* this block of #ifs should be kept exactly identical between
c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
@@ -873,6 +874,29 @@
#define _cffi_to_c_double PyFloat_AsDouble
#define _cffi_to_c_float PyFloat_AsDouble
+#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))
+
+/* inefficient - converts twice! */
+#define _cffi_to_c_float__Complex(op) \
+ ( ((float)(PyComplex_AsCComplex(op).real)) + \
+ I*((float)(PyComplex_AsCComplex(op).imag)) )
+/* not safe!
+//#define _cffi_to_c_float__Complex(op) \
+// ( ((float)((PyComplexObject *)(op))->cval.real) + \
+// I*((float)((PyComplexObject *)(op))->cval.imag) )
+*/
+
+/* inefficient - converts twice! */
+#define _cffi_to_c_double__Complex(op) \
+ ( (PyComplex_AsCComplex(op).real) + \
+ I*(PyComplex_AsCComplex(op).imag) )
+/* not safe!
+//#define _cffi_to_c_double__Complex(op) \
+// ( (((PyComplexObject *)(op))->cval.real) + \
+// I*(((PyComplexObject *)(op))->cval.imag) )
+*/
+
#define _cffi_from_c_int_const(x) \
(((x) > 0) ? \
((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \
diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py
--- a/testing/cffi0/test_verify.py
+++ b/testing/cffi0/test_verify.py
@@ -241,14 +241,15 @@
F = tp.is_float_type()
I = tp.is_integer_type()
assert C == (typename in ('char', 'wchar_t'))
- assert F == (typename in ('float', 'double', 'long double'))
+ assert F == (typename in ('float', 'double', 'long double', 'float
_Complex', 'double _Complex'))
assert I + F + C == 1 # one and only one of them is true
def test_all_integer_and_float_types():
typenames = []
for typename in all_primitive_types:
if (all_primitive_types[typename] == 'c' or
- typename == '_Bool' or typename == 'long double'):
+ typename == '_Bool' or typename == 'long double'
+ or '_Complex' in typename): # omit _Complex since ffi does not
yet support
pass
else:
typenames.append(typename)
diff --git a/testing/cffi1/test_new_ffi_1.py b/testing/cffi1/test_new_ffi_1.py
--- a/testing/cffi1/test_new_ffi_1.py
+++ b/testing/cffi1/test_new_ffi_1.py
@@ -1704,6 +1704,8 @@
"ptrdiff_t",
"size_t",
"ssize_t",
+ 'double _Complex',
+ 'float _Complex',
])
for name in PRIMITIVE_TO_INDEX:
x = ffi.sizeof(name)
diff --git a/testing/cffi1/test_realize_c_type.py
b/testing/cffi1/test_realize_c_type.py
--- a/testing/cffi1/test_realize_c_type.py
+++ b/testing/cffi1/test_realize_c_type.py
@@ -45,8 +45,14 @@
def test_all_primitives():
for name in cffi_opcode.PRIMITIVE_TO_INDEX:
- check(name, name)
+ if '_Complex' not in name:
+ check(name, name)
+def test_complex_primitives():
+ py.test.xfail("ffi does not support complex yet")
+ for name in cffi_opcode.PRIMITIVE_TO_INDEX:
+ if '_Complex' in name:
+ check(name, name)
def check_func(input, expected_output=None):
import _cffi_backend
diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py
--- a/testing/cffi1/test_verify1.py
+++ b/testing/cffi1/test_verify1.py
@@ -221,7 +221,7 @@
F = tp.is_float_type()
I = tp.is_integer_type()
assert C == (typename in ('char', 'wchar_t'))
- assert F == (typename in ('float', 'double', 'long double'))
+ assert F == (typename in ('float', 'double', 'long double', 'float
_Complex', 'double _Complex'))
assert I + F + C == 1 # one and only one of them is true
def test_all_integer_and_float_types():
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit