mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 19:00:54 -06:00
cm*FunctionBlocker: Extract function Replay
This commit is contained in:
@@ -25,6 +25,8 @@ public:
|
||||
bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
|
||||
cmExecutionStatus&) override;
|
||||
bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus);
|
||||
|
||||
std::vector<std::string> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
@@ -63,44 +65,7 @@ bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
// at end of for each execute recorded commands
|
||||
// store the old value
|
||||
std::string oldDef;
|
||||
if (mf.GetDefinition(this->Args[0])) {
|
||||
oldDef = mf.GetDefinition(this->Args[0]);
|
||||
}
|
||||
|
||||
for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
|
||||
// set the variable to the loop value
|
||||
mf.AddDefinition(this->Args[0], arg);
|
||||
// Invoke all the functions that were collected in the block.
|
||||
cmExecutionStatus status(mf);
|
||||
for (cmListFileFunction const& func : this->Functions) {
|
||||
status.Clear();
|
||||
mf.ExecuteCommand(func, status);
|
||||
if (status.GetReturnInvoked()) {
|
||||
inStatus.SetReturnInvoked();
|
||||
// restore the variable to its prior value
|
||||
mf.AddDefinition(this->Args[0], oldDef);
|
||||
return true;
|
||||
}
|
||||
if (status.GetBreakInvoked()) {
|
||||
// restore the variable to its prior value
|
||||
mf.AddDefinition(this->Args[0], oldDef);
|
||||
return true;
|
||||
}
|
||||
if (status.GetContinueInvoked()) {
|
||||
break;
|
||||
}
|
||||
if (cmSystemTools::GetFatalErrorOccured()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore the variable to its prior value
|
||||
mf.AddDefinition(this->Args[0], oldDef);
|
||||
return true;
|
||||
return this->Replay(this->Functions, inStatus);
|
||||
}
|
||||
// close out a nested foreach
|
||||
this->Depth--;
|
||||
@@ -129,6 +94,51 @@ bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmForEachFunctionBlocker::Replay(
|
||||
std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus)
|
||||
{
|
||||
cmMakefile& mf = inStatus.GetMakefile();
|
||||
// at end of for each execute recorded commands
|
||||
// store the old value
|
||||
std::string oldDef;
|
||||
if (mf.GetDefinition(this->Args[0])) {
|
||||
oldDef = mf.GetDefinition(this->Args[0]);
|
||||
}
|
||||
|
||||
for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
|
||||
// set the variable to the loop value
|
||||
mf.AddDefinition(this->Args[0], arg);
|
||||
// Invoke all the functions that were collected in the block.
|
||||
cmExecutionStatus status(mf);
|
||||
for (cmListFileFunction const& func : functions) {
|
||||
status.Clear();
|
||||
mf.ExecuteCommand(func, status);
|
||||
if (status.GetReturnInvoked()) {
|
||||
inStatus.SetReturnInvoked();
|
||||
// restore the variable to its prior value
|
||||
mf.AddDefinition(this->Args[0], oldDef);
|
||||
return true;
|
||||
}
|
||||
if (status.GetBreakInvoked()) {
|
||||
// restore the variable to its prior value
|
||||
mf.AddDefinition(this->Args[0], oldDef);
|
||||
return true;
|
||||
}
|
||||
if (status.GetContinueInvoked()) {
|
||||
break;
|
||||
}
|
||||
if (cmSystemTools::GetFatalErrorOccured()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore the variable to its prior value
|
||||
mf.AddDefinition(this->Args[0], oldDef);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus&)
|
||||
{
|
||||
|
||||
@@ -110,6 +110,8 @@ public:
|
||||
bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
|
||||
cmExecutionStatus&) override;
|
||||
bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& status);
|
||||
|
||||
std::vector<std::string> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
@@ -117,7 +119,7 @@ public:
|
||||
};
|
||||
|
||||
bool cmFunctionFunctionBlocker::IsFunctionBlocked(
|
||||
const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus&)
|
||||
const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus& status)
|
||||
{
|
||||
// record commands until we hit the ENDFUNCTION
|
||||
// at the ENDFUNCTION call we shift gears and start looking for invocations
|
||||
@@ -126,16 +128,8 @@ bool cmFunctionFunctionBlocker::IsFunctionBlocked(
|
||||
} else if (lff.Name.Lower == "endfunction") {
|
||||
// if this is the endfunction for this function then execute
|
||||
if (!this->Depth) {
|
||||
// create a new command and add it to cmake
|
||||
cmFunctionHelperCommand f;
|
||||
f.Args = this->Args;
|
||||
f.Functions = this->Functions;
|
||||
f.FilePath = this->GetStartingContext().FilePath;
|
||||
mf.RecordPolicies(f.Policies);
|
||||
mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
|
||||
// remove the function blocker now that the function is defined
|
||||
mf.RemoveFunctionBlocker(this, lff);
|
||||
return true;
|
||||
auto self = mf.RemoveFunctionBlocker(this, lff);
|
||||
return this->Replay(this->Functions, status);
|
||||
}
|
||||
// decrement for each nested function that ends
|
||||
this->Depth--;
|
||||
@@ -165,6 +159,20 @@ bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmFunctionFunctionBlocker::Replay(
|
||||
std::vector<cmListFileFunction> const& functions, cmExecutionStatus& status)
|
||||
{
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
// create a new command and add it to cmake
|
||||
cmFunctionHelperCommand f;
|
||||
f.Args = this->Args;
|
||||
f.Functions = functions;
|
||||
f.FilePath = this->GetStartingContext().FilePath;
|
||||
mf.RecordPolicies(f.Policies);
|
||||
mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus&)
|
||||
{
|
||||
|
||||
@@ -36,6 +36,8 @@ public:
|
||||
bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
|
||||
cmExecutionStatus&) override;
|
||||
bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus);
|
||||
|
||||
std::vector<cmListFileArgument> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
@@ -64,110 +66,7 @@ bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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--;
|
||||
}
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return this->Replay(this->Functions, inStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +92,117 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmIfFunctionBlocker::Replay(
|
||||
std::vector<cmListFileFunction> const& 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
bool cmIfCommand(std::vector<cmListFileArgument> const& args,
|
||||
cmExecutionStatus& inStatus)
|
||||
|
||||
@@ -144,6 +144,8 @@ public:
|
||||
bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
|
||||
cmExecutionStatus&) override;
|
||||
bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& status);
|
||||
|
||||
std::vector<std::string> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
@@ -152,7 +154,7 @@ public:
|
||||
|
||||
bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
cmMakefile& mf,
|
||||
cmExecutionStatus&)
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
// record commands until we hit the ENDMACRO
|
||||
// at the ENDMACRO call we shift gears and start looking for invocations
|
||||
@@ -161,17 +163,8 @@ bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
} else if (lff.Name.Lower == "endmacro") {
|
||||
// if this is the endmacro for this macro then execute
|
||||
if (!this->Depth) {
|
||||
mf.AppendProperty("MACROS", this->Args[0].c_str());
|
||||
// create a new command and add it to cmake
|
||||
cmMacroHelperCommand f;
|
||||
f.Args = this->Args;
|
||||
f.Functions = this->Functions;
|
||||
f.FilePath = this->GetStartingContext().FilePath;
|
||||
mf.RecordPolicies(f.Policies);
|
||||
mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
|
||||
// remove the function blocker now that the macro is defined
|
||||
mf.RemoveFunctionBlocker(this, lff);
|
||||
return true;
|
||||
auto self = mf.RemoveFunctionBlocker(this, lff);
|
||||
return this->Replay(this->Functions, status);
|
||||
}
|
||||
// decrement for each nested macro that ends
|
||||
this->Depth--;
|
||||
@@ -201,6 +194,21 @@ bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmMacroFunctionBlocker::Replay(
|
||||
std::vector<cmListFileFunction> const& functions, cmExecutionStatus& status)
|
||||
{
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
mf.AppendProperty("MACROS", this->Args[0].c_str());
|
||||
// create a new command and add it to cmake
|
||||
cmMacroHelperCommand f;
|
||||
f.Args = this->Args;
|
||||
f.Functions = functions;
|
||||
f.FilePath = this->GetStartingContext().FilePath;
|
||||
mf.RecordPolicies(f.Policies);
|
||||
mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus&)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,8 @@ public:
|
||||
bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
|
||||
cmExecutionStatus&) override;
|
||||
bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
|
||||
bool Replay(std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus);
|
||||
|
||||
std::vector<cmListFileArgument> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
@@ -62,68 +64,7 @@ bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
if (!fb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string errorString;
|
||||
|
||||
std::vector<cmExpandedCommandArgument> expandedArguments;
|
||||
mf.ExpandArguments(this->Args, expandedArguments);
|
||||
MessageType messageType;
|
||||
|
||||
cmListFileContext execContext = this->GetStartingContext();
|
||||
|
||||
cmCommandContext commandContext;
|
||||
commandContext.Line = execContext.Line;
|
||||
commandContext.Name = execContext.Name;
|
||||
|
||||
cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
|
||||
mf.GetBacktrace(commandContext));
|
||||
|
||||
bool isTrue =
|
||||
conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
|
||||
|
||||
while (isTrue) {
|
||||
if (!errorString.empty()) {
|
||||
std::string err = "had incorrect arguments: ";
|
||||
for (cmListFileArgument const& arg : this->Args) {
|
||||
err += (arg.Delim ? "\"" : "");
|
||||
err += arg.Value;
|
||||
err += (arg.Delim ? "\"" : "");
|
||||
err += " ";
|
||||
}
|
||||
err += "(";
|
||||
err += errorString;
|
||||
err += ").";
|
||||
mf.IssueMessage(messageType, err);
|
||||
if (messageType == MessageType::FATAL_ERROR) {
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke all the functions that were collected in the block.
|
||||
for (cmListFileFunction const& fn : this->Functions) {
|
||||
cmExecutionStatus status(mf);
|
||||
mf.ExecuteCommand(fn, status);
|
||||
if (status.GetReturnInvoked()) {
|
||||
inStatus.SetReturnInvoked();
|
||||
return true;
|
||||
}
|
||||
if (status.GetBreakInvoked()) {
|
||||
return true;
|
||||
}
|
||||
if (status.GetContinueInvoked()) {
|
||||
break;
|
||||
}
|
||||
if (cmSystemTools::GetFatalErrorOccured()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
expandedArguments.clear();
|
||||
mf.ExpandArguments(this->Args, expandedArguments);
|
||||
isTrue = conditionEvaluator.IsTrue(expandedArguments, errorString,
|
||||
messageType);
|
||||
}
|
||||
return true;
|
||||
return this->Replay(this->Functions, inStatus);
|
||||
}
|
||||
// decrement for each nested while that ends
|
||||
this->Depth--;
|
||||
@@ -149,6 +90,74 @@ bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmWhileFunctionBlocker::Replay(
|
||||
std::vector<cmListFileFunction> const& functions,
|
||||
cmExecutionStatus& inStatus)
|
||||
{
|
||||
cmMakefile& mf = inStatus.GetMakefile();
|
||||
std::string errorString;
|
||||
|
||||
std::vector<cmExpandedCommandArgument> expandedArguments;
|
||||
mf.ExpandArguments(this->Args, expandedArguments);
|
||||
MessageType messageType;
|
||||
|
||||
cmListFileContext execContext = this->GetStartingContext();
|
||||
|
||||
cmCommandContext commandContext;
|
||||
commandContext.Line = execContext.Line;
|
||||
commandContext.Name = execContext.Name;
|
||||
|
||||
cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
|
||||
mf.GetBacktrace(commandContext));
|
||||
|
||||
bool isTrue =
|
||||
conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
|
||||
|
||||
while (isTrue) {
|
||||
if (!errorString.empty()) {
|
||||
std::string err = "had incorrect arguments: ";
|
||||
for (cmListFileArgument const& arg : this->Args) {
|
||||
err += (arg.Delim ? "\"" : "");
|
||||
err += arg.Value;
|
||||
err += (arg.Delim ? "\"" : "");
|
||||
err += " ";
|
||||
}
|
||||
err += "(";
|
||||
err += errorString;
|
||||
err += ").";
|
||||
mf.IssueMessage(messageType, err);
|
||||
if (messageType == MessageType::FATAL_ERROR) {
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke all the functions that were collected in the block.
|
||||
for (cmListFileFunction const& fn : functions) {
|
||||
cmExecutionStatus status(mf);
|
||||
mf.ExecuteCommand(fn, status);
|
||||
if (status.GetReturnInvoked()) {
|
||||
inStatus.SetReturnInvoked();
|
||||
return true;
|
||||
}
|
||||
if (status.GetBreakInvoked()) {
|
||||
return true;
|
||||
}
|
||||
if (status.GetContinueInvoked()) {
|
||||
break;
|
||||
}
|
||||
if (cmSystemTools::GetFatalErrorOccured()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
expandedArguments.clear();
|
||||
mf.ExpandArguments(this->Args, expandedArguments);
|
||||
isTrue =
|
||||
conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user