Skip to content

Commit de780ad

Browse files
committed
substitute static parts of the template strings only once
1 parent ef72e2e commit de780ad

7 files changed

Lines changed: 128 additions & 11 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,9 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
10051005
if (mSettings->templateLocation.empty())
10061006
mSettings->templateLocation = "{bold}{file}:{line}:{column}: {dim}note:{reset} {info}\\n{code}";
10071007
}
1008+
// replace static parts of the templates
1009+
substituteTemplateFormatStatic(mSettings->templateFormat);
1010+
substituteTemplateLocationStatic(mSettings->templateLocation);
10081011

10091012
mSettings->project.ignorePaths(mIgnoredPaths);
10101013

lib/color.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,20 @@
2424
#include <sstream> // IWYU pragma: keep
2525
#endif
2626

27-
std::ostream& operator<<(std::ostream & os, const Color& c)
27+
bool isStdOutATty()
2828
{
2929
#ifndef _WIN32
30-
static const bool use_color = isatty(STDOUT_FILENO);
31-
if (use_color)
32-
return os << "\033[" << static_cast<std::size_t>(c) << "m";
30+
static const bool stdout_tty = isatty(STDOUT_FILENO);
3331
#else
34-
(void)c;
32+
static const bool stdout_tty = false;
3533
#endif
34+
return stdout_tty;
35+
}
36+
37+
std::ostream& operator<<(std::ostream & os, const Color& c)
38+
{
39+
if (isStdOutATty())
40+
return os << "\033[" << static_cast<std::size_t>(c) << "m";
3641
return os;
3742
}
3843

lib/color.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ enum class Color {
3838
BgBlue = 44,
3939
BgDefault = 49
4040
};
41+
42+
/** Retruns if stdout is a tty - always false on Windows */
43+
CPPCHECKLIB bool isStdOutATty();
44+
4145
CPPCHECKLIB std::ostream& operator<<(std::ostream& os, const Color& c);
4246

4347
std::string toString(const Color& c);

lib/errorlogger.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
591591

592592
// template is given. Reformat the output according to it
593593
std::string result = templateFormat;
594-
replaceSpecialChars(result);
595594

596-
replaceColors(result);
597595
findAndReplace(result, "{id}", id);
598596

599597
std::string::size_type pos1 = result.find("{inconclusive:");
@@ -636,9 +634,6 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
636634
for (const FileLocation &fileLocation : callStack) {
637635
std::string text = templateLocation;
638636

639-
replaceSpecialChars(text);
640-
641-
replaceColors(text);
642637
findAndReplace(text, "{file}", fileLocation.getfile());
643638
findAndReplace(text, "{line}", MathLib::toString(fileLocation.line));
644639
findAndReplace(text, "{column}", MathLib::toString(fileLocation.column));
@@ -905,3 +900,15 @@ std::string replaceStr(std::string s, const std::string &from, const std::string
905900
}
906901
return s;
907902
}
903+
904+
void substituteTemplateFormatStatic(std::string& templateFormat)
905+
{
906+
replaceSpecialChars(templateFormat);
907+
replaceColors(templateFormat);
908+
}
909+
910+
void substituteTemplateLocationStatic(std::string& templateLocation)
911+
{
912+
replaceSpecialChars(templateLocation);
913+
replaceColors(templateLocation);
914+
}

lib/errorlogger.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,12 @@ class CPPCHECKLIB ErrorLogger {
286286
/** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */
287287
std::string replaceStr(std::string s, const std::string &from, const std::string &to);
288288

289+
/** replaces the static parts of the location template **/
290+
CPPCHECKLIB void substituteTemplateFormatStatic(std::string& templateFormat);
291+
292+
/** replaces the static parts of the location template **/
293+
CPPCHECKLIB void substituteTemplateLocationStatic(std::string& templateLocation);
294+
289295
/// @}
290296
//---------------------------------------------------------------------------
291297
#endif // errorloggerH

test/testcmdlineparser.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include "cmdlineparser.h"
20+
#include "color.h"
2021
#include "cppcheckexecutor.h"
2122
#include "errortypes.h"
2223
#include "platform.h"
@@ -1230,7 +1231,12 @@ class TestCmdlineParser : public TestFixture {
12301231
const char * const argv[] = {"cppcheck", "--template", "gcc", "file.cpp"};
12311232
settings.templateFormat.clear();
12321233
ASSERT(defParser.parseFromArgs(4, argv));
1233-
ASSERT_EQUALS("{bold}{file}:{line}:{column}: {magenta}warning:{default} {message} [{id}]{reset}\\n{code}", settings.templateFormat);
1234+
if (isStdOutATty()) {
1235+
ASSERT_EQUALS("\x1b[1m{file}:{line}:{column}: \x1b[35mwarning:\x1b[39m {message} [{id}]\x1b[0m\n{code}", settings.templateFormat);
1236+
}
1237+
else {
1238+
ASSERT_EQUALS("{file}:{line}:{column}: warning: {message} [{id}]\n{code}", settings.templateFormat);
1239+
}
12341240
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
12351241
}
12361242

test/testerrorlogger.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19+
#include "color.h"
1920
#include "config.h"
2021
#include "cppcheck.h"
2122
#include "errorlogger.h"
@@ -64,6 +65,8 @@ class TestErrorLogger : public TestFixture {
6465
TEST_CASE(SerializeFileLocation);
6566

6667
TEST_CASE(suppressUnmatchedSuppressions);
68+
TEST_CASE(substituteTemplateFormatStatic);
69+
TEST_CASE(substituteTemplateLocationStatic);
6770
}
6871

6972
void TestPatternSearchReplace(const std::string& idPlaceholder, const std::string& id) const {
@@ -482,6 +485,89 @@ class TestErrorLogger : public TestFixture {
482485
reportUnmatchedSuppressions(suppressions);
483486
ASSERT_EQUALS("[a.c:10]: (information) Unmatched suppression: abc\n", errout.str());
484487
}
488+
489+
void substituteTemplateFormatStatic()
490+
{
491+
{
492+
std::string s;
493+
::substituteTemplateFormatStatic(s);
494+
ASSERT_EQUALS("", s);
495+
}
496+
{
497+
std::string s = "template{black}\\z";
498+
::substituteTemplateFormatStatic(s);
499+
ASSERT_EQUALS("template{black}\\z", s);
500+
}
501+
{
502+
std::string s = "{reset}{bold}{dim}{red}{blue}{magenta}{default}\\b\\n\\r\\t";
503+
::substituteTemplateFormatStatic(s);
504+
if (isStdOutATty()) {
505+
ASSERT_EQUALS("\x1b[0m\x1b[1m\x1b[2m\x1b[31m\x1b[34m\x1b[35m\x1b[39m\b\n\r\t", s);
506+
}
507+
else {
508+
ASSERT_EQUALS("\b\n\r\t", s);
509+
}
510+
}
511+
{
512+
std::string s = "\\\\n";
513+
::substituteTemplateFormatStatic(s);
514+
ASSERT_EQUALS("\\\n", s);
515+
}
516+
{
517+
std::string s = "{{red}";
518+
::substituteTemplateFormatStatic(s);
519+
if (isStdOutATty()) {
520+
ASSERT_EQUALS("{\x1b[31m", s);
521+
}
522+
else {
523+
ASSERT_EQUALS("{", s);
524+
}
525+
}
526+
}
527+
528+
void substituteTemplateLocationStatic()
529+
{
530+
{
531+
std::string s;
532+
::substituteTemplateLocationStatic(s);
533+
ASSERT_EQUALS("", s);
534+
}
535+
{
536+
std::string s = "template";
537+
::substituteTemplateLocationStatic(s);
538+
ASSERT_EQUALS("template", s);
539+
}
540+
{
541+
std::string s = "template{black}\\z";
542+
::substituteTemplateFormatStatic(s);
543+
ASSERT_EQUALS("template{black}\\z", s);
544+
}
545+
{
546+
std::string s = "{reset}{bold}{dim}{red}{blue}{magenta}{default}\\b\\n\\r\\t";
547+
::substituteTemplateFormatStatic(s);
548+
if (isStdOutATty()) {
549+
ASSERT_EQUALS("\x1b[0m\x1b[1m\x1b[2m\x1b[31m\x1b[34m\x1b[35m\x1b[39m\b\n\r\t", s);
550+
}
551+
else {
552+
ASSERT_EQUALS("\b\n\r\t", s);
553+
}
554+
}
555+
{
556+
std::string s = "\\\\n";
557+
::substituteTemplateFormatStatic(s);
558+
ASSERT_EQUALS("\\\n", s);
559+
}
560+
{
561+
std::string s = "{{red}";
562+
::substituteTemplateFormatStatic(s);
563+
if (isStdOutATty()) {
564+
ASSERT_EQUALS("{\x1b[31m", s);
565+
}
566+
else {
567+
ASSERT_EQUALS("{", s);
568+
}
569+
}
570+
}
485571
};
486572

487573
REGISTER_TEST(TestErrorLogger)

0 commit comments

Comments
 (0)