diff options
Diffstat (limited to 'Source/cmFindPathCommand.cxx')
-rw-r--r-- | Source/cmFindPathCommand.cxx | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx new file mode 100644 index 0000000..ea26410 --- /dev/null +++ b/Source/cmFindPathCommand.cxx @@ -0,0 +1,153 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFindPathCommand.h" + +#include "cmsys/Glob.hxx" + +#include "cmMakefile.h" +#include "cmStateTypes.h" +#include "cmSystemTools.h" + +class cmExecutionStatus; + +cmFindPathCommand::cmFindPathCommand() +{ + this->EnvironmentPath = "INCLUDE"; + this->IncludeFileInPath = false; +} + +// cmFindPathCommand +bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn, + cmExecutionStatus&) +{ + this->VariableDocumentation = "Path to a file."; + this->CMakePathName = "INCLUDE"; + if (!this->ParseArguments(argsIn)) { + return false; + } + if (this->AlreadyInCache) { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if (this->AlreadyInCacheWithoutMetaInfo) { + this->Makefile->AddCacheDefinition( + this->VariableName, "", this->VariableDocumentation.c_str(), + (this->IncludeFileInPath ? cmStateEnums::FILEPATH + : cmStateEnums::PATH)); + } + return true; + } + + std::string result = this->FindHeader(); + if (!result.empty()) { + this->Makefile->AddCacheDefinition( + this->VariableName, result.c_str(), this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH); + return true; + } + this->Makefile->AddCacheDefinition( + this->VariableName, (this->VariableName + "-NOTFOUND").c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH); + return true; +} + +std::string cmFindPathCommand::FindHeader() +{ + std::string header; + if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) { + header = this->FindFrameworkHeader(); + } + if (header.empty() && !this->SearchFrameworkOnly) { + header = this->FindNormalHeader(); + } + if (header.empty() && this->SearchFrameworkLast) { + header = this->FindFrameworkHeader(); + } + return header; +} + +std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file, + std::string const& dir) +{ + std::string fileName = file; + std::string frameWorkName; + std::string::size_type pos = fileName.find('/'); + // if there is a / in the name try to find the header as a framework + // For example bar/foo.h would look for: + // bar.framework/Headers/foo.h + if (pos != std::string::npos) { + // remove the name from the slash; + fileName = fileName.substr(pos + 1); + frameWorkName = file; + frameWorkName = + frameWorkName.substr(0, frameWorkName.size() - fileName.size() - 1); + // if the framework has a path in it then just use the filename + if (frameWorkName.find('/') != std::string::npos) { + fileName = file; + frameWorkName.clear(); + } + if (!frameWorkName.empty()) { + std::string fpath = dir; + fpath += frameWorkName; + fpath += ".framework"; + std::string intPath = fpath; + intPath += "/Headers/"; + intPath += fileName; + if (cmSystemTools::FileExists(intPath.c_str())) { + if (this->IncludeFileInPath) { + return intPath; + } + return fpath; + } + } + } + // if it is not found yet or not a framework header, then do a glob search + // for all frameworks in the directory: dir/*.framework/Headers/<file> + std::string glob = dir; + glob += "*.framework/Headers/"; + glob += file; + cmsys::Glob globIt; + globIt.FindFiles(glob); + std::vector<std::string> files = globIt.GetFiles(); + if (!files.empty()) { + std::string fheader = cmSystemTools::CollapseFullPath(files[0]); + if (this->IncludeFileInPath) { + return fheader; + } + fheader.resize(fheader.size() - file.size()); + return fheader; + } + return ""; +} + +std::string cmFindPathCommand::FindNormalHeader() +{ + std::string tryPath; + for (std::string const& n : this->Names) { + for (std::string const& sp : this->SearchPaths) { + tryPath = sp; + tryPath += n; + if (cmSystemTools::FileExists(tryPath.c_str())) { + if (this->IncludeFileInPath) { + return tryPath; + } + return sp; + } + } + } + return ""; +} + +std::string cmFindPathCommand::FindFrameworkHeader() +{ + for (std::string const& n : this->Names) { + for (std::string const& sp : this->SearchPaths) { + std::string fwPath = this->FindHeaderInFramework(n, sp); + if (!fwPath.empty()) { + return fwPath; + } + } + } + return ""; +} |