/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMessenger.h" #include "cmAlgorithms.h" #include "cmDocumentationFormatter.h" #include "cmSystemTools.h" #if defined(CMAKE_BUILD_WITH_CMAKE) # include "cmsys/SystemInformation.hxx" #endif #include MessageType cmMessenger::ConvertMessageType(MessageType t) const { bool warningsAsErrors; if (t == MessageType::AUTHOR_WARNING || t == MessageType::AUTHOR_ERROR) { warningsAsErrors = this->GetDevWarningsAsErrors(); if (warningsAsErrors && t == MessageType::AUTHOR_WARNING) { t = MessageType::AUTHOR_ERROR; } else if (!warningsAsErrors && t == MessageType::AUTHOR_ERROR) { t = MessageType::AUTHOR_WARNING; } } else if (t == MessageType::DEPRECATION_WARNING || t == MessageType::DEPRECATION_ERROR) { warningsAsErrors = this->GetDeprecatedWarningsAsErrors(); if (warningsAsErrors && t == MessageType::DEPRECATION_WARNING) { t = MessageType::DEPRECATION_ERROR; } else if (!warningsAsErrors && t == MessageType::DEPRECATION_ERROR) { t = MessageType::DEPRECATION_WARNING; } } return t; } bool cmMessenger::IsMessageTypeVisible(MessageType t) const { bool isVisible = true; if (t == MessageType::DEPRECATION_ERROR) { if (!this->GetDeprecatedWarningsAsErrors()) { isVisible = false; } } else if (t == MessageType::DEPRECATION_WARNING) { if (this->GetSuppressDeprecatedWarnings()) { isVisible = false; } } else if (t == MessageType::AUTHOR_ERROR) { if (!this->GetDevWarningsAsErrors()) { isVisible = false; } } else if (t == MessageType::AUTHOR_WARNING) { if (this->GetSuppressDevWarnings()) { isVisible = false; } } return isVisible; } static bool printMessagePreamble(MessageType t, std::ostream& msg) { // Construct the message header. if (t == MessageType::FATAL_ERROR) { msg << "CMake Error"; } else if (t == MessageType::INTERNAL_ERROR) { msg << "CMake Internal Error (please report a bug)"; } else if (t == MessageType::LOG) { msg << "CMake Debug Log"; } else if (t == MessageType::DEPRECATION_ERROR) { msg << "CMake Deprecation Error"; } else if (t == MessageType::DEPRECATION_WARNING) { msg << "CMake Deprecation Warning"; } else if (t == MessageType::AUTHOR_WARNING) { msg << "CMake Warning (dev)"; } else if (t == MessageType::AUTHOR_ERROR) { msg << "CMake Error (dev)"; } else { msg << "CMake Warning"; } return true; } void printMessageText(std::ostream& msg, std::string const& text) { msg << ":\n"; cmDocumentationFormatter formatter; formatter.SetIndent(" "); formatter.PrintFormatted(msg, text.c_str()); } void displayMessage(MessageType t, std::ostringstream& msg) { // Add a note about warning suppression. if (t == MessageType::AUTHOR_WARNING) { msg << "This warning is for project developers. Use -Wno-dev to suppress " "it."; } else if (t == MessageType::AUTHOR_ERROR) { msg << "This error is for project developers. Use -Wno-error=dev to " "suppress " "it."; } // Add a terminating blank line. msg << "\n"; #if defined(CMAKE_BUILD_WITH_CMAKE) // Add a C++ stack trace to internal errors. if (t == MessageType::INTERNAL_ERROR) { std::string stack = cmsys::SystemInformation::GetProgramStack(0, 0); if (!stack.empty()) { if (cmHasLiteralPrefix(stack, "WARNING:")) { stack = "Note:" + stack.substr(8); } msg << stack << "\n"; } } #endif // Output the message. if (t == MessageType::FATAL_ERROR || t == MessageType::INTERNAL_ERROR || t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) { cmSystemTools::SetErrorOccured(); cmSystemTools::Message(msg.str().c_str(), "Error"); } else { cmSystemTools::Message(msg.str().c_str(), "Warning"); } } void cmMessenger::IssueMessage(MessageType t, const std::string& text, const cmListFileBacktrace& backtrace) const { bool force = false; if (!force) { // override the message type, if needed, for warnings and errors MessageType override = this->ConvertMessageType(t); if (override != t) { t = override; force = true; } } if (!force && !this->IsMessageTypeVisible(t)) { return; } this->DisplayMessage(t, text, backtrace); } void cmMessenger::DisplayMessage(MessageType t, const std::string& text, const cmListFileBacktrace& backtrace) const { std::ostringstream msg; if (!printMessagePreamble(t, msg)) { return; } // Add the immediate context. backtrace.PrintTitle(msg); printMessageText(msg, text); // Add the rest of the context. backtrace.PrintCallStack(msg); displayMessage(t, msg); }