diff options
Diffstat (limited to 'Source/cmFindPathCommand.cxx')
-rw-r--r-- | Source/cmFindPathCommand.cxx | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx new file mode 100644 index 0000000..5531cdf --- /dev/null +++ b/Source/cmFindPathCommand.cxx @@ -0,0 +1,197 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmFindPathCommand.h" +#include "cmCacheManager.h" + +#include <cmsys/Glob.hxx> + +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 ? + cmCacheManager::FILEPATH :cmCacheManager::PATH) + ); + } + return true; + } + + std::string result = this->FindHeader(); + if(result.size() != 0) + { + this->Makefile->AddCacheDefinition + (this->VariableName, result.c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? + cmCacheManager::FILEPATH :cmCacheManager::PATH); + return true; + } + this->Makefile->AddCacheDefinition + (this->VariableName, + (this->VariableName + "-NOTFOUND").c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? + cmCacheManager::FILEPATH :cmCacheManager::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 != fileName.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("/") != frameWorkName.npos) + { + fileName = file; + frameWorkName = ""; + } + if(frameWorkName.size()) + { + 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.size()) + { + std::string fheader = cmSystemTools::CollapseFullPath(files[0].c_str()); + if(this->IncludeFileInPath) + { + return fheader; + } + fheader = cmSystemTools::GetFilenamePath(fheader); + return fheader; + } + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindPathCommand::FindNormalHeader() +{ + std::string tryPath; + for(std::vector<std::string>::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + for(std::vector<std::string>::const_iterator + p = this->SearchPaths.begin(); + p != this->SearchPaths.end(); ++p) + { + tryPath = *p; + tryPath += *ni; + if(cmSystemTools::FileExists(tryPath.c_str())) + { + if(this->IncludeFileInPath) + { + return tryPath; + } + else + { + return *p; + } + } + } + } + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindPathCommand::FindFrameworkHeader() +{ + for(std::vector<std::string>::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + for(std::vector<std::string>::const_iterator + p = this->SearchPaths.begin(); + p != this->SearchPaths.end(); ++p) + { + std::string fwPath = this->FindHeaderInFramework(*ni, *p); + if(!fwPath.empty()) + { + return fwPath; + } + } + } + return ""; +} |