1
0
Эх сурвалжийг харах

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.
Brad King 17 жил өмнө
parent
commit
bca1026250

+ 0 - 9
Source/cmForEachCommand.cxx

@@ -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 &)
 {
 {

+ 0 - 1
Source/cmForEachCommand.h

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

+ 9 - 7
Source/cmFunctionBlocker.h

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

+ 0 - 11
Source/cmFunctionCommand.cxx

@@ -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 &)
 {
 {

+ 0 - 1
Source/cmFunctionCommand.h

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

+ 0 - 18
Source/cmIfCommand.cxx

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

+ 0 - 1
Source/cmIfCommand.h

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

+ 0 - 11
Source/cmMacroCommand.cxx

@@ -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 &)
 {
 {

+ 0 - 1
Source/cmMacroCommand.h

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

+ 20 - 1
Source/cmMakefile.cxx

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

+ 1 - 2
Source/cmMakefile.h

@@ -88,8 +88,7 @@ public:
   /**
   /**
    * Add a function blocker to this makefile
    * 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.
    * Remove the function blocker whose scope ends with the given command.

+ 0 - 9
Source/cmWhileCommand.cxx

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

+ 0 - 1
Source/cmWhileCommand.h

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