| /* 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 "cmState.h" |
| #include "cmSystemTools.h" |
| |
| #if defined(CMAKE_BUILD_WITH_CMAKE) |
| #include "cmsys/SystemInformation.hxx" |
| #endif |
| |
| #include <sstream> |
| |
| cmake::MessageType cmMessenger::ConvertMessageType(cmake::MessageType t) const |
| { |
| bool warningsAsErrors; |
| |
| if (t == cmake::AUTHOR_WARNING || t == cmake::AUTHOR_ERROR) { |
| warningsAsErrors = this->GetDevWarningsAsErrors(); |
| if (warningsAsErrors && t == cmake::AUTHOR_WARNING) { |
| t = cmake::AUTHOR_ERROR; |
| } else if (!warningsAsErrors && t == cmake::AUTHOR_ERROR) { |
| t = cmake::AUTHOR_WARNING; |
| } |
| } else if (t == cmake::DEPRECATION_WARNING || |
| t == cmake::DEPRECATION_ERROR) { |
| warningsAsErrors = this->GetDeprecatedWarningsAsErrors(); |
| if (warningsAsErrors && t == cmake::DEPRECATION_WARNING) { |
| t = cmake::DEPRECATION_ERROR; |
| } else if (!warningsAsErrors && t == cmake::DEPRECATION_ERROR) { |
| t = cmake::DEPRECATION_WARNING; |
| } |
| } |
| |
| return t; |
| } |
| |
| bool cmMessenger::IsMessageTypeVisible(cmake::MessageType t) const |
| { |
| bool isVisible = true; |
| |
| if (t == cmake::DEPRECATION_ERROR) { |
| if (!this->GetDeprecatedWarningsAsErrors()) { |
| isVisible = false; |
| } |
| } else if (t == cmake::DEPRECATION_WARNING) { |
| if (this->GetSuppressDeprecatedWarnings()) { |
| isVisible = false; |
| } |
| } else if (t == cmake::AUTHOR_ERROR) { |
| if (!this->GetDevWarningsAsErrors()) { |
| isVisible = false; |
| } |
| } else if (t == cmake::AUTHOR_WARNING) { |
| if (this->GetSuppressDevWarnings()) { |
| isVisible = false; |
| } |
| } |
| |
| return isVisible; |
| } |
| |
| static bool printMessagePreamble(cmake::MessageType t, std::ostream& msg) |
| { |
| // Construct the message header. |
| if (t == cmake::FATAL_ERROR) { |
| msg << "CMake Error"; |
| } else if (t == cmake::INTERNAL_ERROR) { |
| msg << "CMake Internal Error (please report a bug)"; |
| } else if (t == cmake::LOG) { |
| msg << "CMake Debug Log"; |
| } else if (t == cmake::DEPRECATION_ERROR) { |
| msg << "CMake Deprecation Error"; |
| } else if (t == cmake::DEPRECATION_WARNING) { |
| msg << "CMake Deprecation Warning"; |
| } else if (t == cmake::AUTHOR_WARNING) { |
| msg << "CMake Warning (dev)"; |
| } else if (t == cmake::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(cmake::MessageType t, std::ostringstream& msg) |
| { |
| // Add a note about warning suppression. |
| if (t == cmake::AUTHOR_WARNING) { |
| msg << "This warning is for project developers. Use -Wno-dev to suppress " |
| "it."; |
| } else if (t == cmake::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 == cmake::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 == cmake::FATAL_ERROR || t == cmake::INTERNAL_ERROR || |
| t == cmake::DEPRECATION_ERROR || t == cmake::AUTHOR_ERROR) { |
| cmSystemTools::SetErrorOccured(); |
| cmSystemTools::Message(msg.str().c_str(), "Error"); |
| } else { |
| cmSystemTools::Message(msg.str().c_str(), "Warning"); |
| } |
| } |
| |
| cmMessenger::cmMessenger(cmState* state) |
| : State(state) |
| { |
| } |
| |
| void cmMessenger::IssueMessage(cmake::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 |
| cmake::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(cmake::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); |
| } |
| |
| bool cmMessenger::GetSuppressDevWarnings() const |
| { |
| const char* cacheEntryValue = |
| this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"); |
| return cmSystemTools::IsOn(cacheEntryValue); |
| } |
| |
| bool cmMessenger::GetSuppressDeprecatedWarnings() const |
| { |
| const char* cacheEntryValue = |
| this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED"); |
| return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue); |
| } |
| |
| bool cmMessenger::GetDevWarningsAsErrors() const |
| { |
| const char* cacheEntryValue = |
| this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS"); |
| return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue); |
| } |
| |
| bool cmMessenger::GetDeprecatedWarningsAsErrors() const |
| { |
| const char* cacheEntryValue = |
| this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED"); |
| return cmSystemTools::IsOn(cacheEntryValue); |
| } |