]> git.saurik.com Git - wxWidgets.git/blob - src/unix/dir.cpp
fixed bug #129464 (hopefully)
[wxWidgets.git] / src / unix / dir.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: unix/dir.cpp
3 // Purpose: wxDir implementation for Unix/POSIX systems
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 08.12.99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "dir.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/intl.h"
33 #include "wx/log.h"
34 #endif // PCH
35
36 #include "wx/dir.h"
37 #include "wx/filefn.h" // for wxMatchWild
38
39 #include <sys/types.h>
40
41 #include <dirent.h>
42
43 // ----------------------------------------------------------------------------
44 // macros
45 // ----------------------------------------------------------------------------
46
47 #define M_DIR ((wxDirData *)m_data)
48
49 // ----------------------------------------------------------------------------
50 // private classes
51 // ----------------------------------------------------------------------------
52
53 // this class stores everything we need to enumerate the files
54 class wxDirData
55 {
56 public:
57 wxDirData(const wxString& dirname);
58 ~wxDirData();
59
60 bool IsOk() const { return m_dir != NULL; }
61
62 void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
63 void SetFlags(int flags) { m_flags = flags; }
64
65 void Rewind() { rewinddir(m_dir); }
66 bool Read(wxString *filename);
67
68 private:
69 DIR *m_dir;
70
71 wxString m_dirname;
72 wxString m_filespec;
73
74 int m_flags;
75 };
76
77 // ============================================================================
78 // implementation
79 // ============================================================================
80
81 // ----------------------------------------------------------------------------
82 // wxDirData
83 // ----------------------------------------------------------------------------
84
85 #if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
86
87 wxDirData::wxDirData(const wxString& dirname)
88 : m_dirname(dirname)
89 {
90 m_dir = NULL;
91
92 // throw away the trailing slashes
93 size_t n = m_dirname.length();
94 wxCHECK_RET( n, _T("empty dir name in wxDir") );
95
96 while ( n > 0 && m_dirname[--n] == '/' )
97 ;
98
99 m_dirname.Truncate(n + 1);
100
101 // do open the dir
102 m_dir = opendir(m_dirname.fn_str());
103 }
104
105 wxDirData::~wxDirData()
106 {
107 if ( m_dir )
108 {
109 if ( closedir(m_dir) != 0 )
110 {
111 wxLogLastError(_T("closedir"));
112 }
113 }
114 }
115
116 bool wxDirData::Read(wxString *filename)
117 {
118 dirent *de = (dirent *)NULL; // just to silent compiler warnings
119 bool matches = FALSE;
120
121 while ( !matches )
122 {
123 de = readdir(m_dir);
124 if ( !de )
125 return FALSE;
126
127 // don't return "." and ".." unless asked for
128 if ( de->d_name[0] == '.' &&
129 ((de->d_name[1] == '.' && de->d_name[2] == '\0') ||
130 (de->d_name[1] == '\0')) )
131 {
132 if ( !(m_flags & wxDIR_DOTDOT) )
133 continue;
134 }
135
136 // check the type now
137 if ( !(m_flags & wxDIR_FILES) &&
138 !wxDir::Exists(m_dirname + _T('/') + de->d_name) )
139 {
140 // it's a file, but we don't want them
141 continue;
142 }
143 else if ( !(m_flags & wxDIR_DIRS) &&
144 wxDir::Exists(m_dirname + _T('/') + de->d_name) )
145 {
146 // it's a dir, and we don't want it
147 continue;
148 }
149
150 // finally, check the name
151 if ( !m_filespec )
152 {
153 matches = m_flags & wxDIR_HIDDEN ? TRUE : de->d_name[0] != '.';
154 }
155 else
156 {
157 // test against the pattern
158 matches = wxMatchWild(m_filespec, de->d_name,
159 !(m_flags & wxDIR_HIDDEN));
160 }
161 }
162
163 *filename = de->d_name;
164
165 return TRUE;
166 }
167
168 #else // old VMS (TODO)
169
170 wxDirData::wxDirData(const wxString& WXUNUSED(dirname))
171 {
172 wxFAIL_MSG(_T("not implemented"));
173 }
174
175 wxDirData::~wxDirData()
176 {
177 }
178
179 bool wxDirData::Read(wxString * WXUNUSED(filename))
180 {
181 return FALSE;
182 }
183
184 #endif // not or new VMS/old VMS
185
186 // ----------------------------------------------------------------------------
187 // wxDir helpers
188 // ----------------------------------------------------------------------------
189
190 /* static */
191 bool wxDir::Exists(const wxString& dir)
192 {
193 return wxPathExists(dir);
194 }
195
196 // ----------------------------------------------------------------------------
197 // wxDir construction/destruction
198 // ----------------------------------------------------------------------------
199
200 wxDir::wxDir(const wxString& dirname)
201 {
202 m_data = NULL;
203
204 (void)Open(dirname);
205 }
206
207 bool wxDir::Open(const wxString& dirname)
208 {
209 delete M_DIR;
210 m_data = new wxDirData(dirname);
211
212 if ( !M_DIR->IsOk() )
213 {
214 wxLogSysError(_("Can not enumerate files in directory '%s'"),
215 dirname.c_str());
216
217 delete M_DIR;
218 m_data = NULL;
219
220 return FALSE;
221 }
222
223 return TRUE;
224 }
225
226 bool wxDir::IsOpened() const
227 {
228 return m_data != NULL;
229 }
230
231 wxDir::~wxDir()
232 {
233 delete M_DIR;
234 }
235
236 // ----------------------------------------------------------------------------
237 // wxDir enumerating
238 // ----------------------------------------------------------------------------
239
240 bool wxDir::GetFirst(wxString *filename,
241 const wxString& filespec,
242 int flags) const
243 {
244 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
245
246 M_DIR->Rewind();
247
248 M_DIR->SetFileSpec(filespec);
249 M_DIR->SetFlags(flags);
250
251 return GetNext(filename);
252 }
253
254 bool wxDir::GetNext(wxString *filename) const
255 {
256 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
257
258 wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
259
260 return M_DIR->Read(filename);
261 }