diff options
Diffstat (limited to 'Source/cmIncludeGuardCommand.cxx')
-rw-r--r-- | Source/cmIncludeGuardCommand.cxx | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx new file mode 100644 index 0000000..505b07c --- /dev/null +++ b/Source/cmIncludeGuardCommand.cxx @@ -0,0 +1,108 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmIncludeGuardCommand.h" + +#include "cmExecutionStatus.h" +#include "cmMakefile.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" +#include "cmSystemTools.h" +#include "cmake.h" + +namespace { + +enum IncludeGuardScope +{ + VARIABLE, + DIRECTORY, + GLOBAL +}; + +std::string GetIncludeGuardVariableName(std::string const& filePath) +{ + std::string result = "__INCGUARD_"; +#ifdef CMAKE_BUILD_WITH_CMAKE + result += cmSystemTools::ComputeStringMD5(filePath); +#else + result += cmSystemTools::MakeCidentifier(filePath); +#endif + result += "__"; + return result; +} + +bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar) +{ + if (mf->GetProperty(includeGuardVar)) { + return true; + } + cmStateSnapshot dirSnapshot = + mf->GetStateSnapshot().GetBuildsystemDirectoryParent(); + while (dirSnapshot.GetState()) { + cmStateDirectory stateDir = dirSnapshot.GetDirectory(); + if (stateDir.GetProperty(includeGuardVar)) { + return true; + } + dirSnapshot = dirSnapshot.GetBuildsystemDirectoryParent(); + } + return false; +} + +} // anonymous namespace + +// cmIncludeGuardCommand +bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + if (args.size() > 1) { + this->SetError( + "given an invalid number of arguments. The command takes at " + "most 1 argument."); + return false; + } + + IncludeGuardScope scope = VARIABLE; + + if (!args.empty()) { + std::string const& arg = args[0]; + if (arg == "DIRECTORY") { + scope = DIRECTORY; + } else if (arg == "GLOBAL") { + scope = GLOBAL; + } else { + this->SetError("given an invalid scope: " + arg); + return false; + } + } + + std::string includeGuardVar = GetIncludeGuardVariableName( + this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE")); + + cmMakefile* const mf = this->Makefile; + + switch (scope) { + case VARIABLE: + if (mf->IsDefinitionSet(includeGuardVar)) { + status.SetReturnInvoked(); + return true; + } + mf->AddDefinition(includeGuardVar, true); + break; + case DIRECTORY: + if (CheckIncludeGuardIsSet(mf, includeGuardVar)) { + status.SetReturnInvoked(); + return true; + } + mf->SetProperty(includeGuardVar, "TRUE"); + break; + case GLOBAL: + cmake* const cm = mf->GetCMakeInstance(); + if (cm->GetProperty(includeGuardVar)) { + status.SetReturnInvoked(); + return true; + } + cm->SetProperty(includeGuardVar, "TRUE"); + break; + } + + return true; +} |