ENH: allow loose loop constructs
This commit is contained in:
parent
095e975c81
commit
29a03db7ce
@ -25,14 +25,18 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// at end of for each execute recorded commands
|
if (cmSystemTools::LowerCase(lff.Name) == "foreach")
|
||||||
if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
|
|
||||||
{
|
{
|
||||||
std::vector<std::string> expandedArguments;
|
// record the number of nested foreach commands
|
||||||
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
this->Depth++;
|
||||||
if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
|
}
|
||||||
|
else if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
|
||||||
|
{
|
||||||
|
// if this is the endofreach for this statement
|
||||||
|
if (!this->Depth)
|
||||||
{
|
{
|
||||||
|
// at end of for each execute recorded commands
|
||||||
// store the old value
|
// store the old value
|
||||||
std::string oldDef;
|
std::string oldDef;
|
||||||
if (mf.GetDefinition(this->Args[0].c_str()))
|
if (mf.GetDefinition(this->Args[0].c_str()))
|
||||||
@ -60,8 +64,13 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||||||
mf.RemoveFunctionBlocker(lff);
|
mf.RemoveFunctionBlocker(lff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// close out a nested foreach
|
||||||
|
this->Depth--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// record the command
|
// record the command
|
||||||
this->Functions.push_back(lff);
|
this->Functions.push_back(lff);
|
||||||
|
|
||||||
@ -76,7 +85,9 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
|
|||||||
{
|
{
|
||||||
std::vector<std::string> expandedArguments;
|
std::vector<std::string> expandedArguments;
|
||||||
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
||||||
if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
|
if ((!expandedArguments.empty() &&
|
||||||
|
(expandedArguments[0] == this->Args[0]))
|
||||||
|
|| mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
class cmForEachFunctionBlocker : public cmFunctionBlocker
|
class cmForEachFunctionBlocker : public cmFunctionBlocker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmForEachFunctionBlocker() {this->Executing = false;}
|
cmForEachFunctionBlocker() {this->Executing = false; Depth = 0;}
|
||||||
virtual ~cmForEachFunctionBlocker() {}
|
virtual ~cmForEachFunctionBlocker() {}
|
||||||
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
|
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
|
||||||
cmMakefile &mf);
|
cmMakefile &mf);
|
||||||
@ -39,6 +39,8 @@ public:
|
|||||||
std::vector<std::string> Args;
|
std::vector<std::string> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
bool Executing;
|
bool Executing;
|
||||||
|
private:
|
||||||
|
int Depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class cmForEachCommand
|
/** \class cmForEachCommand
|
||||||
|
@ -34,53 +34,34 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||||||
if (cmSystemTools::LowerCase(lff.Name) == "else" ||
|
if (cmSystemTools::LowerCase(lff.Name) == "else" ||
|
||||||
cmSystemTools::LowerCase(lff.Name) == "endif")
|
cmSystemTools::LowerCase(lff.Name) == "endif")
|
||||||
{
|
{
|
||||||
if (args == this->Args)
|
// if it was an else statement then we should change state
|
||||||
{
|
// and block this Else Command
|
||||||
// if it was an else statement then we should change state
|
if (cmSystemTools::LowerCase(lff.Name) == "else")
|
||||||
// and block this Else Command
|
|
||||||
if (cmSystemTools::LowerCase(lff.Name) == "else")
|
|
||||||
{
|
{
|
||||||
this->IsBlocking = !this->IsBlocking;
|
this->IsBlocking = !this->IsBlocking;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// otherwise it must be an ENDIF statement, in that case remove the
|
// otherwise it must be an ENDIF statement, in that case remove the
|
||||||
// function blocker
|
// function blocker
|
||||||
mf.RemoveFunctionBlocker(lff);
|
mf.RemoveFunctionBlocker(lff);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(args.empty())
|
|
||||||
{
|
|
||||||
std::string err = "Empty arguments for ";
|
|
||||||
err += name;
|
|
||||||
err += ". Did you mean ";
|
|
||||||
err += name;
|
|
||||||
err += "( ";
|
|
||||||
for(std::vector<cmListFileArgument>::const_iterator a =
|
|
||||||
this->Args.begin();
|
|
||||||
a != this->Args.end();++a)
|
|
||||||
{
|
|
||||||
err += (a->Quoted?"\"":"");
|
|
||||||
err += a->Value;
|
|
||||||
err += (a->Quoted?"\"":"");
|
|
||||||
err += " ";
|
|
||||||
}
|
|
||||||
err += ")?";
|
|
||||||
cmSystemTools::Error(err.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this->IsBlocking;
|
return this->IsBlocking;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||||
cmMakefile&)
|
cmMakefile& mf)
|
||||||
{
|
{
|
||||||
if (cmSystemTools::LowerCase(lff.Name) == "endif")
|
if (cmSystemTools::LowerCase(lff.Name) == "endif")
|
||||||
{
|
{
|
||||||
if (lff.Arguments == this->Args)
|
if (mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")
|
||||||
|
|| lff.Arguments == this->Args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,30 +28,44 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// at end of for each execute recorded commands
|
// at end of for each execute recorded commands
|
||||||
if (cmSystemTools::LowerCase(lff.Name) == "endwhile")
|
if (cmSystemTools::LowerCase(lff.Name) == "while")
|
||||||
{
|
{
|
||||||
char* errorString = 0;
|
// record the number of while commands past this one
|
||||||
|
this->Depth++;
|
||||||
|
}
|
||||||
|
else if (cmSystemTools::LowerCase(lff.Name) == "endwhile")
|
||||||
|
{
|
||||||
|
// if this is the endwhile for this while loop then execute
|
||||||
|
if (!this->Depth)
|
||||||
|
{
|
||||||
|
char* errorString = 0;
|
||||||
|
|
||||||
std::vector<std::string> expandedArguments;
|
std::vector<std::string> expandedArguments;
|
||||||
mf.ExpandArguments(this->Args, expandedArguments);
|
|
||||||
bool isTrue =
|
|
||||||
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
|
|
||||||
|
|
||||||
this->Executing = true;
|
|
||||||
while (isTrue)
|
|
||||||
{
|
|
||||||
// Invoke all the functions that were collected in the block.
|
|
||||||
for(unsigned int c = 0; c < this->Functions.size(); ++c)
|
|
||||||
{
|
|
||||||
mf.ExecuteCommand(this->Functions[c]);
|
|
||||||
}
|
|
||||||
expandedArguments.clear();
|
|
||||||
mf.ExpandArguments(this->Args, expandedArguments);
|
mf.ExpandArguments(this->Args, expandedArguments);
|
||||||
isTrue =
|
bool isTrue =
|
||||||
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
|
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
|
||||||
|
|
||||||
|
this->Executing = true;
|
||||||
|
while (isTrue)
|
||||||
|
{
|
||||||
|
// Invoke all the functions that were collected in the block.
|
||||||
|
for(unsigned int c = 0; c < this->Functions.size(); ++c)
|
||||||
|
{
|
||||||
|
mf.ExecuteCommand(this->Functions[c]);
|
||||||
|
}
|
||||||
|
expandedArguments.clear();
|
||||||
|
mf.ExpandArguments(this->Args, expandedArguments);
|
||||||
|
isTrue =
|
||||||
|
cmIfCommand::IsTrue(expandedArguments,&errorString,&mf);
|
||||||
|
}
|
||||||
|
mf.RemoveFunctionBlocker(lff);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// decrement for each nested while that ends
|
||||||
|
this->Depth--;
|
||||||
}
|
}
|
||||||
mf.RemoveFunctionBlocker(lff);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// record the command
|
// record the command
|
||||||
@ -62,11 +76,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool cmWhileFunctionBlocker::
|
bool cmWhileFunctionBlocker::
|
||||||
ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
|
ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
|
||||||
{
|
{
|
||||||
if(cmSystemTools::LowerCase(lff.Name) == "endwhile")
|
if(cmSystemTools::LowerCase(lff.Name) == "endwhile")
|
||||||
{
|
{
|
||||||
if (lff.Arguments == this->Args)
|
if (lff.Arguments == this->Args
|
||||||
|
|| mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
class cmWhileFunctionBlocker : public cmFunctionBlocker
|
class cmWhileFunctionBlocker : public cmFunctionBlocker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cmWhileFunctionBlocker() {Executing = false;}
|
cmWhileFunctionBlocker() {Executing = false; Depth=0;}
|
||||||
virtual ~cmWhileFunctionBlocker() {}
|
virtual ~cmWhileFunctionBlocker() {}
|
||||||
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
|
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
|
||||||
cmMakefile &mf);
|
cmMakefile &mf);
|
||||||
@ -39,6 +39,8 @@ public:
|
|||||||
std::vector<cmListFileArgument> Args;
|
std::vector<cmListFileArgument> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
bool Executing;
|
bool Executing;
|
||||||
|
private:
|
||||||
|
int Depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class cmWhileCommand
|
/** \class cmWhileCommand
|
||||||
|
Loading…
x
Reference in New Issue
Block a user