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>--quiet</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>--verbose</option></arg>
|
||||
<arg choice="opt"><option>--version</option></arg>
|
||||
|
@ -200,6 +201,12 @@ files, this is not needed.</para>
|
|||
<para>Check coding style.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
<term><option>--unused-functions</option></term>
|
||||
<listitem>
|
||||
|
|
|
@ -172,7 +172,22 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
_settings._includePaths.push_back(path);
|
||||
}
|
||||
|
||||
// Include paths
|
||||
|
||||
// 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
|
||||
else if (strcmp(argv[i], "-j") == 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"
|
||||
" -q, --quiet Only print error messages\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"
|
||||
" -v, --verbose More detailed error reports\n"
|
||||
" --version Print out version number\n"
|
||||
|
|
|
@ -112,6 +112,6 @@ void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
|
|||
}
|
||||
else
|
||||
{
|
||||
reportErr(msg.toText());
|
||||
reportErr(msg.toText(_settings._outputFormat));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,15 +158,50 @@ std::string ErrorLogger::ErrorMessage::toXML() const
|
|||
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::ostringstream text;
|
||||
if (!_callStack.empty())
|
||||
text << callStackToString(_callStack) << ": ";
|
||||
if (!_severity.empty())
|
||||
text << "(" << _severity << ") ";
|
||||
text << _msg;
|
||||
return text.str();
|
||||
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;
|
||||
if (!_callStack.empty())
|
||||
text << callStackToString(_callStack) << ": ";
|
||||
if (!_severity.empty())
|
||||
text << "(" << _severity << ") ";
|
||||
text << _msg;
|
||||
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)
|
||||
|
|
|
@ -66,7 +66,21 @@ public:
|
|||
static std::string getXMLHeader();
|
||||
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;
|
||||
bool deserialize(const std::string &data);
|
||||
std::list<FileLocation> _callStack;
|
||||
|
|
|
@ -65,6 +65,10 @@ public:
|
|||
Default value is 0. */
|
||||
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__
|
||||
/** show timing information */
|
||||
bool _showtime;
|
||||
|
|
|
@ -53,6 +53,7 @@ private:
|
|||
TEST_CASE(xml);
|
||||
|
||||
TEST_CASE(include);
|
||||
TEST_CASE(templateFormat);
|
||||
}
|
||||
|
||||
void linenumbers()
|
||||
|
@ -104,6 +105,20 @@ private:
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue