[pypy-commit] cffi default: Tests and fixes that include directly using a file as "FILE *".
arigo
noreply at buildbot.pypy.org
Fri Oct 26 10:03:12 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1008:fa7aacc08b34
Date: 2012-10-26 10:03 +0200
http://bitbucket.org/cffi/cffi/changeset/fa7aacc08b34/
Log: Tests and fixes that include directly using a file as "FILE *".
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -87,6 +87,7 @@
#define CT_CUSTOM_FIELD_POS 32768
#define CT_IS_LONGDOUBLE 65536
#define CT_IS_BOOL 131072
+#define CT_IS_FILE 262144
#define CT_PRIMITIVE_ANY (CT_PRIMITIVE_SIGNED | \
CT_PRIMITIVE_UNSIGNED | \
CT_PRIMITIVE_CHAR | \
@@ -942,6 +943,11 @@
CTypeDescrObject *ctinit;
if (!CData_Check(init)) {
+ if (PyFile_Check(init) &&
+ (ct->ct_itemdescr->ct_flags & CT_IS_FILE)) {
+ *(FILE **)data = PyFile_AsFile(init);
+ return 0;
+ }
expected = "cdata pointer";
goto cannot_convert;
}
@@ -1726,9 +1732,8 @@
/* from a unicode, we add the null terminator */
length = _my_PyUnicode_SizeAsWideChar(init) + 1;
}
- else if (PyFile_Check(init)) {
- if (strcmp(ctptr->ct_itemdescr->ct_name, "struct _IO_FILE") != 0)
- return 0;
+ else if (PyFile_Check(init) &&
+ (ctptr->ct_itemdescr->ct_flags & CT_IS_FILE)) {
output_data[0] = (char *)PyFile_AsFile(init);
return 1;
}
@@ -3028,9 +3033,14 @@
static PyObject *b_new_struct_type(PyObject *self, PyObject *args)
{
char *name;
+ int flag;
if (!PyArg_ParseTuple(args, "s:new_struct_type", &name))
return NULL;
- return _b_struct_or_union_type("struct", name, CT_STRUCT);
+
+ flag = CT_STRUCT;
+ if (strcmp(name, "_IO_FILE") == 0)
+ flag |= CT_IS_FILE;
+ return _b_struct_or_union_type("struct", name, flag);
}
static PyObject *b_new_union_type(PyObject *self, PyObject *args)
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -1222,3 +1222,56 @@
assert ffi_r() is not None
assert lib_r() is not None
assert func() == 42
+
+def test_FILE_stored_in_stdout():
+ ffi = FFI()
+ ffi.cdef("int printf(const char *, ...); FILE *setstdout(FILE *);")
+ lib = ffi.verify("""
+ #include <stdio.h>
+ FILE *setstdout(FILE *f) {
+ FILE *result = stdout;
+ stdout = f;
+ return result;
+ }
+ """)
+ import posix
+ fdr, fdw = posix.pipe()
+ fw1 = posix.fdopen(fdw, 'wb', 256)
+ old_stdout = lib.setstdout(fw1)
+ try:
+ #
+ fw1.write(b"X")
+ r = lib.printf(b"hello, %d!\n", ffi.cast("int", 42))
+ fw1.close()
+ assert r == len("hello, 42!\n")
+ #
+ finally:
+ lib.setstdout(old_stdout)
+ #
+ result = posix.read(fdr, 256)
+ posix.close(fdr)
+ assert result == b"Xhello, 42!\n"
+
+def test_FILE_stored_explicitly():
+ ffi = FFI()
+ ffi.cdef("int myprintf(const char *, int); FILE *myfile;")
+ lib = ffi.verify("""
+ #include <stdio.h>
+ FILE *myfile;
+ int myprintf(const char *out, int value) {
+ return fprintf(myfile, out, value);
+ }
+ """)
+ import posix
+ fdr, fdw = posix.pipe()
+ fw1 = posix.fdopen(fdw, 'wb', 256)
+ lib.myfile = fw1
+ #
+ fw1.write(b"X")
+ r = lib.myprintf(b"hello, %d!\n", ffi.cast("int", 42))
+ fw1.close()
+ assert r == len("hello, 42!\n")
+ #
+ result = posix.read(fdr, 256)
+ posix.close(fdr)
+ assert result == b"Xhello, 42!\n"
More information about the pypy-commit
mailing list