New command line argument added --template
Fix ticket #462 (Allow using template to customize output format) http://sourceforge.net/apps/trac/cppcheck/ticket/462
This commit is contained in:
parent
195cc9aae9
commit
7af4ac4282
|
@ -111,6 +111,7 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
||||||
<arg choice="opt"><option>-j[jobs]</option></arg>
|
<arg choice="opt"><option>-j[jobs]</option></arg>
|
||||||
<arg choice="opt"><option>--quiet</option></arg>
|
<arg choice="opt"><option>--quiet</option></arg>
|
||||||
<arg choice="opt"><option>--style</option></arg>
|
<arg choice="opt"><option>--style</option></arg>
|
||||||
|
<arg choice="opt"><option>--template ['text']</option></arg>
|
||||||
<arg choice="opt"><option>--unused-functions</option></arg>
|
<arg choice="opt"><option>--unused-functions</option></arg>
|
||||||
<arg choice="opt"><option>--verbose</option></arg>
|
<arg choice="opt"><option>--verbose</option></arg>
|
||||||
<arg choice="opt"><option>--version</option></arg>
|
<arg choice="opt"><option>--version</option></arg>
|
||||||
|
@ -200,6 +201,12 @@ files, this is not needed.</para>
|
||||||
<para>Check coding style.</para>
|
<para>Check coding style.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--template ['text']</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Format the error messages. E.g. '{file}:{line},{severity},{id},{message}' or '{file}({line}):({severity}) {message}'</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--unused-functions</option></term>
|
<term><option>--unused-functions</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -172,6 +172,21 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
||||||
_settings._includePaths.push_back(path);
|
_settings._includePaths.push_back(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Output formatter
|
||||||
|
else if (strcmp(argv[i], "--template") == 0)
|
||||||
|
{
|
||||||
|
// "--template path/"
|
||||||
|
if (strcmp(argv[i], "--template") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if (i >= argc)
|
||||||
|
return "cppcheck: argument to '--template' is missing\n";
|
||||||
|
|
||||||
|
_settings._outputFormat = argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Include paths
|
// Include paths
|
||||||
else if (strcmp(argv[i], "-j") == 0 ||
|
else if (strcmp(argv[i], "-j") == 0 ||
|
||||||
strncmp(argv[i], "-j", 2) == 0)
|
strncmp(argv[i], "-j", 2) == 0)
|
||||||
|
@ -308,6 +323,9 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
||||||
" -j [jobs] Start [jobs] threads to do the checking simultaneously.\n"
|
" -j [jobs] Start [jobs] threads to do the checking simultaneously.\n"
|
||||||
" -q, --quiet Only print error messages\n"
|
" -q, --quiet Only print error messages\n"
|
||||||
" -s, --style Check coding style\n"
|
" -s, --style Check coding style\n"
|
||||||
|
" --template '[text]' Format the error messages. E.g.\n"
|
||||||
|
" '{file}:{line},{severity},{id},{message}' or\n"
|
||||||
|
" '{file}({line}):({severity}) {message}'\n"
|
||||||
" --unused-functions Check if there are unused functions\n"
|
" --unused-functions Check if there are unused functions\n"
|
||||||
" -v, --verbose More detailed error reports\n"
|
" -v, --verbose More detailed error reports\n"
|
||||||
" --version Print out version number\n"
|
" --version Print out version number\n"
|
||||||
|
|
|
@ -112,6 +112,6 @@ void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reportErr(msg.toText());
|
reportErr(msg.toText(_settings._outputFormat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,19 @@ std::string ErrorLogger::ErrorMessage::toXML() const
|
||||||
return xml.str();
|
return xml.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ErrorLogger::ErrorMessage::toText() const
|
void ErrorLogger::ErrorMessage::findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith)
|
||||||
|
{
|
||||||
|
std::string::size_type index = 0;
|
||||||
|
while ((index = source.find(searchFor, index)) != std::string::npos)
|
||||||
|
{
|
||||||
|
source.replace(index, searchFor.length(), replaceWith);
|
||||||
|
index += replaceWith.length() - searchFor.length() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ErrorLogger::ErrorMessage::toText(const std::string &outputFormat) const
|
||||||
|
{
|
||||||
|
if (outputFormat.length() == 0)
|
||||||
{
|
{
|
||||||
std::ostringstream text;
|
std::ostringstream text;
|
||||||
if (!_callStack.empty())
|
if (!_callStack.empty())
|
||||||
|
@ -168,6 +180,29 @@ std::string ErrorLogger::ErrorMessage::toText() const
|
||||||
text << _msg;
|
text << _msg;
|
||||||
return text.str();
|
return text.str();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string result = outputFormat;
|
||||||
|
findAndReplace(result, "{id}", _id);
|
||||||
|
findAndReplace(result, "{severity}", _severity);
|
||||||
|
findAndReplace(result, "{message}", _msg);
|
||||||
|
|
||||||
|
if (!_callStack.empty())
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << _callStack.back().line;
|
||||||
|
findAndReplace(result, "{line}", oss.str());
|
||||||
|
findAndReplace(result, "{file}", _callStack.back().getfile());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
findAndReplace(result, "{file}", "");
|
||||||
|
findAndReplace(result, "{line}", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ErrorLogger::_writemsg(const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string &msg, const std::string &id)
|
void ErrorLogger::_writemsg(const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string &msg, const std::string &id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,7 +66,21 @@ public:
|
||||||
static std::string getXMLHeader();
|
static std::string getXMLHeader();
|
||||||
static std::string getXMLFooter();
|
static std::string getXMLFooter();
|
||||||
|
|
||||||
std::string toText() const;
|
/**
|
||||||
|
* Format the error message into a string.
|
||||||
|
* @param outputFormat Empty string to use default output format
|
||||||
|
* or template to be used. E.g. "{file}:{line},{severity},{id},{message}"
|
||||||
|
*/
|
||||||
|
std::string toText(const std::string &outputFormat = "") const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace all occurances of searchFor with replaceWith in the
|
||||||
|
* given source.
|
||||||
|
* @param source The string to modify
|
||||||
|
* @param searchFor What should be searched for
|
||||||
|
* @param replaceWith What will replace the found item
|
||||||
|
*/
|
||||||
|
static void findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith);
|
||||||
std::string serialize() const;
|
std::string serialize() const;
|
||||||
bool deserialize(const std::string &data);
|
bool deserialize(const std::string &data);
|
||||||
std::list<FileLocation> _callStack;
|
std::list<FileLocation> _callStack;
|
||||||
|
|
|
@ -65,6 +65,10 @@ public:
|
||||||
Default value is 0. */
|
Default value is 0. */
|
||||||
int _exitCode;
|
int _exitCode;
|
||||||
|
|
||||||
|
/** The output format in which the errors are printed in text mode,
|
||||||
|
e.g. "{severity} {file}:{line} {message} {id}" */
|
||||||
|
std::string _outputFormat;
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
/** show timing information */
|
/** show timing information */
|
||||||
bool _showtime;
|
bool _showtime;
|
||||||
|
|
|
@ -53,6 +53,7 @@ private:
|
||||||
TEST_CASE(xml);
|
TEST_CASE(xml);
|
||||||
|
|
||||||
TEST_CASE(include);
|
TEST_CASE(include);
|
||||||
|
TEST_CASE(templateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void linenumbers()
|
void linenumbers()
|
||||||
|
@ -104,6 +105,20 @@ private:
|
||||||
ASSERT_EQUALS("[ab/ef.h:0]: ", errmsg.toText());
|
ASSERT_EQUALS("[ab/ef.h:0]: ", errmsg.toText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void templateFormat()
|
||||||
|
{
|
||||||
|
ErrorLogger::ErrorMessage errmsg;
|
||||||
|
ErrorLogger::ErrorMessage::FileLocation loc;
|
||||||
|
loc.file = "some/{file}file.cpp";
|
||||||
|
loc.line = 10;
|
||||||
|
errmsg._callStack.push_back(loc);
|
||||||
|
errmsg._id = "testId";
|
||||||
|
errmsg._severity = "testSeverity";
|
||||||
|
errmsg._msg = "long testMessage";
|
||||||
|
ASSERT_EQUALS("<error file=\"some/{file}file.cpp\" line=\"10\" id=\"testId\" severity=\"testSeverity\" msg=\"long testMessage\"/>", errmsg.toXML());
|
||||||
|
ASSERT_EQUALS("[some/{file}file.cpp:10]: (testSeverity) long testMessage", errmsg.toText());
|
||||||
|
ASSERT_EQUALS("testId-some/{file}file.cpp,testSeverity.10?{long testMessage}", errmsg.toText("{id}-{file},{severity}.{line}?{{message}}"));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestCppcheck)
|
REGISTER_TEST(TestCppcheck)
|
||||||
|
|
Loading…
Reference in New Issue