[pypy-svn] r45475 - in pypy/dist/pypy: rpython/module translator/c/test

arigo at codespeak.net arigo at codespeak.net
Fri Aug 3 15:15:41 CEST 2007


Author: arigo
Date: Fri Aug  3 15:15:41 2007
New Revision: 45475

Modified:
   pypy/dist/pypy/rpython/module/ll_os.py
   pypy/dist/pypy/translator/c/test/test_extfunc.py
Log:
RPython support for os.listdir().  In-progress; the previous
ros.opendir/readdir/closedir interface is still there but the idea is to
get rid of it.


Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py	(original)
+++ pypy/dist/pypy/rpython/module/ll_os.py	Fri Aug  3 15:15:41 2007
@@ -5,7 +5,7 @@
 # Implementation details about those functions
 # might be found in doc/rffi.txt
 
-import os, errno
+import os, sys, errno
 from pypy.rpython.module.support import ll_strcpy, _ll_strfill, OOSupport
 from pypy.rpython.module.support import to_opaque_object, from_opaque_object
 from pypy.rlib import ros
@@ -15,6 +15,7 @@
 from pypy.rpython.extfunc import BaseLazyRegistering, registering
 from pypy.annotation.model import SomeString, SomeInteger
 from pypy.annotation.model import s_ImpossibleValue, s_None, s_Bool
+from pypy.annotation.listdef import s_list_of_strings
 from pypy.rpython.lltypesystem import rffi
 from pypy.rpython.lltypesystem.rffi import platform
 from pypy.rpython.lltypesystem import lltype
@@ -373,6 +374,51 @@
         os_getcwd._obj._marshal_input = os_getcwd_marshal_input
         os_getcwd._obj._unmarshal_output = os_getcwd_unmarshal_output
 
+    @registering(os.listdir)
+    def register_os_listdir(self):
+        # we need a different approach on Windows and on Posix
+        if sys.platform.startswith('win'):
+            XXX   # FindFirstFile, FindNextFile
+        else:
+            INCL = ['sys/types.h', 'dirent.h']
+            DIRP = rffi.COpaque('DIR', includes=INCL)
+            NAME_MAX = platform.intdefined('NAME_MAX', includes=INCL)
+            DIRENTP = rffi.CStruct('dirent',
+                ('d_name', lltype.FixedSizeArray(lltype.Char, NAME_MAX+1)),
+                                   )
+            # XXX so far, DIRENTP cannot be handled by ll2ctypes because
+            #     it contains other fields before 'd_name', at least on Linux
+            os_opendir = rffi.llexternal('opendir', [rffi.CCHARP], DIRP,
+                                         includes = INCL)
+            os_readdir = rffi.llexternal('readdir', [DIRP], DIRENTP,
+                                         includes = INCL)
+            os_closedir = rffi.llexternal('closedir', [DIRP], rffi.INT,
+                                          includes = INCL)
+
+            def os_listdir_lltypeimpl(path):
+                path = rffi.str2charp(path)
+                dirp = os_opendir(path)
+                rffi.free_charp(path)
+                if not dirp:
+                    raise OSError(rffi.c_errno, "os_opendir failed")
+                result = []
+                while True:
+                    direntp = os_readdir(dirp)
+                    if not direntp:
+                        error = rffi.c_errno
+                        break
+                    name = rffi.charp2str(direntp.c_d_name)
+                    if name != '.' and name != '..':
+                        result.append(name)
+                os_closedir(dirp)
+                if error:
+                    raise OSError(error, "os_readdir failed")
+                return result
+
+            self.register(os.listdir, [str], s_list_of_strings,
+                          "ll_os.ll_os_listdir",
+                          llimpl=os_listdir_lltypeimpl)
+
     # ------------------------------- os.W* ---------------------------------
 
     w_star = ['WCOREDUMP', 'WIFCONTINUED', 'WIFSTOPPED',

Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_extfunc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_extfunc.py	Fri Aug  3 15:15:41 2007
@@ -703,6 +703,18 @@
     compared_with.sort()
     assert result == compared_with
 
+def test_listdir():
+    def mylistdir(s):
+        result = os.listdir(s)
+        return '/'.join(result)
+    func = compile(mylistdir, [str])
+    result = func(str(udir))
+    result = result.split('/')
+    result.sort()
+    compared_with = os.listdir(str(udir))
+    compared_with.sort()
+    assert result == compared_with
+
 if hasattr(posix, 'execv'):
     def test_execv():
         filename = str(udir.join('test_execv.txt'))



More information about the Pypy-commit mailing list