Skip to content

Commit

Permalink
Use '_cffi_float_complex_t' or '_cffi_double_complex_t' more systemat…
Browse files Browse the repository at this point in the history
…ically (#111)

* (2) Use '_cffi_float_complex_t' or '_cffi_double_complex_t' more systematically.
Should fix the problem that FFI().typeof('float _Complex') stopped working.

* test fixes
  • Loading branch information
arigo committed Sep 6, 2024
1 parent 88e67cc commit ac407f0
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 16 deletions.
11 changes: 5 additions & 6 deletions src/c/_cffi_backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
#define CT_UNION 0x080 /* union */
#define CT_FUNCTIONPTR 0x100 /* pointer to function */
#define CT_VOID 0x200 /* void */
#define CT_PRIMITIVE_COMPLEX 0x400 /* float _Complex, double _Complex */
#define CT_PRIMITIVE_COMPLEX 0x400 /* _cffi_float/double_complex_t */

/* other flags that may also be set in addition to the base flag: */
#define CT_IS_VOIDCHAR_PTR 0x00001000
Expand Down Expand Up @@ -4728,8 +4728,8 @@ static PyObject *new_primitive_type(const char *name)
EPTYPE(f, float, CT_PRIMITIVE_FLOAT ) \
EPTYPE(d, double, CT_PRIMITIVE_FLOAT ) \
EPTYPE(ld, long double, CT_PRIMITIVE_FLOAT | CT_IS_LONGDOUBLE ) \
EPTYPE2(fc, "float _Complex", cffi_float_complex_t, CT_PRIMITIVE_COMPLEX ) \
EPTYPE2(dc, "double _Complex", cffi_double_complex_t, CT_PRIMITIVE_COMPLEX ) \
EPTYPE2(fc, "_cffi_float_complex_t", cffi_float_complex_t, CT_PRIMITIVE_COMPLEX)\
EPTYPE2(dc, "_cffi_double_complex_t", cffi_double_complex_t, CT_PRIMITIVE_COMPLEX)\
ENUM_PRIMITIVE_TYPES_WCHAR \
EPTYPE2(c16, "char16_t", cffi_char16_t, CT_PRIMITIVE_CHAR ) \
EPTYPE2(c32, "char32_t", cffi_char32_t, CT_PRIMITIVE_CHAR ) \
Expand Down Expand Up @@ -7656,14 +7656,13 @@ static int _testfunc23(char *p)
}

#if 0 /* libffi doesn't properly support complexes currently */
/* also, MSVC might not support _Complex... */
/* if this is enabled one day, remember to also add _Complex
* arguments in addition to return values. */
static float _Complex _testfunc24(float a, float b)
static _cffi_float_complex_t _testfunc24(float a, float b)
{
return a + I*2.0*b;
}
static double _Complex _testfunc25(double a, double b)
static _cffi_double_complex_t _testfunc25(double a, double b)
{
return a + I*2.0*b;
}
Expand Down
4 changes: 2 additions & 2 deletions src/c/realize_c_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ static PyObject *build_primitive_type(int num)
"uint_fast64_t",
"intmax_t",
"uintmax_t",
"float _Complex",
"double _Complex",
"_cffi_float_complex_t",
"_cffi_double_complex_t",
"char16_t",
"char32_t",
};
Expand Down
10 changes: 5 additions & 5 deletions src/c/test_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def test_float_types():
def test_complex_types():
INF = 1E200 * 1E200
for name in ["float", "double"]:
p = new_primitive_type(name + " _Complex")
p = new_primitive_type("_cffi_" + name + "_complex_t")
assert bool(cast(p, 0)) is False
assert bool(cast(p, INF))
assert bool(cast(p, -INF))
Expand Down Expand Up @@ -1246,7 +1246,7 @@ def test_call_function_9():

def test_call_function_24():
BFloat = new_primitive_type("float")
BFloatComplex = new_primitive_type("float _Complex")
BFloatComplex = new_primitive_type("_cffi_float_complex_t")
BFunc3 = new_function_type((BFloat, BFloat), BFloatComplex, False)
if 0: # libffi returning nonsense silently, so logic disabled for now
f = cast(BFunc3, _testfunc(24))
Expand All @@ -1260,7 +1260,7 @@ def test_call_function_24():

def test_call_function_25():
BDouble = new_primitive_type("double")
BDoubleComplex = new_primitive_type("double _Complex")
BDoubleComplex = new_primitive_type("_cffi_double_complex_t")
BFunc3 = new_function_type((BDouble, BDouble), BDoubleComplex, False)
if 0: # libffi returning nonsense silently, so logic disabled for now
f = cast(BFunc3, _testfunc(25))
Expand Down Expand Up @@ -4536,9 +4536,9 @@ def test_unaligned_types():
buf = buffer(pbuf)
#
for name in ['short', 'int', 'long', 'long long', 'float', 'double',
'float _Complex', 'double _Complex']:
'_cffi_float_complex_t', '_cffi_double_complex_t']:
p = new_primitive_type(name)
if name.endswith(' _Complex'):
if name.endswith('_complex_t'):
num = cast(p, 1.23 - 4.56j)
else:
num = cast(p, 0x0123456789abcdef)
Expand Down
2 changes: 2 additions & 0 deletions testing/cffi1/test_parse_c_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ def test_simple():
("long double", lib._CFFI_PRIM_LONGDOUBLE),
(" float _Complex", lib._CFFI_PRIM_FLOATCOMPLEX),
("double _Complex ", lib._CFFI_PRIM_DOUBLECOMPLEX),
("_cffi_float_complex_t", lib._CFFI_PRIM_FLOATCOMPLEX),
(" _cffi_double_complex_t", lib._CFFI_PRIM_DOUBLECOMPLEX),
]:
assert parse(simple_type) == ['->', Prim(expected)]

Expand Down
4 changes: 1 addition & 3 deletions testing/cffi1/test_realize_c_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ def test_funcptr_rewrite_args():
check("int(*)(long[5])", "int(*)(long *)")

def test_all_primitives():
mapping = {"_cffi_float_complex_t": "float _Complex",
"_cffi_double_complex_t": "double _Complex"}
for name in cffi_opcode.PRIMITIVE_TO_INDEX:
check(name, mapping.get(name, name))
check(name, name)

def check_func(input, expected_output=None):
import _cffi_backend
Expand Down

0 comments on commit ac407f0

Please sign in to comment.