]> git.saurik.com Git - wxWidgets.git/blame - src/os2/dir.cpp
corrected path splitting for mac relative paths
[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>
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
bd1a6768 28 #include "wx/os2/private.h"
6ef85b1b
SN
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
6f38c86f 38#define INCL_DOSFILEMGR
19193a2c 39#define INCL_DOSERRORS
6f38c86f
DW
40#include <os2.h>
41
6ef85b1b
SN
42#ifdef __EMX__
43#include <dirent.h>
6ef85b1b
SN
44#endif
45
6f38c86f
DW
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
6ef85b1b
SN
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:
6f38c86f 159 wxDirData(const wxString& rsDirname);
6ef85b1b
SN
160 ~wxDirData();
161
6f38c86f
DW
162 void SetFileSpec(const wxString& rsFilespec) { m_sFilespec = rsFilespec; }
163 void SetFlags(int nFlags) { m_nFlags = nFlags; }
6ef85b1b 164
29d83fc1 165 const wxString& GetName() const { return m_sDirname; }
6f38c86f
DW
166 void Close();
167 void Rewind();
168 bool Read(wxString* rsFilename);
6ef85b1b
SN
169
170private:
6f38c86f
DW
171 FIND_DATA m_vFinddata;
172 wxString m_sDirname;
173 wxString m_sFilespec;
174 int m_nFlags;
175}; // end of CLASS wxDirData
6ef85b1b
SN
176
177// ============================================================================
178// implementation
179// ============================================================================
180
181// ----------------------------------------------------------------------------
182// wxDirData
183// ----------------------------------------------------------------------------
184
6f38c86f
DW
185wxDirData::wxDirData(
186 const wxString& rsDirname
187)
188: m_sDirname(rsDirname)
6ef85b1b 189{
6f38c86f
DW
190 m_vFinddata = InitFindData();
191} // end of wxDirData::wxDirData
6ef85b1b 192
6f38c86f
DW
193wxDirData::~wxDirData()
194{
195 Close();
196} // end of wxDirData::~wxDirData
6ef85b1b 197
6f38c86f
DW
198void wxDirData::Close()
199{
200 if ( IsFindDataOk(m_vFinddata) )
201 {
202 FreeFindData(m_vFinddata);
203 m_vFinddata = InitFindData();
204 }
205} // end of wxDirData::Close
6ef85b1b 206
6f38c86f
DW
207void wxDirData::Rewind()
208{
209 Close();
210} // end of wxDirData::Rewind
6ef85b1b 211
6f38c86f
DW
212bool wxDirData::Read(
213 wxString* psFilename
214)
6ef85b1b 215{
6f38c86f
DW
216 bool bFirst = FALSE;
217
218 FILEFINDBUF3 vFinddata;
219 #define PTR_TO_FINDDATA (&vFinddata)
220
221 if (!IsFindDataOk(m_vFinddata))
6ef85b1b 222 {
6f38c86f
DW
223 //
224 // Open first
225 //
226 wxString sFilespec = m_sDirname;
227
228 if ( !wxEndsWithPathSeparator(sFilespec) )
6ef85b1b 229 {
6f38c86f 230 sFilespec += _T('\\');
6ef85b1b 231 }
6f38c86f
DW
232 sFilespec += (!m_sFilespec ? _T("*.*") : m_sFilespec.c_str());
233
234 m_vFinddata = FindFirst( sFilespec
235 ,PTR_TO_FINDDATA
236 );
237 bFirst = TRUE;
6ef85b1b 238 }
6ef85b1b 239
6f38c86f
DW
240 if ( !IsFindDataOk(m_vFinddata) )
241 {
242 return FALSE;
243 }
6ef85b1b 244
6f38c86f
DW
245 const wxChar* zName;
246 FIND_ATTR vAttr;
247
248 for ( ;; )
6ef85b1b 249 {
6f38c86f
DW
250 if (bFirst)
251 {
252 bFirst = FALSE;
253 }
254 else
6ef85b1b 255 {
6f38c86f
DW
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))
6ef85b1b
SN
275 continue;
276 }
277
6f38c86f
DW
278 //
279 // Check the type now
280 //
281 if (!(m_nFlags & wxDIR_FILES) && !IsDir(vAttr))
6ef85b1b 282 {
6f38c86f
DW
283 //
284 // It's a file, but we don't want them
285 //
6ef85b1b
SN
286 continue;
287 }
6f38c86f 288 else if (!(m_nFlags & wxDIR_DIRS) && IsDir(vAttr) )
6ef85b1b 289 {
6f38c86f
DW
290 //
291 // It's a dir, and we don't want it
292 //
6ef85b1b
SN
293 continue;
294 }
295
6f38c86f
DW
296 //
297 // Finally, check whether it's a hidden file
298 //
299 if (!(m_nFlags & wxDIR_HIDDEN))
6ef85b1b 300 {
6f38c86f
DW
301 if (IsHidden(vAttr))
302 {
303 //
304 // It's a hidden file, skip it
305 //
306 continue;
307 }
6ef85b1b 308 }
6f38c86f
DW
309 *psFilename = zName;
310 break;
6ef85b1b 311 }
6ef85b1b 312 return TRUE;
6f38c86f 313} // end of wxDirData::Read
6ef85b1b
SN
314
315// ----------------------------------------------------------------------------
316// wxDir helpers
317// ----------------------------------------------------------------------------
318
319/* static */
6f38c86f
DW
320bool wxDir::Exists(
321 const wxString& rsDir
322)
6ef85b1b 323{
6f38c86f
DW
324 return wxPathExists(rsDir);
325} // end of wxDir::Exists
6ef85b1b
SN
326
327// ----------------------------------------------------------------------------
328// wxDir construction/destruction
329// ----------------------------------------------------------------------------
330
6f38c86f
DW
331wxDir::wxDir(
332 const wxString& rsDirname
333)
6ef85b1b
SN
334{
335 m_data = NULL;
336
6f38c86f
DW
337 (void)Open(rsDirname);
338} // end of wxDir::wxDir
6ef85b1b 339
6f38c86f
DW
340bool wxDir::Open(
341 const wxString& rsDirname
342)
6ef85b1b
SN
343{
344 delete M_DIR;
6f38c86f 345 m_data = new wxDirData(rsDirname);
6ef85b1b 346 return TRUE;
6f38c86f 347} // end of wxDir::Open
6ef85b1b
SN
348
349bool wxDir::IsOpened() const
350{
351 return m_data != NULL;
6f38c86f 352} // end of wxDir::IsOpen
6ef85b1b 353
29d83fc1
DW
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
6ef85b1b
SN
376wxDir::~wxDir()
377{
378 delete M_DIR;
6f38c86f 379} // end of wxDir::~wxDir
6ef85b1b
SN
380
381// ----------------------------------------------------------------------------
382// wxDir enumerating
383// ----------------------------------------------------------------------------
384
6f38c86f
DW
385bool wxDir::GetFirst(
386 wxString* psFilename
387, const wxString& rsFilespec
388, int nFlags
389) const
6ef85b1b
SN
390{
391 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
6ef85b1b 392 M_DIR->Rewind();
6f38c86f
DW
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
6ef85b1b
SN
401{
402 wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
6f38c86f
DW
403 wxCHECK_MSG( psFilename, FALSE, _T("bad pointer in wxDir::GetNext()") );
404 return M_DIR->Read(psFilename);
405} // end of wxDir::GetNext
6ef85b1b 406