Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r1085:abacd609e512
Date: 2012-11-30 13:38 -0800
http://bitbucket.org/cffi/cffi/changeset/abacd609e512/

Log:    ffi.include().

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -305,6 +305,17 @@
         ctypeptr = self._pointer_to(ctype)
         return self._backend.rawaddressof(ctypeptr, cdata, offset)
 
+    def include(self, ffi_to_include):
+        """Includes the typedefs, structs, unions and enums defined
+        in another FFI instance.  Usage is similar to a #include in C,
+        where a part of the program might include types defined in
+        another part for its own usage.  Note that the include()
+        method has no effect on functions, constants and global
+        variables, which must anyway be accessed directly from the
+        lib object returned by the original FFI instance.
+        """
+        self._parser.include(ffi_to_include._parser)
+
 
 def _make_ffi_library(ffi, libname, flags):
     import os
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -485,3 +485,9 @@
         else:   # opaque enum
             tp = model.EnumType(explicit_name, (), ())
         return tp
+
+    def include(self, other):
+        for name, tp in other._declarations.items():
+            kind = name.split(' ', 1)[0]
+            if kind in ('typedef', 'struct', 'union', 'enum'):
+                self._declare(name, tp)
diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -986,6 +986,16 @@
 Misc methods on ffi
 -------------------
 
+``ffi.include(other_ffi)``: includes the typedefs, structs, unions and
+enums defined in another FFI instance.  Usage is similar to a
+``#include`` in C, where a part of the program might include types
+defined in another part for its own usage.  Note that the include()
+method has no effect on functions, constants and global variables, which
+must anyway be accessed directly from the ``lib`` object returned by the
+original FFI instance.  *New in version 0.5.*
+
+.. "versionadded:: 0.5" --- inlined in the previous paragraph
+
 ``ffi.errno``: the value of ``errno`` received from the most recent C call
 in this thread, and passed to the following C call, is available via
 reads and writes of the property ``ffi.errno``.  On Windows we also save
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -1482,3 +1482,46 @@
         assert foo1.x == 10
         assert foo2.y == 20
         assert foo2.z == 30
+
+    def test_missing_include(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("typedef signed char schar_t;")
+        py.test.raises((AttributeError, TypeError), ffi2.cast, "schar_t", 142)
+
+    def test_include_typedef(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("typedef signed char schar_t;")
+        ffi2.include(ffi1)
+        p = ffi2.cast("schar_t", 142)
+        assert int(p) == 142 - 256
+
+    def test_include_struct(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("struct foo { int x; };")
+        ffi2.include(ffi1)
+        p = ffi2.new("struct foo *", [142])
+        assert p.x == 142
+
+    def test_include_union(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("union foo { int x; };")
+        ffi2.include(ffi1)
+        p = ffi2.new("union foo *", [142])
+        assert p.x == 142
+
+    def test_include_enum(self):
+        backend = self.Backend()
+        ffi1 = FFI(backend=backend)
+        ffi2 = FFI(backend=backend)
+        ffi1.cdef("enum foo { FA, FB, FC };")
+        ffi2.include(ffi1)
+        p = ffi2.cast("enum foo", 1)
+        assert ffi2.string(p) == "FB"
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to