From 54541bd40a6083b3969c2e2dc53292d1a67b69c2 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Thu, 12 Dec 2002 11:36:28 -0500
Subject: ENH: Improved filename/line number reporting in error message.  Macro
 invocations now chain up the error message.

---
 Source/cmListFileCache.cxx | 36 ++++++++++++++++++------------------
 Source/cmListFileCache.h   |  2 +-
 Source/cmMacroCommand.cxx  | 14 +++++++++++---
 Source/cmMakefile.cxx      | 12 +++++++++---
 Source/cmMakefile.h        |  5 +++--
 Source/ctest.cxx           |  4 +++-
 6 files changed, 45 insertions(+), 28 deletions(-)

diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 88cc228..d5dc574 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -97,7 +97,7 @@ bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand)
     {
     cmListFileFunction inFunction;
     if(cmListFileCache::ParseFunction(fin, inFunction, path, parseError,
-                                      &line))
+                                      line))
       {
       inFunction.m_FilePath = path;
       inFile.m_Functions.push_back(inFunction);
@@ -162,7 +162,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
                                     cmListFileFunction& function,
                                     const char* filename,
                                     bool& parseError,
-                                    long* line)
+                                    long& line)
 {
   parseError = false;
   std::string& name = function.m_Name;
@@ -177,7 +177,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
     }
   if(fin.getline(inbuffer, BUFFER_SIZE ) )
     {
-    if(line) { ++*line; }
+    ++line;
     RemoveComments(inbuffer);
     cmRegularExpression blankLine("^[ \t\r]*$");
     cmRegularExpression oneLiner("^[ \t]*([A-Za-z_0-9]*)[ \t]*\\((.*)\\)[ \t\r]*$");
@@ -197,10 +197,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
       name = oneLiner.match(1);
       // break up the arguments
       cmListFileCache::GetArguments(args, arguments);
-      if(line)
-        {
-        function.m_Line = *line;
-        }
+        function.m_Line = line;
       return true;
       }
     // look for a start of a multiline with no trailing ")"  fun(arg arg2 
@@ -209,10 +206,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
       name = multiLine.match(1);
       std::string args = multiLine.match(2);
       cmListFileCache::GetArguments(args, arguments);
-      if(line)
-        {
-        function.m_Line = *line;
-        }
+      function.m_Line = line;
       // Read lines until the closing paren is hit
       bool done = false;
       while(!done)
@@ -220,7 +214,7 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
         // read lines until the end paren is found
         if(fin.getline(inbuffer, BUFFER_SIZE ) )
           {
-          if(line) { ++*line; }
+          ++line;
           RemoveComments(inbuffer);
           // Check for comment lines and ignore them.
           if(blankLine.find(inbuffer))
@@ -234,15 +228,18 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
             }
           else
             {
-            std::string line = inbuffer;
-            cmListFileCache::GetArguments(line, arguments);
+            std::string lineB = inbuffer;
+            cmListFileCache::GetArguments(lineB, arguments);
             }
           }
         else
           {
           parseError = true;
-          cmSystemTools::Error("Parse error in read function missing end )\nIn File: ",
-                               filename, "\nCurrent line:", inbuffer);
+          cmOStringStream error;
+          error << "Error in cmake code at\n"
+                << filename << ":" << line << ":\n"
+                << "Parse error.  Function missing ending \")\".";
+          cmSystemTools::Error(error.str().c_str());
           return false;
           }
         }
@@ -251,8 +248,11 @@ bool cmListFileCache::ParseFunction(std::ifstream& fin,
     else
       {
       parseError = true;
-      cmSystemTools::Error("Parse error in read function\nIn file:", 
-                           filename, "\nCurrent line:", inbuffer);
+      cmOStringStream error;
+      error << "Error in cmake code at\n"
+            << filename << ":" << line << ":\n"
+            << "Parse error.";
+      cmSystemTools::Error(error.str().c_str());
       return false;
       }
     }
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 9dc8073..b28baa5 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -84,7 +84,7 @@ public:
    */
   static bool ParseFunction(std::ifstream&, cmListFileFunction& function,
                             const char* filename, bool& parseError,
-                            long* line = 0);
+                            long& line);
 
   /**
    *  Extract white-space separated arguments from a string.
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 58871a2..f8746d0 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -59,6 +59,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
       // Replace the formal arguments and then invoke the command.
       cmListFileFunction newLFF;
       newLFF.m_Name = m_Functions[c].m_Name;
+      newLFF.m_FilePath = m_Functions[c].m_FilePath;
+      newLFF.m_Line = m_Functions[c].m_Line;
       for (std::vector<cmListFileArgument>::const_iterator k = 
              m_Functions[c].m_Arguments.begin();
            k != m_Functions[c].m_Arguments.end(); ++k)
@@ -74,10 +76,16 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
           }
         cmListFileArgument arg(tmps, k->Quoted);
         newLFF.m_Arguments.push_back(arg);
-        newLFF.m_FilePath = m_Functions[c].m_FilePath;
-        newLFF.m_Line = m_Functions[c].m_Line;
         }
-      mf.ExecuteCommand(newLFF);
+      if(!mf.ExecuteCommand(newLFF))
+        {
+        cmOStringStream error;
+        error << "Error in cmake code at\n"
+              << lff.m_FilePath << ":" << lff.m_Line << ":\n"
+              << "A command failed during the invocation of macro \""
+              << lff.m_Name.c_str() << "\".";
+        cmSystemTools::Error(error.str().c_str());
+        }
       }
     return true;
     }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index db4a1ba..8c44fb8 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -156,13 +156,15 @@ bool cmMakefile::CommandExists(const char* name) const
 {
   return m_LocalGenerator->GetGlobalGenerator()->GetCMakeInstance()->CommandExists(name);
 }
-      
-void cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
+
+bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
 {
+  bool result = true;
   // quick return if blocked
   if(this->IsFunctionBlocked(lff))
     {
-    return;
+    // No error.
+    return result;
     }
   std::string name = lff.m_Name;
   // execute the command
@@ -186,6 +188,7 @@ void cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
                 << lff.m_FilePath << ":" << lff.m_Line << ":\n"
                 << usedCommand->GetError();
           cmSystemTools::Error(error.str().c_str());
+          result = false;
           }
         else
           {
@@ -209,7 +212,10 @@ void cmMakefile::ExecuteCommand(const cmListFileFunction& lff)
           << lff.m_FilePath << ":" << lff.m_Line << ":\n"
           << "Unknown CMake command \"" << lff.m_Name.c_str() << "\".";
     cmSystemTools::Error(error.str().c_str());
+    result = false;
     }
+  
+  return result;
 }
 
 // Parse the given CMakeLists.txt file into a list of classes.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index de8e3eb..0fc79e6 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -510,9 +510,10 @@ public:
   cmData* LookupData(const char*) const;
   
   /**
-   * execute a single CMake command
+   * Execute a single CMake command.  Returns true if the command
+   * succeeded or false if it failed.
    */
-  void ExecuteCommand(const cmListFileFunction& lff);
+  bool ExecuteCommand(const cmListFileFunction& lff);
   
   /** Check if a command exists. */
   bool CommandExists(const char* name) const;
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 20a183e..e88cadc 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -1102,6 +1102,7 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
     }
 
   int firstTest = 1;
+  long line = 0;
   
   std::string name;
   std::vector<std::string> args;
@@ -1113,7 +1114,8 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
   while ( fin )
     {
     cmListFileFunction lff;
-    if(cmListFileCache::ParseFunction(fin, lff, "DartTestfile.txt", parseError))
+    if(cmListFileCache::ParseFunction(fin, lff, "DartTestfile.txt",
+                                      parseError, line))
       {
       const std::string& name = lff.m_Name;
       const std::vector<cmListFileArgument>& args = lff.m_Arguments;
-- 
cgit v0.12