diff options
author | Brad King <brad.king@kitware.com> | 2019-08-05 14:40:43 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-08-05 14:42:50 (GMT) |
commit | 2327cc0e0575175e8dec4b7a6fa6cafd5d0f7ca9 (patch) | |
tree | 0e0ac231e503b95b16112189407c160158def992 /Source/cmIfCommand.cxx | |
parent | c969d4628bff6c5b45c788d3a61fff85c36272f6 (diff) | |
parent | 41364824ad84a40c9906b7b5de492e45a74c8945 (diff) | |
download | CMake-2327cc0e0575175e8dec4b7a6fa6cafd5d0f7ca9.zip CMake-2327cc0e0575175e8dec4b7a6fa6cafd5d0f7ca9.tar.gz CMake-2327cc0e0575175e8dec4b7a6fa6cafd5d0f7ca9.tar.bz2 |
Merge topic 'control-block3'
41364824ad cmFunctionBlocker: Recycle functions
6491270e0d cmFunctionBlocker: Move check for matching args
af24e4ef6e cmFunctionBlocker: Move common logic to base
ef38ff22f7 cm*FunctionBlocker: Extract function Replay
b51fba6298 cmMakefile: Add OnExecuteCommand callback
c76500949d cm*FunctionBlocker: Move to source file
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3632
Diffstat (limited to 'Source/cmIfCommand.cxx')
-rw-r--r-- | Source/cmIfCommand.cxx | 249 |
1 files changed, 119 insertions, 130 deletions
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 385022c..c5cfd8c 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -3,10 +3,14 @@ #include "cmIfCommand.h" #include "cm_memory.hxx" +#include "cm_static_string_view.hxx" +#include "cm_string_view.hxx" #include "cmConditionEvaluator.h" #include "cmExecutionStatus.h" #include "cmExpandedCommandArgument.h" +#include "cmFunctionBlocker.h" +#include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmOutputConverter.h" @@ -28,152 +32,138 @@ static std::string cmIfCommandError( return err; } -//========================================================================= -bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff, - cmMakefile& mf, - cmExecutionStatus& inStatus) +class cmIfFunctionBlocker : public cmFunctionBlocker { - // we start by recording all the functions - if (lff.Name.Lower == "if") { - this->ScopeDepth++; - } else if (lff.Name.Lower == "endif") { - this->ScopeDepth--; - // if this is the endif for this if statement, then start executing - if (!this->ScopeDepth) { - // Remove the function blocker for this scope or bail. - std::unique_ptr<cmFunctionBlocker> fb( - mf.RemoveFunctionBlocker(this, lff)); - if (!fb) { - return false; +public: + cm::string_view StartCommandName() const override { return "if"_s; } + cm::string_view EndCommandName() const override { return "endif"_s; } + + bool ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile&) const override; + + bool Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) override; + + std::vector<cmListFileArgument> Args; + bool IsBlocking; + bool HasRun = false; + bool ElseSeen = false; +}; + +bool cmIfFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff, + cmMakefile&) const +{ + return lff.Arguments.empty() || lff.Arguments == this->Args; +} + +bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions, + cmExecutionStatus& inStatus) +{ + cmMakefile& mf = inStatus.GetMakefile(); + // execute the functions for the true parts of the if statement + cmExecutionStatus status(mf); + int scopeDepth = 0; + for (cmListFileFunction const& func : functions) { + // keep track of scope depth + if (func.Name.Lower == "if") { + scopeDepth++; + } + if (func.Name.Lower == "endif") { + scopeDepth--; + } + // watch for our state change + if (scopeDepth == 0 && func.Name.Lower == "else") { + + if (this->ElseSeen) { + cmListFileBacktrace bt = mf.GetBacktrace(func); + mf.GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, + "A duplicate ELSE command was found inside an IF block.", bt); + cmSystemTools::SetFatalErrorOccured(); + return true; } - // execute the functions for the true parts of the if statement - cmExecutionStatus status(mf); - int scopeDepth = 0; - for (cmListFileFunction const& func : this->Functions) { - // keep track of scope depth - if (func.Name.Lower == "if") { - scopeDepth++; - } - if (func.Name.Lower == "endif") { - scopeDepth--; + this->IsBlocking = this->HasRun; + this->HasRun = true; + this->ElseSeen = true; + + // if trace is enabled, print a (trivially) evaluated "else" + // statement + if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) { + mf.PrintCommandTrace(func); + } + } else if (scopeDepth == 0 && func.Name.Lower == "elseif") { + if (this->ElseSeen) { + cmListFileBacktrace bt = mf.GetBacktrace(func); + mf.GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, + "An ELSEIF command was found after an ELSE command.", bt); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + + if (this->HasRun) { + this->IsBlocking = true; + } else { + // if trace is enabled, print the evaluated "elseif" statement + if (mf.GetCMakeInstance()->GetTrace()) { + mf.PrintCommandTrace(func); } - // watch for our state change - if (scopeDepth == 0 && func.Name.Lower == "else") { - - if (this->ElseSeen) { - cmListFileBacktrace bt = mf.GetBacktrace(func); - mf.GetCMakeInstance()->IssueMessage( - MessageType::FATAL_ERROR, - "A duplicate ELSE command was found inside an IF block.", bt); - cmSystemTools::SetFatalErrorOccured(); - return true; - } - this->IsBlocking = this->HasRun; - this->HasRun = true; - this->ElseSeen = true; + std::string errorString; - // if trace is enabled, print a (trivially) evaluated "else" - // statement - if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) { - mf.PrintCommandTrace(func); - } - } else if (scopeDepth == 0 && func.Name.Lower == "elseif") { - if (this->ElseSeen) { - cmListFileBacktrace bt = mf.GetBacktrace(func); - mf.GetCMakeInstance()->IssueMessage( - MessageType::FATAL_ERROR, - "An ELSEIF command was found after an ELSE command.", bt); + std::vector<cmExpandedCommandArgument> expandedArguments; + mf.ExpandArguments(func.Arguments, expandedArguments); + + MessageType messType; + + cmListFileContext conditionContext = + cmListFileContext::FromCommandContext( + func, this->GetStartingContext().FilePath); + + cmConditionEvaluator conditionEvaluator(mf, conditionContext, + mf.GetBacktrace(func)); + + bool isTrue = + conditionEvaluator.IsTrue(expandedArguments, errorString, messType); + + if (!errorString.empty()) { + std::string err = cmIfCommandError(expandedArguments); + err += errorString; + cmListFileBacktrace bt = mf.GetBacktrace(func); + mf.GetCMakeInstance()->IssueMessage(messType, err, bt); + if (messType == MessageType::FATAL_ERROR) { cmSystemTools::SetFatalErrorOccured(); return true; } - - if (this->HasRun) { - this->IsBlocking = true; - } else { - // if trace is enabled, print the evaluated "elseif" statement - if (mf.GetCMakeInstance()->GetTrace()) { - mf.PrintCommandTrace(func); - } - - std::string errorString; - - std::vector<cmExpandedCommandArgument> expandedArguments; - mf.ExpandArguments(func.Arguments, expandedArguments); - - MessageType messType; - - cmListFileContext conditionContext = - cmListFileContext::FromCommandContext( - func, this->GetStartingContext().FilePath); - - cmConditionEvaluator conditionEvaluator(mf, conditionContext, - mf.GetBacktrace(func)); - - bool isTrue = conditionEvaluator.IsTrue(expandedArguments, - errorString, messType); - - if (!errorString.empty()) { - std::string err = cmIfCommandError(expandedArguments); - err += errorString; - cmListFileBacktrace bt = mf.GetBacktrace(func); - mf.GetCMakeInstance()->IssueMessage(messType, err, bt); - if (messType == MessageType::FATAL_ERROR) { - cmSystemTools::SetFatalErrorOccured(); - return true; - } - } - - if (isTrue) { - this->IsBlocking = false; - this->HasRun = true; - } - } } - // should we execute? - else if (!this->IsBlocking) { - status.Clear(); - mf.ExecuteCommand(func, status); - if (status.GetReturnInvoked()) { - inStatus.SetReturnInvoked(); - return true; - } - if (status.GetBreakInvoked()) { - inStatus.SetBreakInvoked(); - return true; - } - if (status.GetContinueInvoked()) { - inStatus.SetContinueInvoked(); - return true; - } + if (isTrue) { + this->IsBlocking = false; + this->HasRun = true; } } - return true; } - } - // record the command - this->Functions.push_back(lff); - - // always return true - return true; -} - -//========================================================================= -bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, - cmMakefile&) -{ - if (lff.Name.Lower == "endif") { - // if the endif has arguments, then make sure - // they match the arguments of the matching if - if (lff.Arguments.empty() || lff.Arguments == this->Args) { - return true; + // should we execute? + else if (!this->IsBlocking) { + status.Clear(); + mf.ExecuteCommand(func, status); + if (status.GetReturnInvoked()) { + inStatus.SetReturnInvoked(); + return true; + } + if (status.GetBreakInvoked()) { + inStatus.SetBreakInvoked(); + return true; + } + if (status.GetContinueInvoked()) { + inStatus.SetContinueInvoked(); + return true; + } } } - - return false; + return true; } //========================================================================= @@ -208,7 +198,6 @@ bool cmIfCommand(std::vector<cmListFileArgument> const& args, { auto fb = cm::make_unique<cmIfFunctionBlocker>(); // if is isn't true block the commands - fb->ScopeDepth = 1; fb->IsBlocking = !isTrue; if (isTrue) { fb->HasRun = true; |