From bca1026250c5d2006a3829662b736660982e3a33 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 21 Jan 2009 09:48:20 -0500 Subject: [PATCH] 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. --- Source/cmForEachCommand.cxx | 9 --------- Source/cmForEachCommand.h | 1 - Source/cmFunctionBlocker.h | 16 +++++++++------- Source/cmFunctionCommand.cxx | 11 ----------- Source/cmFunctionCommand.h | 1 - Source/cmIfCommand.cxx | 18 ------------------ Source/cmIfCommand.h | 1 - Source/cmMacroCommand.cxx | 11 ----------- Source/cmMacroCommand.h | 1 - Source/cmMakefile.cxx | 21 ++++++++++++++++++++- Source/cmMakefile.h | 3 +-- Source/cmWhileCommand.cxx | 9 --------- Source/cmWhileCommand.h | 1 - 13 files changed, 30 insertions(+), 73 deletions(-) diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 193f0a06c..436a91bcb 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -107,15 +107,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) 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 ::InitialPass(std::vector const& args, cmExecutionStatus &) { diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index 3357ce492..3e0371119 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -35,7 +35,6 @@ public: cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - virtual void ScopeEnded(cmMakefile &mf); std::vector Args; std::vector Functions; diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index a169cc184..1433759de 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -19,6 +19,7 @@ #include "cmStandardIncludes.h" #include "cmExecutionStatus.h" +#include "cmListFileCache.h" class cmMakefile; /** \class cmFunctionBlocker @@ -43,14 +44,15 @@ public: virtual bool ShouldRemove(const cmListFileFunction&, 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() {} + + /** 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 diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index f36eb7477..c1ca8aa29 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -258,17 +258,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) 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 ::InitialPass(std::vector const& args, cmExecutionStatus &) { diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h index aff479224..b9f9010e5 100644 --- a/Source/cmFunctionCommand.h +++ b/Source/cmFunctionCommand.h @@ -34,7 +34,6 @@ public: cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf); - virtual void ScopeEnded(cmMakefile &mf); std::vector Args; std::vector Functions; diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 1a8c81058..74576b5ae 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -157,24 +157,6 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, 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::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 ::InvokeInitialPass(const std::vector& args, diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 0d2802a5d..4148efd04 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -36,7 +36,6 @@ public: cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - virtual void ScopeEnded(cmMakefile &mf); std::vector Args; std::vector Functions; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index e7a27e518..8613044a5 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -302,17 +302,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) 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 const& args, cmExecutionStatus &) { diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index 4fcd597a7..3231d7135 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -34,7 +34,6 @@ public: cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf); - virtual void ScopeEnded(cmMakefile &mf); std::vector Args; std::vector Functions; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 34b4855ee..c6bc4f217 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2365,7 +2365,14 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) this->FunctionBlockers.pop_back(); 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(); } +//---------------------------------------------------------------------------- +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 cmMakefile::RemoveFunctionBlocker(const cmListFileFunction& lff) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index c6b332b0d..d565b2907 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -88,8 +88,7 @@ public: /** * Add a function blocker to this makefile */ - void AddFunctionBlocker(cmFunctionBlocker *fb) - { this->FunctionBlockers.push_back(fb);} + void AddFunctionBlocker(cmFunctionBlocker* fb); /** * Remove the function blocker whose scope ends with the given command. diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 61d5d85b7..b6d8e36e7 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -97,15 +97,6 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& ) 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 ::InvokeInitialPass(const std::vector& args, cmExecutionStatus &) diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h index 39864cd81..25b715de7 100644 --- a/Source/cmWhileCommand.h +++ b/Source/cmWhileCommand.h @@ -35,7 +35,6 @@ public: cmMakefile &mf, cmExecutionStatus &); virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf); - virtual void ScopeEnded(cmMakefile &mf); std::vector Args; std::vector Functions;