--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/dir.h
+// Purpose: wxDir is a class for enumerating the files in a directory
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 08.12.99
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_DIR_H_
+#define _WX_DIR_H_
+
+#ifdef __GNUG__
+ #pragma interface "dir.h"
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// these flags define what kind of filenames is included in the list of files
+// enumerated by GetFirst/GetNext
+enum
+{
+ wxDIR_FILES = 0x0001, // include files
+ wxDIR_DIRS = 0x0002, // include directories
+ wxDIR_HIDDEN = 0x0004, // include hidden files
+ wxDIR_DOTDOT = 0x0008, // include '.' and '..'
+
+ // by default, enumerate everything except '.' and '..'
+ wxDIR_DEFAULT = wxDIR_FILES | wxDIR_DIRS | wxDIR_HIDDEN
+};
+
+// ----------------------------------------------------------------------------
+// wxDir: portable equivalent of {open/read/close}dir functions
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxDir
+{
+public:
+ // test for existence of a directory with the given name
+ static bool Exists(const wxString& dir);
+
+ // ctors
+ // -----
+
+ // default, use Open()
+ wxDir() { m_data = NULL; }
+
+ // opens the directory for enumeration, use IsOpened() to test success
+ wxDir(const wxString& dir);
+
+ // dtor cleans up the associated ressources
+ ~wxDir();
+
+ // open the directory for enumerating
+ bool Open(const wxString& dir);
+
+ // returns TRUE if the directory was successfully opened
+ bool IsOpened() const;
+
+ // file enumeration routines
+ // -------------------------
+
+ // start enumerating all files matching filespec (or all files if it is
+ // empty) and flags, return TRUE on success
+ bool GetFirst(wxString *filename,
+ const wxString& filespec = wxEmptyString,
+ int flags = wxDIR_DEFAULT) const;
+
+ // get next file in the enumeration started with either GetFirst() or
+ // GetFirstNormal()
+ bool GetNext(wxString *filename) const;
+
+ // TODO using scandir() when available later, emulating it otherwise
+#if 0
+ // get all files in the directory into an array, return TRUE on success
+ //
+ // this function uses Select() function to select the files
+ // unless the filespec is explicitly given and Compare() function to sort
+ // them
+ bool Read(wxArrayString& filenames,
+ const wxString& filespec = wxEmptyString) const;
+
+protected:
+ // this function is called by Read() if filespec is not specified in
+ // Read(): it should return TRUE if the file matches our selection
+ // criteria and FALSE otherwise
+ virtual bool Select(const wxChar* filename);
+
+ // This function is called by Read() to sort the array: it should return
+ // -1, 0 or +1 if the first file is less than, equal to or greater than
+ // the second. The base class version does
+ virtual int Compare(const wxChar *filename1, const wxChar *filename2);
+#endif // 0
+
+private:
+ friend class WXDLLEXPORT wxDirData;
+
+ wxDirData *m_data;
+};
+
+#endif // _WX_DIR_H_
// what to test?
//#define TEST_ARRAYS
+#define TEST_DIR
//#define TEST_LOG
-#define TEST_MIME
+//#define TEST_MIME
//#define TEST_STRINGS
//#define TEST_THREADS
//#define TEST_TIME
// implementation
// ============================================================================
+// ----------------------------------------------------------------------------
+// wxDir
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_DIR
+
+#include <wx/dir.h>
+
+static void TestDirEnumHelper(wxDir& dir,
+ int flags = wxDIR_DEFAULT,
+ const wxString& filespec = wxEmptyString)
+{
+ wxString filename;
+
+ if ( !dir.IsOpened() )
+ return;
+
+ bool cont = dir.GetFirst(&filename, filespec, flags);
+ while ( cont )
+ {
+ printf("\t%s\n", filename.c_str());
+
+ cont = dir.GetNext(&filename);
+ }
+
+ puts("");
+}
+
+static void TestDirEnum()
+{
+ wxDir dir(wxGetCwd());
+
+ puts("Enumerating everything in current directory:");
+ TestDirEnumHelper(dir);
+
+ puts("Enumerating really everything in current directory:");
+ TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
+
+ puts("Enumerating object files in current directory:");
+ TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o");
+
+ puts("Enumerating directories in current directory:");
+ TestDirEnumHelper(dir, wxDIR_DIRS);
+
+ puts("Enumerating files in current directory:");
+ TestDirEnumHelper(dir, wxDIR_FILES);
+
+ puts("Enumerating files including hidden in current directory:");
+ TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
+
+#ifdef __UNIX__
+ dir.Open("/");
+#elif defined(__WXMSW__)
+ dir.Open("c:\\");
+#else
+ #error "don't know where the root directory is"
+#endif
+
+ puts("Enumerating everything in root directory:");
+ TestDirEnumHelper(dir, wxDIR_DEFAULT);
+
+ puts("Enumerating directories in root directory:");
+ TestDirEnumHelper(dir, wxDIR_DIRS);
+
+ puts("Enumerating files in root directory:");
+ TestDirEnumHelper(dir, wxDIR_FILES);
+
+ puts("Enumerating files including hidden in root directory:");
+ TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
+
+ puts("Enumerating files in non existing directory:");
+ wxDir dirNo("nosuchdir");
+ TestDirEnumHelper(dirNo);
+}
+
+#endif // TEST_DIR
+
// ----------------------------------------------------------------------------
// MIME types
// ----------------------------------------------------------------------------
PrintArray("a3", a3);
#endif // TEST_ARRAYS
+#ifdef TEST_DIR
+ TestDirEnum();
+#endif // TEST_DIR
+
#ifdef TEST_LOG
wxString s;
for ( size_t n = 0; n < 8000; n++ )
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: msw/dir.cpp
+// Purpose: wxDir implementation for Win32
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 08.12.99
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "dir.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/intl.h"
+ #include "wx/log.h"
+#endif // PCH
+
+#include "wx/dir.h"
+#include "wx/filefn.h" // for wxPathExists()
+
+#include <windows.h>
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+#ifndef MAX_PATH
+ #define MAX_PATH 260 // from VC++ headers
+#endif
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+#define M_DIR ((wxDirData *)m_data)
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+// this class stores everything we need to enumerate the files
+class wxDirData
+{
+public:
+ wxDirData(const wxString& dirname);
+ ~wxDirData();
+
+ void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
+ void SetFlags(int flags) { m_flags = flags; }
+
+ void Close();
+ void Rewind();
+ bool Read(wxString *filename);
+
+private:
+ HANDLE m_handle;
+
+ wxString m_dirname;
+ wxString m_filespec;
+
+ int m_flags;
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxDirData
+// ----------------------------------------------------------------------------
+
+wxDirData::wxDirData(const wxString& dirname)
+ : m_dirname(dirname)
+{
+ m_handle = INVALID_HANDLE_VALUE;
+
+ // throw away the trailing slashes
+ size_t n = m_dirname.length();
+ wxCHECK_RET( n, _T("empty dir name in wxDir") );
+
+ while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) )
+ ;
+
+ m_dirname.Truncate(n + 1);
+}
+
+wxDirData::~wxDirData()
+{
+ Close();
+}
+
+void wxDirData::Close()
+{
+ if ( m_handle != INVALID_HANDLE_VALUE )
+ {
+ if ( !::FindClose(m_handle) )
+ {
+ wxLogLastError(_T("FindClose"));
+ }
+ }
+}
+
+void wxDirData::Rewind()
+{
+ Close();
+}
+
+bool wxDirData::Read(wxString *filename)
+{
+ bool first = FALSE;
+
+ WIN32_FIND_DATA finddata;
+ if ( m_handle == INVALID_HANDLE_VALUE )
+ {
+ // open first
+ m_handle = ::FindFirstFile(!m_filespec ? _T("*.*") : m_filespec.c_str(),
+ &finddata);
+
+ first = TRUE;
+ }
+
+ if ( m_handle == INVALID_HANDLE_VALUE )
+ {
+ DWORD err = ::GetLastError();
+
+ if ( err != ERROR_NO_MORE_FILES )
+ {
+ wxLogSysError(err, _("Can not enumerate files in directory '%s'"),
+ m_dirname.c_str());
+ }
+ //else: not an error, just no (such) files
+
+ return FALSE;
+ }
+
+ bool matches = FALSE;
+
+ const wxChar *name;
+ DWORD attr;
+
+ while ( !matches )
+ {
+ if ( first )
+ {
+ first = FALSE;
+ }
+ else
+ {
+ if ( !::FindNextFile(m_handle, &finddata) )
+ {
+ DWORD err = ::GetLastError();
+
+ if ( err != ERROR_NO_MORE_FILES )
+ {
+ wxLogLastError(_T("FindNext"));
+ }
+ //else: not an error, just no more (such) files
+
+ return FALSE;
+ }
+ }
+
+ name = finddata.cFileName;
+ attr = finddata.dwFileAttributes;
+
+ // don't return "." and ".." unless asked for
+ if ( name[0] == _T('.') &&
+ ((name[1] == _T('.') && name[2] == _T('\0')) ||
+ (name[1] == _T('\0'))) )
+ {
+ if ( !(m_flags & wxDIR_DOTDOT) )
+ continue;
+ }
+
+ // check the type now
+ if ( !(m_flags & wxDIR_FILES) && !(attr & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ // it's a file, but we don't want them
+ continue;
+ }
+ else if ( !(m_flags & wxDIR_DIRS) && (attr & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ // it's a dir, and we don't want it
+ continue;
+ }
+
+ // finally, check whether it's a hidden file
+ if ( !(m_flags & wxDIR_HIDDEN) )
+ {
+ matches = !(attr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM));
+ }
+ }
+
+ *filename = name;
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// wxDir helpers
+// ----------------------------------------------------------------------------
+
+/* static */
+bool wxDir::Exists(const wxString& dir)
+{
+ return wxPathExists(dir);
+}
+
+// ----------------------------------------------------------------------------
+// wxDir construction/destruction
+// ----------------------------------------------------------------------------
+
+wxDir::wxDir(const wxString& dirname)
+{
+ m_data = NULL;
+
+ (void)Open(dirname);
+}
+
+bool wxDir::Open(const wxString& dirname)
+{
+ delete M_DIR;
+ m_data = new wxDirData(dirname);
+
+ return TRUE;
+}
+
+bool wxDir::IsOpened() const
+{
+ return m_data != NULL;
+}
+
+wxDir::~wxDir()
+{
+ delete M_DIR;
+}
+
+// ----------------------------------------------------------------------------
+// wxDir enumerating
+// ----------------------------------------------------------------------------
+
+bool wxDir::GetFirst(wxString *filename,
+ const wxString& filespec,
+ int flags) const
+{
+ wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+
+ M_DIR->Rewind();
+
+ M_DIR->SetFileSpec(filespec);
+ M_DIR->SetFlags(flags);
+
+ return GetNext(filename);
+}
+
+bool wxDir::GetNext(wxString *filename) const
+{
+ wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+
+ wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
+
+ return M_DIR->Read(filename);
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: unix/dir.cpp
+// Purpose: wxDir implementation for Unix/POSIX systems
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 08.12.99
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "dir.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/intl.h"
+ #include "wx/log.h"
+#endif // PCH
+
+#include "wx/dir.h"
+#include "wx/filefn.h" // for wxMatchWild
+
+#include <sys/types.h>
+
+#include <dirent.h>
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+#define M_DIR ((wxDirData *)m_data)
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+// this class stores everything we need to enumerate the files
+class wxDirData
+{
+public:
+ wxDirData(const wxString& dirname);
+ ~wxDirData();
+
+ bool IsOk() const { return m_dir != NULL; }
+
+ void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
+ void SetFlags(int flags) { m_flags = flags; }
+
+ void Rewind() { rewinddir(m_dir); }
+ bool Read(wxString *filename);
+
+private:
+ DIR *m_dir;
+
+ wxString m_dirname;
+ wxString m_filespec;
+
+ int m_flags;
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxDirData
+// ----------------------------------------------------------------------------
+
+#if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
+
+wxDirData::wxDirData(const wxString& dirname)
+ : m_dirname(dirname)
+{
+ m_dir = NULL;
+
+ // throw away the trailing slashes
+ size_t n = m_dirname.length();
+ wxCHECK_RET( n, _T("empty dir name in wxDir") );
+
+ while ( n > 0 && m_dirname[--n] == '/' )
+ ;
+
+ m_dirname.Truncate(n + 1);
+
+ // do open the dir
+ m_dir = opendir(m_dirname.fn_str());
+}
+
+wxDirData::~wxDirData()
+{
+ if ( m_dir )
+ {
+ if ( closedir(m_dir) != 0 )
+ {
+ wxLogLastError(_T("closedir"));
+ }
+ }
+}
+
+bool wxDirData::Read(wxString *filename)
+{
+ dirent *de;
+ bool matches = FALSE;
+
+ while ( !matches )
+ {
+ de = readdir(m_dir);
+ if ( !de )
+ return FALSE;
+
+ // don't return "." and ".." unless asked for
+ if ( de->d_name[0] == '.' &&
+ ((de->d_name[1] == '.' && de->d_name[2] == '\0') ||
+ (de->d_name[1] == '\0')) )
+ {
+ if ( !(m_flags & wxDIR_DOTDOT) )
+ continue;
+ }
+
+ // check the type now
+ if ( !(m_flags & wxDIR_FILES) &&
+ !wxDir::Exists(m_dirname + _T('/') + de->d_name) )
+ {
+ // it's a file, but we don't want them
+ continue;
+ }
+ else if ( !(m_flags & wxDIR_DIRS) &&
+ wxDir::Exists(m_dirname + _T('/') + de->d_name) )
+ {
+ // it's a dir, and we don't want it
+ continue;
+ }
+
+ // finally, check the name
+ if ( !m_filespec )
+ {
+ matches = m_flags & wxDIR_HIDDEN ? TRUE : de->d_name[0] != '.';
+ }
+ else
+ {
+ // test against the pattern
+ matches = wxMatchWild(m_filespec, de->d_name,
+ !(m_flags & wxDIR_HIDDEN));
+ }
+ }
+
+ *filename = de->d_name;
+
+ return TRUE;
+}
+
+#else // old VMS (TODO)
+
+wxDirData::wxDirData(const wxString& WXUNUSED(dirname))
+{
+ wxFAIL_MSG(_T("not implemented"));
+}
+
+wxDirData::~wxDirData()
+{
+}
+
+bool wxDirData::Read(wxString * WXUNUSED(filename))
+{
+ return FALSE;
+}
+
+#endif // not or new VMS/old VMS
+
+// ----------------------------------------------------------------------------
+// wxDir helpers
+// ----------------------------------------------------------------------------
+
+/* static */
+bool wxDir::Exists(const wxString& dir)
+{
+ return wxPathExists(dir);
+}
+
+// ----------------------------------------------------------------------------
+// wxDir construction/destruction
+// ----------------------------------------------------------------------------
+
+wxDir::wxDir(const wxString& dirname)
+{
+ m_data = NULL;
+
+ (void)Open(dirname);
+}
+
+bool wxDir::Open(const wxString& dirname)
+{
+ delete M_DIR;
+ m_data = new wxDirData(dirname);
+
+ if ( !M_DIR->IsOk() )
+ {
+ wxLogSysError(_("Can not enumerate files in directory '%s'"),
+ dirname.c_str());
+
+ delete M_DIR;
+ m_data = NULL;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool wxDir::IsOpened() const
+{
+ return m_data != NULL;
+}
+
+wxDir::~wxDir()
+{
+ delete M_DIR;
+}
+
+// ----------------------------------------------------------------------------
+// wxDir enumerating
+// ----------------------------------------------------------------------------
+
+bool wxDir::GetFirst(wxString *filename,
+ const wxString& filespec,
+ int flags) const
+{
+ wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+
+ M_DIR->Rewind();
+
+ M_DIR->SetFileSpec(filespec);
+ M_DIR->SetFlags(flags);
+
+ return GetNext(filename);
+}
+
+bool wxDir::GetNext(wxString *filename) const
+{
+ wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+
+ wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
+
+ return M_DIR->Read(filename);
+}