optimized template string substitutions a bit (#4840)

This commit is contained in:
Oliver Stöneberg 2023-04-08 22:19:52 +02:00 committed by GitHub
parent 1f2b49142e
commit cfca3a69a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 361 additions and 50 deletions

View File

@ -281,6 +281,7 @@ TESTOBJ = test/fixture.o \
test/testclangimport.o \
test/testclass.o \
test/testcmdlineparser.o \
test/testcolor.o \
test/testcondition.o \
test/testconstructors.o \
test/testcppcheck.o \
@ -714,6 +715,9 @@ test/testclass.o: test/testclass.cpp externals/simplecpp/simplecpp.h lib/check.h
test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp
test/testcolor.o: test/testcolor.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/suppressions.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp
test/testcondition.o: test/testcondition.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkcondition.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp

View File

@ -888,6 +888,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
}
}
// TODO: deprecate "--template <template>"
// Output formatter
else if (std::strcmp(argv[i], "--template") == 0 ||
std::strncmp(argv[i], "--template=", 11) == 0) {
@ -901,6 +902,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
printError("argument to '--template' is missing.");
return false;
}
// TODO: bail out when no placeholders are found?
if (mSettings.templateFormat == "gcc") {
mSettings.templateFormat = "{bold}{file}:{line}:{column}: {magenta}warning:{default} {message} [{id}]{reset}\\n{code}";
@ -922,6 +924,7 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
}
}
// TODO: deprecate "--template-location <template>"
else if (std::strcmp(argv[i], "--template-location") == 0 ||
std::strncmp(argv[i], "--template-location=", 20) == 0) {
// "--template-location format"
@ -931,9 +934,10 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
++i;
mSettings.templateLocation = argv[i];
} else {
printError("argument to '--template' is missing.");
printError("argument to '--template-location' is missing.");
return false;
}
// TODO: bail out when no placeholders are found?
}
else if (std::strncmp(argv[i], "--template-max-time=", 20) == 0) {
@ -1015,6 +1019,9 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
if (mSettings.templateLocation.empty())
mSettings.templateLocation = "{bold}{file}:{line}:{column}: {dim}note:{reset} {info}\\n{code}";
}
// replace static parts of the templates
substituteTemplateFormatStatic(mSettings.templateFormat);
substituteTemplateLocationStatic(mSettings.templateLocation);
mSettings.project.ignorePaths(mIgnoredPaths);

View File

@ -383,7 +383,7 @@ void CppCheckExecutor::reportOut(const std::string &outmsg, Color c)
if (c == Color::Reset)
std::cout << ansiToOEM(outmsg, true) << std::endl;
else
std::cout << toString(c) << ansiToOEM(outmsg, true) << toString(Color::Reset) << std::endl;
std::cout << c << ansiToOEM(outmsg, true) << Color::Reset << std::endl;
}
void CppCheckExecutor::reportProgress(const std::string &filename, const char stage[], const std::size_t value)

View File

@ -20,30 +20,46 @@
#ifndef _WIN32
#include <unistd.h>
#endif
#include <cstddef>
#include <sstream> // IWYU pragma: keep
#include <iostream>
#endif
bool gDisableColors = false;
#ifdef _WIN32
std::ostream& operator<<(std::ostream& os, const Color& /*c*/)
#ifndef _WIN32
static bool isStreamATty(const std::ostream & os)
{
#else
static const bool stdout_tty = isatty(STDOUT_FILENO);
static const bool stderr_tty = isatty(STDERR_FILENO);
if (&os == &std::cout)
return stdout_tty;
if (&os == &std::cerr)
return stderr_tty;
return (stdout_tty && stderr_tty);
}
#endif
std::ostream& operator<<(std::ostream & os, const Color& c)
{
// TODO: handle piping into file as well as other pipes like stderr
static const bool s_is_tty = isatty(STDOUT_FILENO);
if (!gDisableColors && s_is_tty)
#ifndef _WIN32
if (!gDisableColors && isStreamATty(os))
return os << "\033[" << static_cast<std::size_t>(c) << "m";
#else
(void)c;
#endif
return os;
}
std::string toString(const Color& c)
{
#ifndef _WIN32
std::stringstream ss;
ss << c;
return ss.str();
#else
(void)c;
return "";
#endif
}

View File

@ -511,24 +511,64 @@ static std::string readCode(const std::string &file, int linenr, int column, con
return line + endl + std::string((column>0 ? column-1 : 0), ' ') + '^';
}
static void replaceColors(std::string& source)
static void replaceSpecialChars(std::string& source)
{
static const std::string reset_str = ::toString(Color::Reset);
findAndReplace(source, "{reset}", reset_str);
static const std::string bold_str = ::toString(Color::Bold);
findAndReplace(source, "{bold}", bold_str);
static const std::string dim_str = ::toString(Color::Dim);
findAndReplace(source, "{dim}", dim_str);
static const std::string red_str = ::toString(Color::FgRed);
findAndReplace(source, "{red}", red_str);
static const std::string green_str = ::toString(Color::FgGreen);
findAndReplace(source, "{green}", green_str);
static const std::string blue_str = ::toString(Color::FgBlue);
findAndReplace(source, "{blue}", blue_str);
static const std::string magenta_str = ::toString(Color::FgMagenta);
findAndReplace(source, "{magenta}", magenta_str);
static const std::string default_str = ::toString(Color::FgDefault);
findAndReplace(source, "{default}", default_str);
// Support a few special characters to allow to specific formatting, see http://sourceforge.net/apps/phpbb/cppcheck/viewtopic.php?f=4&t=494&sid=21715d362c0dbafd3791da4d9522f814
// Substitution should be done first so messages from cppcheck never get translated.
static const std::unordered_map<char, std::string> substitutionMap = {
{'b', "\b"},
{'n', "\n"},
{'r', "\r"},
{'t', "\t"}
};
std::string::size_type index = 0;
while ((index = source.find('\\', index)) != std::string::npos) {
const char searchFor = source[index+1];
const auto it = substitutionMap.find(searchFor);
if (it == substitutionMap.end()) {
index += 1;
continue;
}
const std::string& replaceWith = it->second;
source.replace(index, 2, replaceWith);
index += replaceWith.length();
}
}
static void replace(std::string& source, const std::unordered_map<std::string, std::string> &substitutionMap)
{
std::string::size_type index = 0;
while ((index = source.find('{', index)) != std::string::npos) {
const std::string::size_type end = source.find('}', index);
if (end == std::string::npos)
break;
const std::string searchFor = source.substr(index, end-index+1);
const auto it = substitutionMap.find(searchFor);
if (it == substitutionMap.end()) {
index += 1;
continue;
}
const std::string& replaceWith = it->second;
source.replace(index, searchFor.length(), replaceWith);
index += replaceWith.length();
}
}
static void replaceColors(std::string& source) {
// TODO: colors are not applied when either stdout or stderr is not a TTY because we resolve them before the stream usage
static const std::unordered_map<std::string, std::string> substitutionMap =
{
{"{reset}", ::toString(Color::Reset)},
{"{bold}", ::toString(Color::Bold)},
{"{dim}", ::toString(Color::Dim)},
{"{red}", ::toString(Color::FgRed)},
{"{green}", ::toString(Color::FgGreen)},
{"{blue}", ::toString(Color::FgBlue)},
{"{magenta}", ::toString(Color::FgMagenta)},
{"{default}", ::toString(Color::FgDefault)},
};
replace(source, substitutionMap);
}
std::string ErrorMessage::toString(bool verbose, const std::string &templateFormat, const std::string &templateLocation) const
@ -555,14 +595,7 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
// template is given. Reformat the output according to it
std::string result = templateFormat;
// Support a few special characters to allow to specific formatting, see http://sourceforge.net/apps/phpbb/cppcheck/viewtopic.php?f=4&t=494&sid=21715d362c0dbafd3791da4d9522f814
// Substitution should be done first so messages from cppcheck never get translated.
findAndReplace(result, "\\b", "\b");
findAndReplace(result, "\\n", "\n");
findAndReplace(result, "\\r", "\r");
findAndReplace(result, "\\t", "\t");
replaceColors(result);
findAndReplace(result, "{id}", id);
std::string::size_type pos1 = result.find("{inconclusive:");
@ -594,23 +627,21 @@ std::string ErrorMessage::toString(bool verbose, const std::string &templateForm
findAndReplace(result, "{code}", readCode(callStack.back().getOrigFile(), callStack.back().line, callStack.back().column, endl));
}
} else {
findAndReplace(result, "{callstack}", emptyString);
findAndReplace(result, "{file}", "nofile");
findAndReplace(result, "{line}", "0");
findAndReplace(result, "{column}", "0");
findAndReplace(result, "{code}", emptyString);
static const std::unordered_map<std::string, std::string> callStackSubstitutionMap =
{
{"{callstack}", ""},
{"{file}", "nofile"},
{"{line}", "0"},
{"{column}", "0"},
{"{code}", ""}
};
replace(result, callStackSubstitutionMap);
}
if (!templateLocation.empty() && callStack.size() >= 2U) {
for (const FileLocation &fileLocation : callStack) {
std::string text = templateLocation;
findAndReplace(text, "\\b", "\b");
findAndReplace(text, "\\n", "\n");
findAndReplace(text, "\\r", "\r");
findAndReplace(text, "\\t", "\t");
replaceColors(text);
findAndReplace(text, "{file}", fileLocation.getfile());
findAndReplace(text, "{line}", MathLib::toString(fileLocation.line));
findAndReplace(text, "{column}", MathLib::toString(fileLocation.column));
@ -877,3 +908,15 @@ std::string replaceStr(std::string s, const std::string &from, const std::string
}
return s;
}
void substituteTemplateFormatStatic(std::string& templateFormat)
{
replaceSpecialChars(templateFormat);
replaceColors(templateFormat);
}
void substituteTemplateLocationStatic(std::string& templateLocation)
{
replaceSpecialChars(templateLocation);
replaceColors(templateLocation);
}

View File

@ -278,6 +278,12 @@ public:
/** Replace substring. Example replaceStr("1,NR,3", "NR", "2") => "1,2,3" */
std::string replaceStr(std::string s, const std::string &from, const std::string &to);
/** replaces the static parts of the location template **/
CPPCHECKLIB void substituteTemplateFormatStatic(std::string& templateFormat);
/** replaces the static parts of the location template **/
CPPCHECKLIB void substituteTemplateLocationStatic(std::string& templateLocation);
/// @}
//---------------------------------------------------------------------------
#endif // errorloggerH

View File

@ -678,9 +678,10 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
const std::string functionnodename = functionnode->Name();
if (functionnodename == "noreturn") {
if (strcmp(functionnode->GetText(), "false") == 0)
const char * const text = functionnode->GetText();
if (strcmp(text, "false") == 0)
mNoReturn[name] = FalseTrueMaybe::False;
else if (strcmp(functionnode->GetText(), "maybe") == 0)
else if (strcmp(text, "maybe") == 0)
mNoReturn[name] = FalseTrueMaybe::Maybe;
else
mNoReturn[name] = FalseTrueMaybe::True; // Safe
@ -757,9 +758,9 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
// Validate the validation expression
const char *p = argnode->GetText();
if (!isCompliantValidationExpression(p))
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, (!p ? "\"\"" : argnode->GetText()));
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, (!p ? "\"\"" : p));
// Set validation expression
ac.valid = argnode->GetText();
ac.valid = p;
}
else if (argnodename == "minsize") {
const char *typeattr = argnode->Attribute("type");

View File

@ -17,6 +17,7 @@
*/
#include "cmdlineparser.h"
#include "color.h"
#include "cppcheckexecutor.h"
#include "errortypes.h"
#include "platform.h"
@ -162,6 +163,16 @@ private:
TEST_CASE(templatesGcc);
TEST_CASE(templatesVs);
TEST_CASE(templatesEdit);
TEST_CASE(templatesCppcheck1);
TEST_CASE(templatesDaca2);
TEST_CASE(templatesSelfcheck);
TEST_CASE(templatesNoPlaceholder);
TEST_CASE(templateFormatInvalid);
TEST_CASE(templateFormatInvalid2);
TEST_CASE(templateFormatEmpty);
TEST_CASE(templateLocationInvalid);
TEST_CASE(templateLocationInvalid2);
TEST_CASE(templateLocationEmpty);
TEST_CASE(xml);
TEST_CASE(xmlver2);
TEST_CASE(xmlver2both);
@ -1252,10 +1263,12 @@ private:
void templates() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--template", "{file}:{line},{severity},{id},{message}", "file.cpp"};
const char * const argv[] = {"cppcheck", "--template", "{file}:{line},{severity},{id},{message}", "--template-location={file}:{line}:{column} {info}", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(4, argv));
ASSERT_EQUALS("{file}:{line},{severity},{id},{message}", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column} {info}", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
@ -1263,8 +1276,10 @@ private:
REDIRECT;
const char * const argv[] = {"cppcheck", "--template", "gcc", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(4, argv));
ASSERT_EQUALS("{bold}{file}:{line}:{column}: {magenta}warning:{default} {message} [{id}]{reset}\\n{code}", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column}: warning: {message} [{id}]\n{code}", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column}: note: {info}\n{code}", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
@ -1272,8 +1287,10 @@ private:
REDIRECT;
const char * const argv[] = {"cppcheck", "--template", "vs", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(4, argv));
ASSERT_EQUALS("{file}({line}): {severity}: {message}", settings.templateFormat);
ASSERT_EQUALS("", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
@ -1281,8 +1298,120 @@ private:
REDIRECT;
const char * const argv[] = {"cppcheck", "--template", "edit", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(4, argv));
ASSERT_EQUALS("{file} +{line}: {severity}: {message}", settings.templateFormat);
ASSERT_EQUALS("", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
void templatesCppcheck1() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--template=cppcheck1", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("{callstack}: ({severity}{inconclusive:, inconclusive}) {message}", settings.templateFormat);
ASSERT_EQUALS("", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
void templatesDaca2() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--template=daca2", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column}: note: {info}", settings.templateLocation);
ASSERT_EQUALS(true, settings.daca);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
void templatesSelfcheck() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--template=selfcheck", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
ASSERT(defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("{file}:{line}:{column}: {severity}:{inconclusive:inconclusive:} {message} [{id}]\n{code}", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column}: note: {info}\n{code}", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
// TODO: we should bail out on this
void templatesNoPlaceholder() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--template=selfchek", "file.cpp"};
settings.templateFormat.clear();
settings.templateLocation.clear();
TODO_ASSERT(!defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("selfchek", settings.templateFormat);
ASSERT_EQUALS("", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
void templateFormatInvalid() {
REDIRECT;
const char* const argv[] = { "cppcheck", "--template", "--template-location={file}", "file.cpp" };
ASSERT(!defParser.parseFromArgs(4, argv));
ASSERT_EQUALS("cppcheck: error: argument to '--template' is missing.\n", GET_REDIRECT_OUTPUT);
}
// TODO: will not error out as he next option does not start with a "-"
void templateFormatInvalid2() {
REDIRECT;
settings.templateFormat.clear();
settings.templateLocation.clear();
const char* const argv[] = { "cppcheck", "--template", "file.cpp" };
TODO_ASSERT(!defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("file.cpp", settings.templateFormat);
ASSERT_EQUALS("", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
// will use the default
// TODO: bail out on empty?
void templateFormatEmpty() {
REDIRECT;
settings.templateFormat.clear();
settings.templateLocation.clear();
const char* const argv[] = { "cppcheck", "--template=", "file.cpp" };
ASSERT(defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("{file}:{line}:{column}: {inconclusive:}{severity}:{inconclusive: inconclusive:} {message} [{id}]\n{code}", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column}: note: {info}\n{code}", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
void templateLocationInvalid() {
REDIRECT;
const char* const argv[] = { "cppcheck", "--template-location", "--template={file}", "file.cpp" };
ASSERT(!defParser.parseFromArgs(4, argv));
ASSERT_EQUALS("cppcheck: error: argument to '--template-location' is missing.\n", GET_REDIRECT_OUTPUT);
}
// TODO: will not error out as he next option does not start with a "-"
void templateLocationInvalid2() {
REDIRECT;
settings.templateFormat.clear();
settings.templateLocation.clear();
const char* const argv[] = { "cppcheck", "--template-location", "file.cpp" };
TODO_ASSERT(!defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("{file}:{line}:{column}: {inconclusive:}{severity}:{inconclusive: inconclusive:} {message} [{id}]\n{code}", settings.templateFormat);
ASSERT_EQUALS("file.cpp", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}
// will use the default
// TODO: bail out on empty?
void templateLocationEmpty() {
REDIRECT;
settings.templateFormat.clear();
settings.templateLocation.clear();
const char* const argv[] = { "cppcheck", "--template-location=", "file.cpp" };
ASSERT(defParser.parseFromArgs(3, argv));
ASSERT_EQUALS("{file}:{line}:{column}: {inconclusive:}{severity}:{inconclusive: inconclusive:} {message} [{id}]\n{code}", settings.templateFormat);
ASSERT_EQUALS("{file}:{line}:{column}: note: {info}\n{code}", settings.templateLocation);
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

38
test/testcolor.cpp Normal file
View File

@ -0,0 +1,38 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2023 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "color.h"
#include "fixture.h"
class TestColor : public TestFixture {
public:
TestColor() : TestFixture("TestColor") {}
private:
void run() override {
TEST_CASE(toString);
}
void toString() const {
// TODO: color conversion is dependent on stdout/stderr being a TTY
ASSERT_EQUALS("", ::toString(Color::FgRed));
}
};
REGISTER_TEST(TestColor)

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "color.h"
#include "config.h"
#include "cppcheck.h"
#include "errorlogger.h"
@ -63,6 +64,8 @@ private:
TEST_CASE(SerializeFileLocation);
TEST_CASE(suppressUnmatchedSuppressions);
TEST_CASE(substituteTemplateFormatStatic);
TEST_CASE(substituteTemplateLocationStatic);
}
void TestPatternSearchReplace(const std::string& idPlaceholder, const std::string& id) const {
@ -481,6 +484,69 @@ private:
reportUnmatchedSuppressions(suppressions);
ASSERT_EQUALS("[a.c:10]: (information) Unmatched suppression: abc\n", errout.str());
}
void substituteTemplateFormatStatic() const
{
{
std::string s;
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("", s);
}
{
std::string s = "template{black}\\z";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("template{black}\\z", s);
}
{
std::string s = "{reset}{bold}{dim}{red}{blue}{magenta}{default}\\b\\n\\r\\t";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("\b\n\r\t", s);
}
{
std::string s = "\\\\n";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("\\\n", s);
}
{
std::string s = "{{red}";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("{", s);
}
}
void substituteTemplateLocationStatic() const
{
{
std::string s;
::substituteTemplateLocationStatic(s);
ASSERT_EQUALS("", s);
}
{
std::string s = "template";
::substituteTemplateLocationStatic(s);
ASSERT_EQUALS("template", s);
}
{
std::string s = "template{black}\\z";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("template{black}\\z", s);
}
{
std::string s = "{reset}{bold}{dim}{red}{blue}{magenta}{default}\\b\\n\\r\\t";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("\b\n\r\t", s);
}
{
std::string s = "\\\\n";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("\\\n", s);
}
{
std::string s = "{{red}";
::substituteTemplateFormatStatic(s);
ASSERT_EQUALS("{", s);
}
}
};
REGISTER_TEST(TestErrorLogger)

View File

@ -55,6 +55,7 @@
<ClCompile Include="testclangimport.cpp" />
<ClCompile Include="testclass.cpp" />
<ClCompile Include="testcmdlineparser.cpp" />
<ClCompile Include="testcolor.cpp" />
<ClCompile Include="testcondition.cpp" />
<ClCompile Include="testconstructors.cpp" />
<ClCompile Include="testcppcheck.cpp" />