diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 7c18e428023..c2511969c59 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1581,7 +1581,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // Default template format.. if (mSettings.templateFormat.empty()) { - mSettings.templateFormat = "{bold}{file}:{line}:{column}: {red}{inconclusive:{magenta}}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}"; + mSettings.templateFormat = "{bold}{file}:{line}:{column}: {inconclusive:}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}"; if (mSettings.templateLocation.empty()) mSettings.templateLocation = "{bold}{file}:{line}:{column}: {dim}note:{reset} {info}\\n{code}"; } diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index e62ed6b806d..0e7233c2d4d 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -644,7 +644,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm // replace id with guideline if present // replace severity with classification if present const std::string idStr = guideline.empty() ? id : guideline; - const std::string severityStr = classification.empty() ? severityToString(severity) : classification; + std::string severityStr = classification.empty() ? coloredSeverityToString(severity) : classification; findAndReplace(result, "{id}", idStr); @@ -656,6 +656,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm findAndReplace(result, replaceFrom, replaceWith); pos1 = result.find("{inconclusive:", pos1); } + replaceColors(severityStr, !templateFormat.empty()); findAndReplace(result, "{severity}", severityStr); findAndReplace(result, "{cwe}", std::to_string(cwe.id)); findAndReplace(result, "{message}", verbose ? mVerboseMessage : mShortMessage); diff --git a/lib/errortypes.cpp b/lib/errortypes.cpp index 0741ea36796..948bc497a86 100644 --- a/lib/errortypes.cpp +++ b/lib/errortypes.cpp @@ -72,6 +72,31 @@ std::string severityToString(Severity severity) cppcheck::unreachable(); } +std::string coloredSeverityToString(Severity severity) +{ + switch (severity) { + case Severity::none: + return ""; + case Severity::error: + return "{red}error"; + case Severity::warning: + return "{magenta}warning"; + case Severity::style: + return "{bold}style"; + case Severity::performance: + return "{bold}performance"; + case Severity::portability: + return "{bold}portability"; + case Severity::information: + return "{green}information"; + case Severity::debug: + return "debug"; + case Severity::internal: + return "internal"; + } + throw InternalError(nullptr, "Unknown severity"); +} + // TODO: bail out on invalid severity Severity severityFromString(const std::string& severity) { diff --git a/lib/errortypes.h b/lib/errortypes.h index e2fe6897447..8ee7f4cd827 100644 --- a/lib/errortypes.h +++ b/lib/errortypes.h @@ -120,6 +120,7 @@ enum class Severity : std::uint8_t { }; CPPCHECKLIB std::string severityToString(Severity severity); +CPPCHECKLIB std::string coloredSeverityToString(Severity severity); CPPCHECKLIB Severity severityFromString(const std::string &severity); struct CWE { diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index 42537ca36fb..b12839e9c47 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -52,6 +52,7 @@ class TestErrorLogger : public TestFixture { TEST_CASE(ErrorMessageVerbose); TEST_CASE(ErrorMessageVerboseLocations); TEST_CASE(ErrorMessageFromInternalError); + TEST_CASE(ErrorMessageColorized); TEST_CASE(CustomFormat); TEST_CASE(CustomFormat2); TEST_CASE(CustomFormatLocations); @@ -341,6 +342,34 @@ class TestErrorLogger : public TestFixture { testReportType(ReportType::certC, Severity::error, "resourceLeak", "L3", "FIO42-C"); } + void ErrorMessageColorized() const { + const bool oDisableColors = gDisableColors; + gDisableColors = false; + setenv("CLICOLOR_FORCE", "1", 1); + std::list locs = { }; + { + ErrorMessage msg(std::move(locs), "", Severity::error, "Programming error.\nVerbose error", "errorId", + Certainty::normal); + ASSERT_EQUALS("{bold} \x1b[31merror: Programming error.", msg.toString(false, "{bold} {severity}: {message}", "")); + } + { + ErrorMessage msg(std::move(locs), "", Severity::warning, "Programming warning.\nVerbose warning", "errorId", + Certainty::normal); + ASSERT_EQUALS("{bold} \x1b[35mwarning: Programming warning.", msg.toString(false, "{bold} {severity}: {message}", "")); + } + { + ErrorMessage msg(std::move(locs), "", Severity::style, "Style.\nVerbose style", "errorId", Certainty::normal); + ASSERT_EQUALS("{bold} \x1b[1mstyle: Style.", msg.toString(false, "{bold} {severity}: {message}", "")); + } + { + ErrorMessage msg(std::move(locs), "", Severity::information, "Programming information.\nProgramming information", + "errorId", Certainty::normal); + ASSERT_EQUALS("{bold} \x1b[32minformation: Programming information.", msg.toString(false, "{bold} {severity}: {message}", "")); + } + setenv("CLICOLOR_FORCE", "", 1); + gDisableColors = oDisableColors; + } + void CustomFormat() const { std::list locs(1, fooCpp5); ErrorMessage msg(std::move(locs), "", Severity::error, "Programming error.\nVerbose error", "errorId", Certainty::normal);