]>
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 wxPathExists(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
);