]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/dir.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/dir.cpp
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 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
33 #include "wx/filefn.h" // for wxMatchWild
34 #include "wx/filename.h"
36 #include <sys/types.h>
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
46 #define M_DIR ((wxDirData *)m_data)
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 // this class stores everything we need to enumerate the files
56 wxDirData(const wxString
& dirname
);
59 bool IsOk() const { return m_dir
!= NULL
; }
61 void SetFileSpec(const wxString
& filespec
) { m_filespec
= filespec
; }
62 void SetFlags(int flags
) { m_flags
= flags
; }
64 void Rewind() { rewinddir(m_dir
); }
65 bool Read(wxString
*filename
);
67 const wxString
& GetName() const { return m_dirname
; }
78 // ============================================================================
80 // ============================================================================
82 // ----------------------------------------------------------------------------
84 // ----------------------------------------------------------------------------
86 #if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
88 wxDirData::wxDirData(const wxString
& dirname
)
93 // throw away the trailing slashes
94 size_t n
= m_dirname
.length();
95 wxCHECK_RET( n
, wxT("empty dir name in wxDir") );
97 while ( n
> 0 && m_dirname
[--n
] == '/' )
100 m_dirname
.Truncate(n
+ 1);
103 m_dir
= opendir(m_dirname
.fn_str());
106 wxDirData::~wxDirData()
110 if ( closedir(m_dir
) != 0 )
112 wxLogLastError(wxT("closedir"));
117 bool wxDirData::Read(wxString
*filename
)
119 dirent
*de
= NULL
; // just to silence compiler warnings
120 bool matches
= false;
122 // speed up string concatenation in the loop a bit
123 wxString path
= m_dirname
;
125 path
.reserve(path
.length() + 255);
136 de_d_name
= wxString(de
->d_name
, *wxConvFileName
);
138 de_d_name
= de
->d_name
;
141 // don't return "." and ".." unless asked for
142 if ( de
->d_name
[0] == '.' &&
143 ((de
->d_name
[1] == '.' && de
->d_name
[2] == '\0') ||
144 (de
->d_name
[1] == '\0')) )
146 if ( !(m_flags
& wxDIR_DOTDOT
) )
149 // we found a valid match
153 // check the type now: notice that we may want to check the type of
154 // the path itself and not whatever it points to in case of a symlink
155 wxFileName fn
= wxFileName::DirName(path
+ de_d_name
);
156 if ( m_flags
& wxDIR_NO_FOLLOW
)
161 if ( !(m_flags
& wxDIR_FILES
) && !fn
.DirExists() )
163 // it's a file, but we don't want them
166 else if ( !(m_flags
& wxDIR_DIRS
) && fn
.DirExists() )
168 // it's a dir, and we don't want it
172 // finally, check the name
173 if ( m_filespec
.empty() )
175 matches
= m_flags
& wxDIR_HIDDEN
? true : de
->d_name
[0] != '.';
179 // test against the pattern
180 matches
= wxMatchWild(m_filespec
, de_d_name
,
181 !(m_flags
& wxDIR_HIDDEN
));
185 *filename
= de_d_name
;
190 #else // old VMS (TODO)
192 wxDirData::wxDirData(const wxString
& WXUNUSED(dirname
))
194 wxFAIL_MSG(wxT("not implemented"));
197 wxDirData::~wxDirData()
201 bool wxDirData::Read(wxString
* WXUNUSED(filename
))
206 #endif // not or new VMS/old VMS
208 // ----------------------------------------------------------------------------
209 // wxDir construction/destruction
210 // ----------------------------------------------------------------------------
212 wxDir::wxDir(const wxString
& dirname
)
219 bool wxDir::Open(const wxString
& dirname
)
222 m_data
= new wxDirData(dirname
);
224 if ( !M_DIR
->IsOk() )
235 bool wxDir::IsOpened() const
237 return m_data
!= NULL
;
240 wxString
wxDir::GetName() const
245 name
= M_DIR
->GetName();
247 // Notice that we need to check for length > 1 as we shouldn't remove
248 // the last slash from the root directory!
249 if ( name
.length() > 1 && (name
.Last() == wxT('/')) )
251 // chop off the last slash
268 // ----------------------------------------------------------------------------
270 // ----------------------------------------------------------------------------
272 bool wxDir::GetFirst(wxString
*filename
,
273 const wxString
& filespec
,
276 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
280 M_DIR
->SetFileSpec(filespec
);
281 M_DIR
->SetFlags(flags
);
283 return GetNext(filename
);
286 bool wxDir::GetNext(wxString
*filename
) const
288 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
290 wxCHECK_MSG( filename
, false, wxT("bad pointer in wxDir::GetNext()") );
292 return M_DIR
->Read(filename
);
295 bool wxDir::HasSubDirs(const wxString
& spec
) const
297 wxCHECK_MSG( IsOpened(), false, wxT("must wxDir::Open() first") );
301 // faster check for presence of any subdirectory: normally each subdir
302 // has a hard link to the parent directory and so, knowing that there
303 // are at least "." and "..", we have a subdirectory if and only if
304 // links number is > 2 - this is just a guess but it works fairly well
307 // note that we may guess wrongly in one direction only: i.e. we may
308 // return true when there are no subdirectories but this is ok as the
309 // caller will learn it soon enough when it calls GetFirst(wxDIR)
312 if ( wxStat(M_DIR
->GetName(), &stBuf
) == 0 )
314 switch ( stBuf
.st_nlink
)
322 // weird filesystem, don't try to guess for it, use dumb
327 // assume we have subdirs - may turn out to be wrong if we
328 // have other hard links to this directory but it's not
329 // that bad as explained above
335 // just try to find first directory
337 return GetFirst(&s
, spec
, wxDIR_DIRS
| wxDIR_HIDDEN
);