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