From 757c264bc10ebc71074ee3f5fb66d670667a09bc Mon Sep 17 00:00:00 2001 From: Kevin Cheng Date: Thu, 18 Apr 2019 11:31:16 -0700 Subject: Add in cffi 1.12.2 (e0c7666) Since this is a mercurial repo, d/led zip of src: https://bitbucket.org/cffi/cffi/get/v1.12.2.zip Also add in misc METADATA/NOTICE/Android.bp/etc files. Bug: 122778810 Test: None Change-Id: I36c58ed07a2cdd4d9d11831908175a5c988f33c1 --- testing/cffi0/test_ownlib.py | 373 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 testing/cffi0/test_ownlib.py (limited to 'testing/cffi0/test_ownlib.py') diff --git a/testing/cffi0/test_ownlib.py b/testing/cffi0/test_ownlib.py new file mode 100644 index 0000000..a06df20 --- /dev/null +++ b/testing/cffi0/test_ownlib.py @@ -0,0 +1,373 @@ +import py, sys, os +import subprocess, weakref +from cffi import FFI +from cffi.backend_ctypes import CTypesBackend +from testing.support import u + + +SOURCE = """\ +#include + +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + +EXPORT int test_getting_errno(void) { + errno = 123; + return -1; +} + +EXPORT int test_setting_errno(void) { + return errno; +}; + +typedef struct { + long x; + long y; +} POINT; + +typedef struct { + long left; + long top; + long right; + long bottom; +} RECT; + + +EXPORT int PointInRect(RECT *prc, POINT pt) +{ + if (pt.x < prc->left) + return 0; + if (pt.x > prc->right) + return 0; + if (pt.y < prc->top) + return 0; + if (pt.y > prc->bottom) + return 0; + return 1; +}; + +EXPORT long left = 10; +EXPORT long top = 20; +EXPORT long right = 30; +EXPORT long bottom = 40; + +EXPORT RECT ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr, + RECT *er, POINT fp, RECT gr) +{ + /*Check input */ + if (ar.left + br->left + dr.left + er->left + gr.left != left * 5) + { + ar.left = 100; + return ar; + } + if (ar.right + br->right + dr.right + er->right + gr.right != right * 5) + { + ar.right = 100; + return ar; + } + if (cp.x != fp.x) + { + ar.left = -100; + } + if (cp.y != fp.y) + { + ar.left = -200; + } + switch(i) + { + case 0: + return ar; + break; + case 1: + return dr; + break; + case 2: + return gr; + break; + + } + return ar; +} + +EXPORT int my_array[7] = {0, 1, 2, 3, 4, 5, 6}; + +EXPORT unsigned short foo_2bytes(unsigned short a) +{ + return (unsigned short)(a + 42); +} +EXPORT unsigned int foo_4bytes(unsigned int a) +{ + return (unsigned int)(a + 42); +} + +EXPORT void modify_struct_value(RECT r) +{ + r.left = r.right = r.top = r.bottom = 500; +} +""" + +class TestOwnLib(object): + Backend = CTypesBackend + + def setup_class(cls): + cls.module = None + from testing.udir import udir + udir.join('testownlib.c').write(SOURCE) + if sys.platform == 'win32': + # did we already build it? + if cls.Backend is CTypesBackend: + dll_path = str(udir) + '\\testownlib1.dll' # only ascii for the ctypes backend + else: + dll_path = str(udir) + '\\' + (u+'testownlib\u03be.dll') # non-ascii char + if os.path.exists(dll_path): + cls.module = dll_path + return + # try (not too hard) to find the version used to compile this python + # no mingw + from distutils.msvc9compiler import get_build_version + version = get_build_version() + toolskey = "VS%0.f0COMNTOOLS" % version + toolsdir = os.environ.get(toolskey, None) + if toolsdir is None: + return + productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC") + productdir = os.path.abspath(productdir) + vcvarsall = os.path.join(productdir, "vcvarsall.bat") + # 64? + arch = 'x86' + if sys.maxsize > 2**32: + arch = 'amd64' + if os.path.isfile(vcvarsall): + cmd = '"%s" %s' % (vcvarsall, arch) + ' & cl.exe testownlib.c ' \ + ' /LD /Fetestownlib.dll' + subprocess.check_call(cmd, cwd = str(udir), shell=True) + os.rename(str(udir) + '\\testownlib.dll', dll_path) + cls.module = dll_path + else: + encoded = None + if cls.Backend is not CTypesBackend: + try: + unicode_name = u+'testownlibcaf\xe9' + encoded = unicode_name.encode(sys.getfilesystemencoding()) + if sys.version_info >= (3,): + encoded = str(unicode_name) + except UnicodeEncodeError: + pass + if encoded is None: + unicode_name = u+'testownlib' + encoded = str(unicode_name) + subprocess.check_call( + "cc testownlib.c -shared -fPIC -o '%s.so'" % (encoded,), + cwd=str(udir), shell=True) + cls.module = os.path.join(str(udir), unicode_name + (u+'.so')) + print(repr(cls.module)) + + def test_getting_errno(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if sys.platform == 'win32': + py.test.skip("fails, errno at multiple addresses") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int test_getting_errno(void); + """) + ownlib = ffi.dlopen(self.module) + res = ownlib.test_getting_errno() + assert res == -1 + assert ffi.errno == 123 + + def test_setting_errno(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if sys.platform == 'win32': + py.test.skip("fails, errno at multiple addresses") + if self.Backend is CTypesBackend and '__pypy__' in sys.modules: + py.test.skip("XXX errno issue with ctypes on pypy?") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int test_setting_errno(void); + """) + ownlib = ffi.dlopen(self.module) + ffi.errno = 42 + res = ownlib.test_setting_errno() + assert res == 42 + assert ffi.errno == 42 + + def test_my_array_7(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int my_array[7]; + """) + ownlib = ffi.dlopen(self.module) + for i in range(7): + assert ownlib.my_array[i] == i + assert len(ownlib.my_array) == 7 + if self.Backend is CTypesBackend: + py.test.skip("not supported by the ctypes backend") + ownlib.my_array = list(range(10, 17)) + for i in range(7): + assert ownlib.my_array[i] == 10 + i + ownlib.my_array = list(range(7)) + for i in range(7): + assert ownlib.my_array[i] == i + + def test_my_array_no_length(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if self.Backend is CTypesBackend: + py.test.skip("not supported by the ctypes backend") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int my_array[]; + """) + ownlib = ffi.dlopen(self.module) + for i in range(7): + assert ownlib.my_array[i] == i + py.test.raises(TypeError, len, ownlib.my_array) + ownlib.my_array = list(range(10, 17)) + for i in range(7): + assert ownlib.my_array[i] == 10 + i + ownlib.my_array = list(range(7)) + for i in range(7): + assert ownlib.my_array[i] == i + + def test_keepalive_lib(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int test_getting_errno(void); + """) + ownlib = ffi.dlopen(self.module) + ffi_r = weakref.ref(ffi) + ownlib_r = weakref.ref(ownlib) + func = ownlib.test_getting_errno + del ffi + import gc; gc.collect() # ownlib stays alive + assert ownlib_r() is not None + assert ffi_r() is not None # kept alive by ownlib + res = func() + assert res == -1 + + def test_keepalive_ffi(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + int test_getting_errno(void); + """) + ownlib = ffi.dlopen(self.module) + ffi_r = weakref.ref(ffi) + ownlib_r = weakref.ref(ownlib) + func = ownlib.test_getting_errno + del ownlib + import gc; gc.collect() # ffi stays alive + assert ffi_r() is not None + assert ownlib_r() is not None # kept alive by ffi + res = func() + assert res == -1 + if sys.platform != 'win32': # else, errno at multiple addresses + assert ffi.errno == 123 + + def test_struct_by_value(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + typedef struct { + long x; + long y; + } POINT; + + typedef struct { + long left; + long top; + long right; + long bottom; + } RECT; + + long left, top, right, bottom; + + RECT ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr, + RECT *er, POINT fp, RECT gr); + """) + ownlib = ffi.dlopen(self.module) + + rect = ffi.new('RECT[1]') + pt = ffi.new('POINT[1]') + pt[0].x = 15 + pt[0].y = 25 + rect[0].left = ownlib.left + rect[0].right = ownlib.right + rect[0].top = ownlib.top + rect[0].bottom = ownlib.bottom + + for i in range(4): + ret = ownlib.ReturnRect(i, rect[0], rect, pt[0], rect[0], + rect, pt[0], rect[0]) + assert ret.left == ownlib.left + assert ret.right == ownlib.right + assert ret.top == ownlib.top + assert ret.bottom == ownlib.bottom + + def test_addressof_lib(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if self.Backend is CTypesBackend: + py.test.skip("not implemented with the ctypes backend") + ffi = FFI(backend=self.Backend()) + ffi.cdef("long left; int test_getting_errno(void);") + lib = ffi.dlopen(self.module) + lib.left = 123456 + p = ffi.addressof(lib, "left") + assert ffi.typeof(p) == ffi.typeof("long *") + assert p[0] == 123456 + p[0] += 1 + assert lib.left == 123457 + pfn = ffi.addressof(lib, "test_getting_errno") + assert ffi.typeof(pfn) == ffi.typeof("int(*)(void)") + assert pfn == lib.test_getting_errno + + def test_char16_char32_t(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if self.Backend is CTypesBackend: + py.test.skip("not implemented with the ctypes backend") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + char16_t foo_2bytes(char16_t); + char32_t foo_4bytes(char32_t); + """) + lib = ffi.dlopen(self.module) + assert lib.foo_2bytes(u+'\u1234') == u+'\u125e' + assert lib.foo_4bytes(u+'\u1234') == u+'\u125e' + assert lib.foo_4bytes(u+'\U00012345') == u+'\U0001236f' + + def test_modify_struct_value(self): + if self.module is None: + py.test.skip("fix the auto-generation of the tiny test lib") + if self.Backend is CTypesBackend: + py.test.skip("fails with the ctypes backend on some architectures") + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + typedef struct { + long left; + long top; + long right; + long bottom; + } RECT; + + void modify_struct_value(RECT r); + """) + lib = ffi.dlopen(self.module) + s = ffi.new("RECT *", [11, 22, 33, 44]) + lib.modify_struct_value(s[0]) + assert s.left == 11 + assert s.top == 22 + assert s.right == 33 + assert s.bottom == 44 -- cgit v1.2.3