46 const std::string& funcname = tok->strAt(2);
53 const std::string pattern = patternTok->
strValue();
54 if (pattern.empty()) {
59 if (pattern.find(
"||") != std::string::npos || pattern.find(
" | ") != std::string::npos || pattern[0] ==
'|' || (pattern[pattern.length() - 1] ==
'|' && pattern[pattern.length() - 2] ==
' '))
63 if (pattern.find_first_of(
"[|") != std::string::npos)
65 if (pattern.find(
"!!") != std::string::npos)
69 size_t index = pattern.find(
'%');
70 while (index != std::string::npos) {
71 if (pattern.length() <= index + 2) {
75 if (pattern[index + 1] ==
'o' && pattern[index + 2] ==
'r')
76 index = pattern.find(
'%', index + 1);
81 index = pattern.find(
'%', index + 1);
92 if (
Token::Match(tok,
"&& Token :: simpleMatch|Match|findsimplematch|findmatch (")) {
105 }
else if (
Token::Match(tok,
"%oror% ! Token :: simpleMatch|Match|findsimplematch|findmatch (")) {
138 const std::string& funcname = tok->
strAt(2);
145 const std::string pattern = patternTok->
strValue();
146 if (pattern.empty()) {
152 unsigned int char_count = 0;
153 for (
const char c : pattern) {
156 }
else if (c ==
']') {
157 if (char_count > 0) {
168 for (
const char c : pattern) {
171 }
else if (c ==
'|') {
172 if (char_count > 0) {
182 if (pattern.length() > 1) {
183 for (
size_t j = 0; j < pattern.length() - 1; j++) {
184 if (pattern[j] ==
'%' && pattern[j + 1] !=
' ')
186 else if (pattern[j] ==
'!' && pattern[j + 1] ==
'!')
195 const std::set<std::string> knownPatterns = {
222 const std::string& funcname = tok->
strAt(2);
229 const std::string pattern = patternTok->
strValue();
231 std::set<std::string>::const_iterator knownPattern, knownPatternsEnd = knownPatterns.cend();
232 for (knownPattern = knownPatterns.cbegin(); knownPattern != knownPatternsEnd; ++knownPattern) {
233 const std::string brokenPattern = knownPattern->substr(0, knownPattern->size() - 1);
235 std::string::size_type pos = 0;
236 while ((pos = pattern.find(brokenPattern, pos)) != std::string::npos) {
238 if (pattern.find(*knownPattern, pos) != pos) {
240 if ((brokenPattern ==
"%var" && pattern.find(
"%varid%", pos) == pos) ||
241 (brokenPattern ==
"%or" && pattern.find(
"%oror%", pos) == pos)) {
269 const std::string pattern = patternTok->
strValue();
270 bool inBrackets =
false;
272 for (std::string::size_type j = 0; j < pattern.length() - 1; j++) {
273 if (pattern[j] ==
'[' && (j == 0 || pattern[j - 1] ==
' '))
275 else if (pattern[j] ==
']')
277 else if (pattern[j] ==
'%' && pattern[j + 1] !=
' ' && pattern[j + 1] !=
'|' && !inBrackets) {
278 const std::string::size_type end = pattern.find(
'%', j + 1);
279 if (end != std::string::npos) {
280 const std::string s = pattern.substr(j, end - j + 1);
281 if (knownPatterns.find(s) == knownPatterns.end())
295 if (tok->
str() !=
".")
299 if (
Token::Match(tok,
"previous ( ) . next|tokAt|strAt|linkAt (") ||
Token::Match(tok,
"next ( ) . previous|tokAt|strAt|linkAt (") ||
301 const std::string& func1 = tok->
str();
302 const std::string& func2 = tok->
linkAt(1)->
strAt(2);
304 if ((func2 ==
"previous" || func2 ==
"next" || func2 ==
"str" || func2 ==
"link") && tok->
linkAt(1)->
strAt(4) !=
")")
308 }
else if (
Token::Match(tok,
"next|previous ( ) . next|previous ( ) . next|previous|linkAt|strAt|link|str (")) {
309 const std::string& func1 = tok->
str();
310 const std::string& func2 = tok->
strAt(8);
312 if ((func2 ==
"previous" || func2 ==
"next" || func2 ==
"str" || func2 ==
"link") && tok->
strAt(10) !=
")")
326 if (!
Token::Match(tok,
"Token :: simpleMatch|findsimplematch|Match|findmatch ("))
329 const std::string& funcname = tok->
strAt(2);
336 const std::string pattern = patternTok->
strValue();
337 if (!pattern.empty() && (pattern[0] ==
' ' || *pattern.crbegin() ==
' '))
341 if (pattern.find(
" ") != std::string::npos)
350 "Bad multicompare pattern (a %cmd% must be first unless it is %or%,%op%,%cop%,%name%,%oror%) inside Token::" + funcname +
"() call: \"" + pattern +
"\""
357 "Found simple pattern inside Token::" + funcname +
"() call: \"" + pattern +
"\""
364 "Found complex pattern inside Token::" + funcname +
"() call: \"" + pattern +
"\""
371 "Missing percent end character in Token::" + funcname +
"() pattern: \"" + pattern +
"\""
378 "Unknown pattern used: \"" + pattern +
"\"");
384 "Call to 'Token::" + func1 +
"()' followed by 'Token::" + func2 +
"()' can be simplified.");
390 "Token::" + funcname +
"() pattern \"" + pattern +
"\" contains \"||\" or \"|\". Replace it by \"%oror%\" or \"%or%\".");
396 "Found extra whitespace inside Token::" + funcname +
"() call: \"" + pattern +
"\""
std::vector< const Token * > getArguments(const Token *ftok)
Get arguments (AST)
Check Internal cppcheck API usage
void checkRedundantNextPrevious()
Check for inefficient usage of Token::next(), Token::previous() and Token::tokAt()
void checkRedundantTokCheckError(const Token *tok)
void redundantNextPreviousError(const Token *tok, const std::string &func1, const std::string &func2)
void complexPatternError(const Token *tok, const std::string &pattern, const std::string &funcname)
void checkUnknownPattern()
Check for unknown (invalid) complex patterns like "%typ%"
void orInComplexPattern(const Token *tok, const std::string &pattern, const std::string &funcname)
void multiComparePatternError(const Token *tok, const std::string &pattern, const std::string &funcname)
void missingPercentCharacterError(const Token *tok, const std::string &pattern, const std::string &funcname)
void checkTokenSimpleMatchPatterns()
Check if a complex pattern is used inside Token::simpleMatch or Token::findsimplematch
void checkTokenMatchPatterns()
Check if a simple pattern is used inside Token::Match or Token::findmatch
void checkMissingPercentCharacter()
Check for missing % end character in Token::Match pattern
void unknownPatternError(const Token *tok, const std::string &pattern)
void checkExtraWhitespace()
Check if there is whitespace at the beginning or at the end of a pattern
void checkRedundantTokCheck()
Check if there is a redundant check for none-nullness of parameter before Match functions,...
void simplePatternError(const Token *tok, const std::string &pattern, const std::string &funcname)
void extraWhitespaceError(const Token *tok, const std::string &pattern, const std::string &funcname)
void reportError(const Token *tok, const Severity severity, const std::string &id, const std::string &msg)
report an error
const Tokenizer *const mTokenizer
const Token * bodyStart
'{' token
const Token * bodyEnd
'}' token
std::vector< const Scope * > functionScopes
Fast access to function scopes.
The token list that the TokenList generates is a linked-list of this class.
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
const std::string & strAt(int index) const
void astOperand1(Token *tok)
std::string expressionString() const
const Token * tokAt(int index) const
Token::Type tokType() const
void astOperand2(Token *tok)
const Token * linkAt(int index) const
std::string strValue() const
This can be called only for tokens that are strings, else the assert() is called.
const Token * nextArgument() const
static bool simpleMatch(const Token *tok, const char(&pattern)[count])
Match given token (or list of tokens) to a pattern list.
void astParent(Token *tok)
const Token * tokens() const
const SymbolDatabase * getSymbolDatabase() const
static const std::string emptyString
@ error
Programming error.