summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-09-08 14:24:36 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2015-09-08 14:24:36 (GMT)
commit4da3315db365f3c80ce5202047955f0f2ec9312f (patch)
tree0446f74abab8d3a7a15996e27747d45f1a884c05 /Source
parent20b7e79d211589eed2668474966e77d00025eb37 (diff)
parent8ea7611bc3650c75c86d22a3127cb117dbcaa9be (diff)
downloadCMake-4da3315db365f3c80ce5202047955f0f2ec9312f.zip
CMake-4da3315db365f3c80ce5202047955f0f2ec9312f.tar.gz
CMake-4da3315db365f3c80ce5202047955f0f2ec9312f.tar.bz2
Merge topic 'find_program-NAMES_PER_DIR'
8ea7611b find_program: Optionally consider all names in each directory fc1990c9 cmFindProgramCommand: Re-implement search using more flexible approach fdbfc9f6 Tests: Add explicit testing for find_program 907a919b cmSystemTools: Drop unused StringEndsWith method ed4de3c9 cmFindProgramCommand: Use Names member instead of passing it bf32b95e cmFindLibraryCommand: Avoid repeating search for the same name
Diffstat (limited to 'Source')
-rw-r--r--Source/cmFindLibraryCommand.cxx11
-rw-r--r--Source/cmFindProgramCommand.cxx153
-rw-r--r--Source/cmFindProgramCommand.h10
-rw-r--r--Source/cmSystemTools.cxx9
-rw-r--r--Source/cmSystemTools.h2
5 files changed, 159 insertions, 26 deletions
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index e8d158e..e7696af 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -203,6 +203,7 @@ struct cmFindLibraryHelper
}
bool HasValidSuffix(std::string const& name);
void AddName(std::string const& name);
+ void SetName(std::string const& name);
bool CheckDirectory(std::string const& path);
bool CheckDirectoryForName(std::string const& path, Name& name);
};
@@ -322,6 +323,13 @@ void cmFindLibraryHelper::AddName(std::string const& name)
}
//----------------------------------------------------------------------------
+void cmFindLibraryHelper::SetName(std::string const& name)
+{
+ this->Names.clear();
+ this->AddName(name);
+}
+
+//----------------------------------------------------------------------------
bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
{
for(std::vector<Name>::iterator i = this->Names.begin();
@@ -459,8 +467,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
ni != this->Names.end() ; ++ni)
{
// Switch to searching for this name.
- std::string const& name = *ni;
- helper.AddName(name);
+ helper.SetName(*ni);
// Search every directory.
for(std::vector<std::string>::const_iterator
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index fbd9fd3..e64ed87 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -16,6 +16,80 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
+//----------------------------------------------------------------------------
+struct cmFindProgramHelper
+{
+ cmFindProgramHelper()
+ {
+#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
+ // Consider platform-specific extensions.
+ this->Extensions.push_back(".com");
+ this->Extensions.push_back(".exe");
+#endif
+ // Consider original name with no extensions.
+ this->Extensions.push_back("");
+ }
+
+ // List of valid extensions.
+ std::vector<std::string> Extensions;
+
+ // Keep track of the best program file found so far.
+ std::string BestPath;
+
+ // Current names under consideration.
+ std::vector<std::string> Names;
+
+ // Current full path under consideration.
+ std::string TestPath;
+
+ void AddName(std::string const& name)
+ {
+ this->Names.push_back(name);
+ }
+ void SetName(std::string const& name)
+ {
+ this->Names.clear();
+ this->AddName(name);
+ }
+ bool CheckDirectory(std::string const& path)
+ {
+ for (std::vector<std::string>::iterator i = this->Names.begin();
+ i != this->Names.end(); ++i)
+ {
+ if (this->CheckDirectoryForName(path, *i))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ bool CheckDirectoryForName(std::string const& path, std::string const& name)
+ {
+ for (std::vector<std::string>::iterator ext = this->Extensions.begin();
+ ext != this->Extensions.end(); ++ext)
+ {
+ this->TestPath = path;
+ this->TestPath += name;
+ if (!ext->empty() && cmSystemTools::StringEndsWith(name, ext->c_str()))
+ {
+ continue;
+ }
+ this->TestPath += *ext;
+ if (cmSystemTools::FileExists(this->TestPath, true))
+ {
+ this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+cmFindProgramCommand::cmFindProgramCommand()
+{
+ this->NamesPerDirAllowed = true;
+}
+
// cmFindProgramCommand
bool cmFindProgramCommand
::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
@@ -41,7 +115,7 @@ bool cmFindProgramCommand
return true;
}
- std::string result = FindProgram(this->Names);
+ std::string result = FindProgram();
if(result != "")
{
// Save the value in the cache
@@ -59,31 +133,92 @@ bool cmFindProgramCommand
return true;
}
-std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
+std::string cmFindProgramCommand::FindProgram()
{
std::string program = "";
if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
{
- program = FindAppBundle(names);
+ program = FindAppBundle();
}
if(program.empty() && !this->SearchAppBundleOnly)
{
- program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
+ program = this->FindNormalProgram();
}
if(program.empty() && this->SearchAppBundleLast)
{
- program = this->FindAppBundle(names);
+ program = this->FindAppBundle();
}
return program;
}
-std::string cmFindProgramCommand
-::FindAppBundle(std::vector<std::string> names)
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgram()
+{
+ if(this->NamesPerDir)
+ {
+ return this->FindNormalProgramNamesPerDir();
+ }
+ else
+ {
+ return this->FindNormalProgramDirsPerName();
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
+{
+ // Search for all names in each directory.
+ cmFindProgramHelper helper;
+ for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ helper.AddName(*ni);
+ }
+ // Search every directory.
+ for (std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin(); p != this->SearchPaths.end(); ++p)
+ {
+ if(helper.CheckDirectory(*p))
+ {
+ return helper.BestPath;
+ }
+ }
+ // Couldn't find the program.
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
+{
+ // Search the entire path for each name.
+ cmFindProgramHelper helper;
+ for (std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ // Switch to searching for this name.
+ helper.SetName(*ni);
+
+ // Search every directory.
+ for (std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin();
+ p != this->SearchPaths.end(); ++p)
+ {
+ if (helper.CheckDirectory(*p))
+ {
+ return helper.BestPath;
+ }
+ }
+ }
+ // Couldn't find the program.
+ return "";
+}
+
+std::string cmFindProgramCommand::FindAppBundle()
{
- for(std::vector<std::string>::const_iterator name = names.begin();
- name != names.end() ; ++name)
+ for(std::vector<std::string>::const_iterator name = this->Names.begin();
+ name != this->Names.end() ; ++name)
{
std::string appName = *name + std::string(".app");
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index 70f758f..f88186b 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -25,6 +25,7 @@
class cmFindProgramCommand : public cmFindBase
{
public:
+ cmFindProgramCommand();
/**
* This is a virtual constructor for the command.
*/
@@ -52,11 +53,12 @@ public:
cmTypeMacro(cmFindProgramCommand, cmFindBase);
-protected:
- std::string FindProgram(std::vector<std::string> names);
-
private:
- std::string FindAppBundle(std::vector<std::string> names);
+ std::string FindProgram();
+ std::string FindNormalProgram();
+ std::string FindNormalProgramDirsPerName();
+ std::string FindNormalProgramNamesPerDir();
+ std::string FindAppBundle();
std::string GetBundleExecutable(std::string bundlePath);
};
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 64eeed6..b1b7f47 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1409,15 +1409,6 @@ std::string cmSystemTools::ConvertToRunCommandPath(const char* path)
#endif
}
-bool cmSystemTools::StringEndsWith(const char* str1, const char* str2)
-{
- if ( !str1 || !str2 || strlen(str1) < strlen(str2) )
- {
- return 0;
- }
- return !strncmp(str1 + (strlen(str1)-strlen(str2)), str2, strlen(str2));
-}
-
// compute the relative path from here to there
std::string cmSystemTools::RelativePath(const char* local, const char* remote)
{
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index c12a1db..d14897f 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -336,8 +336,6 @@ public:
// be used when RunCommand is called from cmake, because the
// running cmake needs paths to be in its format
static std::string ConvertToRunCommandPath(const char* path);
- //! Check if the first string ends with the second one.
- static bool StringEndsWith(const char* str1, const char* str2);
/** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory.