Commits

Ronny Pfannschmidt committed 5dd0f42

change file layout

* ffi as package
* test -> testing
* kill src dir

Comments (0)

Files changed (13)

+__all__ = ['FFI']
+
+from ffi.api import FFI
+import pycparser    # http://code.google.com/p/pycparser/
+
+
+class FFIError(Exception):
+    pass
+
+
+class FFI(object):
+    
+    def __init__(self, backend=None):
+        if backend is None:
+            from . import backend_ctypes
+            backend = backend_ctypes.CTypesBackend()
+        self._backend = backend
+        self._functions = {}
+        self._primitive_types = {}
+        self.C = FFILibrary(self, self._backend.load_library())
+
+    def cdef(self, csource):
+        parser = pycparser.CParser()
+        ast = parser.parse(csource)
+        v = CVisitor(self)
+        v.visit(ast)
+
+    def load(self, name):
+        assert isinstance(name, str)
+        return FFILibrary(self, self._backend.load_library(name))
+
+    def typeof(self, cdecl):
+        typenode = self._parse_type(cdecl)
+        return self._get_type(typenode)
+
+    def _parse_type(self, cdecl):
+        parser = pycparser.CParser()
+        csource = 'void __dummy(%s);' % cdecl
+        ast = parser.parse(csource)
+        # XXX: insert some sanity check
+        typenode = ast.ext[0].type.args.params[0].type
+        return typenode
+
+    def _get_type(self, typenode):
+        if isinstance(typenode, pycparser.c_ast.ArrayDecl):
+            # array type
+            assert isinstance(typenode.dim, pycparser.c_ast.Constant), (
+                "non-constant array length")
+            length = int(typenode.dim.value)
+            bitem = self._get_type(typenode.type)
+            return self._backend.new_array_type(bitem, length)
+        else:
+            # assume a primitive type
+            ident = ' '.join(typenode.type.names)
+            if ident not in self._primitive_types:
+                btype = self._backend.new_primitive_type(ident)
+                self._primitive_types[ident] = btype
+            return self._primitive_types[ident]
+
+
+class FFILibrary(object):
+
+    def __init__(self, ffi, backendlib):
+        # XXX hide these attributes better
+        self._ffi = ffi
+        self._backendlib = backendlib
+
+    def __getattr__(self, name):
+        if name in self._ffi._functions:
+            node = self._ffi._functions[name]
+            name = node.type.declname
+            args = [self._ffi._get_type(argdeclnode.type)
+                    for argdeclnode in node.args.params]
+            result = self._ffi._get_type(node.type)
+            value = self._backendlib.load_function(name, args, result)
+            setattr(self, name, value)
+            return value
+        raise AttributeError(name)
+
+
+class CVisitor(pycparser.c_ast.NodeVisitor):
+
+    def __init__(self, ffi):
+        self.ffi = ffi
+
+    def visit_FuncDecl(self, node):
+        # assume for now primitive args and result types
+        name = node.type.declname
+        if name in self.ffi._functions:
+            raise FFIError("multiple declaration of function %r" % (name,))
+        self.ffi._functions[name] = node

ffi/backend_ctypes.py

+import ctypes, ctypes.util
+
+
+class CTypesBackend(object):
+
+    PRIMITIVE_TYPES = {
+        'double': ctypes.c_double,
+    }
+
+    def load_library(self, name=Ellipsis):
+        if name is Ellipsis:
+            name = 'c'    # on Posix only
+        path = ctypes.util.find_library(name)
+        cdll = ctypes.CDLL(path)
+        return CTypesLibrary(cdll)
+
+    def new_primitive_type(self, name):
+        return self.PRIMITIVE_TYPES[name]
+
+
+class CTypesLibrary(object):
+
+    def __init__(self, cdll):
+        self.cdll = cdll
+
+    def load_function(self, name, args, result):
+        func = getattr(self.cdll, name)
+        func.argtypes = args
+        func.restype = result
+        return func

src/backend_ctypes.py

-import ctypes, ctypes.util
-
-
-class CTypesBackend(object):
-
-    PRIMITIVE_TYPES = {
-        'double': ctypes.c_double,
-    }
-
-    def load_library(self, name=Ellipsis):
-        if name is Ellipsis:
-            name = 'c'    # on Posix only
-        path = ctypes.util.find_library(name)
-        cdll = ctypes.CDLL(path)
-        return CTypesLibrary(cdll)
-
-    def new_primitive_type(self, name):
-        return self.PRIMITIVE_TYPES[name]
-
-
-class CTypesLibrary(object):
-
-    def __init__(self, cdll):
-        self.cdll = cdll
-
-    def load_function(self, name, args, result):
-        func = getattr(self.cdll, name)
-        func.argtypes = args
-        func.restype = result
-        return func

src/ffi.py

-import pycparser    # http://code.google.com/p/pycparser/
-
-
-class FFIError(Exception):
-    pass
-
-
-class FFI(object):
-    
-    def __init__(self, backend=None):
-        if backend is None:
-            import backend_ctypes
-            backend = backend_ctypes.CTypesBackend()
-        self._backend = backend
-        self._functions = {}
-        self._primitive_types = {}
-        self.C = FFILibrary(self, self._backend.load_library())
-
-    def cdef(self, csource):
-        parser = pycparser.CParser()
-        ast = parser.parse(csource)
-        v = CVisitor(self)
-        v.visit(ast)
-
-    def load(self, name):
-        assert isinstance(name, str)
-        return FFILibrary(self, self._backend.load_library(name))
-
-    def typeof(self, cdecl):
-        typenode = self._parse_type(cdecl)
-        return self._get_type(typenode)
-
-    def _parse_type(self, cdecl):
-        parser = pycparser.CParser()
-        csource = 'void __dummy(%s);' % cdecl
-        ast = parser.parse(csource)
-        # XXX: insert some sanity check
-        typenode = ast.ext[0].type.args.params[0].type
-        return typenode
-
-    def _get_type(self, typenode):
-        if isinstance(typenode, pycparser.c_ast.ArrayDecl):
-            # array type
-            assert isinstance(typenode.dim, pycparser.c_ast.Constant), (
-                "non-constant array length")
-            length = int(typenode.dim.value)
-            bitem = self._get_type(typenode.type)
-            return self._backend.new_array_type(bitem, length)
-        else:
-            # assume a primitive type
-            ident = ' '.join(typenode.type.names)
-            if ident not in self._primitive_types:
-                btype = self._backend.new_primitive_type(ident)
-                self._primitive_types[ident] = btype
-            return self._primitive_types[ident]
-
-
-class FFILibrary(object):
-
-    def __init__(self, ffi, backendlib):
-        # XXX hide these attributes better
-        self._ffi = ffi
-        self._backendlib = backendlib
-
-    def __getattr__(self, name):
-        if name in self._ffi._functions:
-            node = self._ffi._functions[name]
-            name = node.type.declname
-            args = [self._ffi._get_type(argdeclnode.type)
-                    for argdeclnode in node.args.params]
-            result = self._ffi._get_type(node.type)
-            value = self._backendlib.load_function(name, args, result)
-            setattr(self, name, value)
-            return value
-        raise AttributeError(name)
-
-
-class CVisitor(pycparser.c_ast.NodeVisitor):
-
-    def __init__(self, ffi):
-        self.ffi = ffi
-
-    def visit_FuncDecl(self, node):
-        # assume for now primitive args and result types
-        name = node.type.declname
-        if name in self.ffi._functions:
-            raise FFIError("multiple declaration of function %r" % (name,))
-        self.ffi._functions[name] = node
Add a comment to this file

src/test/__init__.py

Empty file removed.

src/test/test_cdata.py

-import py
-from ffi import FFI
-
-class FakeBackend(object):
-
-    def load_library(self):
-        return None
-    
-    def new_primitive_type(self, name):
-        return FakePrimitiveType(name)
-
-class FakePrimitiveType(object):
-
-    def __init__(self, cdecl):
-        self.cdecl = cdecl
-
-
-def test_typeof():
-    ffi = FFI(backend=FakeBackend())
-    clong = ffi.typeof("long")
-    assert isinstance(clong, FakePrimitiveType)
-    assert clong.cdecl == 'long'
-
-def test_new_array_no_arg():
-    ffi = FFI(backend=FakeBackend())
-    p = ffi.new("int[10]")
-    # the object was zero-initialized:
-    for i in range(10):
-        assert p[i] == 0
-
-def test_array_indexing():
-    ffi = FFI(backend=FakeBackend())
-    p = ffi.new("int[10]")
-    p[0] = 42
-    p[9] = 43
-    assert p[0] == 42
-    assert p[9] == 43
-    py.test.raises(IndexError, "p[10]")
-    py.test.raises(IndexError, "p[10] = 44")
-    py.test.raises(IndexError, "p[-1]")
-    py.test.raises(IndexError, "p[-1] = 44")

src/test/test_math.py

-from ffi import FFI
-import math
-
-
-def test_sin():
-    ffi = FFI()
-    ffi.cdef("""
-        double sin(double x);
-    """)
-    m = ffi.load("m")
-    x = m.sin(1.23)
-    assert x == math.sin(1.23)

src/test/test_parsing.py

-from ffi import FFI
-
-
-class FakeBackend(object):
-    
-    def load_library(self, name=Ellipsis):
-        assert name in [Ellipsis, "foobar"]
-        return FakeLibrary()
-
-    def new_primitive_type(self, name):
-        return '<%s>' % name
-
-    def new_array_type(self, itemtype, length):
-        return '<array[%d] of %s>' % (length, itemtype)
-
-class FakeLibrary(object):
-    
-    def load_function(self, name, args, result):
-        return FakeFunction(name, args, result)
-
-class FakeFunction(object):
-
-    def __init__(self, name, args, result):
-        self.name = name
-        self.args = args
-        self.result = result
-
-
-def test_simple():
-    ffi = FFI(backend=FakeBackend())
-    ffi.cdef("double sin(double x);")
-    m = ffi.load("foobar")
-    func = m.sin    # should be a callable on real backends
-    assert func.name == 'sin'
-    assert func.args == ['<double>']
-    assert func.result == '<double>'
-
-def test_pipe():
-    ffi = FFI(backend=FakeBackend())
-    ffi.cdef("int pipe(int pipefd[2]);")
-    func = ffi.C.pipe
-    assert func.name == 'pipe'
-    assert func.args == ['<array[2] of <int>>']
-    assert func.result == '<int>'

Empty file added.

testing/test_cdata.py

+import py
+from ffi import FFI
+
+class FakeBackend(object):
+
+    def load_library(self):
+        return None
+    
+    def new_primitive_type(self, name):
+        return FakePrimitiveType(name)
+
+class FakePrimitiveType(object):
+
+    def __init__(self, cdecl):
+        self.cdecl = cdecl
+
+
+def test_typeof():
+    ffi = FFI(backend=FakeBackend())
+    clong = ffi.typeof("long")
+    assert isinstance(clong, FakePrimitiveType)
+    assert clong.cdecl == 'long'
+
+def test_new_array_no_arg():
+    ffi = FFI(backend=FakeBackend())
+    p = ffi.new("int[10]")
+    # the object was zero-initialized:
+    for i in range(10):
+        assert p[i] == 0
+
+def test_array_indexing():
+    ffi = FFI(backend=FakeBackend())
+    p = ffi.new("int[10]")
+    p[0] = 42
+    p[9] = 43
+    assert p[0] == 42
+    assert p[9] == 43
+    py.test.raises(IndexError, "p[10]")
+    py.test.raises(IndexError, "p[10] = 44")
+    py.test.raises(IndexError, "p[-1]")
+    py.test.raises(IndexError, "p[-1] = 44")

testing/test_math.py

+from ffi import FFI
+import math
+
+
+def test_sin():
+    ffi = FFI()
+    ffi.cdef("""
+        double sin(double x);
+    """)
+    m = ffi.load("m")
+    x = m.sin(1.23)
+    assert x == math.sin(1.23)

testing/test_parsing.py

+from ffi import FFI
+
+
+class FakeBackend(object):
+    
+    def load_library(self, name=Ellipsis):
+        assert name in [Ellipsis, "foobar"]
+        return FakeLibrary()
+
+    def new_primitive_type(self, name):
+        return '<%s>' % name
+
+    def new_array_type(self, itemtype, length):
+        return '<array[%d] of %s>' % (length, itemtype)
+
+class FakeLibrary(object):
+    
+    def load_function(self, name, args, result):
+        return FakeFunction(name, args, result)
+
+class FakeFunction(object):
+
+    def __init__(self, name, args, result):
+        self.name = name
+        self.args = args
+        self.result = result
+
+
+def test_simple():
+    ffi = FFI(backend=FakeBackend())
+    ffi.cdef("double sin(double x);")
+    m = ffi.load("foobar")
+    func = m.sin    # should be a callable on real backends
+    assert func.name == 'sin'
+    assert func.args == ['<double>']
+    assert func.result == '<double>'
+
+def test_pipe():
+    ffi = FFI(backend=FakeBackend())
+    ffi.cdef("int pipe(int pipefd[2]);")
+    func = ffi.C.pipe
+    assert func.name == 'pipe'
+    assert func.args == ['<array[2] of <int>>']
+    assert func.result == '<int>'
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.