summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/Glob.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/Glob.cxx')
-rw-r--r--Source/kwsys/Glob.cxx93
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;
}