ENH: Better error message for unclosed blocks
This centralizes construction of the error message for an unclosed logical block (if, foreach, etc.). We record the line at which each block is opened so it can be reported in the error message.
This commit is contained in:
parent
b8f5a934ec
commit
bca1026250
|
@ -107,15 +107,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmForEachFunctionBlocker::
|
|
||||||
ScopeEnded(cmMakefile &mf)
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("The end of a CMakeLists file was reached with a "
|
|
||||||
"FOREACH statement that was not closed properly. "
|
|
||||||
"Within the directory: ",
|
|
||||||
mf.GetCurrentDirectory());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmForEachCommand
|
bool cmForEachCommand
|
||||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,6 @@ public:
|
||||||
cmMakefile &mf,
|
cmMakefile &mf,
|
||||||
cmExecutionStatus &);
|
cmExecutionStatus &);
|
||||||
virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
|
virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
|
||||||
virtual void ScopeEnded(cmMakefile &mf);
|
|
||||||
|
|
||||||
std::vector<std::string> Args;
|
std::vector<std::string> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "cmStandardIncludes.h"
|
#include "cmStandardIncludes.h"
|
||||||
#include "cmExecutionStatus.h"
|
#include "cmExecutionStatus.h"
|
||||||
|
#include "cmListFileCache.h"
|
||||||
class cmMakefile;
|
class cmMakefile;
|
||||||
|
|
||||||
/** \class cmFunctionBlocker
|
/** \class cmFunctionBlocker
|
||||||
|
@ -43,14 +44,15 @@ public:
|
||||||
virtual bool ShouldRemove(const cmListFileFunction&,
|
virtual bool ShouldRemove(const cmListFileFunction&,
|
||||||
cmMakefile&) {return false;}
|
cmMakefile&) {return false;}
|
||||||
|
|
||||||
/**
|
|
||||||
* When the end of a CMakeList file is reached this method is called. It
|
|
||||||
* is not called on the end of an INCLUDE cmake file, just at the end of a
|
|
||||||
* regular CMakeList file
|
|
||||||
*/
|
|
||||||
virtual void ScopeEnded(cmMakefile&) {}
|
|
||||||
|
|
||||||
virtual ~cmFunctionBlocker() {}
|
virtual ~cmFunctionBlocker() {}
|
||||||
|
|
||||||
|
/** Set/Get the context in which this blocker is created. */
|
||||||
|
void SetStartingContext(cmListFileContext const& lfc)
|
||||||
|
{ this->StartingContext = lfc; }
|
||||||
|
cmListFileContext const& GetStartingContext()
|
||||||
|
{ return this->StartingContext; }
|
||||||
|
private:
|
||||||
|
cmListFileContext StartingContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -258,17 +258,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmFunctionFunctionBlocker::
|
|
||||||
ScopeEnded(cmMakefile &mf)
|
|
||||||
{
|
|
||||||
// functions should end with an EndFunction
|
|
||||||
cmSystemTools::Error(
|
|
||||||
"The end of a CMakeLists file was reached with a FUNCTION statement that "
|
|
||||||
"was not closed properly. Within the directory: ",
|
|
||||||
mf.GetCurrentDirectory(), " with function ",
|
|
||||||
this->Args[0].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmFunctionCommand
|
bool cmFunctionCommand
|
||||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,6 @@ public:
|
||||||
cmMakefile &mf,
|
cmMakefile &mf,
|
||||||
cmExecutionStatus &);
|
cmExecutionStatus &);
|
||||||
virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
|
virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
|
||||||
virtual void ScopeEnded(cmMakefile &mf);
|
|
||||||
|
|
||||||
std::vector<std::string> Args;
|
std::vector<std::string> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
|
|
|
@ -157,24 +157,6 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
void cmIfFunctionBlocker::ScopeEnded(cmMakefile &mf)
|
|
||||||
{
|
|
||||||
std::string errmsg = "The end of a CMakeLists file was reached with an "
|
|
||||||
"IF statement that was not closed properly.\nWithin the directory: ";
|
|
||||||
errmsg += mf.GetCurrentDirectory();
|
|
||||||
errmsg += "\nThe arguments are: ";
|
|
||||||
for(std::vector<cmListFileArgument>::const_iterator j = this->Args.begin();
|
|
||||||
j != this->Args.end(); ++j)
|
|
||||||
{
|
|
||||||
errmsg += (j->Quoted?"\"":"");
|
|
||||||
errmsg += j->Value;
|
|
||||||
errmsg += (j->Quoted?"\"":"");
|
|
||||||
errmsg += " ";
|
|
||||||
}
|
|
||||||
cmSystemTools::Message(errmsg.c_str(), "Warning");
|
|
||||||
}
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
bool cmIfCommand
|
bool cmIfCommand
|
||||||
::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
|
::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
|
||||||
|
|
|
@ -36,7 +36,6 @@ public:
|
||||||
cmExecutionStatus &);
|
cmExecutionStatus &);
|
||||||
virtual bool ShouldRemove(const cmListFileFunction& lff,
|
virtual bool ShouldRemove(const cmListFileFunction& lff,
|
||||||
cmMakefile &mf);
|
cmMakefile &mf);
|
||||||
virtual void ScopeEnded(cmMakefile &mf);
|
|
||||||
|
|
||||||
std::vector<cmListFileArgument> Args;
|
std::vector<cmListFileArgument> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
|
|
|
@ -302,17 +302,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmMacroFunctionBlocker::
|
|
||||||
ScopeEnded(cmMakefile &mf)
|
|
||||||
{
|
|
||||||
// macros should end with an EndMacro
|
|
||||||
cmSystemTools::Error(
|
|
||||||
"The end of a CMakeLists file was reached with a MACRO statement that "
|
|
||||||
"was not closed properly. Within the directory: ",
|
|
||||||
mf.GetCurrentDirectory(), " with macro ",
|
|
||||||
this->Args[0].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
|
bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
|
||||||
cmExecutionStatus &)
|
cmExecutionStatus &)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,6 @@ public:
|
||||||
cmMakefile &mf,
|
cmMakefile &mf,
|
||||||
cmExecutionStatus &);
|
cmExecutionStatus &);
|
||||||
virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
|
virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
|
||||||
virtual void ScopeEnded(cmMakefile &mf);
|
|
||||||
|
|
||||||
std::vector<std::string> Args;
|
std::vector<std::string> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
|
|
|
@ -2365,7 +2365,14 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
|
||||||
this->FunctionBlockers.pop_back();
|
this->FunctionBlockers.pop_back();
|
||||||
if(reportError)
|
if(reportError)
|
||||||
{
|
{
|
||||||
fb->ScopeEnded(*this);
|
// Report the context in which the unclosed block was opened.
|
||||||
|
cmListFileContext const& lfc = fb->GetStartingContext();
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "A logical block opening on the line\n"
|
||||||
|
<< " " << lfc << "\n"
|
||||||
|
<< "is not closed.";
|
||||||
|
this->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||||
|
reportError = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2402,6 +2409,18 @@ bool cmMakefile::ExpandArguments(
|
||||||
return !cmSystemTools::GetFatalErrorOccured();
|
return !cmSystemTools::GetFatalErrorOccured();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
|
||||||
|
{
|
||||||
|
if(!this->CallStack.empty())
|
||||||
|
{
|
||||||
|
// Record the context in which the blocker is created.
|
||||||
|
fb->SetStartingContext(*(this->CallStack.back().Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->FunctionBlockers.push_back(fb);
|
||||||
|
}
|
||||||
|
|
||||||
cmsys::auto_ptr<cmFunctionBlocker>
|
cmsys::auto_ptr<cmFunctionBlocker>
|
||||||
cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
|
cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff)
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,8 +88,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Add a function blocker to this makefile
|
* Add a function blocker to this makefile
|
||||||
*/
|
*/
|
||||||
void AddFunctionBlocker(cmFunctionBlocker *fb)
|
void AddFunctionBlocker(cmFunctionBlocker* fb);
|
||||||
{ this->FunctionBlockers.push_back(fb);}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the function blocker whose scope ends with the given command.
|
* Remove the function blocker whose scope ends with the given command.
|
||||||
|
|
|
@ -97,15 +97,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmWhileFunctionBlocker::
|
|
||||||
ScopeEnded(cmMakefile &mf)
|
|
||||||
{
|
|
||||||
cmSystemTools::Error(
|
|
||||||
"The end of a CMakeLists file was reached with a WHILE statement that "
|
|
||||||
"was not closed properly. Within the directory: ",
|
|
||||||
mf.GetCurrentDirectory());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cmWhileCommand
|
bool cmWhileCommand
|
||||||
::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
|
::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
|
||||||
cmExecutionStatus &)
|
cmExecutionStatus &)
|
||||||
|
|
|
@ -35,7 +35,6 @@ public:
|
||||||
cmMakefile &mf,
|
cmMakefile &mf,
|
||||||
cmExecutionStatus &);
|
cmExecutionStatus &);
|
||||||
virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
|
virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
|
||||||
virtual void ScopeEnded(cmMakefile &mf);
|
|
||||||
|
|
||||||
std::vector<cmListFileArgument> Args;
|
std::vector<cmListFileArgument> Args;
|
||||||
std::vector<cmListFileFunction> Functions;
|
std::vector<cmListFileFunction> Functions;
|
||||||
|
|
Loading…
Reference in New Issue