diff options
author | Brad King <brad.king@kitware.com> | 2017-06-28 12:53:21 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2017-06-28 12:53:30 (GMT) |
commit | 0552747b58799afd6cb23db1cc5296a605cfde18 (patch) | |
tree | 4d8765b3cbc64a3e0ad40d5dcfecf836ec2bb99d /Source | |
parent | 45ca0403ac11a78550997a38d9d55a06439220c9 (diff) | |
parent | c96f43b7dd1d41379fe63b4e8b508b2b034520b6 (diff) | |
download | CMake-0552747b58799afd6cb23db1cc5296a605cfde18.zip CMake-0552747b58799afd6cb23db1cc5296a605cfde18.tar.gz CMake-0552747b58799afd6cb23db1cc5296a605cfde18.tar.bz2 |
Merge topic 'feature/include_guard'
c96f43b7 include_guard: add tests for the feature
80f1221f include_guard: add doc pages and a release note
85b52a04 include_guard: add vim syntax highlighting rules
d44bd1c2 include_guard: implement new command
Acked-by: Kitware Robot <kwrobot@kitware.com>
Reviewed-by: Craig Scott <craig.scott@crascit.com>
Merge-request: !928
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmCommands.cxx | 2 | ||||
-rw-r--r-- | Source/cmIncludeGuardCommand.cxx | 108 | ||||
-rw-r--r-- | Source/cmIncludeGuardCommand.h | 37 |
4 files changed, 149 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1878b8a..660d632 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -469,6 +469,8 @@ set(SRCS cmIncludeDirectoryCommand.h cmIncludeExternalMSProjectCommand.cxx cmIncludeExternalMSProjectCommand.h + cmIncludeGuardCommand.cxx + cmIncludeGuardCommand.h cmIncludeRegularExpressionCommand.cxx cmIncludeRegularExpressionCommand.h cmInstallCommand.cxx diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index e1d8ef1..485dd50 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -42,6 +42,7 @@ #include "cmIfCommand.h" #include "cmIncludeCommand.h" #include "cmIncludeDirectoryCommand.h" +#include "cmIncludeGuardCommand.h" #include "cmIncludeRegularExpressionCommand.h" #include "cmInstallCommand.h" #include "cmInstallFilesCommand.h" @@ -132,6 +133,7 @@ void GetScriptingCommands(cmState* state) state->AddBuiltinCommand("get_property", new cmGetPropertyCommand); state->AddBuiltinCommand("if", new cmIfCommand); state->AddBuiltinCommand("include", new cmIncludeCommand); + state->AddBuiltinCommand("include_guard", new cmIncludeGuardCommand); state->AddBuiltinCommand("list", new cmListCommand); state->AddBuiltinCommand("macro", new cmMacroCommand); state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand); 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; +} diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h new file mode 100644 index 0000000..140c04f --- /dev/null +++ b/Source/cmIncludeGuardCommand.h @@ -0,0 +1,37 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmIncludeGuardCommand_h +#define cmIncludeGuardCommand_h + +#include "cmConfigure.h" + +#include <string> +#include <vector> + +#include "cmCommand.h" + +class cmExecutionStatus; + +/** \class cmIncludeGuardCommand + * \brief cmIncludeGuardCommand identical to C++ #pragma_once command + * Can work in 3 modes: GLOBAL (works on global properties), + * DIRECTORY(use directory property), VARIABLE(unnamed overload without + * arguments) define an ordinary variable to be used as include guard checker + */ +class cmIncludeGuardCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + cmCommand* Clone() CM_OVERRIDE { return new cmIncludeGuardCommand; } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) CM_OVERRIDE; +}; + +#endif |