]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/dir.cpp
Handle IN_MOVE inotify events better.
[wxWidgets.git] / src / unix / dir.cpp
index 4680a338ce16bf902a1484d41ad0c56c930e324b..2924741545652a961e616360d0e390e274d97735 100644 (file)
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        unix/dir.cpp
+// Name:        src/unix/dir.cpp
 // Purpose:     wxDir implementation for Unix/POSIX systems
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     08.12.99
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
 // Purpose:     wxDir implementation for Unix/POSIX systems
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     08.12.99
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 /////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "dir.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -35,6 +31,7 @@
 
 #include "wx/dir.h"
 #include "wx/filefn.h"          // for wxMatchWild
 
 #include "wx/dir.h"
 #include "wx/filefn.h"          // for wxMatchWild
+#include "wx/filename.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -95,7 +92,7 @@ wxDirData::wxDirData(const wxString& dirname)
 
     // throw away the trailing slashes
     size_t n = m_dirname.length();
 
     // throw away the trailing slashes
     size_t n = m_dirname.length();
-    wxCHECK_RET( n, _T("empty dir name in wxDir") );
+    wxCHECK_RET( n, wxT("empty dir name in wxDir") );
 
     while ( n > 0 && m_dirname[--n] == '/' )
         ;
 
     while ( n > 0 && m_dirname[--n] == '/' )
         ;
@@ -112,34 +109,34 @@ wxDirData::~wxDirData()
     {
         if ( closedir(m_dir) != 0 )
         {
     {
         if ( closedir(m_dir) != 0 )
         {
-            wxLogLastError(_T("closedir"));
+            wxLogLastError(wxT("closedir"));
         }
     }
 }
 
 bool wxDirData::Read(wxString *filename)
 {
         }
     }
 }
 
 bool wxDirData::Read(wxString *filename)
 {
-    dirent *de = (dirent *)NULL;    // just to silence compiler warnings
-    bool matches = FALSE;
+    dirent *de = NULL;    // just to silence compiler warnings
+    bool matches = false;
 
     // speed up string concatenation in the loop a bit
     wxString path = m_dirname;
 
     // speed up string concatenation in the loop a bit
     wxString path = m_dirname;
-    path += _T('/');
+    path += wxT('/');
     path.reserve(path.length() + 255);
     path.reserve(path.length() + 255);
-    
+
     wxString de_d_name;
 
     while ( !matches )
     {
         de = readdir(m_dir);
         if ( !de )
     wxString de_d_name;
 
     while ( !matches )
     {
         de = readdir(m_dir);
         if ( !de )
-            return FALSE;
-            
+            return false;
+
 #if wxUSE_UNICODE
 #if wxUSE_UNICODE
-        de_d_name = wxConvLibc.cMB2WC( de->d_name );
+        de_d_name = wxString(de->d_name, *wxConvFileName);
 #else
         de_d_name = de->d_name;
 #else
         de_d_name = de->d_name;
-#endif            
+#endif
 
         // don't return "." and ".." unless asked for
         if ( de->d_name[0] == '.' &&
 
         // don't return "." and ".." unless asked for
         if ( de->d_name[0] == '.' &&
@@ -153,13 +150,20 @@ bool wxDirData::Read(wxString *filename)
             break;
         }
 
             break;
         }
 
-        // check the type now
-        if ( !(m_flags & wxDIR_FILES) && !wxDir::Exists(path + de_d_name) )
+        // check the type now: notice that we may want to check the type of
+        // the path itself and not whatever it points to in case of a symlink
+        wxFileName fn = wxFileName::DirName(path + de_d_name);
+        if ( m_flags & wxDIR_NO_FOLLOW )
+        {
+            fn.DontFollowLink();
+        }
+
+        if ( !(m_flags & wxDIR_FILES) && !fn.DirExists() )
         {
             // it's a file, but we don't want them
             continue;
         }
         {
             // it's a file, but we don't want them
             continue;
         }
-        else if ( !(m_flags & wxDIR_DIRS) && wxDir::Exists(path + de_d_name) )
+        else if ( !(m_flags & wxDIR_DIRS) && fn.DirExists() )
         {
             // it's a dir, and we don't want it
             continue;
         {
             // it's a dir, and we don't want it
             continue;
@@ -168,30 +172,26 @@ bool wxDirData::Read(wxString *filename)
         // finally, check the name
         if ( m_filespec.empty() )
         {
         // finally, check the name
         if ( m_filespec.empty() )
         {
-            matches = m_flags & wxDIR_HIDDEN ? TRUE : de->d_name[0] != '.';
+            matches = m_flags & wxDIR_HIDDEN ? true : de->d_name[0] != '.';
         }
         else
         {
         }
         else
         {
-#if wxUSE_UNICODE
-            matches = TRUE;  // FIXME
-#else
             // test against the pattern
             matches = wxMatchWild(m_filespec, de_d_name,
                                   !(m_flags & wxDIR_HIDDEN));
             // test against the pattern
             matches = wxMatchWild(m_filespec, de_d_name,
                                   !(m_flags & wxDIR_HIDDEN));
-#endif
         }
     }
 
     *filename = de_d_name;
 
         }
     }
 
     *filename = de_d_name;
 
-    return TRUE;
+    return true;
 }
 
 #else // old VMS (TODO)
 
 wxDirData::wxDirData(const wxString& WXUNUSED(dirname))
 {
 }
 
 #else // old VMS (TODO)
 
 wxDirData::wxDirData(const wxString& WXUNUSED(dirname))
 {
-    wxFAIL_MSG(_T("not implemented"));
+    wxFAIL_MSG(wxT("not implemented"));
 }
 
 wxDirData::~wxDirData()
 }
 
 wxDirData::~wxDirData()
@@ -200,21 +200,11 @@ wxDirData::~wxDirData()
 
 bool wxDirData::Read(wxString * WXUNUSED(filename))
 {
 
 bool wxDirData::Read(wxString * WXUNUSED(filename))
 {
-    return FALSE;
+    return false;
 }
 
 #endif // not or new VMS/old VMS
 
 }
 
 #endif // not or new VMS/old VMS
 
-// ----------------------------------------------------------------------------
-// wxDir helpers
-// ----------------------------------------------------------------------------
-
-/* static */
-bool wxDir::Exists(const wxString& dir)
-{
-    return wxPathExists(dir);
-}
-
 // ----------------------------------------------------------------------------
 // wxDir construction/destruction
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxDir construction/destruction
 // ----------------------------------------------------------------------------
@@ -233,16 +223,13 @@ bool wxDir::Open(const wxString& dirname)
 
     if ( !M_DIR->IsOk() )
     {
 
     if ( !M_DIR->IsOk() )
     {
-        wxLogSysError(_("Can not enumerate files in directory '%s'"),
-                      dirname.c_str());
-
         delete M_DIR;
         m_data = NULL;
 
         delete M_DIR;
         m_data = NULL;
 
-        return FALSE;
+        return false;
     }
 
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxDir::IsOpened() const
 }
 
 bool wxDir::IsOpened() const
@@ -256,19 +243,26 @@ wxString wxDir::GetName() const
     if ( m_data )
     {
         name = M_DIR->GetName();
     if ( m_data )
     {
         name = M_DIR->GetName();
-        if ( !name.empty() && (name.Last() == _T('/')) )
+
+        // Notice that we need to check for length > 1 as we shouldn't remove
+        // the last slash from the root directory!
+        if ( name.length() > 1 && (name.Last() == wxT('/')) )
         {
         {
-            // chop off the last (back)slash
-            name.Truncate(name.length() - 1);
+            // chop off the last slash
+            name.RemoveLast();
         }
     }
 
     return name;
 }
 
         }
     }
 
     return name;
 }
 
-wxDir::~wxDir()
+void wxDir::Close()
 {
 {
-    delete M_DIR;
+    if ( m_data )
+    {
+        delete m_data;
+        m_data = NULL;
+    }
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -279,7 +273,7 @@ bool wxDir::GetFirst(wxString *filename,
                      const wxString& filespec,
                      int flags) const
 {
                      const wxString& filespec,
                      int flags) const
 {
-    wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+    wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
 
     M_DIR->Rewind();
 
 
     M_DIR->Rewind();
 
@@ -291,16 +285,16 @@ bool wxDir::GetFirst(wxString *filename,
 
 bool wxDir::GetNext(wxString *filename) const
 {
 
 bool wxDir::GetNext(wxString *filename) const
 {
-    wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+    wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
 
 
-    wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
+    wxCHECK_MSG( filename, false, wxT("bad pointer in wxDir::GetNext()") );
 
     return M_DIR->Read(filename);
 }
 
 
     return M_DIR->Read(filename);
 }
 
-bool wxDir::HasSubDirs(const wxString& spec)
+bool wxDir::HasSubDirs(const wxString& spec) const
 {
 {
-    wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+    wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
 
     if ( spec.empty() )
     {
 
     if ( spec.empty() )
     {
@@ -315,13 +309,13 @@ bool wxDir::HasSubDirs(const wxString& spec)
         // caller will learn it soon enough when it calls GetFirst(wxDIR)
         // anyhow
         wxStructStat stBuf;
         // caller will learn it soon enough when it calls GetFirst(wxDIR)
         // anyhow
         wxStructStat stBuf;
-        if ( wxStat(M_DIR->GetName().c_str(), &stBuf) == 0 )
+        if ( wxStat(M_DIR->GetName(), &stBuf) == 0 )
         {
             switch ( stBuf.st_nlink )
             {
                 case 2:
                     // just "." and ".."
         {
             switch ( stBuf.st_nlink )
             {
                 case 2:
                     // just "." and ".."
-                    return FALSE;
+                    return false;
 
                 case 0:
                 case 1:
 
                 case 0:
                 case 1:
@@ -333,7 +327,7 @@ bool wxDir::HasSubDirs(const wxString& spec)
                     // assume we have subdirs - may turn out to be wrong if we
                     // have other hard links to this directory but it's not
                     // that bad as explained above
                     // assume we have subdirs - may turn out to be wrong if we
                     // have other hard links to this directory but it's not
                     // that bad as explained above
-                    return TRUE;
+                    return true;
             }
         }
     }
             }
         }
     }