summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2003-07-14 13:15:13 (GMT)
committerAndy Cedilnik <andy.cedilnik@kitware.com>2003-07-14 13:15:13 (GMT)
commit274535d36642e5615a3b8b1d098396759a9e09f9 (patch)
treefdce84aed2f10ca0b68447fba707708dc5d11ad7 /Source
parent2910c30dd5b0042f476110d63e9c300b4e2feb0d (diff)
downloadCMake-274535d36642e5615a3b8b1d098396759a9e09f9.zip
CMake-274535d36642e5615a3b8b1d098396759a9e09f9.tar.gz
CMake-274535d36642e5615a3b8b1d098396759a9e09f9.tar.bz2
ENH: Recurse subdirectories
Diffstat (limited to 'Source')
-rw-r--r--Source/cmFileCommand.cxx10
-rw-r--r--Source/cmFileCommand.h8
-rw-r--r--Source/cmGlob.cxx39
-rw-r--r--Source/cmGlob.h11
4 files changed, 64 insertions, 4 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 49f79d1..018c605 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -41,7 +41,11 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args)
}
else if ( subCommand == "GLOB" )
{
- return this->HandleGlobCommand(args);
+ return this->HandleGlobCommand(args, false);
+ }
+ else if ( subCommand == "GLOB_RECURSE" )
+ {
+ return this->HandleGlobCommand(args, true);
}
else if ( subCommand == "MAKE_DIRECTORY" )
{
@@ -135,7 +139,8 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
}
//----------------------------------------------------------------------------
-bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args)
+bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
+ bool recurse)
{
if ( args.size() < 2 )
{
@@ -150,6 +155,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args)
std::string variable = *i;
i++;
cmGlob g;
+ g.SetRecurse(recurse);
std::string output = "";
bool first = true;
for ( ; i != args.end(); ++i )
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 7cfa3e7..0f02239 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -70,6 +70,7 @@ public:
" FILE(APPEND filename \"message to write\"... )\n"
" FILE(READ filename variable)\n"
" FILE(GLOB variable [globbing expressions]...)\n"
+ " FILE(GLOB_RECURSE variable [globbing expressions]...)\n"
"WRITE will write a message into a file called 'filename'. It "
"overwrites the file if it already exists, and creates the file "
"if it does not exists.\n"
@@ -84,6 +85,11 @@ public:
" *.cxx - match all files with extension cxx\n"
" *.vt? - match all files with extension vta, vtb, ... vtz\n"
" f[3-5].txt - match files f3.txt, f4.txt, f5.txt\n"
+ "GLOB_RECURSE will generate similar list as the regular GLOB, except "
+ "it will traverse all the subdirectories of the matched directory and "
+ "match the files.\n"
+ "Example of recursive globbing:\n"
+ " /dir/*.py - match all python files /dir and subdirectories\n"
"MAKE_DIRECTORY will create a directory at the specified location";
}
@@ -92,7 +98,7 @@ public:
protected:
bool HandleWriteCommand(std::vector<std::string> const& args, bool append);
bool HandleReadCommand(std::vector<std::string> const& args);
- bool HandleGlobCommand(std::vector<std::string> const& args);
+ bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
};
diff --git a/Source/cmGlob.cxx b/Source/cmGlob.cxx
index bb4d421..2ac32c7 100644
--- a/Source/cmGlob.cxx
+++ b/Source/cmGlob.cxx
@@ -32,6 +32,7 @@ public:
cmGlob::cmGlob()
{
m_Internals = new cmGlobInternal;
+ m_Recurse = false;
}
cmGlob::~cmGlob()
@@ -137,9 +138,46 @@ std::string cmGlob::ConvertExpression(const std::string& expr)
return res + "$";
}
+void cmGlob::RecurseDirectory(const std::string& dir, bool dir_only)
+{
+ cmsys::Directory d;
+ if ( !d.Load(dir.c_str()) )
+ {
+ return;
+ }
+ unsigned long cc;
+ std::string fullname;
+ for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
+ {
+ if ( strcmp(d.GetFile(cc), ".") == 0 ||
+ strcmp(d.GetFile(cc), "..") == 0 )
+ {
+ continue;
+ }
+ fullname = dir + "/" + d.GetFile(cc);
+ if ( !dir_only || !cmsys::SystemTools::FileIsDirectory(fullname.c_str()) )
+ {
+ if ( m_Internals->Expressions[m_Internals->Expressions.size()-1].find(d.GetFile(cc)) )
+ {
+ m_Internals->Files.push_back(fullname);
+ }
+ }
+ if ( cmsys::SystemTools::FileIsDirectory(fullname.c_str()) )
+ {
+ this->RecurseDirectory(fullname, dir_only);
+ }
+ }
+}
+
void cmGlob::ProcessDirectory(std::string::size_type start,
const std::string& dir, bool dir_only)
{
+ bool last = ( start == m_Internals->Expressions.size()-1 );
+ if ( last && m_Recurse )
+ {
+ this->RecurseDirectory(dir, dir_only);
+ return;
+ }
cmsys::Directory d;
if ( !d.Load(dir.c_str()) )
{
@@ -147,7 +185,6 @@ void cmGlob::ProcessDirectory(std::string::size_type start,
}
unsigned long cc;
std::string fullname;
- bool last = ( start == m_Internals->Expressions.size()-1 );
for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
{
if ( strcmp(d.GetFile(cc), ".") == 0 ||
diff --git a/Source/cmGlob.h b/Source/cmGlob.h
index 1cfa4f8..125cd73 100644
--- a/Source/cmGlob.h
+++ b/Source/cmGlob.h
@@ -38,11 +38,21 @@ public:
//! Return the list of files that matched.
std::vector<std::string>& GetFiles();
+ //! Set recurse to true to match subdirectories.
+ void RecurseOn() { this->SetRecurse(true); }
+ void RecurseOff() { this->SetRecurse(false); }
+ void SetRecurse(bool i) { m_Recurse = i; }
+ bool GetRecurse() { return m_Recurse; }
+
protected:
//! Process directory
void ProcessDirectory(std::string::size_type start,
const std::string& dir, bool dir_only);
+ //! Process last directory, but only when recurse flags is on. That is
+ // effectively like saying: /path/to/file/**/file
+ void RecurseDirectory(const std::string& dir, bool dir_only);
+
//! Escape all non-alphanumeric characters in pattern.
void Escape(int ch, char* buffer);
@@ -55,6 +65,7 @@ protected:
void AddExpression(const char* expr);
cmGlobInternal* m_Internals;
+ bool m_Recurse;
};