cmake/Source/cmIncludeGuardCommand.cxx

110 lines
2.7 KiB
C++
Raw Normal View History

2018-01-26 17:06:56 +01:00
/* 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"
2021-11-20 13:41:27 +01:00
#include "cmValue.h"
2018-01-26 17:06:56 +01:00
#include "cmake.h"
namespace {
enum IncludeGuardScope
{
VARIABLE,
DIRECTORY,
GLOBAL
};
std::string GetIncludeGuardVariableName(std::string const& filePath)
{
std::string result = "__INCGUARD_";
2020-02-01 23:06:01 +01:00
#ifndef CMAKE_BOOTSTRAP
2018-01-26 17:06:56 +01:00
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
2020-02-01 23:06:01 +01:00
bool cmIncludeGuardCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
2018-01-26 17:06:56 +01:00
{
if (args.size() > 1) {
2020-02-01 23:06:01 +01:00
status.SetError(
2018-01-26 17:06:56 +01:00
"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 {
2020-02-01 23:06:01 +01:00
status.SetError("given an invalid scope: " + arg);
2018-01-26 17:06:56 +01:00
return false;
}
}
std::string includeGuardVar = GetIncludeGuardVariableName(
2021-09-14 00:13:48 +02:00
*status.GetMakefile().GetDefinition("CMAKE_CURRENT_LIST_FILE"));
2018-01-26 17:06:56 +01:00
2020-02-01 23:06:01 +01:00
cmMakefile* const mf = &status.GetMakefile();
2018-01-26 17:06:56 +01:00
switch (scope) {
case VARIABLE:
if (mf->IsDefinitionSet(includeGuardVar)) {
status.SetReturnInvoked();
return true;
}
2020-02-01 23:06:01 +01:00
mf->AddDefinitionBool(includeGuardVar, true);
2018-01-26 17:06:56 +01:00
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;
}