diff options
Diffstat (limited to 'Source/kwsys/Glob.cxx')
-rw-r--r-- | Source/kwsys/Glob.cxx | 93 |
1 files changed, 81 insertions, 12 deletions
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 1476c25..11bfd16 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -19,6 +19,7 @@ #include KWSYS_HEADER(Directory.hxx) #include KWSYS_HEADER(stl/string) #include KWSYS_HEADER(stl/vector) +#include KWSYS_HEADER(stl/algorithm) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. @@ -30,6 +31,8 @@ # include "SystemTools.hxx.in" # include "kwsys_stl.hxx.in" # include "kwsys_stl_string.hxx.in" +# include "kwsys_stl_vector.hxx.in" +# include "kwsys_stl_algorithm.hxx.in" #endif #include <ctype.h> @@ -66,6 +69,10 @@ Glob::Glob() // RecurseThroughSymlinks is true by default for backwards compatibility, // not because it's a good idea... this->FollowedSymlinkCount = 0; + + // Keep separate variables for directory listing for back compatibility + this->ListDirs = true; + this->RecurseListDirs = false; } //---------------------------------------------------------------------------- @@ -214,13 +221,13 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern, } //---------------------------------------------------------------------------- -void Glob::RecurseDirectory(kwsys_stl::string::size_type start, - const kwsys_stl::string& dir) +bool Glob::RecurseDirectory(kwsys_stl::string::size_type start, + const kwsys_stl::string& dir, GlobMessages* messages) { kwsys::Directory d; if ( !d.Load(dir) ) { - return; + return true; } unsigned long cc; kwsys_stl::string realname; @@ -255,8 +262,67 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start, if (isSymLink) { ++this->FollowedSymlinkCount; + kwsys_stl::string realPathErrorMessage; + kwsys_stl::string canonicalPath(SystemTools::GetRealPath(dir, + &realPathErrorMessage)); + + if(!realPathErrorMessage.empty()) + { + if(messages) + { + messages->push_back(Message( + Glob::error, "Canonical path generation from path '" + + dir + "' failed! Reason: '" + realPathErrorMessage + "'")); + } + return false; + } + + if(kwsys_stl::find(this->VisitedSymlinks.begin(), + this->VisitedSymlinks.end(), + canonicalPath) == this->VisitedSymlinks.end()) + { + if(this->RecurseListDirs) + { + // symlinks are treated as directories + this->AddFile(this->Internals->Files, realname); + } + + this->VisitedSymlinks.push_back(canonicalPath); + if(!this->RecurseDirectory(start+1, realname, messages)) + { + this->VisitedSymlinks.pop_back(); + + return false; + } + this->VisitedSymlinks.pop_back(); + } + // else we have already visited this symlink - prevent cyclic recursion + else if(messages) + { + kwsys_stl::string message; + for(kwsys_stl::vector<kwsys_stl::string>::const_iterator + pathIt = kwsys_stl::find(this->VisitedSymlinks.begin(), + this->VisitedSymlinks.end(), + canonicalPath); + pathIt != this->VisitedSymlinks.end(); ++pathIt) + { + message += *pathIt + "\n"; + } + message += canonicalPath + "/" + fname; + messages->push_back(Message(Glob::cyclicRecursion, message)); + } + } + else + { + if(this->RecurseListDirs) + { + this->AddFile(this->Internals->Files, realname); + } + if(!this->RecurseDirectory(start+1, realname, messages)) + { + return false; + } } - this->RecurseDirectory(start+1, realname); } else { @@ -267,17 +333,19 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start, } } } + + return true; } //---------------------------------------------------------------------------- void Glob::ProcessDirectory(kwsys_stl::string::size_type start, - const kwsys_stl::string& dir) + const kwsys_stl::string& dir, GlobMessages* messages) { //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl; bool last = ( start == this->Internals->Expressions.size()-1 ); if ( last && this->Recurse ) { - this->RecurseDirectory(start, dir); + this->RecurseDirectory(start, dir, messages); return; } @@ -321,8 +389,9 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start, // << this->Internals->TextExpressions[start].c_str() << kwsys_ios::endl; //kwsys_ios::cout << "Real name: " << realname << kwsys_ios::endl; - if ( !last && - !kwsys::SystemTools::FileIsDirectory(realname) ) + if( (!last && !kwsys::SystemTools::FileIsDirectory(realname)) + || (!this->ListDirs && last && + kwsys::SystemTools::FileIsDirectory(realname)) ) { continue; } @@ -335,14 +404,14 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start, } else { - this->ProcessDirectory(start+1, realname); + this->ProcessDirectory(start+1, realname, messages); } } } } //---------------------------------------------------------------------------- -bool Glob::FindFiles(const kwsys_stl::string& inexpr) +bool Glob::FindFiles(const kwsys_stl::string& inexpr, GlobMessages* messages) { kwsys_stl::string cexpr; kwsys_stl::string::size_type cc; @@ -438,11 +507,11 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr) // Handle network paths if ( skip > 0 ) { - this->ProcessDirectory(0, fexpr.substr(0, skip) + "/"); + this->ProcessDirectory(0, fexpr.substr(0, skip) + "/", messages); } else { - this->ProcessDirectory(0, "/"); + this->ProcessDirectory(0, "/", messages); } return true; } |