Author: Armin Rigo <[email protected]>
Branch:
Changeset: r2170:792c0cbe632d
Date: 2015-06-07 16:00 +0200
http://bitbucket.org/cffi/cffi/changeset/792c0cbe632d/
Log: Support "[][...]", "[5][...]", etc.
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -337,7 +337,7 @@
length = self._parse_constant(
typenode.dim, partial_length_ok=partial_length_ok)
tp = self._get_type(typenode.type,
- partial_length_ok=(length == '...'))
+ partial_length_ok=partial_length_ok)
return model.ArrayType(tp, length)
#
if isinstance(typenode, pycparser.c_ast.PtrDecl):
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -749,10 +749,12 @@
# named structs or unions
def _field_type(self, tp_struct, field_name, tp_field):
- if isinstance(tp_field, model.ArrayType) and tp_field.length == '...':
- ptr_struct_name = tp_struct.get_c_name('*')
- actual_length = '_cffi_array_len(((%s)0)->%s)' % (
- ptr_struct_name, field_name)
+ if isinstance(tp_field, model.ArrayType):
+ actual_length = tp_field.length
+ if actual_length == '...':
+ ptr_struct_name = tp_struct.get_c_name('*')
+ actual_length = '_cffi_array_len(((%s)0)->%s)' % (
+ ptr_struct_name, field_name)
tp_item = self._field_type(tp_struct, '%s[0]' % field_name,
tp_field.item)
tp_field = model.ArrayType(tp_item, actual_length)
@@ -1055,8 +1057,10 @@
# global variables
def _global_type(self, tp, global_name):
- if isinstance(tp, model.ArrayType) and tp.length == '...':
- actual_length = '_cffi_array_len(%s)' % (global_name,)
+ if isinstance(tp, model.ArrayType):
+ actual_length = tp.length
+ if actual_length == '...':
+ actual_length = '_cffi_array_len(%s)' % (global_name,)
tp_item = self._global_type(tp.item, '%s[0]' % global_name)
tp = model.ArrayType(tp_item, actual_length)
return tp
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -3,6 +3,19 @@
======================
+1.1.2
+=====
+
+* Out-of-line mode: ``int a[][...];`` can be used to declare a structure
+ field or global variable which is simultanously of total length
+ unknown to the C compiler (the ``[]`` part), but each element is an
+ array of N integers, where the value of N *is* known to the C compiler
+ (the ``int [...]`` part around). Similarly, ``int a[5][...];`` is
+ supported (but probably less useful). Remember that in the order of
+ the C syntax, it means an array of 5 things, each of which is an array
+ of N integers---and ask the C compiler for the value of N.
+
+
1.1.1
=====
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
@@ -924,6 +924,18 @@
assert ffi.typeof(s.a) == ffi.typeof("int[5][8]")
assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]")
+def test_struct_array_guess_length_3():
+ ffi = FFI()
+ ffi.cdef("struct foo_s { int a[][...]; };")
+ lib = verify(ffi, 'test_struct_array_guess_length_3',
+ "struct foo_s { int x; int a[5][7]; int y; };")
+ assert ffi.sizeof('struct foo_s') == 37 * ffi.sizeof('int')
+ s = ffi.new("struct foo_s *")
+ assert ffi.typeof(s.a) == ffi.typeof("int(*)[7]")
+ assert s.a[4][6] == 0
+ py.test.raises(IndexError, 's.a[4][7]')
+ assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]")
+
def test_global_var_array_2():
ffi = FFI()
ffi.cdef("int a[...][...];")
@@ -935,6 +947,27 @@
assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]")
assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
+def test_global_var_array_3():
+ ffi = FFI()
+ ffi.cdef("int a[][...];")
+ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];')
+ lib.a[9][7] = 123456
+ assert lib.a[9][7] == 123456
+ py.test.raises(IndexError, 'lib.a[0][8]')
+ assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]")
+ assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
+
+def test_global_var_array_4():
+ ffi = FFI()
+ ffi.cdef("int a[10][...];")
+ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];')
+ lib.a[9][7] = 123456
+ assert lib.a[9][7] == 123456
+ py.test.raises(IndexError, 'lib.a[0][8]')
+ py.test.raises(IndexError, 'lib.a[10][8]')
+ assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]")
+ assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]")
+
def test_some_integer_type():
ffi = FFI()
ffi.cdef("""
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit