X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6235846c0c15bdbabe2809eef87e4e12d6137bd2..ab7049776d45e622f621dd06216a4c1a1ad34b15:/src/common/filename.cpp?ds=sidebyside diff --git a/src/common/filename.cpp b/src/common/filename.cpp index b70eb4fd8d..79e2cae278 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -148,6 +148,12 @@ #define MAX_PATH _MAX_PATH #endif +#ifndef S_ISREG + #define S_ISREG(mode) ((mode) & S_IFREG) +#endif +#ifndef S_ISDIR + #define S_ISDIR(mode) ((mode) & S_IFDIR) +#endif #if wxUSE_LONGLONG extern const wxULongLong wxInvalidSize = (unsigned)-1; @@ -593,98 +599,143 @@ wxFileName wxFileName::DirName(const wxString& dir, wxPathFormat format) // existence tests // ---------------------------------------------------------------------------- -bool wxFileName::FileExists() const +namespace { - return wxFileName::FileExists( GetFullPath() ); -} -/* static */ -bool wxFileName::FileExists( const wxString &filePath ) +// Flags for wxFileSystemObjectExists() asking it to check for: +enum { -#if defined(__WXPALMOS__) - return false; -#elif defined(__WIN32__) && !defined(__WXMICROWIN__) - // we must use GetFileAttributes() instead of the ANSI C functions because - // it can cope with network (UNC) paths unlike them - DWORD ret = ::GetFileAttributes(filePath.t_str()); - - return (ret != INVALID_FILE_ATTRIBUTES) && !(ret & FILE_ATTRIBUTE_DIRECTORY); -#else // !__WIN32__ - #ifndef S_ISREG - #define S_ISREG(mode) ((mode) & S_IFREG) - #endif - wxStructStat st; + wxFileSystemObject_File = 1, // file existence + wxFileSystemObject_Dir = 2, // directory existence + wxFileSystemObject_Other = 4, // existence of something else, e.g. + // device, socket, FIFO under Unix + wxFileSystemObject_Any = 7 // existence of anything at all +}; - return (wxStat( filePath, &st) == 0 && S_ISREG(st.st_mode)) -#ifdef __OS2__ - || (errno == EACCES) // if access is denied something with that name - // exists and is opened in exclusive mode. -#endif - ; -#endif // __WIN32__/!__WIN32__ -} +#if defined(__WINDOWS__) && !defined(__WXMICROWIN__) -bool wxFileName::DirExists() const +void RemoveTrailingSeparatorsFromPath(wxString& strPath) { - return wxFileName::DirExists( GetPath() ); -} - -/* static */ -bool wxFileName::DirExists( const wxString &dirPath ) -{ - wxString strPath(dirPath); - -#if defined(__WINDOWS__) || defined(__OS2__) // 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 // the paths "d:\" (which are different from "d:"), for just "\" or for // windows unique volume names ("\\?\Volume{GUID}\") - while ( wxEndsWithPathSeparator(strPath) ) + while ( wxEndsWithPathSeparator( strPath ) ) { size_t len = strPath.length(); if ( len == 1 || (len == 3 && strPath[len - 2] == wxT(':')) || - (len == wxMSWUniqueVolumePrefixLength && - wxFileName::IsMSWUniqueVolumeNamePath(strPath))) + (len == wxMSWUniqueVolumePrefixLength && + wxFileName::IsMSWUniqueVolumeNamePath(strPath))) { break; } strPath.Truncate(len - 1); } -#endif // __WINDOWS__ +} -#ifdef __OS2__ - // OS/2 can't handle "d:", it wants either "d:\" or "d:." - if (strPath.length() == 2 && strPath[1u] == wxT(':')) - strPath << wxT('.'); -#endif +#endif // __WINDOWS__ || __OS2__ -#if defined(__WXPALMOS__) - return false; -#elif defined(__WIN32__) && !defined(__WXMICROWIN__) - // stat() can't cope with network paths - DWORD ret = ::GetFileAttributes(strPath.t_str()); +bool wxFileSystemObjectExists(const wxString& path, int flags) +{ + // Should the existence of file/directory with this name be accepted, i.e. + // result in the true return value from this function? + const bool acceptFile = (flags & wxFileSystemObject_File) != 0; + const bool acceptDir = (flags & wxFileSystemObject_Dir) != 0; + + wxString strPath(path); + +#if defined(__WINDOWS__) && !defined(__WXMICROWIN__) + if ( acceptDir ) + { + // Ensure that the path doesn't have any trailing separators when + // checking for directories. + RemoveTrailingSeparatorsFromPath(strPath); + } + + // we must use GetFileAttributes() instead of the ANSI C functions because + // it can cope with network (UNC) paths unlike them + DWORD ret = ::GetFileAttributes(path.t_str()); - return (ret != INVALID_FILE_ATTRIBUTES) && (ret & FILE_ATTRIBUTE_DIRECTORY); + if ( ret == INVALID_FILE_ATTRIBUTES ) + return false; + + if ( ret & FILE_ATTRIBUTE_DIRECTORY ) + return acceptDir; + + // Anything else must be a file (perhaps we should check for + // FILE_ATTRIBUTE_REPARSE_POINT?) + return acceptFile; #elif defined(__OS2__) + if ( acceptDir ) + { + // OS/2 can't handle "d:", it wants either "d:\" or "d:." + if (strPath.length() == 2 && strPath[1u] == wxT(':')) + strPath << wxT('.'); + } + FILESTATUS3 Info = {{0}}; APIRET rc = ::DosQueryPathInfo((PSZ)(WXSTRINGCAST strPath), FIL_STANDARD, - (void*) &Info, sizeof(FILESTATUS3)); + (void*) &Info, sizeof(FILESTATUS3)); + + if ( rc == NO_ERROR ) + { + if ( Info.attrFile & FILE_DIRECTORY ) + return acceptDir; + else + return acceptFile; + } - return ((rc == NO_ERROR) && (Info.attrFile & FILE_DIRECTORY)) || - (rc == ERROR_SHARING_VIOLATION); - // If we got a sharing violation, there must be something with this name. -#else // !__WIN32__ + // We consider that the path must exist if we get a sharing violation for + // it but we don't know what is it in this case. + if ( rc == ERROR_SHARING_VIOLATION ) + return flags & wxFileSystemObject_Other; + // Any other error (usually ERROR_PATH_NOT_FOUND), means there is nothing + // there. + return false; +#else // Non-MSW, non-OS/2 wxStructStat st; -#ifndef __VISAGECPP__ - return wxStat(strPath, &st) == 0 && ((st.st_mode & S_IFMT) == S_IFDIR); -#else - // S_IFMT not supported in VA compilers.. st_mode is a 2byte value only - return wxStat(strPath, &st) == 0 && (st.st_mode == S_IFDIR); -#endif + if ( wxStat(strPath, &st) != 0 ) + return false; + + if ( S_ISREG(st.st_mode) ) + return acceptFile; + if ( S_ISDIR(st.st_mode) ) + return acceptDir; + + return flags & wxFileSystemObject_Other; +#endif // Platforms +} + +} // anonymous namespace + +bool wxFileName::FileExists() const +{ + return wxFileName::FileExists( GetFullPath() ); +} + +/* static */ +bool wxFileName::FileExists( const wxString &filePath ) +{ + return wxFileSystemObjectExists(filePath, wxFileSystemObject_File); +} + +bool wxFileName::DirExists() const +{ + return wxFileName::DirExists( GetPath() ); +} + +/* static */ +bool wxFileName::DirExists( const wxString &dirPath ) +{ + return wxFileSystemObjectExists(dirPath, wxFileSystemObject_Dir); +} -#endif // __WIN32__/!__WIN32__ +/* static */ +bool wxFileName::Exists(const wxString& path) +{ + return wxFileSystemObjectExists(path, wxFileSystemObject_Any); } // ---------------------------------------------------------------------------- @@ -809,7 +860,7 @@ static bool wxTempOpen(wxFFile *file, const wxString& path, bool *deleteOnClose) int fd = wxTempOpen(path, deleteOnClose); if (fd == -1) return false; - file->Attach(wx_fdopen(fd, "w+b")); + file->Attach(wx_fdopen(fd, "w+b"), path); return file->IsOpened(); #endif // wx_fdopen } @@ -920,7 +971,7 @@ static wxString wxCreateTempImpl( if ( ffileTemp ) { #ifdef wx_fdopen - ffileTemp->Attach(wx_fdopen(fdTemp, "r+b")); + ffileTemp->Attach(wx_fdopen(fdTemp, "r+b"), path); #else ffileTemp->Open(path, wxT("r+b")); close(fdTemp); @@ -950,7 +1001,7 @@ static wxString wxCreateTempImpl( } #else // !HAVE_MKTEMP (includes __DOS__) // generate the unique file name ourselves - #if !defined(__DOS__) && !defined(__PALMOS__) && (!defined(__MWERKS__) || defined(__DARWIN__) ) + #if !defined(__DOS__) && (!defined(__MWERKS__) || defined(__DARWIN__) ) path << (unsigned int)getpid(); #endif @@ -1743,8 +1794,16 @@ bool wxFileName::SameAs(const wxFileName& filepath, wxPathFormat format) const if ( fn1.GetFullPath() == fn2.GetFullPath() ) return true; - // TODO: compare inodes for Unix, this works even when filenames are - // different but files are the same (symlinks) (VZ) +#if defined(__UNIX__) + wxStructStat st1, st2; + if ( wxStat(fn1.GetFullPath(), &st1) == 0 && + wxStat(fn2.GetFullPath(), &st2) == 0 ) + { + if ( st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev ) + return true; + } + //else: It's not an error if one or both files don't exist. +#endif // defined __UNIX__ return false; } @@ -2607,12 +2666,14 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess, wxStructStat stBuf; if ( wxStat( GetFullPath(), &stBuf) == 0 ) { + // Android defines st_*time fields as unsigned long, but time_t as long, + // hence the static_casts. if ( dtAccess ) - dtAccess->Set(stBuf.st_atime); + dtAccess->Set(static_cast(stBuf.st_atime)); if ( dtMod ) - dtMod->Set(stBuf.st_mtime); + dtMod->Set(static_cast(stBuf.st_mtime)); if ( dtCreate ) - dtCreate->Set(stBuf.st_ctime); + dtCreate->Set(static_cast(stBuf.st_ctime)); return true; } @@ -2643,10 +2704,7 @@ wxULongLong wxFileName::GetSize(const wxString &filename) if (!wxFileExists(filename)) return wxInvalidSize; -#if defined(__WXPALMOS__) - // TODO - return wxInvalidSize; -#elif defined(__WIN32__) +#if defined(__WIN32__) wxFileHandle f(filename, wxFileHandle::ReadAttr); if (!f.IsOk()) return wxInvalidSize;