#include "wx/intl.h"
#include "wx/file.h"
#include "wx/filename.h"
+#include "wx/dir.h"
// there are just too many of those...
#ifdef __VISUALC__
#endif
#endif
+#if defined(__WXMAC__)
+ #include "wx/mac/private.h" // includes mac headers
+#endif
+
#include <time.h>
#ifndef __MWERKS__
#include <process.h>
#include "wx/os2/private.h"
#endif
-#ifdef __WINDOWS__
+#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
#if !defined( __GNUWIN32__ ) && !defined( __MWERKS__ ) && !defined(__SALFORDC__)
#include <direct.h>
#include <dos.h>
#endif // __WINDOWS__
#endif // native Win compiler
+#if defined(__DOS__)
+ #ifdef __WATCOMC__
+ #include <direct.h>
+ #include <dos.h>
+ #include <io.h>
+ #endif
+ #ifdef __DJGPP__
+ #include <unistd.h>
+ #endif
+#endif
+
#ifdef __GNUWIN32__
#include <wchar.h>
#ifndef __TWIN32__
bool
wxFileExists (const wxString& filename)
{
-#ifdef __WINDOWS__
+#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
// GetFileAttributes can copy with network paths
DWORD ret = GetFileAttributes(filename);
DWORD isDir = (ret & FILE_ATTRIBUTE_DIRECTORY);
// assume mkdir() has 2 args on non Windows-OS/2 platforms and on Windows too
// for the GNU compiler
-#if (!(defined(__WXMSW__) || defined(__WXPM__))) || (defined(__GNUWIN32__) && !defined(__MINGW32__)) || defined(__WXWINE__) || defined(__WXMICROWIN__)
+#if (!(defined(__WXMSW__) || defined(__WXPM__) || defined(__DOS__))) || (defined(__GNUWIN32__) && !defined(__MINGW32__)) || defined(__WXWINE__) || defined(__WXMICROWIN__)
if ( mkdir(wxFNCONV(dirname), perm) != 0 )
#elif defined(__WXPM__)
if (::DosCreateDir((PSZ)dirname, NULL) != 0) // enhance for EAB's??
-#else // !MSW and !OS/2 VAC++
+#elif defined(__DOS__)
+ #if defined(__WATCOMC__)
+ (void)perm;
+ if ( wxMkDir(wxFNSTRINGCAST wxFNCONV(dirname)) != 0 )
+ #elif defined(__DJGPP__)
+ if ( mkdir(wxFNCONV(dirname), perm) != 0 )
+ #else
+ #error "Unsupported DOS compiler!"
+ #endif
+#else // !MSW, !DOS and !OS/2 VAC++
(void)perm;
if ( wxMkDir(wxFNSTRINGCAST wxFNCONV(dirname)) != 0 )
#endif // !MSW/MSW
}
#endif // __WINDOWS__
-#ifdef __WINDOWS__
+#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
// Stat can't cope with network paths
DWORD ret = GetFileAttributes(strPath.c_str());
DWORD isDir = (ret & FILE_ATTRIBUTE_DIRECTORY);
// Get a temporary filename, opening and closing the file.
wxChar *wxGetTempFileName(const wxString& prefix, wxChar *buf)
{
-#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
-
-#ifndef __WIN32__
- wxChar tmp[144];
- ::GetTempFileName(0, WXSTRINGCAST prefix, 0, tmp);
-#else
- wxChar tmp[MAX_PATH];
- wxChar tmpPath[MAX_PATH];
- ::GetTempPath(MAX_PATH, tmpPath);
- ::GetTempFileName(tmpPath, WXSTRINGCAST prefix, 0, tmp);
-#endif
- if (buf) wxStrcpy(buf, tmp);
- else buf = copystring(tmp);
- return buf;
+ wxString filename = wxFileName::CreateTempFileName(prefix);
+ if ( filename.empty() )
+ return NULL;
-#else
- static short last_temp = 0; // cache last to speed things a bit
- // At most 1000 temp files to a process! We use a ring count.
- wxChar tmp[100]; // FIXME static buffer
+ if ( buf )
+ wxStrcpy(buf, filename);
+ else
+ buf = copystring(filename);
- for (short suffix = last_temp + 1; suffix != last_temp; ++suffix %= 1000)
- {
- wxSprintf (tmp, wxT("/tmp/%s%d.%03x"), WXSTRINGCAST prefix, (int) getpid (), (int) suffix);
- if (!wxFileExists( tmp ))
- {
- // Touch the file to create it (reserve name)
- FILE *fd = fopen (wxFNCONV(tmp), "w");
- if (fd)
- fclose (fd);
- last_temp = suffix;
- if (buf)
- wxStrcpy( buf, tmp);
- else
- buf = copystring( tmp );
- return buf;
- }
- }
- wxLogError( _("wxWindows: error finding temporary file name.\n") );
- if (buf) buf[0] = 0;
- return (wxChar *) NULL;
-#endif
+ return buf;
}
bool wxGetTempFileName(const wxString& prefix, wxString& buf)
{
- wxChar buf2[512];
- if (wxGetTempFileName(prefix, buf2) != (wxChar*) NULL)
- {
- buf = buf2;
- return TRUE;
- }
- else
- return FALSE;
+ buf = wxFileName::CreateTempFileName(prefix);
+
+ return !buf.empty();
}
// Get first file name matching given wild card.
-#if defined(__UNIX__)
-
-// Get first file name matching given wild card.
-// Flags are reserved for future use.
-
-#if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
- static DIR *gs_dirStream = (DIR *) NULL;
- static wxString gs_strFileSpec;
- static int gs_findFlags = 0;
-#endif
+static wxDir *gs_dir = NULL;
+static wxString gs_dirPath;
wxString wxFindFirstFile(const wxChar *spec, int flags)
{
- wxString result;
-#ifdef __VMS
- wxChar *specvms = NULL;
-#endif
-
-#if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
- if (gs_dirStream)
- closedir(gs_dirStream); // edz 941103: better housekeping
-
- gs_findFlags = flags;
-
- gs_strFileSpec = spec;
-
- // Find path only so we can concatenate
- // found file onto path
- wxString path(wxPathOnly(gs_strFileSpec));
-
- // special case: path is really "/"
- if ( !path && gs_strFileSpec[0u] == wxT('/') )
-#ifdef __VMS
- {
- wxStrcpy( specvms , wxT( "[000000]" ) );
- gs_strFileSpec = specvms;
- wxString path_vms(wxPathOnly(gs_strFileSpec));
- path = path_vms;
- }
-#else
- path = wxT('/');
-#endif
- // path is empty => Local directory
- if ( !path )
-#ifdef __VMS
- {
- wxStrcpy( specvms , wxT( "[]" ) );
- gs_strFileSpec = specvms;
- wxString path_vms1(wxPathOnly(gs_strFileSpec));
- path = path_vms1;
- }
-#else
- path = wxT('.');
-#endif
-
- gs_dirStream = opendir(path.fn_str());
- if ( !gs_dirStream )
- {
- wxLogSysError(_("Can not enumerate files in directory '%s'"),
- path.c_str());
- }
- else
- {
- result = wxFindNextFile();
- }
-#endif // !VMS6.x or earlier
-
- return result;
-}
-
-wxString wxFindNextFile()
-{
- wxString result;
-
-#if !defined( __VMS__ ) || ( __VMS_VER >= 70000000 )
- wxCHECK_MSG( gs_dirStream, result, wxT("must call wxFindFirstFile first") );
-
- // Find path only so we can concatenate
- // found file onto path
- wxString path(wxPathOnly(gs_strFileSpec));
- wxString name(wxFileNameFromPath(gs_strFileSpec));
-
- /* MATTHEW: special case: path is really "/" */
- if ( !path && gs_strFileSpec[0u] == wxT('/'))
- path = wxT('/');
-
- // Do the reading
- struct dirent *nextDir;
- for ( nextDir = readdir(gs_dirStream);
- nextDir != NULL;
- nextDir = readdir(gs_dirStream) )
+ gs_dirPath = wxPathOnly(spec);
+ if ( gs_dirPath.IsEmpty() )
+ gs_dirPath = wxT(".");
+ if ( gs_dirPath.Last() != wxFILE_SEP_PATH )
+ gs_dirPath << wxFILE_SEP_PATH;
+
+ if (gs_dir)
+ delete gs_dir;
+ gs_dir = new wxDir(gs_dirPath);
+
+ if ( !gs_dir->IsOpened() )
{
- if (wxMatchWild(name, nextDir->d_name, FALSE) && // RR: added FALSE to find hidden files
- strcmp(nextDir->d_name, ".") &&
- strcmp(nextDir->d_name, "..") )
- {
- result.Empty();
- if ( !path.IsEmpty() )
- {
- result = path;
- if ( path != wxT('/') )
- result += wxT('/');
- }
-
- result += nextDir->d_name;
-
- // Only return "." and ".." when they match
- bool isdir;
- if ( (strcmp(nextDir->d_name, ".") == 0) ||
- (strcmp(nextDir->d_name, "..") == 0))
- {
- if ( (gs_findFlags & wxDIR) != 0 )
- isdir = TRUE;
- else
- continue;
- }
- else
- isdir = wxDirExists(result);
-
- // and only return directories when flags & wxDIR
- if ( !gs_findFlags ||
- ((gs_findFlags & wxDIR) && isdir) ||
- ((gs_findFlags & wxFILE) && !isdir) )
- {
- return result;
- }
- }
+ wxLogSysError(_("Can not enumerate files '%s'"), spec);
+ return wxEmptyString;
}
-
- result.Empty(); // not found
-
- closedir(gs_dirStream);
- gs_dirStream = (DIR *) NULL;
-#endif // !VMS6.2 or earlier
-
- return result;
-}
-
-#elif defined(__WXMAC__)
-
-struct MacDirectoryIterator
-{
- CInfoPBRec m_CPB ;
- wxInt16 m_index ;
- long m_dirId ;
- Str255 m_name ;
-} ;
-
-static int g_iter_flags ;
-
-static MacDirectoryIterator g_iter ;
-wxString g_iter_spec ;
-
-wxString wxFindFirstFile(const wxChar *spec, int flags)
-{
- wxString result;
-
- g_iter_spec = spec ;
- g_iter_spec.MakeUpper() ;
- g_iter_flags = flags; /* MATTHEW: [5] Remember flags */
-
- // Find path only so we can concatenate found file onto path
- wxString path(wxPathOnly(spec));
- FSSpec fsspec ;
-
- wxMacFilename2FSSpec( path , &fsspec ) ;
- g_iter.m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ;
- g_iter.m_CPB.hFileInfo.ioNamePtr = g_iter.m_name ;
- g_iter.m_index = 0 ;
-
- Boolean isDir ;
- FSpGetDirectoryID( &fsspec , &g_iter.m_dirId , &isDir ) ;
- if ( !isDir )
- return wxEmptyString ;
-
- return wxFindNextFile( ) ;
-}
-
-wxString wxFindNextFile()
-{
- wxString result;
-
- short err = noErr ;
- wxString name ;
- while(1)
+ int dirFlags = 0;
+ switch (flags)
{
- while ( err == noErr )
- {
- g_iter.m_index++ ;
- g_iter.m_CPB.dirInfo.ioFDirIndex = g_iter.m_index;
- g_iter.m_CPB.dirInfo.ioDrDirID = g_iter.m_dirId; /* we need to do this every time */
- err = PBGetCatInfoSync((CInfoPBPtr)&g_iter.m_CPB);
- if ( err != noErr )
- break ;
-
- if ( ( g_iter.m_CPB.dirInfo.ioFlAttrib & ioDirMask) != 0 && (g_iter_flags & wxDIR) ) // we have a directory
- break ;
-
- if ( ( g_iter.m_CPB.dirInfo.ioFlAttrib & ioDirMask) == 0 && !(g_iter_flags & wxFILE ) )
- continue ;
-
- // hit !
- break ;
- }
- if ( err != noErr )
- {
- return wxEmptyString ;
- }
- FSSpec spec ;
-
- FSMakeFSSpecCompat(g_iter.m_CPB.hFileInfo.ioVRefNum,
- g_iter.m_dirId,
- g_iter.m_name,
- &spec) ;
-
- wxString name = wxMacFSSpec2MacFilename( &spec ) ;
- if ( g_iter_spec.Right(4)==(":*.*") || g_iter_spec.Right(2)==(":*") || name.Upper().Matches(g_iter_spec) )
- return name ;
+ case wxDIR: dirFlags = wxDIR_DIRS; break;
+ case wxFILE: dirFlags = wxDIR_FILES; break;
+ default: dirFlags = wxDIR_DIRS | wxDIR_FILES; break;
}
- return wxEmptyString ;
-}
-
-#elif defined(__WXMSW__)
-
-#ifdef __WIN32__
- static HANDLE gs_hFileStruct = INVALID_HANDLE_VALUE;
- static WIN32_FIND_DATA gs_findDataStruct;
-#else // Win16
- #ifdef __BORLANDC__
- static struct ffblk gs_findDataStruct;
- #else
- static struct _find_t gs_findDataStruct;
- #endif // Borland
-#endif // Win32/16
-
-static wxString gs_strFileSpec;
-static int gs_findFlags = 0;
-
-wxString wxFindFirstFile(const wxChar *spec, int flags)
-{
+
wxString result;
-
- gs_strFileSpec = spec;
- gs_findFlags = flags; /* MATTHEW: [5] Remember flags */
-
- // Find path only so we can concatenate found file onto path
- wxString path(wxPathOnly(gs_strFileSpec));
- if ( !path.IsEmpty() )
- result << path << wxT('\\');
-
-#ifdef __WIN32__
- if ( gs_hFileStruct != INVALID_HANDLE_VALUE )
- FindClose(gs_hFileStruct);
-
- gs_hFileStruct = ::FindFirstFile(WXSTRINGCAST spec, &gs_findDataStruct);
-
- if ( gs_hFileStruct == INVALID_HANDLE_VALUE )
+ gs_dir->GetFirst(&result, wxFileNameFromPath(spec), dirFlags);
+ if ( result.IsEmpty() )
{
- result.Empty();
-
+ wxDELETE(gs_dir);
return result;
}
- bool isdir = !!(gs_findDataStruct.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
-
- if (isdir && !(flags & wxDIR))
- return wxFindNextFile();
- else if (!isdir && flags && !(flags & wxFILE))
- return wxFindNextFile();
-
- result += gs_findDataStruct.cFileName;
-
- return result;
-#else // !Win32
- int flag = _A_NORMAL;
- if (flags & wxDIR)
- flag = _A_SUBDIR;
-
-#ifdef __BORLANDC__
- if (findfirst(WXSTRINGCAST spec, &gs_findDataStruct, flag) == 0)
-#else
- if (_dos_findfirst(WXSTRINGCAST spec, flag, &gs_findDataStruct) == 0)
-#endif
- {
- char attrib;
-
-#ifdef __BORLANDC__
- attrib = gs_findDataStruct.ff_attrib;
-#else
- attrib = gs_findDataStruct.attrib;
-#endif
-
- if (attrib & _A_SUBDIR) {
- if (!(gs_findFlags & wxDIR))
- return wxFindNextFile();
- } else if (gs_findFlags && !(gs_findFlags & wxFILE))
- return wxFindNextFile();
-
- result +=
-#ifdef __BORLANDC__
- gs_findDataStruct.ff_name
-#else
- gs_findDataStruct.name
-#endif
- ;
- }
-
- return result;
-#endif // __WIN32__
+ return gs_dirPath + result;
}
-
wxString wxFindNextFile()
{
- wxString result;
-
- // Find path only so we can concatenate found file onto path
- wxString path(wxPathOnly(gs_strFileSpec));
-
-try_again:
-
-#ifdef __WIN32__
- if (gs_hFileStruct == INVALID_HANDLE_VALUE)
- return result;
-
- bool success = (FindNextFile(gs_hFileStruct, &gs_findDataStruct) != 0);
- if (!success)
- {
- FindClose(gs_hFileStruct);
- gs_hFileStruct = INVALID_HANDLE_VALUE;
- }
- else
- {
- bool isdir = !!(gs_findDataStruct.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
-
- if (isdir && !(gs_findFlags & wxDIR))
- goto try_again;
- else if (!isdir && gs_findFlags && !(gs_findFlags & wxFILE))
- goto try_again;
-
- if ( !path.IsEmpty() )
- result << path << wxT('\\');
- result << gs_findDataStruct.cFileName;
- }
-
- return result;
-#else // Win16
-
-#ifdef __BORLANDC__
- if (findnext(&gs_findDataStruct) == 0)
-#else
- if (_dos_findnext(&gs_findDataStruct) == 0)
-#endif
- {
- /* MATTHEW: [5] Check directory flag */
- char attrib;
+ wxASSERT_MSG( gs_dir, wxT("You must call wxFindFirstFile before!") );
-#ifdef __BORLANDC__
- attrib = gs_findDataStruct.ff_attrib;
-#else
- attrib = gs_findDataStruct.attrib;
-#endif
-
- if (attrib & _A_SUBDIR) {
- if (!(gs_findFlags & wxDIR))
- goto try_again;
- } else if (gs_findFlags && !(gs_findFlags & wxFILE))
- goto try_again;
-
-
- result +=
-#ifdef __BORLANDC__
- gs_findDataStruct.ff_name
-#else
- gs_findDataStruct.name
-#endif
- ;
- }
-
- return result;
-#endif // Win32/16
-}
-
-#elif defined(__WXPM__)
-
-wxString wxFindFirstFile(const wxChar *spec, int flags)
-{
wxString result;
-
- /*
- // TODO: figure something out here for OS/2
- gs_strFileSpec = spec;
- gs_findFlags = flags;
-
- // Find path only so we can concatenate found file onto path
- wxString path(wxPathOnly(gs_strFileSpec));
- if ( !path.IsEmpty() )
- result << path << wxT('\\');
-
- int flag = _A_NORMAL;
- if (flags & wxDIR)
- flag = _A_SUBDIR;
-
- if (_dos_findfirst(WXSTRINGCAST spec, flag, &gs_findDataStruct) == 0)
+ gs_dir->GetNext(&result);
+
+ if ( result.IsEmpty() )
{
- char attrib;
- attrib = gs_findDataStruct.attrib;
-
- if (attrib & _A_SUBDIR) {
- if (!(gs_findFlags & wxDIR))
- return wxFindNextFile();
- } else if (gs_findFlags && !(gs_findFlags & wxFILE))
- return wxFindNextFile();
-
- result += gs_findDataStruct.name;
+ wxDELETE(gs_dir);
+ return result;
}
- */
- return result;
-}
-
-wxString wxFindNextFile()
-{
- wxString result;
- // TODO:
- return result;
+
+ return gs_dirPath + result;
}
-#endif // Unix/Windows/OS/2
// Get current working directory.
// If buf is NULL, allocates space using new, else
delete [] cbuf;
}
#endif
+
+#ifdef __DJGPP__
+ // VS: DJGPP is a strange mix of DOS and UNIX API and returns paths with
+ // / deliminers. We don't like that.
+ for (wxChar *ch = buf; *ch; ch++)
+ if (*ch == wxT('/')) *ch = wxT('\\');
+#endif
+
return buf;
}
bool wxSetWorkingDirectory(const wxString& d)
{
-#if defined( __UNIX__ ) || defined( __WXMAC__ )
+#if defined(__UNIX__) || defined(__WXMAC__) || defined(__DOS__)
return (chdir(wxFNSTRINGCAST d.fn_str()) == 0);
#elif defined(__WXPM__)
return (::DosSetCurrentDir((PSZ)d.c_str()) == 0);
bool wxEndsWithPathSeparator(const wxChar *pszFileName)
{
- size_t len = wxStrlen(pszFileName);
- if ( len == 0 )
- return FALSE;
- else
- return wxIsPathSeparator(pszFileName[len - 1]);
+ size_t len = wxStrlen(pszFileName);
+
+ return len && wxIsPathSeparator(pszFileName[len - 1]);
}
// find a file in a list of directories, returns false if not found
#ifdef __VISUALC__
#pragma warning(default:4706) // assignment within conditional expression
#endif // VC++
+
+//------------------------------------------------------------------------
+// Missing functions in Unicode for Win9x
+//------------------------------------------------------------------------
+
+// NB: MSLU only covers Win32 API, it doesn't provide Unicode implementation of
+// libc functions. Unfortunately, some of MSVCRT wchar_t functions
+// (e.g. _wopen) don't work on Windows 9x, so we have to workaround it
+// by calling the char version. We still want to use wchar_t version on
+// NT/2000/XP, though, because they allow for Unicode file names.
+#if wxUSE_UNICODE_MSLU
+
+ #if defined( __VISUALC__ ) \
+ || ( defined(__MINGW32__) && wxCHECK_W32API_VERSION( 0, 5 ) ) \
+ || ( defined(__MWERKS__) && defined(__WXMSW__) )
+ WXDLLEXPORT int wxOpen(const wxChar *name, int flags, int mode)
+ {
+ if ( wxGetOsVersion() == wxWINDOWS_NT )
+ return _wopen(name, flags, mode);
+ else
+ return _open(wxConvFile.cWX2MB(name), flags, mode);
+ }
+ #endif
+
+#endif // wxUSE_UNICODE_MSLU