[pypy-commit] cffi default: Test and fix: passing structures to functions through ffi.verify()
arigo
noreply at buildbot.pypy.org
Thu Jun 28 11:49:03 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r549:1139c2b9f312
Date: 2012-06-28 00:33 +0200
http://bitbucket.org/cffi/cffi/changeset/1139c2b9f312/
Log: Test and fix: passing structures to functions through ffi.verify()
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3571,6 +3571,7 @@
save_errno,
_cffi_from_c_char,
convert_to_object,
+ convert_from_object,
};
/************************************************************/
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -145,15 +145,14 @@
# ----------
- def convert_to_c(self, tp, fromvar, tovar, errcode, is_funcarg=False):
+ def convert_funcarg_to_c(self, tp, fromvar, tovar, errcode):
extraarg = ''
if isinstance(tp, model.PrimitiveType):
converter = '_cffi_to_c_%s' % (tp.name.replace(' ', '_'),)
errvalue = '-1'
#
elif isinstance(tp, model.PointerType):
- if (is_funcarg and
- isinstance(tp.totype, model.PrimitiveType) and
+ if (isinstance(tp.totype, model.PrimitiveType) and
tp.totype.name == 'char'):
converter = '_cffi_to_c_char_p'
else:
@@ -161,6 +160,13 @@
extraarg = ', _cffi_type(%d)' % self.gettypenum(tp)
errvalue = 'NULL'
#
+ elif isinstance(tp, model.StructType):
+ # a struct (not a struct pointer) as a function argument
+ self.prnt(' if (_cffi_to_c((char*)&%s, _cffi_type(%d), %s) < 0)'
+ % (tovar, self.gettypenum(tp), fromvar))
+ self.prnt(' %s;' % errcode)
+ return
+ #
else:
raise NotImplementedError(tp)
#
@@ -231,8 +237,8 @@
prnt()
#
for i, type in enumerate(tp.args):
- self.convert_to_c(type, 'arg%d' % i, 'x%d' % i, 'return NULL',
- is_funcarg=True)
+ self.convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i,
+ 'return NULL')
prnt()
#
prnt(' _cffi_restore_errno();')
@@ -606,7 +612,9 @@
((PyObject *(*)(char))_cffi_exports[15])
#define _cffi_from_c_deref \
((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16])
-#define _CFFI_NUM_EXPORTS 17
+#define _cffi_to_c \
+ ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17])
+#define _CFFI_NUM_EXPORTS 18
#if SIZEOF_LONG < SIZEOF_LONG_LONG
# define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -50,6 +50,12 @@
lib = ffi.verify("#include <string.h>")
assert lib.strlen("hi there!") == 9
+def test_strlen_array_of_char():
+ ffi = FFI()
+ ffi.cdef("int strlen(char[]);")
+ lib = ffi.verify("#include <string.h>")
+ assert lib.strlen("hello") == 5
+
all_integer_types = ['short', 'int', 'long', 'long long',
'signed char', 'unsigned char',
@@ -537,3 +543,18 @@
""")
s = ffi.new("struct foo_s", ['B', 1])
assert lib.foo(50, s[0]) == ord('A')
+
+def test_autofilled_struct_as_argument():
+ ffi = FFI()
+ ffi.cdef("struct foo_s { char a; int b; ...; }; int foo(struct foo_s);")
+ lib = ffi.verify("""
+ struct foo_s {
+ int pad1, b, pad2, pad3;
+ char a;
+ };
+ int foo(struct foo_s s) {
+ return s.a - s.b;
+ }
+ """)
+ s = ffi.new("struct foo_s", ['B', 1])
+ assert lib.foo(s[0]) == ord('A')
More information about the pypy-commit
mailing list