def test_vararg(self): if not sys.platform.startswith('linux'): py.test.skip("probably no symbol 'stderr' in the lib") ffi = FFI(backend=self.Backend()) ffi.cdef(""" int fprintf(void *, const char *format, ...); void *stderr; """) ffi.C = ffi.dlopen(None) with FdWriteCapture() as fd: ffi.C.fprintf(ffi.C.stderr, b"hello with no arguments\n") ffi.C.fprintf(ffi.C.stderr, b"hello, %s!\n", ffi.new("char[]", b"world")) ffi.C.fprintf(ffi.C.stderr, ffi.new("char[]", b"hello, %s!\n"), ffi.new("char[]", b"world2")) ffi.C.fprintf(ffi.C.stderr, b"hello int %d long %ld long long %lld\n", ffi.cast("int", 42), ffi.cast("long", 84), ffi.cast("long long", 168)) ffi.C.fprintf(ffi.C.stderr, b"hello %p\n", ffi.NULL) res = fd.getvalue() assert res == (b"hello with no arguments\n" b"hello, world!\n" b"hello, world2!\n" b"hello int 42 long 84 long long 168\n" b"hello (nil)\n")
def test_function_pointer(self): ffi = FFI(backend=self.Backend()) def cb(charp): assert repr(charp).startswith("<cdata 'char *' 0x") return 42 fptr = ffi.callback("int(*)(const char *txt)", cb) assert fptr != ffi.callback("int(*)(const char *)", cb) assert repr(fptr) == "<cdata 'int(*)(char *)' calling %r>" % (cb,) res = fptr(b"Hello") assert res == 42 # if not sys.platform.startswith('linux'): py.test.skip("probably no symbol 'stderr' in the lib") ffi.cdef(""" int fputs(const char *, void *); void *stderr; """) ffi.C = ffi.dlopen(None) fptr = ffi.cast("int(*)(const char *txt, void *)", ffi.C.fputs) assert fptr == ffi.C.fputs assert repr(fptr).startswith("<cdata 'int(*)(char *, void *)' 0x") with FdWriteCapture() as fd: fptr(b"world\n", ffi.C.stderr) res = fd.getvalue() assert res == b'world\n'
def test_function_pointer(self): ffi = FFI(backend=self.Backend()) def cb(charp): assert repr(charp).startswith("<cdata 'char *' 0x") return 42 fptr = ffi.callback("int(*)(const char *txt)", cb) assert fptr != ffi.callback("int(*)(const char *)", cb) assert repr(fptr) == "<cdata 'int(*)(char *)' calling %r>" % (cb, ) res = fptr(b"Hello") assert res == 42 # if not sys.platform.startswith('linux'): py.test.skip("probably no symbol 'stderr' in the lib") ffi.cdef(""" int fputs(const char *, void *); void *stderr; """) ffi.C = ffi.dlopen(None) fptr = ffi.cast("int(*)(const char *txt, void *)", ffi.C.fputs) assert fptr == ffi.C.fputs assert repr(fptr).startswith("<cdata 'int(*)(char *, void *)' 0x") with FdWriteCapture() as fd: fptr(b"world\n", ffi.C.stderr) res = fd.getvalue() assert res == b'world\n'
def test_must_specify_type_of_vararg(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int printf(const char *format, ...); """) ffi.C = ffi.dlopen(None) e = py.test.raises(TypeError, ffi.C.printf, b"hello %d\n", 42) assert str(e.value) == ("argument 2 passed in the variadic part " "needs to be a cdata object (got int)")
def test_strchr(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" char *strchr(const char *s, int c); """) ffi.C = ffi.dlopen(None) p = ffi.new("char[]", b"hello world!") q = ffi.C.strchr(p, ord('w')) assert ffi.string(q) == b"world!"
def test_passing_array(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int strlen(char[]); """) ffi.C = ffi.dlopen(None) p = ffi.new("char[]", b"hello") res = ffi.C.strlen(p) assert res == 5
def test_function_has_a_c_type(self): ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(const char *); """) ffi.C = ffi.dlopen(None) fptr = ffi.C.puts assert ffi.typeof(fptr) == ffi.typeof("int(*)(const char*)") if self.Backend is CTypesBackend: assert repr(fptr).startswith("<cdata 'int puts(char *)' 0x")
def test_fputs_without_const(self): if not sys.platform.startswith('linux'): py.test.skip("probably no symbol 'stderr' in the lib") ffi = FFI(backend=self.Backend()) ffi.cdef(""" int fputs(char *, void *); void *stderr; """) ffi.C = ffi.dlopen(None) ffi.C.fputs # fetch before capturing, for easier debugging with FdWriteCapture() as fd: ffi.C.fputs(b"hello\n", ffi.C.stderr) ffi.C.fputs(b" world\n", ffi.C.stderr) res = fd.getvalue() assert res == b'hello\n world\n'
def test_function_with_struct_argument(self): if sys.platform == 'win32': py.test.skip("no 'inet_ntoa'") if (self.Backend is CTypesBackend and '__pypy__' in sys.builtin_module_names): py.test.skip("ctypes limitation on pypy") ffi = FFI(backend=self.Backend()) ffi.cdef(""" struct in_addr { unsigned int s_addr; }; char *inet_ntoa(struct in_addr in); """) ffi.C = ffi.dlopen(None) ina = ffi.new("struct in_addr *", [0x04040404]) a = ffi.C.inet_ntoa(ina[0]) assert ffi.string(a) == b'4.4.4.4'
def test_write_variable(self): if not sys.platform.startswith('linux'): py.test.skip("probably no symbol 'stdout' in the lib") ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(const char *); void *stdout, *stderr; """) ffi.C = ffi.dlopen(None) pout = ffi.C.stdout perr = ffi.C.stderr assert repr(pout).startswith("<cdata 'void *' 0x") assert repr(perr).startswith("<cdata 'void *' 0x") with FdWriteCapture(2) as fd: # capturing stderr ffi.C.stdout = perr try: ffi.C.puts(b"hello!") # goes to stdout, which is equal to stderr now finally: ffi.C.stdout = pout res = fd.getvalue() assert res == b"hello!\n"
def test_write_variable(self): if not sys.platform.startswith('linux'): py.test.skip("probably no symbol 'stdout' in the lib") ffi = FFI(backend=self.Backend()) ffi.cdef(""" int puts(const char *); void *stdout, *stderr; """) ffi.C = ffi.dlopen(None) pout = ffi.C.stdout perr = ffi.C.stderr assert repr(pout).startswith("<cdata 'void *' 0x") assert repr(perr).startswith("<cdata 'void *' 0x") with FdWriteCapture(2) as fd: # capturing stderr ffi.C.stdout = perr try: ffi.C.puts( b"hello!") # goes to stdout, which is equal to stderr now finally: ffi.C.stdout = pout res = fd.getvalue() assert res == b"hello!\n"
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); int openat(int dirfd, const char *pathname, int flags); DIR *fdopendir(int fd); int closedir(DIR *dirp); static const int DT_DIR; """ ) ffi.C = ffi.verify( """ #ifndef _ATFILE_SOURCE # define _ATFILE_SOURCE #endif #ifndef _BSD_SOURCE # define _BSD_SOURCE #endif #include <fcntl.h> #include <sys/types.h> #include <dirent.h> """ ) def walk(basefd, path): print "{", path dirfd = ffi.C.openat(basefd, path, 0) if dirfd < 0: # error in openat() return dir = ffi.C.fdopendir(dirfd)
struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* offset to the next dirent */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file; not supported by all file system types */ char d_name[256]; /* filename */ }; int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); int openat(int dirfd, const char *pathname, int flags); DIR *fdopendir(int fd); int closedir(DIR *dirp); """) ffi.C = ffi.dlopen(None) def walk(basefd, path): print '{', path dirfd = ffi.C.openat(basefd, path, 0) if dirfd < 0: # error in openat() return dir = ffi.C.fdopendir(dirfd) dirent = ffi.new("struct dirent *") result = ffi.new("struct dirent **") while True: if ffi.C.readdir_r(dir, dirent, result): # error in readdir_r()
struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* offset to the next dirent */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file; not supported by all file system types */ char d_name[256]; /* filename */ }; int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); int openat(int dirfd, const char *pathname, int flags); DIR *fdopendir(int fd); int closedir(DIR *dirp); """) ffi.C = ffi.dlopen(None) def walk(basefd, path): print '{', path dirfd = ffi.C.openat(basefd, path, 0) if dirfd < 0: # error in openat() return dir = ffi.C.fdopendir(dirfd) dirent = ffi.new("struct dirent *") result = ffi.new("struct dirent **") while True: if ffi.C.readdir_r(dir, dirent, result): # error in readdir_r() break
}; int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); int openat(int dirfd, const char *pathname, int flags); DIR *fdopendir(int fd); int closedir(DIR *dirp); static const int DT_DIR; """) ffi.C = ffi.verify(""" #ifndef _ATFILE_SOURCE # define _ATFILE_SOURCE #endif #ifndef _BSD_SOURCE # define _BSD_SOURCE #endif #include <fcntl.h> #include <sys/types.h> #include <dirent.h> """) def walk(basefd, path): print '{', path dirfd = ffi.C.openat(basefd, path, 0) if dirfd < 0: # error in openat() return dir = ffi.C.fdopendir(dirfd) dirent = ffi.new("struct dirent *")