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

fijal at codespeak.net fijal at codespeak.net
Tue Oct 16 09:41:28 CEST 2007


Author: fijal
Date: Tue Oct 16 09:41:28 2007
New Revision: 47485

Modified:
   pypy/dist/pypy/module/_ffi/app_ffi.py
   pypy/dist/pypy/module/_ffi/interp_ffi.py
   pypy/dist/pypy/module/_ffi/structure.py
   pypy/dist/pypy/module/_ffi/test/test__ffi.py
   pypy/dist/pypy/module/_ffi/test/test_struct.py
Log:
* 'P' for pointer, 'p' for pascal string (not supported)
* add a dummy __setattr__ (working only for int) on structure
* add a test and few fixes for returning structure pointer


Modified: pypy/dist/pypy/module/_ffi/app_ffi.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/app_ffi.py	(original)
+++ pypy/dist/pypy/module/_ffi/app_ffi.py	Tue Oct 16 09:41:28 2007
@@ -4,6 +4,12 @@
     def __init__(self, fields):
         self.fields = fields
 
-    def __call__(self, **kwds):
+    def __call__(self, *args, **kwds):
         from _ffi import StructureInstance
-        return StructureInstance(self, kwds)
+        if args:
+            if len(args) > 1:
+                raise TypeError("Can give at most one non-keyword argument")
+            if kwds:
+                raise TypeError("Keyword arguments not allowed when passing address argument")
+            return StructureInstance(self, args[0], None)
+        return StructureInstance(self, None, kwds)

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	Tue Oct 16 09:41:28 2007
@@ -26,7 +26,6 @@
     'f' : ffi_type_float,
     'd' : ffi_type_double,
     's' : ffi_type_pointer,
-    'p' : ffi_type_pointer,
     'P' : ffi_type_pointer,
 }
 
@@ -45,7 +44,6 @@
     'f' : rffi.FLOAT,
     'd' : rffi.DOUBLE,
     's' : rffi.CCHARP,
-    'p' : rffi.CCHARP,
     'P' : rffi.VOIDP,    
 }
 
@@ -132,7 +130,7 @@
         ll_str = rffi.str2charp(space.str_w(w_arg))
         ptr.push_arg(ll_str)
         to_free.append(ll_str)
-    elif argtype == "p":
+    elif argtype == "P":
         # check for NULL ptr
         if space.is_w(w_arg, space.w_None):
             ptr.push_arg(lltype.nullptr(rffi.VOIDP.TO))
@@ -158,11 +156,11 @@
 def wrap_result(space, restype, func):
     for c, ll_type in ll_typemap_iter:
         if restype == c:
-            if c == 's' or c == 'p':
+            if c == 's':
                 return space.wrap(rffi.charp2str(func(rffi.CCHARP)))
             elif c == 'P':
                 res = func(rffi.VOIDP)
-                return space.wrap(lltype.cast_ptr_to_int(res))
+                return space.wrap(rffi.cast(rffi.INT, res))
             elif c == 'q' or c == 'Q' or c == 'L':
                 return space.newlong(func(ll_type))
             else:

Modified: pypy/dist/pypy/module/_ffi/structure.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/structure.py	(original)
+++ pypy/dist/pypy/module/_ffi/structure.py	Tue Oct 16 09:41:28 2007
@@ -39,7 +39,7 @@
     return size, pos
 
 class W_StructureInstance(Wrappable):
-    def __init__(self, space, w_shape, w_fieldinits):
+    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"))
@@ -47,8 +47,13 @@
         fields = unpack_fields(space, w_fields)
         size, pos = size_and_pos(fields)
         self.fields = fields
-        self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
-                                       zero=True)
+        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
+            self.ll_buffer = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw',
+                                           zero=True)
         self.ll_positions = pos
         self.next_pos = 0
 
@@ -60,6 +65,8 @@
     cast_pos._annspecialcase_ = 'specialize:arg(1)'
 
     def getattr(self, space, attr):
+        if attr.startswith('tm'):
+            pass
         for i in range(len(self.fields)):
             name, c = self.fields[i]
             if name == attr:
@@ -70,14 +77,27 @@
             "C Structure has no attribute %s" % name))
     getattr.unwrap_spec = ['self', ObjSpace, str]
 
+    def setattr(self, space, attr, value):
+        # XXX value is now always int, needs fixing
+        for i in range(len(self.fields)):
+            name, c = self.fields[i]
+            if name == attr:
+                pos = rffi.ptradd(self.ll_buffer, self.ll_positions[i])
+                TP = rffi.CArrayPtr(rffi.INT)
+                rffi.cast(TP, pos)[0] = value
+                return
+    setattr.unwrap_spec = ['self', ObjSpace, str, int]
+
     def __del__(self):
-        lltype.free(self.ll_buffer, flavor='raw')
+        if self.free_afterwards:
+            lltype.free(self.ll_buffer, flavor='raw')
 
-def descr_new_structure_instance(space, w_type, w_shape, w_fieldinits):
-    return W_StructureInstance(space, w_shape, w_fieldinits)
+def descr_new_structure_instance(space, w_type, w_shape, w_adr, w_fieldinits):
+    return W_StructureInstance(space, w_shape, w_adr, w_fieldinits)
 
 W_StructureInstance.typedef = TypeDef(
     'StructureInstance',
     __new__     = interp2app(descr_new_structure_instance),
     __getattr__ = interp2app(W_StructureInstance.getattr),
+    __setattr__ = interp2app(W_StructureInstance.setattr),
 )

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	Tue Oct 16 09:41:28 2007
@@ -9,8 +9,20 @@
         py.test.skip("Linux only tests by now")
 
 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;
+        }
+        """))
+    prepare_c_example = staticmethod(prepare_c_example)
+    
     def setup_class(cls):
         cls.space = gettestobjspace(usemodules=('_ffi','struct'))
+        cls.prepare_c_example()
 
     def test_libload(self):
         import _ffi
@@ -52,7 +64,7 @@
         strlen = libc.ptr('strlen', ['s'], 'i')
         assert strlen("dupa") == 4
         assert strlen("zupa") == 4
-        strlen = libc.ptr('strlen', ['p'], 'i')
+        strlen = libc.ptr('strlen', ['P'], 'i')
         assert strlen("ddd\x00") == 3
         strdup = libc.ptr('strdup', ['s'], 's')
         assert strdup("xxx") == "xxx"
@@ -60,7 +72,7 @@
     def test_time(self):
         import _ffi
         libc = _ffi.CDLL('libc.so.6')
-        time = libc.ptr('time', ['p'], 'l')
+        time = libc.ptr('time', ['P'], 'l')
         assert time(None) != 0
 
     def test_gettimeofday(self):
@@ -68,7 +80,7 @@
         struct_type = _ffi.Structure([('tv_sec', 'l'), ('tv_usec', 'l')])
         structure = struct_type()
         libc = _ffi.CDLL('libc.so.6')
-        gettimeofday = libc.ptr('gettimeofday', ['p', 'p'], 'i')
+        gettimeofday = libc.ptr('gettimeofday', ['P', 'P'], 'i')
         assert gettimeofday(structure, None) == 0
         struct2 = struct_type()
         assert gettimeofday(struct2, None) == 0
@@ -76,4 +88,27 @@
         assert (structure.tv_sec == struct2.tv_sec) or (structure.tv_sec == struct2.tv_sec - 1)
         raises(AttributeError, "structure.xxx")
 
-    
+    def test_structreturn(self):
+        import _ffi
+        X = _ffi.Structure([('x', 'l')])
+        x = X()
+        x.x = 121
+        Tm = _ffi.Structure([('tm_sec', 'i'),
+                             ('tm_min', 'i'),
+                             ('tm_hour', 'i'),
+                             ("tm_mday", 'i'),
+                             ("tm_mon", 'i'),
+                             ("tm_year", 'i'),
+                             ("tm_wday", 'i'),
+                             ("tm_yday", 'i'),
+                             ("tm_isdst", 'i')])
+        libc = _ffi.CDLL('libc.so.6')
+        gmtime = libc.ptr('gmtime', ['P'], 'P')
+        t = Tm(gmtime(x))
+        assert t.tm_year == 70
+        assert t.tm_sec == 1
+        assert t.tm_min == 2
+        
+
+    #def test_nested_structures(self):
+    #    

Modified: pypy/dist/pypy/module/_ffi/test/test_struct.py
==============================================================================
--- pypy/dist/pypy/module/_ffi/test/test_struct.py	(original)
+++ pypy/dist/pypy/module/_ffi/test/test_struct.py	Tue Oct 16 09:41:28 2007
@@ -1,5 +1,7 @@
 
-from pypy.module._ffi.structure import sizeof
+from pypy.module._ffi.structure import size_and_pos
+
+sizeof = lambda x : size_and_pos(x)[0]
 
 def unpack(desc):
     return [('x', i) for i in desc]



More information about the Pypy-commit mailing list