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

cmMessenger: Adopt backtrace printing functions

Move backtrace printing functions from `cmListFileBacktrace` over to
`cmMessenger`, their primary caller.  Thread `cmMessenger` instances
through APIs needed to update other call sites.
Brad King 3 жил өмнө
parent
commit
3d378541bb

+ 11 - 8
Source/cmGlobVerificationManager.cxx

@@ -8,11 +8,14 @@
 
 #include "cmGeneratedFileStream.h"
 #include "cmListFileCache.h"
+#include "cmMessageType.h"
+#include "cmMessenger.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmVersion.h"
 
-bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
+bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path,
+                                                       cmMessenger* messenger)
 {
   if (this->Cache.empty()) {
     return true;
@@ -52,7 +55,7 @@ bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
 
     for (auto const& bt : v.Backtraces) {
       verifyScriptFile << "# " << std::get<0>(bt);
-      std::get<1>(bt).PrintTitle(verifyScriptFile);
+      messenger->PrintBacktraceTitle(verifyScriptFile, std::get<1>(bt));
       verifyScriptFile << "\n";
     }
 
@@ -145,7 +148,7 @@ void cmGlobVerificationManager::AddCacheEntry(
   const bool recurse, const bool listDirectories, const bool followSymlinks,
   const std::string& relative, const std::string& expression,
   const std::vector<std::string>& files, const std::string& variable,
-  const cmListFileBacktrace& backtrace)
+  const cmListFileBacktrace& backtrace, cmMessenger* messenger)
 {
   CacheEntryKey key = CacheEntryKey(recurse, listDirectories, followSymlinks,
                                     relative, expression);
@@ -157,17 +160,17 @@ void cmGlobVerificationManager::AddCacheEntry(
   } else if (value.Initialized && value.Files != files) {
     std::ostringstream message;
     message << std::boolalpha;
-    message << "The glob expression\n";
+    message << "The glob expression\n ";
     key.PrintGlobCommand(message, variable);
-    backtrace.PrintTitle(message);
-    message << "\nwas already present in the glob cache but the directory\n"
+    message << "\nwas already present in the glob cache but the directory "
                "contents have changed during the configuration run.\n";
     message << "Matching glob expressions:";
     for (auto const& bt : value.Backtraces) {
       message << "\n  " << std::get<0>(bt);
-      std::get<1>(bt).PrintTitle(message);
+      messenger->PrintBacktraceTitle(message, std::get<1>(bt));
     }
-    cmSystemTools::Error(message.str());
+    messenger->IssueMessage(MessageType::FATAL_ERROR, message.str(),
+                            backtrace);
   } else {
     value.Backtraces.emplace_back(variable, backtrace);
   }

+ 4 - 2
Source/cmGlobVerificationManager.h

@@ -12,6 +12,8 @@
 
 #include "cmListFileCache.h"
 
+class cmMessenger;
+
 /** \class cmGlobVerificationManager
  * \brief Class for expressing build-time dependencies on glob expressions.
  *
@@ -23,7 +25,7 @@ class cmGlobVerificationManager
 protected:
   //! Save verification script for given makefile.
   //! Saves to output <path>/<CMakeFilesDirectory>/VerifyGlobs.cmake
-  bool SaveVerificationScript(const std::string& path);
+  bool SaveVerificationScript(const std::string& path, cmMessenger* messenger);
 
   //! Add an entry into the glob cache
   void AddCacheEntry(bool recurse, bool listDirectories, bool followSymlinks,
@@ -31,7 +33,7 @@ protected:
                      const std::string& expression,
                      const std::vector<std::string>& files,
                      const std::string& variable,
-                     const cmListFileBacktrace& bt);
+                     const cmListFileBacktrace& bt, cmMessenger* messenger);
 
   //! Clear the glob cache for state reset.
   void Reset();

+ 0 - 48
Source/cmListFileCache.cxx

@@ -14,7 +14,6 @@
 #include "cmListFileLexer.h"
 #include "cmMessageType.h"
 #include "cmMessenger.h"
-#include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -540,53 +539,6 @@ cmListFileContext const& cmListFileBacktrace::Top() const
   return this->TopEntry->Context;
 }
 
-void cmListFileBacktrace::PrintTitle(std::ostream& out) const
-{
-  // The title exists only if we have a call on top of the bottom.
-  if (!this->TopEntry || this->TopEntry->IsBottom()) {
-    return;
-  }
-  cmListFileContext lfc = this->TopEntry->Context;
-  cmStateSnapshot bottom = this->GetBottom();
-  if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) {
-    lfc.FilePath = cmSystemTools::RelativeIfUnder(
-      bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
-  }
-  out << (lfc.Line ? " at " : " in ") << lfc;
-}
-
-void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
-{
-  // The call stack exists only if we have at least two calls on top
-  // of the bottom.
-  if (!this->TopEntry || this->TopEntry->IsBottom() ||
-      this->TopEntry->Parent->IsBottom()) {
-    return;
-  }
-
-  bool first = true;
-  cmStateSnapshot bottom = this->GetBottom();
-  for (Entry const* cur = this->TopEntry->Parent.get(); !cur->IsBottom();
-       cur = cur->Parent.get()) {
-    if (cur->Context.Name.empty() &&
-        cur->Context.Line != cmListFileContext::DeferPlaceholderLine) {
-      // Skip this whole-file scope.  When we get here we already will
-      // have printed a more-specific context within the file.
-      continue;
-    }
-    if (first) {
-      first = false;
-      out << "Call Stack (most recent call first):\n";
-    }
-    cmListFileContext lfc = cur->Context;
-    if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) {
-      lfc.FilePath = cmSystemTools::RelativeIfUnder(
-        bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
-    }
-    out << "  " << lfc << "\n";
-  }
-}
-
 size_t cmListFileBacktrace::Depth() const
 {
   size_t depth = 0;

+ 0 - 6
Source/cmListFileCache.h

@@ -191,12 +191,6 @@ public:
   // This may be called only if Empty() would return false.
   cmListFileContext const& Top() const;
 
-  // Print the top of the backtrace.
-  void PrintTitle(std::ostream& out) const;
-
-  // Print the call stack below the top of the backtrace.
-  void PrintCallStack(std::ostream& out) const;
-
   // Get the number of 'frames' in this backtrace
   size_t Depth() const;
 

+ 56 - 2
Source/cmMessenger.cxx

@@ -4,6 +4,8 @@
 
 #include "cmDocumentationFormatter.h"
 #include "cmMessageMetadata.h"
+#include "cmState.h"
+#include "cmStateSnapshot.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -151,6 +153,42 @@ static void displayMessage(MessageType t, std::ostringstream& msg)
   }
 }
 
+namespace {
+void PrintCallStack(std::ostream& out, cmListFileBacktrace bt)
+{
+  // The call stack exists only if we have at least two calls on top
+  // of the bottom.
+  if (bt.Empty()) {
+    return;
+  }
+  bt = bt.Pop();
+  if (bt.Empty()) {
+    return;
+  }
+
+  bool first = true;
+  cmStateSnapshot bottom = bt.GetBottom();
+  for (; !bt.Empty(); bt = bt.Pop()) {
+    cmListFileContext lfc = bt.Top();
+    if (lfc.Name.empty() &&
+        lfc.Line != cmListFileContext::DeferPlaceholderLine) {
+      // Skip this whole-file scope.  When we get here we already will
+      // have printed a more-specific context within the file.
+      continue;
+    }
+    if (first) {
+      first = false;
+      out << "Call Stack (most recent call first):\n";
+    }
+    if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) {
+      lfc.FilePath = cmSystemTools::RelativeIfUnder(
+        bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
+    }
+    out << "  " << lfc << "\n";
+  }
+}
+}
+
 void cmMessenger::IssueMessage(MessageType t, const std::string& text,
                                const cmListFileBacktrace& backtrace) const
 {
@@ -176,12 +214,28 @@ void cmMessenger::DisplayMessage(MessageType t, const std::string& text,
   }
 
   // Add the immediate context.
-  backtrace.PrintTitle(msg);
+  this->PrintBacktraceTitle(msg, backtrace);
 
   printMessageText(msg, text);
 
   // Add the rest of the context.
-  backtrace.PrintCallStack(msg);
+  PrintCallStack(msg, backtrace);
 
   displayMessage(t, msg);
 }
+
+void cmMessenger::PrintBacktraceTitle(std::ostream& out,
+                                      cmListFileBacktrace const& bt) const
+{
+  // The title exists only if we have a call on top of the bottom.
+  if (bt.Empty()) {
+    return;
+  }
+  cmListFileContext lfc = bt.Top();
+  cmStateSnapshot bottom = bt.GetBottom();
+  if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) {
+    lfc.FilePath = cmSystemTools::RelativeIfUnder(
+      bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
+  }
+  out << (lfc.Line ? " at " : " in ") << lfc;
+}

+ 5 - 0
Source/cmMessenger.h

@@ -4,6 +4,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <iosfwd>
 #include <string>
 
 #include "cmListFileCache.h"
@@ -47,6 +48,10 @@ public:
     return this->DeprecatedWarningsAsErrors;
   }
 
+  // Print the top of a backtrace.
+  void PrintBacktraceTitle(std::ostream& out,
+                           cmListFileBacktrace const& bt) const;
+
 private:
   bool IsMessageTypeVisible(MessageType t) const;
   MessageType ConvertMessageType(MessageType t) const;

+ 10 - 10
Source/cmState.cxx

@@ -228,22 +228,22 @@ std::string const& cmState::GetGlobVerifyStamp() const
   return this->GlobVerificationManager->GetVerifyStamp();
 }
 
-bool cmState::SaveVerificationScript(const std::string& path)
+bool cmState::SaveVerificationScript(const std::string& path,
+                                     cmMessenger* messenger)
 {
-  return this->GlobVerificationManager->SaveVerificationScript(path);
+  return this->GlobVerificationManager->SaveVerificationScript(path,
+                                                               messenger);
 }
 
-void cmState::AddGlobCacheEntry(bool recurse, bool listDirectories,
-                                bool followSymlinks,
-                                const std::string& relative,
-                                const std::string& expression,
-                                const std::vector<std::string>& files,
-                                const std::string& variable,
-                                cmListFileBacktrace const& backtrace)
+void cmState::AddGlobCacheEntry(
+  bool recurse, bool listDirectories, bool followSymlinks,
+  const std::string& relative, const std::string& expression,
+  const std::vector<std::string>& files, const std::string& variable,
+  cmListFileBacktrace const& backtrace, cmMessenger* messenger)
 {
   this->GlobVerificationManager->AddCacheEntry(
     recurse, listDirectories, followSymlinks, relative, expression, files,
-    variable, backtrace);
+    variable, backtrace, messenger);
 }
 
 void cmState::RemoveCacheEntry(std::string const& key)

+ 3 - 2
Source/cmState.h

@@ -238,13 +238,14 @@ private:
   bool DoWriteGlobVerifyTarget() const;
   std::string const& GetGlobVerifyScript() const;
   std::string const& GetGlobVerifyStamp() const;
-  bool SaveVerificationScript(const std::string& path);
+  bool SaveVerificationScript(const std::string& path, cmMessenger* messenger);
   void AddGlobCacheEntry(bool recurse, bool listDirectories,
                          bool followSymlinks, const std::string& relative,
                          const std::string& expression,
                          const std::vector<std::string>& files,
                          const std::string& variable,
-                         cmListFileBacktrace const& bt);
+                         cmListFileBacktrace const& bt,
+                         cmMessenger* messenger);
 
   cmPropertyDefinitionMap PropertyDefinitions;
   std::vector<std::string> EnabledLanguages;

+ 3 - 2
Source/cmake.cxx

@@ -2155,7 +2155,8 @@ int cmake::ActualConfigure()
       "CMakeLists.txt ?");
   }
 
-  this->State->SaveVerificationScript(this->GetHomeOutputDirectory());
+  this->State->SaveVerificationScript(this->GetHomeOutputDirectory(),
+                                      this->Messenger.get());
   this->SaveCache(this->GetHomeOutputDirectory());
   if (cmSystemTools::GetErrorOccuredFlag()) {
     return -1;
@@ -2452,7 +2453,7 @@ void cmake::AddGlobCacheEntry(bool recurse, bool listDirectories,
 {
   this->State->AddGlobCacheEntry(recurse, listDirectories, followSymlinks,
                                  relative, expression, files, variable,
-                                 backtrace);
+                                 backtrace, this->Messenger.get());
 }
 
 std::vector<std::string> cmake::GetAllExtensions() const

+ 15 - 7
Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt

@@ -1,7 +1,15 @@
-^CMake Error: The glob expression
-.* at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)
-was already present in the glob cache but the directory
-contents have changed during the configuration run.
-Matching glob expressions:
-  CONTENT_LIST_1 at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)
-  CONTENT_LIST_2 at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)$
+^CMake Error at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\):
+  The glob expression
+
+   [^
+]*
+
+  was already present in the glob cache but the directory contents have
+  changed during the configuration run.
+
+  Matching glob expressions:
+
+    CONTENT_LIST_1 at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)
+    CONTENT_LIST_2 at GLOB-error-CONFIGURE_DEPENDS-modified\.cmake:[0-9]+ \(file\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$