diff options
author | Brad King <brad.king@kitware.com> | 2015-09-08 14:24:36 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2015-09-08 14:24:36 (GMT) |
commit | 4da3315db365f3c80ce5202047955f0f2ec9312f (patch) | |
tree | 0446f74abab8d3a7a15996e27747d45f1a884c05 /Source | |
parent | 20b7e79d211589eed2668474966e77d00025eb37 (diff) | |
parent | 8ea7611bc3650c75c86d22a3127cb117dbcaa9be (diff) | |
download | CMake-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.cxx | 11 | ||||
-rw-r--r-- | Source/cmFindProgramCommand.cxx | 153 | ||||
-rw-r--r-- | Source/cmFindProgramCommand.h | 10 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 9 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 2 |
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. |