]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/dir.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDir implementation for Unix/POSIX systems 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "dir.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  37 #include "wx/filefn.h"          // for wxMatchWild 
  39 #include <sys/types.h> 
  45 // ---------------------------------------------------------------------------- 
  47 // ---------------------------------------------------------------------------- 
  49 #define M_DIR       ((wxDirData *)m_data) 
  51 // ---------------------------------------------------------------------------- 
  53 // ---------------------------------------------------------------------------- 
  55 // this class stores everything we need to enumerate the files 
  59     wxDirData(const wxString
& dirname
); 
  62     bool IsOk() const { return m_dir 
!= NULL
; } 
  64     void SetFileSpec(const wxString
& filespec
) { m_filespec 
= filespec
; } 
  65     void SetFlags(int flags
) { m_flags 
= flags
; } 
  67     void Rewind() { rewinddir(m_dir
); } 
  68     bool Read(wxString 
*filename
); 
  70     const wxString
& GetName() const { return m_dirname
; } 
  81 // ============================================================================ 
  83 // ============================================================================ 
  85 // ---------------------------------------------------------------------------- 
  87 // ---------------------------------------------------------------------------- 
  89 #if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 ) 
  91 wxDirData::wxDirData(const wxString
& dirname
) 
  96     // throw away the trailing slashes 
  97     size_t n 
= m_dirname
.length(); 
  98     wxCHECK_RET( n
, _T("empty dir name in wxDir") ); 
 100     while ( n 
> 0 && m_dirname
[--n
] == '/' ) 
 103     m_dirname
.Truncate(n 
+ 1); 
 106     m_dir 
= opendir(m_dirname
.fn_str()); 
 109 wxDirData::~wxDirData() 
 113         if ( closedir(m_dir
) != 0 ) 
 115             wxLogLastError(_T("closedir")); 
 120 bool wxDirData::Read(wxString 
*filename
) 
 122     dirent 
*de 
= (dirent 
*)NULL
;    // just to silence compiler warnings 
 123     bool matches 
= FALSE
; 
 125     // speed up string concatenation in the loop a bit 
 126     wxString path 
= m_dirname
; 
 128     path
.reserve(path
.length() + 255); 
 136         // don't return "." and ".." unless asked for 
 137         if ( de
->d_name
[0] == '.' && 
 138              ((de
->d_name
[1] == '.' && de
->d_name
[2] == '\0') || 
 139               (de
->d_name
[1] == '\0')) ) 
 141             if ( !(m_flags 
& wxDIR_DOTDOT
) ) 
 144             // we found a valid match 
 148         // check the type now 
 149         if ( !(m_flags 
& wxDIR_FILES
) && !wxDir::Exists(path 
+ de
->d_name
) ) 
 151             // it's a file, but we don't want them 
 154         else if ( !(m_flags 
& wxDIR_DIRS
) && wxDir::Exists(path 
+ de
->d_name
) ) 
 156             // it's a dir, and we don't want it 
 160         // finally, check the name 
 161         if ( m_filespec
.empty() ) 
 163             matches 
= m_flags 
& wxDIR_HIDDEN 
? TRUE 
: de
->d_name
[0] != '.'; 
 167             // test against the pattern 
 168             matches 
= wxMatchWild(m_filespec
, de
->d_name
, 
 169                                   !(m_flags 
& wxDIR_HIDDEN
)); 
 173     *filename 
= de
->d_name
; 
 178 #else // old VMS (TODO) 
 180 wxDirData::wxDirData(const wxString
& WXUNUSED(dirname
)) 
 182     wxFAIL_MSG(_T("not implemented")); 
 185 wxDirData::~wxDirData() 
 189 bool wxDirData::Read(wxString 
* WXUNUSED(filename
)) 
 194 #endif // not or new VMS/old VMS 
 196 // ---------------------------------------------------------------------------- 
 198 // ---------------------------------------------------------------------------- 
 201 bool wxDir::Exists(const wxString
& dir
) 
 203     return wxPathExists(dir
); 
 206 // ---------------------------------------------------------------------------- 
 207 // wxDir construction/destruction 
 208 // ---------------------------------------------------------------------------- 
 210 wxDir::wxDir(const wxString
& dirname
) 
 217 bool wxDir::Open(const wxString
& dirname
) 
 220     m_data 
= new wxDirData(dirname
); 
 222     if ( !M_DIR
->IsOk() ) 
 224         wxLogSysError(_("Can not enumerate files in directory '%s'"), 
 236 bool wxDir::IsOpened() const 
 238     return m_data 
!= NULL
; 
 241 wxString 
wxDir::GetName() const 
 246         name 
= M_DIR
->GetName(); 
 247         if ( !name
.empty() && (name
.Last() == _T('/')) ) 
 249             // chop off the last (back)slash 
 250             name
.Truncate(name
.length() - 1); 
 262 // ---------------------------------------------------------------------------- 
 264 // ---------------------------------------------------------------------------- 
 266 bool wxDir::GetFirst(wxString 
*filename
, 
 267                      const wxString
& filespec
, 
 270     wxCHECK_MSG( IsOpened(), FALSE
, _T("must wxDir::Open() first") ); 
 274     M_DIR
->SetFileSpec(filespec
); 
 275     M_DIR
->SetFlags(flags
); 
 277     return GetNext(filename
); 
 280 bool wxDir::GetNext(wxString 
*filename
) const 
 282     wxCHECK_MSG( IsOpened(), FALSE
, _T("must wxDir::Open() first") ); 
 284     wxCHECK_MSG( filename
, FALSE
, _T("bad pointer in wxDir::GetNext()") ); 
 286     return M_DIR
->Read(filename
); 
 289 bool wxDir::HasSubDirs(const wxString
& spec
) 
 291     wxCHECK_MSG( IsOpened(), FALSE
, _T("must wxDir::Open() first") ); 
 295         // faster check for presence of any subdirectory: normally each subdir 
 296         // has a hard link to the parent directory and so, knowing that there 
 297         // are at least "." and "..", we have a subdirectory if and only if 
 298         // links number is > 2 - this is just a guess but it works fairly well 
 301         // note that we may guess wrongly in one direction only: i.e. we may 
 302         // return true when there are no subdirectories but this is ok as the 
 303         // caller will learn it soon enough when it calls GetFirst(wxDIR) 
 306         if ( wxStat(M_DIR
->GetName(), &stBuf
) == 0 ) 
 308             switch ( stBuf
.st_nlink 
) 
 316                     // weird filesystem, don't try to guess for it, use dumb 
 321                     // assume we have subdirs - may turn out to be wrong if we 
 322                     // have other hard links to this directory but it's not 
 323                     // that bad as explained above 
 329     // just try to find first directory 
 331     return GetFirst(&s
, spec
, wxDIR_DIRS 
| wxDIR_HIDDEN
);