From 3d378541bb22f00e3a22bf5f12e97b7943a81294 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 7 Dec 2021 15:18:17 -0500 Subject: 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. --- Source/cmGlobVerificationManager.cxx | 19 ++++--- Source/cmGlobVerificationManager.h | 6 ++- Source/cmListFileCache.cxx | 48 ------------------ Source/cmListFileCache.h | 6 --- Source/cmMessenger.cxx | 58 +++++++++++++++++++++- Source/cmMessenger.h | 5 ++ Source/cmState.cxx | 20 ++++---- Source/cmState.h | 5 +- Source/cmake.cxx | 5 +- ...LOB-error-CONFIGURE_DEPENDS-modified-stderr.txt | 22 +++++--- 10 files changed, 107 insertions(+), 87 deletions(-) diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx index 9ac5cd5..89c5b01 100644 --- a/Source/cmGlobVerificationManager.cxx +++ b/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& 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); } diff --git a/Source/cmGlobVerificationManager.h b/Source/cmGlobVerificationManager.h index b618fb0..52d71aa 100644 --- a/Source/cmGlobVerificationManager.h +++ b/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 //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& files, const std::string& variable, - const cmListFileBacktrace& bt); + const cmListFileBacktrace& bt, cmMessenger* messenger); //! Clear the glob cache for state reset. void Reset(); diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 2e444f2..4c434a3 100644 --- a/Source/cmListFileCache.cxx +++ b/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; diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 98cb4a7..0e2e299 100644 --- a/Source/cmListFileCache.h +++ b/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; diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx index 2eead6b..52c9dd0 100644 --- a/Source/cmMessenger.cxx +++ b/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; +} diff --git a/Source/cmMessenger.h b/Source/cmMessenger.h index b6f5712..8287e70 100644 --- a/Source/cmMessenger.h +++ b/Source/cmMessenger.h @@ -4,6 +4,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include #include #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; diff --git a/Source/cmState.cxx b/Source/cmState.cxx index e79949d..07b4759 100644 --- a/Source/cmState.cxx +++ b/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& 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& 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) diff --git a/Source/cmState.h b/Source/cmState.h index a1666ca..b834bba 100644 --- a/Source/cmState.h +++ b/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& files, const std::string& variable, - cmListFileBacktrace const& bt); + cmListFileBacktrace const& bt, + cmMessenger* messenger); cmPropertyDefinitionMap PropertyDefinitions; std::vector EnabledLanguages; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 8c6a2ec..d927d27 100644 --- a/Source/cmake.cxx +++ b/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 cmake::GetAllExtensions() const diff --git a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt b/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt index d7b36eb..4c1aa67 100644 --- a/Tests/RunCMake/file/GLOB-error-CONFIGURE_DEPENDS-modified-stderr.txt +++ b/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\)$ -- cgit v0.12