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:
parent
7c9afb5738
commit
aa84d26e63
93
Glob.cxx
93
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;
|
||||
}
|
||||
|
|
47
Glob.hxx.in
47
Glob.hxx.in
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue