ENH: allow loose loop constructs

This commit is contained in:
Ken Martin 2006-05-18 13:50:01 -04:00
parent 095e975c81
commit 29a03db7ce
5 changed files with 74 additions and 63 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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