KWSys 2015-03-03 (4890f30c)

Extract upstream KWSys using the following shell commands.

$ git archive --prefix=upstream-kwsys/ 4890f30c | tar x
$ git shortlog --no-merges --abbrev=8 --format='%h %s' d2aa1afd..4890f30c
Domen Vrankar (2):
      5d6204e9 Glob: Handle symlink cycles in directory paths
      4890f30c Glob: Add support for directory listing

Change-Id: Id8b77dabf8f50efeffdeaf1c826154fd2a25e17b
This commit is contained in:
KWSys Robot 2015-03-03 08:50:09 -05:00 committed by Brad King
parent 7c9afb5738
commit aa84d26e63
2 changed files with 124 additions and 16 deletions

View File

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

View File

@ -39,12 +39,37 @@ 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.