]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/filefn.cpp
Added some notes on the Nano-X port.
[wxWidgets.git] / src / common / filefn.cpp
index fc22b03128b011fa8f68633451895c808a9401fc..c990c980ed7f1ed907f1f85acef72e1ccb5c2d3c 100644 (file)
     #endif
 #endif
 
     #endif
 #endif
 
+#if defined(__WXMAC__)
+  #include  "wx/mac/private.h"  // includes mac headers
+#endif
+
 #include <time.h>
 
 #ifndef __MWERKS__
 #include <time.h>
 
 #ifndef __MWERKS__
     #endif
 #endif
 
     #endif
 #endif
 
-#ifdef __GNUWIN32__
-    #include <wchar.h>
-    #ifndef __TWIN32__
-        #include <sys/unistd.h>
-    #endif
-#endif
-
 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
                     // this (3.1 I believe) and how to test for it.
                     // If this works for Borland 4.0 as well, then no worries.
 #ifdef __BORLANDC__ // Please someone tell me which version of Borland needs
                     // this (3.1 I believe) and how to test for it.
                     // If this works for Borland 4.0 as well, then no worries.
 
 #ifdef __WINDOWS__
     #include <windows.h>
 
 #ifdef __WINDOWS__
     #include <windows.h>
+    #include "wx/msw/mslu.h"
+    
+    // sys/cygwin.h is needed for cygwin_conv_to_full_win32_path()
+    //
+    // note that it must be included after <windows.h>
+    #ifdef __GNUWIN32__
+        #ifdef __CYGWIN__
+            #include <sys/cygwin.h>
+        #endif
+        #include <wchar.h>
+        #ifndef __TWIN32__
+            #include <sys/unistd.h>
+        #endif
+    #endif // __GNUWIN32__
+#endif // __WINDOWS__
+
+// TODO: Borland probably has _wgetcwd as well?
+#ifdef _MSC_VER
+    #define HAVE_WGETCWD
 #endif
 
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
 
 #endif
 
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
 
-#define _MAXPATHLEN 500
-
-extern wxChar *wxBuffer;
+#ifndef _MAXPATHLEN
+    #define _MAXPATHLEN 1024
+#endif
 
 #ifdef __WXMAC__
 #    include "MoreFiles.h"
 
 #ifdef __WXMAC__
 #    include "MoreFiles.h"
@@ -270,8 +286,8 @@ wxString wxPathList::FindAbsoluteValidPath (const wxString& file)
         return f;
 
     wxString buf;
         return f;
 
     wxString buf;
-    wxGetWorkingDirectory(buf.GetWriteBuf(_MAXPATHLEN), _MAXPATHLEN - 1);
-    buf.UngetWriteBuf();
+    wxGetWorkingDirectory(wxStringBuffer(buf, _MAXPATHLEN), _MAXPATHLEN);
+
     if ( !wxEndsWithPathSeparator(buf) )
     {
         buf += wxFILE_SEP_PATH;
     if ( !wxEndsWithPathSeparator(buf) )
     {
         buf += wxFILE_SEP_PATH;
@@ -284,11 +300,11 @@ wxString wxPathList::FindAbsoluteValidPath (const wxString& file)
 bool
 wxFileExists (const wxString& filename)
 {
 bool
 wxFileExists (const wxString& filename)
 {
-#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
-    // GetFileAttributes can copy with network paths
-    DWORD ret = GetFileAttributes(filename);
-    DWORD isDir = (ret & FILE_ATTRIBUTE_DIRECTORY);
-    return ((ret != 0xffffffff) && (isDir == 0));
+#if defined(__WIN32__) && !defined(__WXMICROWIN__)
+    // GetFileAttributes can copy with network paths unlike stat()
+    DWORD ret = ::GetFileAttributes(filename);
+
+    return (ret != (DWORD)-1) && !(ret & FILE_ATTRIBUTE_DIRECTORY);
 #else
     wxStructStat stbuf;
     if ( !filename.empty() && wxStat (OS_FILENAME(filename), &stbuf) == 0 )
 #else
     wxStructStat stbuf;
     if ( !filename.empty() && wxStat (OS_FILENAME(filename), &stbuf) == 0 )
@@ -306,7 +322,7 @@ wxIsAbsolutePath (const wxString& filename)
 #if defined(__WXMAC__) && !defined(__DARWIN__)
         // Classic or Carbon CodeWarrior like
         // Carbon with Apple DevTools is Unix like
 #if defined(__WXMAC__) && !defined(__DARWIN__)
         // Classic or Carbon CodeWarrior like
         // Carbon with Apple DevTools is Unix like
-        
+
         // This seems wrong to me, but there is no fix. since
         // "MacOS:MyText.txt" is absolute whereas "MyDir:MyText.txt"
         // is not. Or maybe ":MyDir:MyText.txt" has to be used? RR.
         // This seems wrong to me, but there is no fix. since
         // "MacOS:MyText.txt" is absolute whereas "MyDir:MyText.txt"
         // is not. Or maybe ":MyDir:MyText.txt" has to be used? RR.
@@ -563,7 +579,6 @@ wxChar *wxExpandPath(wxChar *buf, const wxChar *name)
 
     /* Expand ~ and ~user */
     nm = lnm;
 
     /* Expand ~ and ~user */
     nm = lnm;
-    s = wxT("");
     if (nm[0] == wxT('~') && !q)
     {
         /* prefix ~ */
     if (nm[0] == wxT('~') && !q)
     {
         /* prefix ~ */
@@ -587,7 +602,7 @@ wxChar *wxExpandPath(wxChar *buf, const wxChar *name)
             if ((home = WXSTRINGCAST wxGetUserHome(wxString(nm + 1))) == NULL) {
                if (was_sep) /* replace only if it was there: */
                    *s = SEP;
             if ((home = WXSTRINGCAST wxGetUserHome(wxString(nm + 1))) == NULL) {
                if (was_sep) /* replace only if it was there: */
                    *s = SEP;
-                s = wxT("");
+                s = NULL;
             } else {
                 nm = nnm;
                 s = home;
             } else {
                 nm = nnm;
                 s = home;
@@ -673,7 +688,7 @@ wxChar *wxFileNameFromPath (wxChar *path)
     if (path)
     {
         register wxChar *tcp;
     if (path)
     {
         register wxChar *tcp;
-        
+
         tcp = path + wxStrlen (path);
         while (--tcp >= path)
         {
         tcp = path + wxStrlen (path);
         while (--tcp >= path)
         {
@@ -707,7 +722,7 @@ wxString wxFileNameFromPath (const wxString& path1)
     {
         wxChar *path = WXSTRINGCAST path1 ;
         register wxChar *tcp;
     {
         wxChar *path = WXSTRINGCAST path1 ;
         register wxChar *tcp;
-        
+
         tcp = path + wxStrlen (path);
         while (--tcp >= path)
         {
         tcp = path + wxStrlen (path);
         while (--tcp >= path)
         {
@@ -744,13 +759,13 @@ wxPathOnly (wxChar *path)
     if (path && *path)
     {
         static wxChar buf[_MAXPATHLEN];
     if (path && *path)
     {
         static wxChar buf[_MAXPATHLEN];
-        
+
         // Local copy
         wxStrcpy (buf, path);
         // Local copy
         wxStrcpy (buf, path);
-        
+
         int l = wxStrlen(path);
         int i = l - 1;
         int l = wxStrlen(path);
         int i = l - 1;
-        
+
         // Search backward for a backward or forward slash
         while (i > -1)
         {
         // Search backward for a backward or forward slash
         while (i > -1)
         {
@@ -779,7 +794,7 @@ wxPathOnly (wxChar *path)
 #endif
             i --;
         }
 #endif
             i --;
         }
-        
+
 #if defined(__WXMSW__) || defined(__WXPM__)
         // Try Drive specifier
         if (wxIsalpha (buf[0]) && buf[1] == wxT(':'))
 #if defined(__WXMSW__) || defined(__WXPM__)
         // Try Drive specifier
         if (wxIsalpha (buf[0]) && buf[1] == wxT(':'))
@@ -800,10 +815,10 @@ wxString wxPathOnly (const wxString& path)
     if (path != wxT(""))
     {
         wxChar buf[_MAXPATHLEN];
     if (path != wxT(""))
     {
         wxChar buf[_MAXPATHLEN];
-        
+
         // Local copy
         wxStrcpy (buf, WXSTRINGCAST path);
         // Local copy
         wxStrcpy (buf, WXSTRINGCAST path);
-        
+
         int l = path.Length();
         int i = l - 1;
 
         int l = path.Length();
         int i = l - 1;
 
@@ -835,7 +850,7 @@ wxString wxPathOnly (const wxString& path)
 #endif
             i --;
         }
 #endif
             i --;
         }
-        
+
 #if defined(__WXMSW__) || defined(__WXPM__)
         // Try Drive specifier
         if (wxIsalpha (buf[0]) && buf[1] == wxT(':'))
 #if defined(__WXMSW__) || defined(__WXPM__)
         // Try Drive specifier
         if (wxIsalpha (buf[0]) && buf[1] == wxT(':'))
@@ -865,7 +880,7 @@ wxString wxMacFSSpec2MacFilename( const FSSpec *spec )
     (void) FSpMakeFSRef( spec, &theRef );
     // get the POSIX path associated with the FSRef
     (void) FSRefMakePath( &theRef, (UInt8 *)thePath, sizeof(thePath) );
     (void) FSpMakeFSRef( spec, &theRef );
     // get the POSIX path associated with the FSRef
     (void) FSRefMakePath( &theRef, (UInt8 *)thePath, sizeof(thePath) );
-    
+
     // create path string for return value
     wxString result( thePath ) ;
 #else
     // create path string for return value
     wxString result( thePath ) ;
 #else
@@ -879,7 +894,7 @@ wxString wxMacFSSpec2MacFilename( const FSSpec *spec )
     (*myPath)[length] = 0 ;
     if ((length > 0) && ((*myPath)[length-1] == ':'))
         (*myPath)[length-1] = 0 ;
     (*myPath)[length] = 0 ;
     if ((length > 0) && ((*myPath)[length-1] == ':'))
         (*myPath)[length-1] = 0 ;
-    
+
     // create path string for return value
     wxString result( (char*) *myPath ) ;
 
     // create path string for return value
     wxString result( (char*) *myPath ) ;
 
@@ -922,7 +937,7 @@ wxString wxMac2UnixFilename (const char *str)
             *s = '.' ;
         else
             *s = '/' ;
             *s = '.' ;
         else
             *s = '/' ;
-        
+
         while (*s)
         {
             if (*s == ':')
         while (*s)
         {
             if (*s == ':')
@@ -1071,11 +1086,15 @@ wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite)
     // instead of our code if available
     //
     // NB: 3rd parameter is bFailIfExists i.e. the inverse of overwrite
     // instead of our code if available
     //
     // NB: 3rd parameter is bFailIfExists i.e. the inverse of overwrite
-    return ::CopyFile(file1, file2, !overwrite) != 0;
+    if ( !::CopyFile(file1, file2, !overwrite) )
+    {
+        wxLogSysError(_("Failed to copy the file '%s' to '%s'"),
+                      file1.c_str(), file2.c_str());
+
+        return FALSE;
+    }
 #elif defined(__WXPM__)
 #elif defined(__WXPM__)
-    if (::DosCopy(file2, file2, overwrite ? DCPY_EXISTING : 0) == 0)
-        return TRUE;
-    else
+    if ( ::DosCopy(file2, file2, overwrite ? DCPY_EXISTING : 0) != 0 )
         return FALSE;
 #else // !Win32
     wxStructStat fbuf;
         return FALSE;
 #else // !Win32
     wxStructStat fbuf;
@@ -1154,9 +1173,9 @@ wxCopyFile (const wxString& file1, const wxString& file2, bool overwrite)
         return FALSE;
     }
 #endif // OS/2 || Mac
         return FALSE;
     }
 #endif // OS/2 || Mac
+#endif // __WXMSW__ && __WIN32__
 
     return TRUE;
 
     return TRUE;
-#endif // __WXMSW__ && __WIN32__
 }
 
 bool
 }
 
 bool
@@ -1246,6 +1265,7 @@ bool wxRmdir(const wxString& dir, int WXUNUSED(flags))
 bool wxPathExists(const wxChar *pszPathName)
 {
     wxString strPath(pszPathName);
 bool wxPathExists(const wxChar *pszPathName)
 {
     wxString strPath(pszPathName);
+
 #ifdef __WINDOWS__
     // Windows fails to find directory named "c:\dir\" even if "c:\dir" exists,
     // so remove all trailing backslashes from the path - but don't do this for
 #ifdef __WINDOWS__
     // Windows fails to find directory named "c:\dir\" even if "c:\dir" exists,
     // so remove all trailing backslashes from the path - but don't do this for
@@ -1260,12 +1280,12 @@ bool wxPathExists(const wxChar *pszPathName)
     }
 #endif // __WINDOWS__
 
     }
 #endif // __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);
-    return ((ret != 0xffffffff) && (isDir != 0));
-#else
+#if defined(__WIN32__) && !defined(__WXMICROWIN__)
+    // stat() can't cope with network paths
+    DWORD ret = ::GetFileAttributes(strPath);
+
+    return (ret != (DWORD)-1) && (ret & FILE_ATTRIBUTE_DIRECTORY);
+#else // !__WIN32__
 
     wxStructStat st;
 #ifndef __VISAGECPP__
 
     wxStructStat st;
 #ifndef __VISAGECPP__
@@ -1277,7 +1297,7 @@ bool wxPathExists(const wxChar *pszPathName)
         (st.st_mode == S_IFDIR);
 #endif
 
         (st.st_mode == S_IFDIR);
 #endif
 
-#endif
+#endif // __WIN32__/!__WIN32__
 }
 
 // Get a temporary filename, opening and closing the file.
 }
 
 // Get a temporary filename, opening and closing the file.
@@ -1318,13 +1338,13 @@ wxString wxFindFirstFile(const wxChar *spec, int flags)
     if (gs_dir)
         delete gs_dir;
     gs_dir = new wxDir(gs_dirPath);
     if (gs_dir)
         delete gs_dir;
     gs_dir = new wxDir(gs_dirPath);
-    
+
     if ( !gs_dir->IsOpened() )
     {
         wxLogSysError(_("Can not enumerate files '%s'"), spec);
         return wxEmptyString;
     }
     if ( !gs_dir->IsOpened() )
     {
         wxLogSysError(_("Can not enumerate files '%s'"), spec);
         return wxEmptyString;
     }
-    
+
     int dirFlags = 0;
     switch (flags)
     {
     int dirFlags = 0;
     switch (flags)
     {
@@ -1332,7 +1352,7 @@ wxString wxFindFirstFile(const wxChar *spec, int flags)
         case wxFILE: dirFlags = wxDIR_FILES; break;
         default:     dirFlags = wxDIR_DIRS | wxDIR_FILES; break;
     }
         case wxFILE: dirFlags = wxDIR_FILES; break;
         default:     dirFlags = wxDIR_DIRS | wxDIR_FILES; break;
     }
-    
+
     wxString result;
     gs_dir->GetFirst(&result, wxFileNameFromPath(spec), dirFlags);
     if ( result.IsEmpty() )
     wxString result;
     gs_dir->GetFirst(&result, wxFileNameFromPath(spec), dirFlags);
     if ( result.IsEmpty() )
@@ -1350,13 +1370,13 @@ wxString wxFindNextFile()
 
     wxString result;
     gs_dir->GetNext(&result);
 
     wxString result;
     gs_dir->GetNext(&result);
-    
+
     if ( result.IsEmpty() )
     {
         wxDELETE(gs_dir);
         return result;
     }
     if ( result.IsEmpty() )
     {
         wxDELETE(gs_dir);
         return result;
     }
-    
+
     return gs_dirPath + result;
 }
 
     return gs_dirPath + result;
 }
 
@@ -1366,103 +1386,129 @@ wxString wxFindNextFile()
 // copies into buf.
 wxChar *wxGetWorkingDirectory(wxChar *buf, int sz)
 {
 // copies into buf.
 wxChar *wxGetWorkingDirectory(wxChar *buf, int sz)
 {
-  if (!buf)
-    buf = new wxChar[sz+1];
-#if wxUSE_UNICODE
-  char *cbuf = new char[sz+1];
-#ifdef _MSC_VER
-  if (_getcwd(cbuf, sz) == NULL) {
-#elif defined(__WXMAC__) && !defined(__DARWIN__)
-    enum
+    if ( !buf )
     {
     {
-        SFSaveDisk = 0x214, CurDirStore = 0x398
-    };
-    FSSpec cwdSpec ;
-
-    FSMakeFSSpec( - *(short *) SFSaveDisk , *(long *) CurDirStore , NULL , &cwdSpec ) ;
-    wxString res = wxMacFSSpec2UnixFilename( &cwdSpec ) ;
-    strcpy( buf , res ) ;
-    if (0) {
-#else
-  if (getcwd(cbuf, sz) == NULL) {
-#endif
-    delete [] cbuf;
-#else // wxUnicode
-#ifdef _MSC_VER
-  if (_getcwd(buf, sz) == NULL) {
-#elif defined(__WXMAC__) && !defined(__DARWIN__)
-    FSSpec cwdSpec ;
-    FCBPBRec pb;
-    OSErr error;
-    Str255  fileName ;
-    pb.ioNamePtr = (StringPtr) &fileName;
-    pb.ioVRefNum = 0;
-    pb.ioRefNum = LMGetCurApRefNum();
-    pb.ioFCBIndx = 0;
-    error = PBGetFCBInfoSync(&pb);
-    if ( error == noErr )
+        buf = new wxChar[sz + 1];
+    }
+
+    bool ok = FALSE;
+
+    // for the compilers which have Unicode version of _getcwd(), call it
+    // directly, for the others call the ANSI version and do the translation
+#if !wxUSE_UNICODE
+       #define cbuf buf
+#else // wxUSE_UNICODE
+       bool needsANSI = TRUE;
+
+       #if !defined(HAVE_WGETCWD) || wxUSE_UNICODE_MSLU
+        wxCharBuffer c_buffer(sz);
+               char *cbuf = (char*)(const char*)c_buffer;
+       #endif
+
+    #ifdef HAVE_WGETCWD
+               #if     wxUSE_UNICODE_MSLU
+                       if ( wxGetOsVersion() != wxWIN95 )
+               #endif
+                       {
+                               ok = _wgetcwd(buf, sz) != NULL;
+                               needsANSI = FALSE;
+                       }
+    #endif
+
+       if ( needsANSI )
+#endif // wxUSE_UNICODE
+       {
+    #ifdef _MSC_VER
+        ok = _getcwd(cbuf, sz) != NULL;
+    #elif defined(__WXMAC__) && !defined(__DARWIN__)
+        FSSpec cwdSpec ;
+        FCBPBRec pb;
+        OSErr error;
+        Str255  fileName ;
+        pb.ioNamePtr = (StringPtr) &fileName;
+        pb.ioVRefNum = 0;
+        pb.ioRefNum = LMGetCurApRefNum();
+        pb.ioFCBIndx = 0;
+        error = PBGetFCBInfoSync(&pb);
+        if ( error == noErr )
+        {
+            cwdSpec.vRefNum = pb.ioFCBVRefNum;
+            cwdSpec.parID = pb.ioFCBParID;
+            cwdSpec.name[0] = 0 ;
+            wxString res = wxMacFSSpec2MacFilename( &cwdSpec ) ;
+
+            strcpy( cbuf , res ) ;
+            cbuf[res.length()]=0 ;
+
+            ok = TRUE;
+        }
+        else
+        {
+            ok = FALSE;
+        }
+    #elif defined(__VISAGECPP__) || (defined (__OS2__) && defined (__WATCOMC__))
+        APIRET rc;
+        rc = ::DosQueryCurrentDir( 0 // current drive
+                                  ,cbuf
+                                  ,(PULONG)&sz
+                                 );
+        ok = rc != 0;
+    #else // !Win32/VC++ !Mac !OS2
+        ok = getcwd(cbuf, sz) != NULL;
+    #endif // platform
+       }
+
+    if ( !ok )
     {
     {
-        cwdSpec.vRefNum = pb.ioFCBVRefNum;
-        cwdSpec.parID = pb.ioFCBParID;
-        cwdSpec.name[0] = 0 ;
-        wxString res = wxMacFSSpec2MacFilename( &cwdSpec ) ;
+        wxLogSysError(_("Failed to get the working directory"));
 
 
-        strcpy( buf , res ) ;
-        buf[res.length()]=0 ;
+        // VZ: the old code used to return "." on error which didn't make any
+        //     sense at all to me - empty string is a better error indicator
+        //     (NULL might be even better but I'm afraid this could lead to
+        //     problems with the old code assuming the return is never NULL)
+        buf[0] = _T('\0');
     }
     }
-    else
-        buf[0] = 0 ;
-    /*
-    this version will not always give back the application directory on mac
-    enum
+    else // ok, but we might need to massage the path into the right format
     {
     {
-        SFSaveDisk = 0x214, CurDirStore = 0x398
-    };
-    FSSpec cwdSpec ;
+#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 // __DJGPP__
 
 
-    FSMakeFSSpec( - *(short *) SFSaveDisk , *(long *) CurDirStore , NULL , &cwdSpec ) ;
-    wxString res = wxMacFSSpec2UnixFilename( &cwdSpec ) ;
-    strcpy( buf , res ) ;
-    */
-    if (0) {
-#elif defined(__VISAGECPP__) || (defined (__OS2__) && defined (__WATCOMC__))
-    APIRET rc;
-    rc = ::DosQueryCurrentDir( 0 // current drive
-                              ,buf
-                              ,(PULONG)&sz
-                             );
-    if (rc != 0) {
-#else
-  if (getcwd(buf, sz) == NULL) {
-#endif
-#endif
-    buf[0] = wxT('.');
-    buf[1] = wxT('\0');
-  }
+#ifdef __CYGWIN__
+        // another example of DOS/Unix mix (Cygwin)
+        wxString pathUnix = buf;
+        cygwin_conv_to_full_win32_path(pathUnix, buf);
+#endif // __CYGWIN__
+
+        // finally convert the result to Unicode if needed
 #if wxUSE_UNICODE
 #if wxUSE_UNICODE
-  else {
-    wxConvFile.MB2WC(buf, cbuf, sz);
-    delete [] cbuf;
-  }
-#endif
+        wxConvFile.MB2WC(buf, cbuf, sz);
+#endif // wxUSE_UNICODE
+    }
 
 
-#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;
 
 
-  return buf;
+#if !wxUSE_UNICODE
+       #undef cbuf
+#endif
 }
 
 wxString wxGetCwd()
 {
 }
 
 wxString wxGetCwd()
 {
-    static const size_t maxPathLen = 1024;
-
     wxString str;
     wxString str;
-    wxGetWorkingDirectory(str.GetWriteBuf(maxPathLen), maxPathLen);
-    str.UngetWriteBuf();
+
+    // we can't create wxStringBuffer object inline: Sun CC generates buggy
+    // code in this case!
+    {
+        wxStringBuffer buf(str, _MAXPATHLEN);
+        wxGetWorkingDirectory(buf, _MAXPATHLEN);
+    }
 
     return str;
 }
 
     return str;
 }
@@ -1519,11 +1565,9 @@ wxString wxGetOSDirectory()
 
 bool wxEndsWithPathSeparator(const wxChar *pszFileName)
 {
 
 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
 }
 
 // find a file in a list of directories, returns false if not found