]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/dir.cpp
Don't do the wx cleanup if wxPython didn't do the initialization.
[wxWidgets.git] / src / os2 / dir.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: os2/dir.cpp
3// Purpose: wxDir implementation for OS/2
4// Author: Vadim Zeitlin
5// Modified by: Stefan Neis
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#ifndef WX_PRECOMP
28 #include "wx/os2/private.h"
29 #include "wx/intl.h"
30 #include "wx/log.h"
31#endif // PCH
32
33#include "wx/dir.h"
34#include "wx/filefn.h" // for wxMatchWild
35
36#include <sys/types.h>
37
38#define INCL_DOSFILEMGR
39#define INCL_DOSERRORS
40#include <os2.h>
41
42#ifdef __EMX__
43#include <dirent.h>
44#endif
45
46// ----------------------------------------------------------------------------
47// define the types and functions used for file searching
48// ----------------------------------------------------------------------------
49
50typedef FILEFINDBUF3 FIND_STRUCT;
51typedef HDIR FIND_DATA;
52typedef ULONG FIND_ATTR;
53
54static inline FIND_DATA InitFindData() { return ERROR_INVALID_HANDLE; }
55
56static inline bool IsFindDataOk(
57 FIND_DATA vFd
58)
59{
60 return vFd != ERROR_INVALID_HANDLE;
61}
62
63static inline void FreeFindData(
64 FIND_DATA vFd
65)
66{
67 if (!::DosFindClose(vFd))
68 {
69 wxLogLastError(_T("DosFindClose"));
70 }
71}
72
73static inline FIND_DATA FindFirst(
74 const wxString& rsSpec
75, FIND_STRUCT* pFinddata
76)
77{
78 ULONG ulFindCount = 1;
79 FIND_DATA hDir;
80 FIND_ATTR rc;
81
82 rc = ::DosFindFirst( rsSpec.c_str()
83 ,&hDir
84 ,FILE_NORMAL
85 ,pFinddata
86 ,sizeof(FILEFINDBUF3)
87 ,&ulFindCount
88 ,FIL_STANDARD
89 );
90 if (rc != 0)
91 return 0;
92 return hDir;
93}
94
95static inline bool FindNext(
96 FIND_DATA vFd
97, FIND_STRUCT* pFinddata
98)
99{
100 ULONG ulFindCount = 1;
101
102 return ::DosFindNext( vFd
103 ,pFinddata
104 ,sizeof(FILEFINDBUF3)
105 ,&ulFindCount
106 ) != 0;
107}
108
109static const wxChar* GetNameFromFindData(
110 FIND_STRUCT* pFinddata
111)
112{
113 return pFinddata->achName;
114}
115
116static const FIND_ATTR GetAttrFromFindData(
117 FIND_STRUCT* pFinddata
118)
119{
120 return pFinddata->attrFile;
121}
122
123static inline bool IsDir(
124 FIND_ATTR vAttr
125)
126{
127 return (vAttr & FILE_DIRECTORY) != 0;
128}
129
130static inline bool IsHidden(
131 FIND_ATTR vAttr
132)
133{
134 return (vAttr & (FILE_HIDDEN | FILE_SYSTEM)) != 0;
135}
136
137// ----------------------------------------------------------------------------
138// constants
139// ----------------------------------------------------------------------------
140
141#ifndef MAX_PATH
142 #define MAX_PATH 260 // from PM++ headers
143#endif
144
145// ----------------------------------------------------------------------------
146// macros
147// ----------------------------------------------------------------------------
148
149#define M_DIR ((wxDirData *)m_data)
150
151// ----------------------------------------------------------------------------
152// private classes
153// ----------------------------------------------------------------------------
154
155// this class stores everything we need to enumerate the files
156class wxDirData
157{
158public:
159 wxDirData(const wxString& rsDirname);
160 ~wxDirData();
161
162 void SetFileSpec(const wxString& rsFilespec) { m_sFilespec = rsFilespec; }
163 void SetFlags(int nFlags) { m_nFlags = nFlags; }
164
165 const wxString& GetName() const { return m_sDirname; }
166 void Close();
167 void Rewind();
168 bool Read(wxString* rsFilename);
169
170private:
171 FIND_DATA m_vFinddata;
172 wxString m_sDirname;
173 wxString m_sFilespec;
174 int m_nFlags;
175}; // end of CLASS wxDirData
176
177// ============================================================================
178// implementation
179// ============================================================================
180
181// ----------------------------------------------------------------------------
182// wxDirData
183// ----------------------------------------------------------------------------
184
185wxDirData::wxDirData(
186 const wxString& rsDirname
187)
188: m_sDirname(rsDirname)
189{
190 m_vFinddata = InitFindData();
191} // end of wxDirData::wxDirData
192
193wxDirData::~wxDirData()
194{
195 Close();
196} // end of wxDirData::~wxDirData
197
198void wxDirData::Close()
199{
200 if ( IsFindDataOk(m_vFinddata) )
201 {
202 FreeFindData(m_vFinddata);
203 m_vFinddata = InitFindData();
204 }
205} // end of wxDirData::Close
206
207void wxDirData::Rewind()
208{
209 Close();
210} // end of wxDirData::Rewind
211
212bool wxDirData::Read(
213 wxString* psFilename
214)
215{
216 bool bFirst = FALSE;
217
218 FILEFINDBUF3 vFinddata;
219 #define PTR_TO_FINDDATA (&vFinddata)
220
221 if (!IsFindDataOk(m_vFinddata))
222 {
223 //
224 // Open first
225 //
226 wxString sFilespec = m_sDirname;
227
228 if ( !wxEndsWithPathSeparator(sFilespec) )
229 {
230 sFilespec += _T('\\');
231 }
232 sFilespec += (!m_sFilespec ? _T("*.*") : m_sFilespec.c_str());
233
234 m_vFinddata = FindFirst( sFilespec
235 ,PTR_TO_FINDDATA
236 );
237 bFirst = TRUE;
238 }
239
240 if ( !IsFindDataOk(m_vFinddata) )
241 {
242 return FALSE;
243 }
244
245 const wxChar* zName;
246 FIND_ATTR vAttr;
247
248 for ( ;; )
249 {
250 if (bFirst)
251 {
252 bFirst = FALSE;
253 }
254 else
255 {
256 if (!FindNext( m_vFinddata
257 ,PTR_TO_FINDDATA
258 ))
259 {
260 return FALSE;
261 }
262 }
263
264 zName = GetNameFromFindData(PTR_TO_FINDDATA);
265 vAttr = GetAttrFromFindData(PTR_TO_FINDDATA);
266
267 //
268 // Don't return "." and ".." unless asked for
269 //
270 if ( zName[0] == _T('.') &&
271 ((zName[1] == _T('.') && zName[2] == _T('\0')) ||
272 (zName[1] == _T('\0'))) )
273 {
274 if (!(m_nFlags & wxDIR_DOTDOT))
275 continue;
276 }
277
278 //
279 // Check the type now
280 //
281 if (!(m_nFlags & wxDIR_FILES) && !IsDir(vAttr))
282 {
283 //
284 // It's a file, but we don't want them
285 //
286 continue;
287 }
288 else if (!(m_nFlags & wxDIR_DIRS) && IsDir(vAttr) )
289 {
290 //
291 // It's a dir, and we don't want it
292 //
293 continue;
294 }
295
296 //
297 // Finally, check whether it's a hidden file
298 //
299 if (!(m_nFlags & wxDIR_HIDDEN))
300 {
301 if (IsHidden(vAttr))
302 {
303 //
304 // It's a hidden file, skip it
305 //
306 continue;
307 }
308 }
309 *psFilename = zName;
310 break;
311 }
312 return TRUE;
313} // end of wxDirData::Read
314
315// ----------------------------------------------------------------------------
316// wxDir helpers
317// ----------------------------------------------------------------------------
318
319/* static */
320bool wxDir::Exists(
321 const wxString& rsDir
322)
323{
324 return wxPathExists(rsDir);
325} // end of wxDir::Exists
326
327// ----------------------------------------------------------------------------
328// wxDir construction/destruction
329// ----------------------------------------------------------------------------
330
331wxDir::wxDir(
332 const wxString& rsDirname
333)
334{
335 m_data = NULL;
336
337 (void)Open(rsDirname);
338} // end of wxDir::wxDir
339
340bool wxDir::Open(
341 const wxString& rsDirname
342)
343{
344 delete M_DIR;
345 m_data = new wxDirData(rsDirname);
346 return TRUE;
347} // end of wxDir::Open
348
349bool wxDir::IsOpened() const
350{
351 return m_data != NULL;
352} // end of wxDir::IsOpen
353
354wxString wxDir::GetName() const
355{
356 wxString name;
357 if ( m_data )
358 {
359 name = M_DIR->GetName();
360 if ( !name.empty() )
361 {
362 // bring to canonical Windows form
363 name.Replace(_T("/"), _T("\\"));
364
365 if ( name.Last() == _T('\\') )
366 {
367 // chop off the last (back)slash
368 name.Truncate(name.length() - 1);
369 }
370 }
371 }
372
373 return name;
374}
375
376wxDir::~wxDir()
377{
378 delete M_DIR;
379} // end of wxDir::~wxDir
380
381// ----------------------------------------------------------------------------
382// wxDir enumerating
383// ----------------------------------------------------------------------------
384
385bool wxDir::GetFirst(
386 wxString* psFilename
387, const wxString& rsFilespec
388, int nFlags
389) const
390{
391 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
392 M_DIR->Rewind();
393 M_DIR->SetFileSpec(rsFilespec);
394 M_DIR->SetFlags(nFlags);
395 return GetNext(psFilename);
396} // end of wxDir::GetFirst
397
398bool wxDir::GetNext(
399 wxString* psFilename
400) const
401{
402 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
403 wxCHECK_MSG( psFilename, FALSE, _T("bad pointer in wxDir::GetNext()") );
404 return M_DIR->Read(psFilename);
405} // end of wxDir::GetNext
406