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