From 6d23dd7e455a7b2088c4ec6dce760d8243b84ee6 Mon Sep 17 00:00:00 2001 From: Ben Boeckel <ben.boeckel@kitware.com> Date: Tue, 2 Aug 2016 16:02:37 -0400 Subject: [PATCH] SystemTools: add a PathExists method This method checks if a path by the given name exists. The problem with FileExists is that it returns `false` even for broken (or self-referential) symlinks which may not be what the user wants. Change-Id: I71b8af6e12a5ae4b1319a3bec83db6c3cef36f90 --- SystemTools.cxx | 26 ++++++++++++++++++++++++++ SystemTools.hxx.in | 5 +++++ testSystemTools.cxx | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/SystemTools.cxx b/SystemTools.cxx index d479ee1..eb2bec6 100644 --- a/SystemTools.cxx +++ b/SystemTools.cxx @@ -1291,6 +1291,32 @@ bool SystemTools::SameFile(const std::string& file1, const std::string& file2) #endif } +//---------------------------------------------------------------------------- +bool SystemTools::PathExists(const std::string& path) +{ + if(path.empty()) + { + return false; + } +#if defined(__CYGWIN__) + // Convert path to native windows path if possible. + char winpath[MAX_PATH]; + if(SystemTools::PathCygwinToWin32(path.c_str(), winpath)) + { + return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES); + } + struct stat st; + return lstat(path.c_str(), &st) == 0; +#elif defined(_WIN32) + return (GetFileAttributesW( + SystemTools::ConvertToWindowsExtendedPath(path).c_str()) + != INVALID_FILE_ATTRIBUTES); +#else + struct stat st; + return lstat(path.c_str(), &st) == 0; +#endif +} + //---------------------------------------------------------------------------- bool SystemTools::FileExists(const char* filename) { diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in index aa1bf1b..28ff0b3 100644 --- a/SystemTools.hxx.in +++ b/SystemTools.hxx.in @@ -305,6 +305,11 @@ public: */ static std::string ConvertToWindowsOutputPath(const std::string&); + /** + * Return true if a path with the given name exists in the current directory. + */ + static bool PathExists(const std::string& path); + /** * Return true if a file exists in the current directory. * If isFile = true, then make sure the file is a file and diff --git a/testSystemTools.cxx b/testSystemTools.cxx index 4dab347..9252ea6 100644 --- a/testSystemTools.cxx +++ b/testSystemTools.cxx @@ -204,6 +204,14 @@ static bool CheckFileOperations() << testNewDir << std::endl; res = false; } + // check existence + if (!kwsys::SystemTools::PathExists(testNewDir)) + { + std::cerr + << "Problem with PathExists for: " + << testNewDir << std::endl; + res = false; + } // remove it if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) { @@ -221,6 +229,15 @@ static bool CheckFileOperations() << testNewDir << std::endl; res = false; } + // check existence + if (kwsys::SystemTools::PathExists(testNewDir)) + { + std::cerr + << "After RemoveADirectory: " + << "Problem with PathExists for: " + << testNewDir << std::endl; + res = false; + } // create it using the char* version if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str())) { @@ -329,6 +346,31 @@ static bool CheckFileOperations() res = false; } + // calling with an empty string should return false + if (kwsys::SystemTools::PathExists(std::string())) + { + std::cerr + << "Problem with PathExists(std::string())" + << std::endl; + res = false; + } + // PathExists(x) should return true on a directory + if (!kwsys::SystemTools::PathExists(testNewDir)) + { + std::cerr + << "Problem with PathExists for: " + << testNewDir << std::endl; + res = false; + } + // should work, was created as new file before + if (!kwsys::SystemTools::PathExists(testNewFile)) + { + std::cerr + << "Problem with PathExists for: " + << testNewDir << std::endl; + res = false; + } + // Reset umask #if defined(_WIN32) && !defined(__CYGWIN__) // NOTE: Windows doesn't support toggling _S_IREAD. -- GitLab