summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-03-09 13:45:54 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2015-03-09 13:45:54 (GMT)
commit3f66bde4f70566166437dc4d7c9beaeba1ee33ee (patch)
treee929025f5d54af7e3ce853ae14c52936a029d967
parent387466dd9508ae57a864cdd8f2c8d8d28140b74c (diff)
parent44ef47000eb4f4ac7b4fc041afd3579ebe355469 (diff)
downloadCMake-3f66bde4f70566166437dc4d7c9beaeba1ee33ee.zip
CMake-3f66bde4f70566166437dc4d7c9beaeba1ee33ee.tar.gz
CMake-3f66bde4f70566166437dc4d7c9beaeba1ee33ee.tar.bz2
Merge topic 'update-kwsys'
44ef4700 Merge branch 'upstream-kwsys' into update-kwsys aa84d26e KWSys 2015-03-03 (4890f30c)
-rw-r--r--Source/kwsys/Glob.cxx93
-rw-r--r--Source/kwsys/Glob.hxx.in47
2 files changed, 124 insertions, 16 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;
}
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
index d8b8491..39b7ce7 100644
--- a/Source/kwsys/Glob.hxx.in
+++ b/Source/kwsys/Glob.hxx.in
@@ -40,11 +40,36 @@ class GlobInternals;
class @KWSYS_NAMESPACE@_EXPORT Glob
{
public:
+ enum MessageType
+ {
+ error,
+ cyclicRecursion
+ };
+
+ struct Message
+ {
+ MessageType type;
+ kwsys_stl::string content;
+
+ Message(MessageType t, const kwsys_stl::string& c) :
+ type(t),
+ content(c)
+ {}
+ Message(const Message& msg) :
+ type(msg.type),
+ content(msg.content)
+ {}
+ };
+
+ typedef kwsys_stl::vector<Message> GlobMessages;
+ typedef kwsys_stl::vector<Message>::iterator GlobMessagesIterator;
+public:
Glob();
~Glob();
//! Find all files that match the pattern.
- bool FindFiles(const kwsys_stl::string& inexpr);
+ bool FindFiles(const kwsys_stl::string& inexpr,
+ GlobMessages* messages = 0);
//! Return the list of files that matched.
kwsys_stl::vector<kwsys_stl::string>& GetFiles();
@@ -80,15 +105,26 @@ public:
bool require_whole_string = true,
bool preserve_case = false);
+ /** Getters and setters for enabling and disabling directory
+ listing in recursive and non recursive globbing mode.
+ If listing is enabled in recursive mode it also lists
+ directory symbolic links even if follow symlinks is enabled. */
+ void SetListDirs(bool list) { this->ListDirs=list; }
+ bool GetListDirs() const { return this->ListDirs; }
+ void SetRecurseListDirs(bool list) { this->RecurseListDirs=list; }
+ bool GetRecurseListDirs() const { return this->RecurseListDirs; }
+
protected:
//! Process directory
void ProcessDirectory(kwsys_stl::string::size_type start,
- const kwsys_stl::string& dir);
+ const kwsys_stl::string& dir,
+ GlobMessages* messages);
//! Process last directory, but only when recurse flags is on. That is
// effectively like saying: /path/to/file/**/file
- void RecurseDirectory(kwsys_stl::string::size_type start,
- const kwsys_stl::string& dir);
+ bool RecurseDirectory(kwsys_stl::string::size_type start,
+ const kwsys_stl::string& dir,
+ GlobMessages* messages);
//! Add regular expression
void AddExpression(const kwsys_stl::string& expr);
@@ -101,6 +137,9 @@ protected:
kwsys_stl::string Relative;
bool RecurseThroughSymlinks;
unsigned int FollowedSymlinkCount;
+ kwsys_stl::vector<kwsys_stl::string> VisitedSymlinks;
+ bool ListDirs;
+ bool RecurseListDirs;
private:
Glob(const Glob&); // Not implemented.