|
|
@@ -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;
|
|
|
}
|