[pypy-svn] r47507 - in pypy/dist/pypy/module/_ffi: . test

fijal at codespeak.net fijal at codespeak.net
Wed Oct 17 00:15:16 CEST 2007


Author: fijal
Date: Wed Oct 17 00:15:14 2007
New Revision: 47507

Modified:
   pypy/dist/pypy/module/_ffi/interp_ffi.py
   pypy/dist/pypy/module/_ffi/structure.py
   pypy/dist/pypy/module/_ffi/test/test__ffi.py
Log:
* Increase testibility
* Few fixes
* Make it non-rpythonic again


Modified: pypy/dist/pypy/module/_ffi/interp_ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/interp_ffi.py	(original)
+++ pypy/dist/pypy/module/_ffi/interp_ffi.py	Wed Oct 17 00:15:14 2007
@@ -11,11 +11,11 @@
 
 TYPEMAP = {
     # XXX A mess with unsigned/signed/normal chars :-/
-    #'c' : ffi_type_uchar,
-    #'b' : ffi_type_schar,
-    #'B' : ffi_type_uchar,
-    #'h' : ffi_type_sshort,
-    #'H' : ffi_type_ushort,
+    'c' : ffi_type_uchar,
+    'b' : ffi_type_schar,
+    'B' : ffi_type_uchar,
+    'h' : ffi_type_sshort,
+    'H' : ffi_type_ushort,
     'i' : ffi_type_sint,
     'I' : ffi_type_uint,
     'l' : ffi_type_slong,
@@ -30,11 +30,11 @@
 }
 
 LL_TYPEMAP = {
-    #'c' : rffi.CHAR,
-    #'b' : rffi.UCHAR,
-    #'B' : rffi.CHAR,
-    #'h' : rffi.SHORT,
-    #'H' : rffi.USHORT,
+    'c' : rffi.CHAR,
+    'b' : rffi.UCHAR,
+    'B' : rffi.CHAR,
+    'h' : rffi.SHORT,
+    'H' : rffi.USHORT,
     'i' : rffi.INT,
     'I' : rffi.UINT,
     'l' : rffi.LONG,
@@ -166,7 +166,10 @@
     for c, ll_type in ll_typemap_iter:
         if restype == c:
             if c == 's':
-                return space.wrap(rffi.charp2str(func(arg, rffi.CCHARP)))
+                ptr = func(arg, rffi.CCHARP)
+                if not ptr:
+                    return space.w_None
+                return space.wrap(rffi.charp2str(ptr))
             elif c == 'P':
                 res = func(arg, rffi.VOIDP)
                 return space.wrap(rffi.cast(rffi.INT, res))

Modified: pypy/dist/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/structure.py	(original)
+++ pypy/dist/pypy/module/_ffi/structure.py	Wed Oct 17 00:15:14 2007
@@ -59,15 +59,12 @@
 
 class W_StructureInstance(Wrappable):
     def __init__(self, space, w_shape, w_address, w_fieldinits):
-        if space.is_true(w_fieldinits):
-            raise OperationError(space.w_ValueError, space.wrap(
-                "Fields should be not initialized with values by now"))
+        self.free_afterwards = False
         w_fields = space.getattr(w_shape, space.wrap('fields'))
         fields = unpack_fields(space, w_fields)
         size, pos = size_and_pos(fields)
         self.fields = fields
         if space.is_true(w_address):
-            self.free_afterwards = False
             self.ll_buffer = rffi.cast(rffi.VOIDP, space.int_w(w_address))
         else:
             self.free_afterwards = True
@@ -75,6 +72,10 @@
                                            zero=True)
         self.ll_positions = pos
         self.next_pos = 0
+        if space.is_true(w_fieldinits):
+            for w_field in space.unpackiterable(w_fieldinits):
+                w_value = space.getitem(w_fieldinits, w_field)
+                self.setattr(space, space.str_w(w_field), w_value)
 
     def getattr(self, space, attr):
         if attr.startswith('tm'):

Modified: pypy/dist/pypy/module/_ffi/test/test__ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/test/test__ffi.py	(original)
+++ pypy/dist/pypy/module/_ffi/test/test__ffi.py	Wed Oct 17 00:15:14 2007
@@ -1,6 +1,7 @@
 
 
 from pypy.conftest import gettestobjspace
+from pypy.translator.tool.cbuild import compile_c_module
 
 import os, sys, py
 
@@ -11,18 +12,62 @@
 class AppTestCTypes:
     def prepare_c_example():
         from pypy.tool.udir import udir
-        udir.join("xlib.c").write(py.code.Source("""
-        typedef struct x {
-           char x1;
-           long x2;
-           struct x *x3;
+        c_file = udir.join("xlib.c")
+        c_file.write(py.code.Source('''
+        #include <stdlib.h>
+        #include <stdio.h>
+
+        struct x
+        {
+           int x1;
+           short x2;
+           char x3;
+           struct x* next;
+        };
+
+        char inner_struct_elem(struct x *x1)
+        {
+           return x1->next->x3;
         }
-        """))
+
+        struct x* create_double_struct()
+        {
+           struct x* x1, *x2;
+
+           x1 = (struct x*)malloc(sizeof(struct x));
+           x2 = (struct x*)malloc(sizeof(struct x));
+           x1->next = x2;
+           x2->x2 = 3;
+           return x1;
+        }
+        
+        const char *static_str = "xxxxxx";
+        
+        unsigned short add_shorts(short one, short two)
+        {
+           return one + two;
+        }
+
+        char get_char(char* s, unsigned short num)
+        {
+           return s[num];
+        }
+
+        char *char_check(char x, char y)
+        {
+           if (y == static_str[0])
+              return static_str;
+           return NULL;
+        }
+        '''))
+        compile_c_module([c_file], 'x')
+        return str(udir.join('x.so'))
     prepare_c_example = staticmethod(prepare_c_example)
     
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=('_ffi','struct'))
-        cls.prepare_c_example()
+        space = gettestobjspace(usemodules=('_ffi','struct'))
+        cls.space = space
+        cls.w_lib_name = space.wrap(cls.prepare_c_example())
 
     def test_libload(self):
         import _ffi
@@ -37,6 +82,28 @@
         assert isinstance(func, _ffi.FuncPtr)
         raises(AttributeError, "libc.xxxxxxxxxxxxxx")
 
+    def test_getchar(self):
+        import _ffi
+        lib = _ffi.CDLL(self.lib_name)
+        get_char = lib.ptr('get_char', ['s', 'H'], 'c')
+        assert get_char('dupa', 2) == 'p'
+        assert get_char('dupa', 1) == 'u'
+        skip("this module does not do overflow checking by now")
+        raises(OverflowError, "get_char('xxx', 2 ** 17)")
+
+    def test_returning_str(self):
+        import _ffi
+        lib = _ffi.CDLL(self.lib_name)
+        char_check = lib.ptr('char_check', ['c', 'c'], 's')
+        assert char_check('y', 'x') == 'xxxxxx'
+        assert char_check('x', 'y') is None
+
+    def test_short_addition(self):
+        import _ffi
+        lib = _ffi.CDLL(self.lib_name)
+        short_add = lib.ptr('add_shorts', ['h', 'h'], 'H')
+        assert short_add(1, 2) == 3
+
     def test_rand(self):
         import _ffi
         libc = _ffi.CDLL('libc.so.6')
@@ -107,8 +174,20 @@
         t = Tm(gmtime(x))
         assert t.tm_year == 70
         assert t.tm_sec == 1
-        assert t.tm_min == 2
-        
+        assert t.tm_min == 2        
+
+    def test_nested_structures(self):
+        import _ffi
+        lib = _ffi.CDLL(self.lib_name)
+        inner = lib.ptr("inner_struct_elem", ['P'], 'c')
+        X = _ffi.Structure([('x1', 'i'), ('x2', 'h'), ('x3', 'c'), ('next', 'P')])
+        x = X(next=X(next=None, x3='x'), x1=1, x2=2, x3='x')
+        assert X(x.next).x3 == 'x'
+        assert inner(x) == 'x'
+        create_double_struct = lib.ptr("create_double_struct", [], 'P')
+        x = create_double_struct()
+        assert X(X(x).next).x2 == 3
+
+    def test_longs_ulongs(self):
+        skip("Not implemented yet")
 
-    #def test_nested_structures(self):
-    #    



More information about the Pypy-commit mailing list