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;
|
||||
}
|
||||
|
||||
// at end of for each execute recorded commands
|
||||
if (cmSystemTools::LowerCase(lff.Name) == "endforeach")
|
||||
|
||||
if (cmSystemTools::LowerCase(lff.Name) == "foreach")
|
||||
{
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(lff.Arguments, expandedArguments);
|
||||
if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
|
||||
// record the number of nested foreach commands
|
||||
this->Depth++;
|
||||
}
|
||||
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
|
||||
std::string oldDef;
|
||||
if (mf.GetDefinition(this->Args[0].c_str()))
|
||||
|
@ -60,8 +64,13 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||
mf.RemoveFunctionBlocker(lff);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// close out a nested foreach
|
||||
this->Depth--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// record the command
|
||||
this->Functions.push_back(lff);
|
||||
|
||||
|
@ -76,7 +85,9 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
|
|||
{
|
||||
std::vector<std::string> 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;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
class cmForEachFunctionBlocker : public cmFunctionBlocker
|
||||
{
|
||||
public:
|
||||
cmForEachFunctionBlocker() {this->Executing = false;}
|
||||
cmForEachFunctionBlocker() {this->Executing = false; Depth = 0;}
|
||||
virtual ~cmForEachFunctionBlocker() {}
|
||||
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
cmMakefile &mf);
|
||||
|
@ -39,6 +39,8 @@ public:
|
|||
std::vector<std::string> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
bool Executing;
|
||||
private:
|
||||
int Depth;
|
||||
};
|
||||
|
||||
/** \class cmForEachCommand
|
||||
|
|
|
@ -34,53 +34,34 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||
if (cmSystemTools::LowerCase(lff.Name) == "else" ||
|
||||
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 (cmSystemTools::LowerCase(lff.Name) == "else")
|
||||
// if it was an else statement then we should change state
|
||||
// and block this Else Command
|
||||
if (cmSystemTools::LowerCase(lff.Name) == "else")
|
||||
{
|
||||
this->IsBlocking = !this->IsBlocking;
|
||||
return true;
|
||||
}
|
||||
// otherwise it must be an ENDIF statement, in that case remove the
|
||||
// function blocker
|
||||
mf.RemoveFunctionBlocker(lff);
|
||||
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());
|
||||
}
|
||||
}
|
||||
// otherwise it must be an ENDIF statement, in that case remove the
|
||||
// function blocker
|
||||
mf.RemoveFunctionBlocker(lff);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this->IsBlocking;
|
||||
}
|
||||
|
||||
bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||
cmMakefile&)
|
||||
cmMakefile& mf)
|
||||
{
|
||||
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 false;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,30 +28,44 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||
}
|
||||
|
||||
// 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;
|
||||
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();
|
||||
std::vector<std::string> expandedArguments;
|
||||
mf.ExpandArguments(this->Args, expandedArguments);
|
||||
isTrue =
|
||||
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);
|
||||
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
|
||||
|
@ -62,11 +76,12 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
|
|||
}
|
||||
|
||||
bool cmWhileFunctionBlocker::
|
||||
ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
|
||||
ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
class cmWhileFunctionBlocker : public cmFunctionBlocker
|
||||
{
|
||||
public:
|
||||
cmWhileFunctionBlocker() {Executing = false;}
|
||||
cmWhileFunctionBlocker() {Executing = false; Depth=0;}
|
||||
virtual ~cmWhileFunctionBlocker() {}
|
||||
virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
|
||||
cmMakefile &mf);
|
||||
|
@ -39,6 +39,8 @@ public:
|
|||
std::vector<cmListFileArgument> Args;
|
||||
std::vector<cmListFileFunction> Functions;
|
||||
bool Executing;
|
||||
private:
|
||||
int Depth;
|
||||
};
|
||||
|
||||
/** \class cmWhileCommand
|
||||
|
|
Loading…
Reference in New Issue