Skip to content

Commit 92fd059

Browse files
committed
Merge branch 'master' of https://www.github.com/danmar/cppcheck
2 parents e76f1e7 + 7c5058a commit 92fd059

9 files changed

Lines changed: 328 additions & 273 deletions

cli/cmdlineparser.cpp

Lines changed: 94 additions & 46 deletions
Large diffs are not rendered by default.

cli/cmdlineparser.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,47 +49,47 @@ class CmdLineParser {
4949
* Parse given command line.
5050
* @return true if command line was ok, false if there was an error.
5151
*/
52-
bool ParseFromArgs(int argc, const char* const argv[]);
52+
bool parseFromArgs(int argc, const char* const argv[]);
5353

5454
/**
5555
* Return if user wanted to see program version.
5656
*/
57-
bool GetShowVersion() const {
57+
bool getShowVersion() const {
5858
return _showVersion;
5959
}
6060

6161
/**
6262
* Return if user wanted to see list of error messages.
6363
*/
64-
bool GetShowErrorMessages() const {
64+
bool getShowErrorMessages() const {
6565
return _showErrorMessages;
6666
}
6767

6868
/**
6969
* Return the path names user gave to command line.
7070
*/
71-
const std::vector<std::string>& GetPathNames() const {
71+
const std::vector<std::string>& getPathNames() const {
7272
return _pathnames;
7373
}
7474

7575
/**
7676
* Return if help is shown to user.
7777
*/
78-
bool GetShowHelp() const {
78+
bool getShowHelp() const {
7979
return _showHelp;
8080
}
8181

8282
/**
8383
* Return if we should exit after printing version, help etc.
8484
*/
85-
bool ExitAfterPrinting() const {
85+
bool exitAfterPrinting() const {
8686
return _exitAfterPrint;
8787
}
8888

8989
/**
9090
* Return a list of paths user wants to ignore.
9191
*/
92-
const std::vector<std::string>& GetIgnoredPaths() const {
92+
const std::vector<std::string>& getIgnoredPaths() const {
9393
return _ignoredPaths;
9494
}
9595

@@ -98,13 +98,13 @@ class CmdLineParser {
9898
/**
9999
* Print help text to the console.
100100
*/
101-
static void PrintHelp();
101+
static void printHelp();
102102

103103
/**
104104
* Print message (to console?).
105105
*/
106-
static void PrintMessage(const std::string &message);
107-
static void PrintMessage(const char* message);
106+
static void printMessage(const std::string &message);
107+
static void printMessage(const char* message);
108108

109109
private:
110110
std::vector<std::string> _pathnames;

cli/cppcheckexecutor.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
9292
{
9393
Settings& settings = cppcheck->settings();
9494
CmdLineParser parser(&settings);
95-
const bool success = parser.ParseFromArgs(argc, argv);
95+
const bool success = parser.parseFromArgs(argc, argv);
9696

9797
if (success) {
98-
if (parser.GetShowVersion() && !parser.GetShowErrorMessages()) {
98+
if (parser.getShowVersion() && !parser.getShowErrorMessages()) {
9999
const char * const extraVersion = cppcheck->extraVersion();
100100
if (*extraVersion != 0)
101101
std::cout << "Cppcheck " << cppcheck->version() << " ("
@@ -104,14 +104,14 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
104104
std::cout << "Cppcheck " << cppcheck->version() << std::endl;
105105
}
106106

107-
if (parser.GetShowErrorMessages()) {
107+
if (parser.getShowErrorMessages()) {
108108
errorlist = true;
109109
std::cout << ErrorLogger::ErrorMessage::getXMLHeader();
110110
cppcheck->getErrorMessages();
111111
std::cout << ErrorLogger::ErrorMessage::getXMLFooter() << std::endl;
112112
}
113113

114-
if (parser.ExitAfterPrinting()) {
114+
if (parser.exitAfterPrinting()) {
115115
settings.terminate();
116116
return true;
117117
}
@@ -138,9 +138,9 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
138138

139139
// Output a warning for the user if he tries to exclude headers
140140
bool warn = false;
141-
const std::vector<std::string>& ignored = parser.GetIgnoredPaths();
142-
for (std::vector<std::string>::const_iterator i = ignored.cbegin(); i != ignored.cend(); ++i) {
143-
if (Path::isHeader(*i)) {
141+
const std::vector<std::string>& ignored = parser.getIgnoredPaths();
142+
for (const std::string &i : ignored) {
143+
if (Path::isHeader(i)) {
144144
warn = true;
145145
break;
146146
}
@@ -150,7 +150,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
150150
std::cout << "cppcheck: Please use --suppress for ignoring results from the header files." << std::endl;
151151
}
152152

153-
const std::vector<std::string>& pathnames = parser.GetPathNames();
153+
const std::vector<std::string>& pathnames = parser.getPathNames();
154154

155155
#if defined(_WIN32)
156156
// For Windows we want case-insensitive path matching
@@ -1040,7 +1040,7 @@ void CppCheckExecutor::reportErr(const ErrorLogger::ErrorMessage &msg)
10401040
} else if (_settings->xml) {
10411041
reportErr(msg.toXML());
10421042
} else {
1043-
reportErr(msg.toString(_settings->verbose, _settings->outputFormat));
1043+
reportErr(msg.toString(_settings->verbose, _settings->templateFormat, _settings->templateLocation));
10441044
}
10451045
}
10461046

lib/check.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class CPPCHECKLIB Check {
163163
ErrorPath errorPath;
164164
if (!value) {
165165
errorPath.emplace_back(errtok,bug);
166-
} else if (_settings->verbose || _settings->xml || _settings->outputFormat == "daca2") {
166+
} else if (_settings->verbose || _settings->xml || !_settings->templateLocation.empty()) {
167167
errorPath = value->errorPath;
168168
errorPath.emplace_back(errtok,bug);
169169
} else {

lib/checkbufferoverrun.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void CheckBufferOverrun::arrayIndexOutOfBoundsError(const Token *tok, const Arra
9393
}
9494

9595
std::list<ErrorPathItem> errorPath;
96-
if (_settings->xml || _settings->outputFormat == "daca2") {
96+
if (_settings->xml || !_settings->templateLocation.empty()) {
9797
for (std::size_t i = 0; i < index.size(); ++i) {
9898
const ErrorPath &e = getErrorPath(tok, &index[i], "");
9999
for (ErrorPath::const_iterator it = e.begin(); it != e.end(); ++it) {

lib/errorlogger.cpp

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,15 @@ static std::string readCode(const std::string &file, unsigned int linenr, unsign
444444
const std::string::size_type endPos = line.find_last_not_of("\r\n\t ");
445445
if (endPos + 1 < line.size())
446446
line.erase(endPos + 1);
447-
return line + endl + std::string(column,' ') + '^';
447+
return line + endl + std::string((column>0 ? column-1 : column), ' ') + '^';
448448
}
449449

450-
std::string ErrorLogger::ErrorMessage::toString(bool verbose, const std::string &outputFormat) const
450+
std::string ErrorLogger::ErrorMessage::toString(bool verbose, const std::string &templateFormat, const std::string &templateLocation) const
451451
{
452452
// Save this ErrorMessage in plain text.
453453

454454
// No template is given
455-
if (outputFormat.empty()) {
455+
if (templateFormat.empty()) {
456456
std::ostringstream text;
457457
if (!_callStack.empty())
458458
text << callStackToString(_callStack) << ": ";
@@ -466,76 +466,77 @@ std::string ErrorLogger::ErrorMessage::toString(bool verbose, const std::string
466466
return text.str();
467467
}
468468

469-
else if (outputFormat == "daca2") {
470-
// This is a clang-like output format for daca2
471-
std::ostringstream text;
472-
if (_callStack.empty()) {
473-
text << "nofile:0:0: ";
474-
} else {
475-
const ErrorLogger::ErrorMessage::FileLocation &loc = _callStack.back();
476-
text << loc.getfile() << ':' << loc.line << ':' << loc.col << ": ";
469+
// template is given. Reformat the output according to it
470+
std::string result = templateFormat;
471+
// 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
472+
// Substitution should be done first so messages from cppcheck never get translated.
473+
findAndReplace(result, "\\b", "\b");
474+
findAndReplace(result, "\\n", "\n");
475+
findAndReplace(result, "\\r", "\r");
476+
findAndReplace(result, "\\t", "\t");
477+
478+
findAndReplace(result, "{id}", _id);
479+
if (result.find("{inconclusive:") != std::string::npos) {
480+
const std::string::size_type pos1 = result.find("{inconclusive:");
481+
const std::string::size_type pos2 = result.find("}", pos1+1);
482+
const std::string replaceFrom = result.substr(pos1,pos2-pos1+1);
483+
const std::string replaceWith = result.substr(pos1+14, pos2-pos1-14);
484+
findAndReplace(result, replaceFrom, replaceWith);
485+
}
486+
findAndReplace(result, "{severity}", Severity::toString(_severity));
487+
findAndReplace(result, "{message}", verbose ? _verboseMessage : _shortMessage);
488+
findAndReplace(result, "{callstack}", _callStack.empty() ? emptyString : callStackToString(_callStack));
489+
if (!_callStack.empty()) {
490+
findAndReplace(result, "{file}", _callStack.back().getfile());
491+
findAndReplace(result, "{line}", MathLib::toString(_callStack.back().line));
492+
findAndReplace(result, "{column}", MathLib::toString(_callStack.back().col));
493+
if (result.find("{code}") != std::string::npos) {
494+
const std::string::size_type pos = result.find("\r");
495+
const char *endl;
496+
if (pos == std::string::npos)
497+
endl = "\n";
498+
else if (pos+1 < result.size() && result[pos+1] == '\n')
499+
endl = "\r\n";
500+
else
501+
endl = "\r";
502+
findAndReplace(result, "{code}", readCode(_callStack.back().getfile(), _callStack.back().line, _callStack.back().col, endl));
477503
}
478-
479-
if (_inconclusive)
480-
text << "inconclusive ";
481-
text << Severity::toString(_severity) << ": ";
482-
483-
text << (verbose ? _verboseMessage : _shortMessage)
484-
<< " [" << _id << ']';
485-
486-
if (_callStack.size() <= 1U)
487-
return text.str();
488-
489-
for (std::list<FileLocation>::const_iterator loc = _callStack.begin(); loc != _callStack.end(); ++loc)
490-
text << std::endl
491-
<< loc->getfile()
492-
<< ':'
493-
<< loc->line
494-
<< ':'
495-
<< loc->col
496-
<< ": note: "
497-
<< (loc->getinfo().empty() ? _shortMessage : loc->getinfo());
498-
return text.str();
504+
} else {
505+
findAndReplace(result, "{file}", "nofile");
506+
findAndReplace(result, "{line}", "0");
507+
findAndReplace(result, "{column}", "0");
508+
findAndReplace(result, "{code}", emptyString);
499509
}
500510

501-
// template is given. Reformat the output according to it
502-
else {
503-
std::string result = outputFormat;
504-
// 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
505-
// Substitution should be done first so messages from cppcheck never get translated.
506-
findAndReplace(result, "\\b", "\b");
507-
findAndReplace(result, "\\n", "\n");
508-
findAndReplace(result, "\\r", "\r");
509-
findAndReplace(result, "\\t", "\t");
510-
511-
findAndReplace(result, "{id}", _id);
512-
findAndReplace(result, "{severity}", Severity::toString(_severity));
513-
findAndReplace(result, "{message}", verbose ? _verboseMessage : _shortMessage);
514-
findAndReplace(result, "{callstack}", _callStack.empty() ? emptyString : callStackToString(_callStack));
515-
if (!_callStack.empty()) {
516-
findAndReplace(result, "{file}", _callStack.back().getfile());
517-
findAndReplace(result, "{line}", MathLib::toString(_callStack.back().line));
518-
findAndReplace(result, "{column}", MathLib::toString(_callStack.back().col));
519-
if (result.find("{code}") != std::string::npos) {
520-
const std::string::size_type pos = result.find("\r");
511+
if (!templateLocation.empty() && _callStack.size() >= 2U) {
512+
for (const FileLocation &fileLocation : _callStack) {
513+
std::string text = templateLocation;
514+
515+
findAndReplace(text, "\\b", "\b");
516+
findAndReplace(text, "\\n", "\n");
517+
findAndReplace(text, "\\r", "\r");
518+
findAndReplace(text, "\\t", "\t");
519+
520+
findAndReplace(text, "{file}", fileLocation.getfile());
521+
findAndReplace(text, "{line}", MathLib::toString(fileLocation.line));
522+
findAndReplace(text, "{column}", MathLib::toString(fileLocation.col));
523+
findAndReplace(text, "{info}", fileLocation.getinfo().empty() ? _shortMessage : fileLocation.getinfo());
524+
if (text.find("{code}") != std::string::npos) {
525+
const std::string::size_type pos = text.find("\r");
521526
const char *endl;
522527
if (pos == std::string::npos)
523528
endl = "\n";
524-
else if (pos+1 < result.size() && result[pos+1] == '\n')
529+
else if (pos+1 < text.size() && text[pos+1] == '\n')
525530
endl = "\r\n";
526531
else
527532
endl = "\r";
528-
findAndReplace(result, "{code}", readCode(_callStack.back().getfile(), _callStack.back().line, _callStack.back().col, endl));
533+
findAndReplace(text, "{code}", readCode(fileLocation.getfile(), fileLocation.line, fileLocation.col, endl));
529534
}
530-
} else {
531-
findAndReplace(result, "{file}", emptyString);
532-
findAndReplace(result, "{line}", emptyString);
533-
findAndReplace(result, "{column}", emptyString);
534-
findAndReplace(result, "{code}", emptyString);
535+
result += '\n' + text;
535536
}
536-
537-
return result;
538537
}
538+
539+
return result;
539540
}
540541

541542
void ErrorLogger::reportUnmatchedSuppressions(const std::list<Suppressions::Suppression> &unmatched)

lib/errorlogger.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,13 @@ class CPPCHECKLIB ErrorLogger {
256256
/**
257257
* Format the error message into a string.
258258
* @param verbose use verbose message
259-
* @param outputFormat Empty string to use default output format
259+
* @param templateFormat Empty string to use default output format
260260
* or template to be used. E.g. "{file}:{line},{severity},{id},{message}"
261+
* @param templateLocation Format Empty string to use default output format
262+
* or template to be used. E.g. "{file}:{line},{info}"
261263
* @return formatted string
262264
*/
263-
std::string toString(bool verbose, const std::string &outputFormat = emptyString) const;
265+
std::string toString(bool verbose, const std::string &templateFormat = emptyString, const std::string &templateLocation = emptyString) const;
264266

265267
std::string serialize() const;
266268
bool deserialize(const std::string &data);

lib/settings.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@ class CPPCHECKLIB Settings : public cppcheck::Platform {
158158

159159
/** @brief The output format in which the errors are printed in text mode,
160160
e.g. "{severity} {file}:{line} {message} {id}" */
161-
std::string outputFormat;
161+
std::string templateFormat;
162+
163+
/** @brief The output format in which the error locations are printed in
164+
* text mode, e.g. "{file}:{line} {info}" */
165+
std::string templateLocation;
162166

163167
/** @brief show timing information (--showtime=file|summary|top5) */
164168
SHOWTIME_MODES showtime;

0 commit comments

Comments
 (0)