]>
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 licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  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); 
 139         de_d_name 
= wxConvFileName
->cMB2WC( de
->d_name 
); 
 141         de_d_name 
= de
->d_name
; 
 144         // don't return "." and ".." unless asked for 
 145         if ( de
->d_name
[0] == '.' && 
 146              ((de
->d_name
[1] == '.' && de
->d_name
[2] == '\0') || 
 147               (de
->d_name
[1] == '\0')) ) 
 149             if ( !(m_flags 
& wxDIR_DOTDOT
) ) 
 152             // we found a valid match 
 156         // check the type now 
 157         if ( !(m_flags 
& wxDIR_FILES
) && !wxDir::Exists(path 
+ de_d_name
) ) 
 159             // it's a file, but we don't want them 
 162         else if ( !(m_flags 
& wxDIR_DIRS
) && wxDir::Exists(path 
+ de_d_name
) ) 
 164             // it's a dir, and we don't want it 
 168         // finally, check the name 
 169         if ( m_filespec
.empty() ) 
 171             matches 
= m_flags 
& wxDIR_HIDDEN 
? true : de
->d_name
[0] != '.'; 
 175             // test against the pattern 
 176             matches 
= wxMatchWild(m_filespec
, de_d_name
, 
 177                                   !(m_flags 
& wxDIR_HIDDEN
)); 
 181     *filename 
= de_d_name
; 
 186 #else // old VMS (TODO) 
 188 wxDirData::wxDirData(const wxString
& WXUNUSED(dirname
)) 
 190     wxFAIL_MSG(_T("not implemented")); 
 193 wxDirData::~wxDirData() 
 197 bool wxDirData::Read(wxString 
* WXUNUSED(filename
)) 
 202 #endif // not or new VMS/old VMS 
 204 // ---------------------------------------------------------------------------- 
 206 // ---------------------------------------------------------------------------- 
 209 bool wxDir::Exists(const wxString
& dir
) 
 211     return wxDirExists(dir
); 
 214 // ---------------------------------------------------------------------------- 
 215 // wxDir construction/destruction 
 216 // ---------------------------------------------------------------------------- 
 218 wxDir::wxDir(const wxString
& dirname
) 
 225 bool wxDir::Open(const wxString
& dirname
) 
 228     m_data 
= new wxDirData(dirname
); 
 230     if ( !M_DIR
->IsOk() ) 
 232         wxLogSysError(_("Can not enumerate files in directory '%s'"), 
 244 bool wxDir::IsOpened() const 
 246     return m_data 
!= NULL
; 
 249 wxString 
wxDir::GetName() const 
 254         name 
= M_DIR
->GetName(); 
 255         if ( !name
.empty() && (name
.Last() == _T('/')) ) 
 257             // chop off the last (back)slash 
 258             name
.Truncate(name
.length() - 1); 
 270 // ---------------------------------------------------------------------------- 
 272 // ---------------------------------------------------------------------------- 
 274 bool wxDir::GetFirst(wxString 
*filename
, 
 275                      const wxString
& filespec
, 
 278     wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 
 282     M_DIR
->SetFileSpec(filespec
); 
 283     M_DIR
->SetFlags(flags
); 
 285     return GetNext(filename
); 
 288 bool wxDir::GetNext(wxString 
*filename
) const 
 290     wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 
 292     wxCHECK_MSG( filename
, false, _T("bad pointer in wxDir::GetNext()") ); 
 294     return M_DIR
->Read(filename
); 
 297 bool wxDir::HasSubDirs(const wxString
& spec
) 
 299     wxCHECK_MSG( IsOpened(), false, _T("must wxDir::Open() first") ); 
 303         // faster check for presence of any subdirectory: normally each subdir 
 304         // has a hard link to the parent directory and so, knowing that there 
 305         // are at least "." and "..", we have a subdirectory if and only if 
 306         // links number is > 2 - this is just a guess but it works fairly well 
 309         // note that we may guess wrongly in one direction only: i.e. we may 
 310         // return true when there are no subdirectories but this is ok as the 
 311         // caller will learn it soon enough when it calls GetFirst(wxDIR) 
 314         if ( wxStat(M_DIR
->GetName().c_str(), &stBuf
) == 0 ) 
 316             switch ( stBuf
.st_nlink 
) 
 324                     // weird filesystem, don't try to guess for it, use dumb 
 329                     // assume we have subdirs - may turn out to be wrong if we 
 330                     // have other hard links to this directory but it's not 
 331                     // that bad as explained above 
 337     // just try to find first directory 
 339     return GetFirst(&s
, spec
, wxDIR_DIRS 
| wxDIR_HIDDEN
);