summaryrefslogtreecommitdiffstats
path: root/Source/cmGlob.cxx
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2003-07-08 18:18:17 (GMT)
committerAndy Cedilnik <andy.cedilnik@kitware.com>2003-07-08 18:18:17 (GMT)
commitdb77d2e0192893ad9dda95bec0ebd9d6287fea14 (patch)
tree5aedd49117119e12af9b50647fdb696042d5ab29 /Source/cmGlob.cxx
parent1a4ec91593b8133897c2741d6dd43b2216ebb590 (diff)
downloadCMake-db77d2e0192893ad9dda95bec0ebd9d6287fea14.zip
CMake-db77d2e0192893ad9dda95bec0ebd9d6287fea14.tar.gz
CMake-db77d2e0192893ad9dda95bec0ebd9d6287fea14.tar.bz2
ENH: Add globbing to FILE command
Diffstat (limited to 'Source/cmGlob.cxx')
-rw-r--r--Source/cmGlob.cxx240
1 files changed, 240 insertions, 0 deletions
diff --git a/Source/cmGlob.cxx b/Source/cmGlob.cxx
new file mode 100644
index 0000000..6430c48
--- /dev/null
+++ b/Source/cmGlob.cxx
@@ -0,0 +1,240 @@
+/*=========================================================================
+
+ Program: CMake - Cross-Platform Makefile Generator
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmGlob.h"
+
+#include <cmsys/Directory.hxx>
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/SystemTools.hxx>
+
+#include <stdio.h>
+
+class cmGlobInternal
+{
+public:
+ std::vector<std::string> Files;
+ std::vector<cmsys::RegularExpression> Expressions;
+};
+
+cmGlob::cmGlob()
+{
+ m_Internals = new cmGlobInternal;
+}
+
+cmGlob::~cmGlob()
+{
+ delete m_Internals;
+}
+
+void cmGlob::Escape(int ch, char* buffer)
+{
+ if (! (
+ 'a' <= ch && ch <= 'z' ||
+ 'A' <= ch && ch <= 'Z' ||
+ '0' <= ch && ch <= '9') )
+ {
+ sprintf(buffer, "\\%c", ch);
+ }
+ else
+ {
+ sprintf(buffer, "%c", ch);
+ }
+}
+
+std::vector<std::string>& cmGlob::GetFiles()
+{
+ return m_Internals->Files;
+}
+
+std::string cmGlob::ConvertExpression(const std::string& expr)
+{
+
+ std::string::size_type i = 0;
+ std::string::size_type n = expr.size();
+
+ std::string res = "^";
+ std::string stuff = "";
+
+ while ( i < n )
+ {
+ int c = expr[i];
+ i = i+1;
+ if ( c == '*' )
+ {
+ res = res + ".*";
+ }
+ else if ( c == '?' )
+ {
+ res = res + ".";
+ }
+ else if ( c == '[' )
+ {
+ std::string::size_type j = i;
+ if ( j < n && expr[j] == '!' )
+ {
+ j = j+1;
+ }
+ if ( j < n && expr[j] == ']' )
+ {
+ j = j+1;
+ }
+ while ( j < n && expr[j] != ']' )
+ {
+ j = j+1;
+ }
+ if ( j >= n )
+ {
+ res = res + "\\[";
+ }
+ else
+ {
+ stuff = "";
+ std::string::size_type cc;
+ for ( cc = i; cc < j; cc ++ )
+ {
+ if ( expr[cc] == '\\' )
+ {
+ stuff += "\\\\";
+ }
+ else
+ {
+ stuff += expr[cc];
+ }
+ }
+ i = j+1;
+ if ( stuff[0] == '!' )
+ {
+ stuff = '^' + stuff.substr(1);
+ }
+ else if ( stuff[0] == '^' )
+ {
+ stuff = '\\' + stuff;
+ }
+ res = res + "[" + stuff + "]";
+ }
+ }
+ else
+ {
+ char buffer[100];
+ buffer[0] = 0;
+ this->Escape(c, buffer);
+ res = res + buffer;
+ }
+ }
+ return res + "$";
+}
+
+void cmGlob::ProcessDirectory(std::string::size_type start,
+ const std::string& dir, bool dir_only)
+{
+ cmsys::Directory d;
+ if ( !d.Load(dir.c_str()) )
+ {
+ //std::cout << "Cannot open directory: " << dir.c_str() << std::endl;
+ return;
+ }
+ unsigned long cc;
+ std::string fullname;
+ bool last = ( start == m_Internals->Expressions.size()-1 );
+ //std::cout << "Last: " << last << " Dironly: " << dir_only << std::endl;
+ for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
+ {
+ if ( strcmp(d.GetFile(cc), ".") == 0 ||
+ strcmp(d.GetFile(cc), "..") == 0 )
+ {
+ continue;
+ }
+ if ( start == 0 )
+ {
+ fullname = dir + d.GetFile(cc);
+ }
+ else
+ {
+ fullname = dir + "/" + d.GetFile(cc);
+ }
+
+ if ( (!dir_only || !last) && !cmsys::SystemTools::FileIsDirectory(fullname.c_str()) )
+ {
+ //std::cout << " Ignore: " << fullname.c_str() << std::endl;
+ continue;
+ }
+ if ( m_Internals->Expressions[start].find(d.GetFile(cc)) )
+ {
+ //std::cout << " Matches: " << fullname.c_str() << std::endl;
+ if ( last )
+ {
+ //std::cout << "--- find file: " << fullname.c_str() << "---" << std::endl;
+ m_Internals->Files.push_back(fullname);
+ }
+ else
+ {
+ this->ProcessDirectory(start+1, fullname, dir_only);
+ }
+ }
+ else
+ {
+ //std::cout << " Not Matches: " << fullname.c_str() << std::endl;
+ }
+ }
+}
+
+bool cmGlob::FindFiles(const std::string& inexpr)
+{
+ std::string cexpr;
+ std::string::size_type cc;
+ std::string expr = inexpr;
+
+ m_Internals->Expressions.empty();
+ m_Internals->Files.empty();
+
+ if ( !cmsys::SystemTools::FileIsFullPath(expr.c_str()) )
+ {
+ expr = cmsys::SystemTools::GetCurrentWorkingDirectory();
+ expr += "/" + inexpr;
+ }
+ std::cout << "Expr: " << expr << std::endl;
+ for ( cc = 0; cc < expr.size(); cc ++ )
+ {
+ int ch = expr[cc];
+ if ( ch == '/' )
+ {
+ if ( cexpr.size() > 0 )
+ {
+ this->AddExpression(cexpr.c_str());
+ }
+ cexpr = "";
+ }
+ else
+ {
+ cexpr.append(1, (char)ch);
+ }
+ }
+ if ( cexpr.size() > 0 )
+ {
+ this->AddExpression(cexpr.c_str());
+ }
+
+ this->ProcessDirectory(0, "/", true);
+ return true;
+}
+
+void cmGlob::AddExpression(const char* expr)
+{
+ m_Internals->Expressions.push_back(
+ cmsys::RegularExpression(
+ this->ConvertExpression(expr).c_str()));
+}
+