diff --git a/democlient/democlient.cpp b/democlient/democlient.cpp index 0f0e7088cde..859882e0ce6 100644 --- a/democlient/democlient.cpp +++ b/democlient/democlient.cpp @@ -72,7 +72,9 @@ class CppcheckExecutor : public ErrorLogger { void reportOut(const std::string & /*outmsg*/, Color /*c*/) override {} void reportErr(const ErrorMessage &msg) override { - const std::string s = msg.toString(true); + static const std::string templateFormat = "{bold}{file}:{line}:{column}: {red}{inconclusive:{magenta}}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}"; + static const std::string templateLocation = "{bold}{file}:{line}:{column}: {dim}note:{reset} {info}\\n{code}"; + const std::string s = msg.toString(true, templateFormat, templateLocation); std::cout << s << std::endl; diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 7024969117a..fbb6c4cce95 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -1867,6 +1867,7 @@ void CppCheck::purgedConfigurationMessage(const std::string &file, const std::st void CppCheck::getErrorMessages(ErrorLogger &errorlogger) { Settings settings; + settings.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: get rid of this Suppressions supprs; CppCheck cppcheck(settings, supprs, errorlogger, true, nullptr); diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 43f3369b5eb..b035856213f 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -610,30 +610,9 @@ static void replaceColors(std::string& source) { replace(source, substitutionMap); } -// TODO: remove default parameters std::string ErrorMessage::toString(bool verbose, const std::string &templateFormat, const std::string &templateLocation) const { - // Save this ErrorMessage in plain text. - - // TODO: should never happen - remove this - // No template is given - // (not 100%) equivalent templateFormat: {callstack} ({severity}{inconclusive:, inconclusive}) {message} - if (templateFormat.empty()) { - std::string text; - if (!callStack.empty()) { - text += ErrorLogger::callStackToString(callStack); - text += ": "; - } - if (severity != Severity::none) { - text += '('; - text += severityToString(severity); - if (certainty == Certainty::inconclusive) - text += ", inconclusive"; - text += ") "; - } - text += (verbose ? mVerboseMessage : mShortMessage); - return text; - } + assert(!templateFormat.empty()); // template is given. Reformat the output according to it std::string result = templateFormat; diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 2d24e5f44fe..3f82986b01e 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -158,8 +158,8 @@ class CPPCHECKLIB ErrorMessage { * @return formatted string */ std::string toString(bool verbose, - const std::string &templateFormat = emptyString, - const std::string &templateLocation = emptyString) const; + const std::string &templateFormat, + const std::string &templateLocation) const; std::string serialize() const; void deserialize(const std::string &data); diff --git a/oss-fuzz/main.cpp b/oss-fuzz/main.cpp index 358910595bc..dd8f77a80b1 100644 --- a/oss-fuzz/main.cpp +++ b/oss-fuzz/main.cpp @@ -49,6 +49,8 @@ static Settings create_settings() { // TODO: load std.cfg Settings s; + s.templateFormat = "{bold}{file}:{line}:{column}: {red}{inconclusive:{magenta}}{severity}:{inconclusive: inconclusive:}{default} {message} [{id}]{reset}\\n{code}"; + s.templateLocation = "{bold}{file}:{line}:{column}: {dim}note:{reset} {info}\\n{code}"; s.addEnabled("all"); s.certainty.setEnabled(Certainty::inconclusive, true); return s; diff --git a/test/fixture.cpp b/test/fixture.cpp index 29a64e02647..3a4b685466a 100644 --- a/test/fixture.cpp +++ b/test/fixture.cpp @@ -429,7 +429,26 @@ void TestFixture::reportErr(const ErrorMessage &msg) return; if (msg.severity == Severity::information && msg.id == "normalCheckLevelMaxBranches") return; - const std::string errormessage(msg.toString(mVerbose, mTemplateFormat, mTemplateLocation)); + std::string errormessage; + if (!mTemplateFormat.empty()) { + errormessage = msg.toString(mVerbose, mTemplateFormat, mTemplateLocation); + } + else { + if (!msg.callStack.empty()) { + // TODO: add column + errormessage += ErrorLogger::callStackToString(msg.callStack); + errormessage += ": "; + } + if (msg.severity != Severity::none) { + errormessage += '('; + errormessage += severityToString(msg.severity); + if (msg.certainty == Certainty::inconclusive) + errormessage += ", inconclusive"; + errormessage += ") "; + } + errormessage += msg.shortMessage(); + // TODO: add ID + } mErrout << errormessage << std::endl; } diff --git a/test/testcppcheck.cpp b/test/testcppcheck.cpp index aa9e90d15fa..78b343ffed0 100644 --- a/test/testcppcheck.cpp +++ b/test/testcppcheck.cpp @@ -38,6 +38,7 @@ class TestCppcheck : public TestFixture { TestCppcheck() : TestFixture("TestCppcheck") {} private: + const std::string templateFormat{"{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]"}; class ErrorLogger2 : public ErrorLogger { public: @@ -113,7 +114,8 @@ class TestCppcheck : public TestFixture { " return 0;\n" "}"); - const Settings s; + /*const*/ Settings s; + s.templateFormat = templateFormat; Suppressions supprs; ErrorLogger2 errorLogger; CppCheck cppcheck(s, supprs, errorLogger, false, {}); @@ -135,7 +137,8 @@ class TestCppcheck : public TestFixture { " return 0;\n" "}"); - const Settings s; + /*const*/ Settings s; + s.templateFormat = templateFormat; Suppressions supprs; ErrorLogger2 errorLogger; CppCheck cppcheck(s, supprs, errorLogger, false, {}); @@ -184,7 +187,9 @@ class TestCppcheck : public TestFixture { ScopedFile test_file_b("b.cpp", "#include \"inc.h\""); - const Settings s; + /*const*/ Settings s; + // this is the "simple" format + s.templateFormat = templateFormat; // TODO: remove when we only longer rely on toString() in unique message handling Suppressions supprs; ErrorLogger2 errorLogger; CppCheck cppcheck(s, supprs, errorLogger, false, {}); @@ -215,9 +220,9 @@ class TestCppcheck : public TestFixture { "(void)b;\n" "}"); - Settings s; + /*const*/ Settings s; // this is the "simple" format - s.templateFormat = "{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]"; + s.templateFormat = templateFormat; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; ErrorLogger2 errorLogger; CppCheck cppcheck(s, supprs, errorLogger, false, {}); diff --git a/test/testerrorlogger.cpp b/test/testerrorlogger.cpp index cdd74a95aa8..125e87aebd2 100644 --- a/test/testerrorlogger.cpp +++ b/test/testerrorlogger.cpp @@ -33,6 +33,8 @@ class TestErrorLogger : public TestFixture { TestErrorLogger() : TestFixture("TestErrorLogger") {} private: + const std::string templateFormat{"{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"}; + const ErrorMessage::FileLocation fooCpp5{"foo.cpp", 5, 1}; const ErrorMessage::FileLocation barCpp8{"bar.cpp", 8, 1}; const ErrorMessage::FileLocation barCpp8_i{"bar.cpp", "รค", 8, 1}; @@ -81,13 +83,13 @@ class TestErrorLogger : public TestFixture { ErrorMessage message; message.id = id; - std::string serialized = message.toString(true, idPlaceholder + plainText + idPlaceholder); + std::string serialized = message.toString(true, idPlaceholder + plainText + idPlaceholder, ""); ASSERT_EQUALS(id + plainText + id, serialized); - serialized = message.toString(true, idPlaceholder + idPlaceholder); + serialized = message.toString(true, idPlaceholder + idPlaceholder, ""); ASSERT_EQUALS(id + id, serialized); - serialized = message.toString(true, plainText + idPlaceholder + plainText); + serialized = message.toString(true, plainText + idPlaceholder + plainText, ""); ASSERT_EQUALS(plainText + id + plainText, serialized); } @@ -133,8 +135,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.verboseMessage()); - ASSERT_EQUALS("[foo.cpp:5]: (error) Programming error.", msg.toString(false)); - ASSERT_EQUALS("[foo.cpp:5]: (error) Programming error.", msg.toString(true)); + ASSERT_EQUALS("[foo.cpp:5]: (error) Programming error.", msg.toString(false, templateFormat, "")); + ASSERT_EQUALS("[foo.cpp:5]: (error) Programming error.", msg.toString(true, templateFormat, "")); } void ErrorMessageConstructLocations() const { @@ -143,8 +145,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(2, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Programming error.", msg.verboseMessage()); - ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Programming error.", msg.toString(false)); - ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Programming error.", msg.toString(true)); + ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Programming error.", msg.toString(false, templateFormat, "")); + ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Programming error.", msg.toString(true, templateFormat, "")); } void ErrorMessageVerbose() const { @@ -153,8 +155,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); - ASSERT_EQUALS("[foo.cpp:5]: (error) Programming error.", msg.toString(false)); - ASSERT_EQUALS("[foo.cpp:5]: (error) Verbose error", msg.toString(true)); + ASSERT_EQUALS("[foo.cpp:5]: (error) Programming error.", msg.toString(false, templateFormat, "")); + ASSERT_EQUALS("[foo.cpp:5]: (error) Verbose error", msg.toString(true, templateFormat, "")); } void ErrorMessageVerboseLocations() const { @@ -163,8 +165,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(2, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); - ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Programming error.", msg.toString(false)); - ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Verbose error", msg.toString(true)); + ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Programming error.", msg.toString(false, templateFormat, "")); + ASSERT_EQUALS("[foo.cpp:5] -> [bar.cpp:8]: (error) Verbose error", msg.toString(true, templateFormat, "")); } void ErrorMessageFromInternalError() const { @@ -179,8 +181,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(0, loc.column); ASSERT_EQUALS("message", msg.shortMessage()); ASSERT_EQUALS("message", msg.verboseMessage()); - ASSERT_EQUALS("[file.c:0]: (error) message", msg.toString(false)); - ASSERT_EQUALS("[file.c:0]: (error) message", msg.toString(true)); + ASSERT_EQUALS("[file.c:0]: (error) message", msg.toString(false, templateFormat, "")); + ASSERT_EQUALS("[file.c:0]: (error) message", msg.toString(true, templateFormat, "")); } { InternalError internalError(nullptr, "message", "details", InternalError::INTERNAL); @@ -192,8 +194,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(0, loc.column); ASSERT_EQUALS("msg: message", msg.shortMessage()); ASSERT_EQUALS("msg: message: details", msg.verboseMessage()); - ASSERT_EQUALS("[file.cpp:0]: (error) msg: message", msg.toString(false)); - ASSERT_EQUALS("[file.cpp:0]: (error) msg: message: details", msg.toString(true)); + ASSERT_EQUALS("[file.cpp:0]: (error) msg: message", msg.toString(false, templateFormat, "")); + ASSERT_EQUALS("[file.cpp:0]: (error) msg: message: details", msg.toString(true, templateFormat, "")); } } @@ -207,7 +209,7 @@ class TestErrorLogger : public TestFixture { msg.classification = getClassification(msg.guideline, reportType); ASSERT_EQUALS("Advisory", msg.classification); ASSERT_EQUALS("2.8", msg.guideline); - ASSERT_EQUALS("Advisory 2.8", msg.toString(true, format)); + ASSERT_EQUALS("Advisory 2.8", msg.toString(true, format, "")); } void ErrorMessageReportTypeCertC() const { @@ -220,7 +222,7 @@ class TestErrorLogger : public TestFixture { msg.classification = getClassification(msg.guideline, reportType); ASSERT_EQUALS("L3", msg.classification); ASSERT_EQUALS("FIO42-C", msg.guideline); - ASSERT_EQUALS("L3 FIO42-C", msg.toString(true, format)); + ASSERT_EQUALS("L3 FIO42-C", msg.toString(true, format, "")); } void CustomFormat() const { @@ -229,8 +231,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); - ASSERT_EQUALS("foo.cpp:5,error,errorId,Programming error.", msg.toString(false, "{file}:{line},{severity},{id},{message}")); - ASSERT_EQUALS("foo.cpp:5,error,errorId,Verbose error", msg.toString(true, "{file}:{line},{severity},{id},{message}")); + ASSERT_EQUALS("foo.cpp:5,error,errorId,Programming error.", msg.toString(false, "{file}:{line},{severity},{id},{message}", "")); + ASSERT_EQUALS("foo.cpp:5,error,errorId,Verbose error", msg.toString(true, "{file}:{line},{severity},{id},{message}", "")); } void CustomFormat2() const { @@ -239,8 +241,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(1, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); - ASSERT_EQUALS("Programming error. - foo.cpp(5):(error,errorId)", msg.toString(false, "{message} - {file}({line}):({severity},{id})")); - ASSERT_EQUALS("Verbose error - foo.cpp(5):(error,errorId)", msg.toString(true, "{message} - {file}({line}):({severity},{id})")); + ASSERT_EQUALS("Programming error. - foo.cpp(5):(error,errorId)", msg.toString(false, "{message} - {file}({line}):({severity},{id})", "")); + ASSERT_EQUALS("Verbose error - foo.cpp(5):(error,errorId)", msg.toString(true, "{message} - {file}({line}):({severity},{id})", "")); } void CustomFormatLocations() const { @@ -250,8 +252,8 @@ class TestErrorLogger : public TestFixture { ASSERT_EQUALS(2, msg.callStack.size()); ASSERT_EQUALS("Programming error.", msg.shortMessage()); ASSERT_EQUALS("Verbose error", msg.verboseMessage()); - ASSERT_EQUALS("Programming error. - bar.cpp(8):(error,errorId)", msg.toString(false, "{message} - {file}({line}):({severity},{id})")); - ASSERT_EQUALS("Verbose error - bar.cpp(8):(error,errorId)", msg.toString(true, "{message} - {file}({line}):({severity},{id})")); + ASSERT_EQUALS("Programming error. - bar.cpp(8):(error,errorId)", msg.toString(false, "{message} - {file}({line}):({severity},{id})", "")); + ASSERT_EQUALS("Verbose error - bar.cpp(8):(error,errorId)", msg.toString(true, "{message} - {file}({line}):({severity},{id})", "")); } void ToXmlV2() const { diff --git a/test/testexecutor.cpp b/test/testexecutor.cpp index b2d69d78b26..e11f563b553 100644 --- a/test/testexecutor.cpp +++ b/test/testexecutor.cpp @@ -47,34 +47,9 @@ class TestExecutor : public TestFixture { private: void run() override { - TEST_CASE(hasToLogDefault); TEST_CASE(hasToLogSimple); } - void hasToLogDefault() { - const std::list<FileWithDetails> files{FileWithDetails{"test.c"}}; - const std::list<FileSettings> fileSettings; - Suppressions supprs; - DummyExecutor executor(files, fileSettings, settingsDefault, supprs, *this); - - ErrorMessage::FileLocation loc1("test.c", 1, 2); - ErrorMessage msg({std::move(loc1)}, "test.c", Severity::error, "error", "id", Certainty::normal); - - ASSERT(executor.hasToLog_(msg)); - ASSERT(!executor.hasToLog_(msg)); - - ErrorMessage::FileLocation loc2("test.c", 1, 12); - msg.callStack = {std::move(loc2)}; - - // TODO: the default message does not include the column - TODO_ASSERT(executor.hasToLog_(msg)); - - msg.id = "id2"; - - // TODO: the default message does not include the id - TODO_ASSERT(executor.hasToLog_(msg)); - } - void hasToLogSimple() { const std::list<FileWithDetails> files{FileWithDetails{"test.c"}}; const std::list<FileSettings> fileSettings; diff --git a/test/testprocessexecutor.cpp b/test/testprocessexecutor.cpp index 56cbb640cfc..aa350557d06 100644 --- a/test/testprocessexecutor.cpp +++ b/test/testprocessexecutor.cpp @@ -95,6 +95,7 @@ class TestProcessExecutorBase : public TestFixture { s.quiet = opt.quiet; if (opt.plistOutput) s.plistOutput = opt.plistOutput; + s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; Suppressions supprs; bool executeCommandCalled = false; diff --git a/test/testsingleexecutor.cpp b/test/testsingleexecutor.cpp index c2ad6d586b8..ac11ea1d64b 100644 --- a/test/testsingleexecutor.cpp +++ b/test/testsingleexecutor.cpp @@ -100,6 +100,7 @@ class TestSingleExecutorBase : public TestFixture { if (opt.plistOutput) s.plistOutput = opt.plistOutput; s.clangTidy = opt.clangTidy; + s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs; diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index b630658a6bc..ecab7fa3586 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -44,6 +44,8 @@ class TestSuppressions : public TestFixture { private: + const std::string templateFormat{"{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"}; + void run() override { TEST_CASE(suppressionsBadId1); TEST_CASE(suppressionsDosFormat); // Ticket #1836 @@ -253,6 +255,7 @@ class TestSuppressions : public TestFixture { settings.severity.enable(Severity::information); if (suppression == "unusedFunction") settings.checks.setEnabled(Checks::unusedFunction, true); + settings.templateFormat = templateFormat; std::vector<std::unique_ptr<ScopedFile>> scopedfiles; scopedfiles.reserve(filelist.size()); @@ -294,6 +297,7 @@ class TestSuppressions : public TestFixture { $.quiet = true, $.inlineSuppressions = true); settings.severity.enable(Severity::information); + settings.templateFormat = templateFormat; Suppressions supprs; if (!suppression.empty()) { @@ -340,6 +344,7 @@ class TestSuppressions : public TestFixture { $.quiet = true, $.inlineSuppressions = true); settings.severity.enable(Severity::information); + settings.templateFormat = templateFormat; Suppressions supprs; if (!suppression.empty()) { @@ -1198,6 +1203,7 @@ class TestSuppressions : public TestFixture { Settings settings; settings.quiet = true; settings.exitCode = 1; + settings.templateFormat = templateFormat; Suppressions supprs; ASSERT_EQUALS("", supprs.nomsg.addSuppressionLine("uninitvar")); @@ -1238,6 +1244,7 @@ class TestSuppressions : public TestFixture { settings.inlineSuppressions = true; settings.relativePaths = true; settings.basePaths.emplace_back("/somewhere"); + settings.templateFormat = templateFormat; const char code[] = "struct Point\n" "{\n" diff --git a/test/testthreadexecutor.cpp b/test/testthreadexecutor.cpp index 419ce19d384..e4ebdc3b930 100644 --- a/test/testthreadexecutor.cpp +++ b/test/testthreadexecutor.cpp @@ -96,6 +96,7 @@ class TestThreadExecutorBase : public TestFixture { if (opt.plistOutput) s.plistOutput = opt.plistOutput; s.clangTidy = opt.clangTidy; + s.templateFormat = "{callstack}: ({severity}) {inconclusive:inconclusive: }{message}"; // TODO: remove when we only longer rely on toString() in unique message handling? Suppressions supprs;