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