Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r373:96f9a1b9fe69 Date: 2012-06-15 20:39 +0200 http://bitbucket.org/cffi/cffi/changeset/96f9a1b9fe69/
Log: Accessing global array variables. C is fun :-/ diff --git a/c/_ffi_backend.c b/c/_ffi_backend.c --- a/c/_ffi_backend.c +++ b/c/_ffi_backend.c @@ -3411,6 +3411,7 @@ _cffi_restore_errno, _cffi_save_errno, _cffi_from_c_char, + convert_to_object, }; /************************************************************/ diff --git a/cffi/verifier.py b/cffi/verifier.py --- a/cffi/verifier.py +++ b/cffi/verifier.py @@ -165,6 +165,9 @@ elif isinstance(tp, model.PointerType): return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( var, self.gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_deref((char *)%s, _cffi_type(%d))' % ( + var, self.gettypenum(tp)) else: raise NotImplementedError(tp) @@ -351,7 +354,8 @@ # ---------- # constants, likely declared with '#define' - def _generate_cpy_const(self, is_int, name, tp=None, category='const'): + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + vartp=None): prnt = self.prnt funcname = '_cffi_%s_%s' % (category, name) prnt('static int %s(PyObject *lib)' % funcname) @@ -359,7 +363,7 @@ prnt(' PyObject *o;') prnt(' int res;') if not is_int: - prnt(' %s;' % tp.get_c_name(' i')) + prnt(' %s;' % (vartp or tp).get_c_name(' i')) else: assert category == 'const' # @@ -452,13 +456,19 @@ # global variables def generate_cpy_variable_decl(self, tp, name): - tp_ptr = model.PointerType(tp) - self._generate_cpy_const(False, name, tp_ptr, category='var') + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + self._generate_cpy_const(False, name, tp, vartp=tp_ptr) + else: + tp_ptr = model.PointerType(tp) + self._generate_cpy_const(False, name, tp_ptr, category='var') generate_cpy_variable_method = generate_nothing loading_cpy_variable = loaded_noop def loaded_cpy_variable(self, tp, name, module, library): + if isinstance(tp, model.ArrayType): # a[5] is "constant" in the + return # sense that "a=..." is forbidden # remove ptr=<cdata 'int *'> from the library instance, and replace # it by a property on the class, which reads/writes into ptr[0]. ptr = getattr(library, name) @@ -541,7 +551,9 @@ ((void(*)(void))_cffi_exports[14]) #define _cffi_from_c_char \ ((PyObject *(*)(char))_cffi_exports[15]) -#define _CFFI_NUM_EXPORTS 16 +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16]) +#define _CFFI_NUM_EXPORTS 17 #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 @@ -373,3 +373,20 @@ lib.somenumber = -6 assert lib.foo() == -42 assert lib.somenumber == -6 + +def test_access_array_variable(): + ffi = FFI() + ffi.cdef("int foo(int);\n" + "int somenumber[5];") + lib = ffi.verify(""" + static int somenumber[] = {2, 2, 3, 4, 5}; + static int foo(int i) { + return somenumber[i] * 7; + } + """) + assert lib.somenumber[3] == 4 + assert lib.foo(3) == 28 + lib.somenumber[3] = -6 + assert lib.foo(3) == -42 + assert lib.somenumber[3] == -6 + assert lib.somenumber[4] == 5 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit