Author: Amaury Forgeot d'Arc <[email protected]>
Branch: more-rposix
Changeset: r74390:8d7118f6770e
Date: 2014-11-07 22:36 +0100
http://bitbucket.org/pypy/pypy/changeset/8d7118f6770e/

Log:    os.listdir()

diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -144,7 +144,7 @@
 else:
     includes = ['unistd.h',  'sys/types.h',
                 'utime.h', 'sys/time.h', 'sys/times.h',
-                'grp.h']
+                'grp.h', 'dirent.h']
     libraries = ['util']
 eci = ExternalCompilationInfo(
     includes=includes,
@@ -284,14 +284,6 @@
     return os.rename(_as_bytes(path1), _as_bytes(path2))
 
 @specialize.argtype(0)
-def listdir(dirname):
-    return os.listdir(_as_bytes(dirname))
-
[email protected](0)
-def access(path, mode):
-    return os.access(_as_bytes(path), mode)
-
[email protected](0)
 def chmod(path, mode):
     return os.chmod(_as_bytes(path), mode)
 
@@ -526,6 +518,92 @@
     lltype.free(buf, flavor='raw')
     return result
 
+if not _WIN32:
+    class CConfig:
+        _compilation_info_ = eci
+        DIRENT = rffi_platform.Struct('struct dirent',
+            [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))])
+
+    DIRP = rffi.COpaquePtr('DIR')
+    config = rffi_platform.configure(CConfig)
+    DIRENT = config['DIRENT']
+    DIRENTP = lltype.Ptr(DIRENT)
+    c_opendir = external('opendir', [rffi.CCHARP], DIRP)
+    # XXX macro=True is hack to make sure we get the correct kind of
+    # dirent struct (which depends on defines)
+    c_readdir = external('readdir', [DIRP], DIRENTP, macro=True)
+    c_closedir = external('closedir', [DIRP], rffi.INT)
+
+@replace_os_function('listdir')
[email protected](0)
+def listdir(path):
+    if not _WIN32:
+        path = _as_bytes0(path)
+        dirp = c_opendir(path)
+        if not dirp:
+            raise OSError(get_errno(), "opendir failed")
+        result = []
+        while True:
+            set_errno(0)
+            direntp = c_readdir(dirp)
+            if not direntp:
+                error = get_errno()
+                break
+            namep = rffi.cast(rffi.CCHARP, direntp.c_d_name)
+            name = rffi.charp2str(namep)
+            if name != '.' and name != '..':
+                result.append(name)
+        c_closedir(dirp)
+        if error:
+            raise OSError(error, "readdir failed")
+        return result
+    else:  # _WIN32 case
+        from rpython.rlib.rwin32file import make_win32_traits
+        traits = _preferred_traits(path)
+        win32traits = make_win32_traits(traits)
+        path = traits.as_str0(path)
+
+        if traits.str is unicode:
+            if path and path[-1] not in (u'/', u'\\', u':'):
+                path += u'/'
+            mask = path + u'*.*'
+        else:
+            if path and path[-1] not in ('/', '\\', ':'):
+                path += '/'
+            mask = path + '*.*'
+
+        filedata = lltype.malloc(win32traits.WIN32_FIND_DATA, flavor='raw')
+        try:
+            result = []
+            hFindFile = win32traits.FindFirstFile(mask, filedata)
+            if hFindFile == rwin32.INVALID_HANDLE_VALUE:
+                error = rwin32.GetLastError()
+                if error == win32traits.ERROR_FILE_NOT_FOUND:
+                    return result
+                else:
+                    raise WindowsError(error,  "FindFirstFile failed")
+            while True:
+                name = traits.charp2str(rffi.cast(traits.CCHARP,
+                                                  filedata.c_cFileName))
+                if traits.str is unicode:
+                    if not (name == u"." or name == u".."):
+                        result.append(name)
+                else:
+                    if not (name == "." or name == ".."):
+                        result.append(name)
+                if not win32traits.FindNextFile(hFindFile, filedata):
+                    break
+            # FindNextFile sets error to ERROR_NO_MORE_FILES if
+            # it got to the end of the directory
+            error = rwin32.GetLastError()
+            win32traits.FindClose(hFindFile)
+            if error == win32traits.ERROR_NO_MORE_FILES:
+                return result
+            else:
+                raise WindowsError(error,  "FindNextFile failed")
+        finally:
+            lltype.free(filedata, flavor='raw')
+
 #___________________________________________________________________
 
 c_execv = external('execv', [rffi.CCHARP, rffi.CCHARPP], rffi.INT)
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -173,61 +173,6 @@
                 separate_module_sources = ["\n".join(defs)]
             ))
 
-    @registering_str_unicode(os.listdir)
-    def register_os_listdir(self, traits):
-        # we need a different approach on Windows and on Posix
-        if sys.platform.startswith('win'):
-            from rpython.rtyper.module.ll_win32file import make_listdir_impl
-            os_listdir_llimpl = make_listdir_impl(traits)
-        else:
-            assert traits.str is str
-            compilation_info = ExternalCompilationInfo(
-                includes = ['sys/types.h', 'dirent.h']
-            )
-            class CConfig:
-                _compilation_info_ = compilation_info
-                DIRENT = platform.Struct('struct dirent',
-                    [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))])
-
-            DIRP = rffi.COpaquePtr('DIR')
-            config = platform.configure(CConfig)
-            DIRENT = config['DIRENT']
-            DIRENTP = lltype.Ptr(DIRENT)
-            os_opendir = self.llexternal('opendir', [rffi.CCHARP], DIRP,
-                                         compilation_info=compilation_info)
-            # XXX macro=True is hack to make sure we get the correct kind of
-            # dirent struct (which depends on defines)
-            os_readdir = self.llexternal('readdir', [DIRP], DIRENTP,
-                                         compilation_info=compilation_info,
-                                         macro=True)
-            os_closedir = self.llexternal('closedir', [DIRP], rffi.INT,
-                                          compilation_info=compilation_info)
-
-            def os_listdir_llimpl(path):
-                dirp = os_opendir(path)
-                if not dirp:
-                    raise OSError(rposix.get_errno(), "os_opendir failed")
-                result = []
-                while True:
-                    rposix.set_errno(0)
-                    direntp = os_readdir(dirp)
-                    if not direntp:
-                        error = rposix.get_errno()
-                        break
-                    namep = rffi.cast(rffi.CCHARP, direntp.c_d_name)
-                    name = rffi.charp2str(namep)
-                    if name != '.' and name != '..':
-                        result.append(name)
-                os_closedir(dirp)
-                if error:
-                    raise OSError(error, "os_readdir failed")
-                return result
-
-        return extdef([traits.str0],  # a single argument which is a str
-                      [traits.str0],  # returns a list of strings
-                      traits.ll_os_name('listdir'),
-                      llimpl=os_listdir_llimpl)
-
     @registering(os.pipe)
     def register_os_pipe(self):
         # we need a different approach on Windows and on Posix
diff --git a/rpython/rtyper/module/ll_win32file.py 
b/rpython/rtyper/module/ll_win32file.py
--- a/rpython/rtyper/module/ll_win32file.py
+++ b/rpython/rtyper/module/ll_win32file.py
@@ -12,65 +12,6 @@
 
 
 #_______________________________________________________________
-# listdir
-
-def make_listdir_impl(traits):
-    from rpython.rlib import rwin32
-    from rpython.rlib.rwin32file import make_win32_traits
-
-    win32traits = make_win32_traits(traits)
-
-    if traits.str is unicode:
-        def make_listdir_mask(path):
-            if path and path[-1] not in (u'/', u'\\', u':'):
-                path += u'/'
-            return path + u'*.*'
-
-        def skip_listdir(name):
-            return name == u"." or name == u".."
-    else:
-        def make_listdir_mask(path):
-            if path and path[-1] not in ('/', '\\', ':'):
-                path += '/'
-            return path + '*.*'
-
-        def skip_listdir(name):
-            return name == "." or name == ".."
-
-    @func_renamer('listdir_llimpl_%s' % traits.str.__name__)
-    def listdir_llimpl(path):
-        mask = make_listdir_mask(path)
-        filedata = lltype.malloc(win32traits.WIN32_FIND_DATA, flavor='raw')
-        try:
-            result = []
-            hFindFile = win32traits.FindFirstFile(mask, filedata)
-            if hFindFile == rwin32.INVALID_HANDLE_VALUE:
-                error = rwin32.GetLastError()
-                if error == win32traits.ERROR_FILE_NOT_FOUND:
-                    return result
-                else:
-                    raise WindowsError(error,  "FindFirstFile failed")
-            while True:
-                name = traits.charp2str(rffi.cast(traits.CCHARP,
-                                                  filedata.c_cFileName))
-                if not skip_listdir(name):
-                    result.append(name)
-                if not win32traits.FindNextFile(hFindFile, filedata):
-                    break
-            # FindNextFile sets error to ERROR_NO_MORE_FILES if
-            # it got to the end of the directory
-            error = rwin32.GetLastError()
-            win32traits.FindClose(hFindFile)
-            if error == win32traits.ERROR_NO_MORE_FILES:
-                return result
-            else:
-                raise WindowsError(error,  "FindNextFile failed")
-        finally:
-            lltype.free(filedata, flavor='raw')
-
-    return listdir_llimpl
-
-#_______________________________________________________________
 # chdir
 
 def make_chdir_impl(traits):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to