Skip to content

Commit 5479c73

Browse files
authored
a new method to declare inline suppress which is more readable and more convenient. (#2533)
1 parent ef26b55 commit 5479c73

4 files changed

Lines changed: 332 additions & 10 deletions

File tree

lib/preprocessor.cpp

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,69 @@ namespace {
7676
};
7777
}
7878

79-
static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list<BadInlineSuppression> *bad)
79+
static void parseCommentToken(const simplecpp::Token *tok, std::list<Suppressions::Suppression> &inlineSuppressions, std::list<BadInlineSuppression> *bad)
8080
{
81-
std::list<Suppressions::Suppression> inlineSuppressions;
82-
for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) {
83-
if (tok->comment) {
84-
Suppressions::Suppression s;
81+
const std::size_t position=tok->str().find("cppcheck-suppress");
82+
if (position != std::string::npos) {
83+
if ((tok->str().length() > position+17) && (tok->str()[position+17] == '[')) { //multi suppress format
8584
std::string errmsg;
86-
if (!s.parseComment(tok->str(), &errmsg))
87-
continue;
85+
std::vector<Suppressions::Suppression> ss;
86+
ss = Suppressions::parseMultiSuppressComment(tok->str(), &errmsg);
87+
8888
if (!errmsg.empty())
8989
bad->push_back(BadInlineSuppression(tok->location, errmsg));
90+
91+
for (std::vector<Suppressions::Suppression>::iterator iter = ss.begin(); iter!=ss.end(); ++iter) {
92+
if (!(*iter).errorId.empty())
93+
inlineSuppressions.push_back(*iter);
94+
}
95+
}
96+
else { //single suppress format
97+
std::string errmsg;
98+
Suppressions::Suppression s;
99+
if (!s.parseComment(tok->str(), &errmsg))
100+
return;
101+
90102
if (!s.errorId.empty())
91103
inlineSuppressions.push_back(s);
104+
105+
if (!errmsg.empty())
106+
bad->push_back(BadInlineSuppression(tok->location, errmsg));
107+
}
108+
}
109+
110+
return;
111+
}
112+
113+
static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSettings, std::list<BadInlineSuppression> *bad)
114+
{
115+
const simplecpp::Token *current_non_comment_tok;
116+
std::list<Suppressions::Suppression> inlineSuppressions;
117+
118+
for (const simplecpp::Token *tok = tokens.cfront(); tok; /*none*/) {
119+
//parse all comment before current non-comment tok
120+
if (tok->comment) {
121+
parseCommentToken(tok, inlineSuppressions, bad);
122+
tok = tok->next;
92123
continue;
93124
}
94125

95-
if (inlineSuppressions.empty())
126+
current_non_comment_tok = tok;
127+
128+
//parse all comment tok after current non-comment tok in the same line
129+
for (tok = tok->next; tok; tok = tok->next) {
130+
if ((tok->location.line != current_non_comment_tok->location.line) || !(tok->comment))
131+
break;
132+
parseCommentToken(tok, inlineSuppressions, bad);
133+
}
134+
135+
//if there is no suppress, jump it!
136+
if (inlineSuppressions.empty()) {
96137
continue;
138+
}
97139

98140
// Relative filename
99-
std::string relativeFilename(tok->location.file());
141+
std::string relativeFilename(current_non_comment_tok->location.file());
100142
if (mSettings.relativePaths) {
101143
for (const std::string & basePath : mSettings.basePaths) {
102144
const std::string bp = basePath + "/";
@@ -110,7 +152,7 @@ static void inlineSuppressions(const simplecpp::TokenList &tokens, Settings &mSe
110152
// Add the suppressions.
111153
for (Suppressions::Suppression &suppr : inlineSuppressions) {
112154
suppr.fileName = relativeFilename;
113-
suppr.lineNumber = tok->location.line;
155+
suppr.lineNumber = current_non_comment_tok->location.line;
114156
mSettings.nomsg.addSuppression(suppr);
115157
}
116158
inlineSuppressions.clear();

lib/suppressions.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,99 @@ std::string Suppressions::parseXmlFile(const char *filename)
112112
return "";
113113
}
114114

115+
std::vector<Suppressions::Suppression> Suppressions::parseMultiSuppressComment(std::string comment, std::string *errorMessage)
116+
{
117+
std::vector<Suppression> suppressions;
118+
if (comment.size() < 2)
119+
return suppressions;
120+
121+
const std::size_t first_non_blank_position = comment.find_first_not_of(" \t\n", 2);
122+
const std::size_t suppress_position = comment.find("cppcheck-suppress", 2);
123+
if (suppress_position == std::string::npos)
124+
return suppressions;
125+
if (suppress_position != first_non_blank_position) {
126+
if (errorMessage && errorMessage->empty())
127+
*errorMessage = "Bad multi suppression '" + comment + "'. there shouldn't have non-blank character before cppcheck-suppress";
128+
return suppressions;
129+
}
130+
131+
const std::size_t start_position = comment.find("[", suppress_position);
132+
const std::size_t end_position = comment.find("]", suppress_position);
133+
if ( start_position == std::string::npos
134+
|| end_position == std::string::npos
135+
|| start_position != suppress_position+17 //there must be no space before "["
136+
|| start_position >= end_position)
137+
{
138+
if (errorMessage && errorMessage->empty())
139+
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
140+
return suppressions;
141+
}
142+
143+
//extract supressions
144+
std::size_t current_comma_position = 0;
145+
//multi_suppressions_word maybe "[errorId1, errorId2 symbolName=arr", who just has left bracket
146+
std::string multi_suppressions_word = comment.substr(start_position, end_position-start_position);
147+
do
148+
{
149+
std::string suppression_word;
150+
151+
//single suppression word
152+
const std::size_t previous_comma_position=current_comma_position;
153+
current_comma_position=multi_suppressions_word.find(",", previous_comma_position+1); //find "," after previous comma
154+
if (current_comma_position == std::string::npos)
155+
{
156+
suppression_word = multi_suppressions_word.substr(previous_comma_position+1);
157+
}
158+
else
159+
{
160+
suppression_word = multi_suppressions_word.substr(previous_comma_position+1, current_comma_position-previous_comma_position-1);
161+
}
162+
163+
//parse single suppression word
164+
Suppression s;
165+
std::string word;
166+
std::string errorId;
167+
std::string symbolName;
168+
std::istringstream iss(suppression_word);
169+
170+
iss >> errorId;
171+
if (!iss)
172+
{
173+
if (errorMessage && errorMessage->empty())
174+
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
175+
suppressions.clear();
176+
return suppressions;
177+
}
178+
179+
while (iss)
180+
{
181+
iss >> word;
182+
if (!iss)
183+
break;
184+
if (word.find_first_not_of("+-*/%#;") == std::string::npos)
185+
break;
186+
if (word.compare(0, 11, "symbolName=") == 0)
187+
{
188+
symbolName = word.substr(11);
189+
}
190+
else
191+
{
192+
if (errorMessage && errorMessage->empty())
193+
*errorMessage = "Bad multi suppression '" + comment + "'. legal format is cppcheck-suppress[errorId, errorId symbolName=arr, ...]";
194+
suppressions.clear();
195+
return suppressions;
196+
}
197+
}
198+
199+
s.errorId = errorId;
200+
s.symbolName = symbolName;
201+
suppressions.push_back(s);
202+
203+
} while(current_comma_position!=std::string::npos);
204+
205+
return suppressions;
206+
}
207+
115208
std::string Suppressions::addSuppressionLine(const std::string &line)
116209
{
117210
std::istringstream lineStream(line);

lib/suppressions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <list>
2727
#include <set>
2828
#include <string>
29+
#include <vector>
2930

3031
/// @addtogroup Core
3132
/// @{
@@ -115,6 +116,14 @@ class CPPCHECKLIB Suppressions {
115116
*/
116117
std::string parseXmlFile(const char *filename);
117118

119+
/**
120+
* Parse multi inline suppression in comment
121+
* @param comment the full comment text
122+
* @param errorMessage output parameter for error message (wrong suppression attribute)
123+
* @return empty vector if something wrong.
124+
*/
125+
static std::vector<Suppression> parseMultiSuppressComment(std::string comment, std::string *errorMessage);
126+
118127
/**
119128
* @brief Don't show the given error.
120129
* @param line Description of error to suppress (in id:file:line format).

0 commit comments

Comments
 (0)