Skip to content

Commit 17b47f1

Browse files
committed
New internal check: Catch extra whitespace in match patterns
Inspired by a recent commit from PKEuS.
1 parent 208761f commit 17b47f1

3 files changed

Lines changed: 84 additions & 0 deletions

File tree

lib/checkinternal.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,32 @@ void CheckInternal::checkRedundantNextPrevious()
283283
}
284284
}
285285

286+
void CheckInternal::checkExtraWhitespace()
287+
{
288+
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
289+
if (!Token::simpleMatch(tok, "Token :: simpleMatch (") &&
290+
!Token::simpleMatch(tok, "Token :: findsimplematch (") &&
291+
!Token::simpleMatch(tok, "Token :: Match (") &&
292+
!Token::simpleMatch(tok, "Token :: findmatch ("))
293+
continue;
294+
295+
const std::string& funcname = tok->strAt(2);
296+
297+
// Get pattern string
298+
const Token *pattern_tok = tok->tokAt(4)->nextArgument();
299+
if (!pattern_tok || pattern_tok->type() != Token::eString)
300+
continue;
301+
302+
const std::string pattern = pattern_tok->strValue();
303+
if (!pattern.empty() && (pattern[0] == ' ' || *pattern.rbegin() == ' '))
304+
extraWhitespaceError(tok, pattern, funcname);
305+
306+
// two whitespaces or more
307+
if (pattern.find(" ") != std::string::npos)
308+
extraWhitespaceError(tok, pattern, funcname);
309+
}
310+
}
311+
286312
void CheckInternal::multiComparePatternError(const Token* tok, const std::string& pattern, const std::string &funcname)
287313
{
288314
reportError(tok, Severity::error, "multiComparePatternError",
@@ -329,4 +355,11 @@ void CheckInternal::orInComplexPattern(const Token* tok, const std::string& patt
329355
"Token::" + funcname + "() pattern \"" + pattern + "\" contains \"||\" or \"|\". Replace it by \"%oror%\" or \"%or%\".");
330356
}
331357

358+
void CheckInternal::extraWhitespaceError(const Token* tok, const std::string& pattern, const std::string &funcname)
359+
{
360+
reportError(tok, Severity::warning, "extraWhitespaceError",
361+
"Found extra whitespace inside Token::" + funcname + "() call: \"" + pattern + "\""
362+
);
363+
}
364+
332365
#endif // #ifdef CHECK_INTERNAL

lib/checkinternal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class CPPCHECKLIB CheckInternal : public Check {
5353
checkInternal.checkMissingPercentCharacter();
5454
checkInternal.checkUnknownPattern();
5555
checkInternal.checkRedundantNextPrevious();
56+
checkInternal.checkExtraWhitespace();
5657
}
5758

5859
/** @brief %Check if a simple pattern is used inside Token::Match or Token::findmatch */
@@ -70,6 +71,9 @@ class CPPCHECKLIB CheckInternal : public Check {
7071
/** @brief %Check for inefficient usage of Token::next(), Token::previous() and Token::tokAt() */
7172
void checkRedundantNextPrevious();
7273

74+
/** @brief %Check if there is whitespace at the beginning or at the end of a pattern */
75+
void checkExtraWhitespace();
76+
7377
private:
7478
void multiComparePatternError(const Token *tok, const std::string &pattern, const std::string &funcname);
7579
void simplePatternError(const Token *tok, const std::string &pattern, const std::string &funcname);
@@ -78,6 +82,7 @@ class CPPCHECKLIB CheckInternal : public Check {
7882
void unknownPatternError(const Token* tok, const std::string& pattern);
7983
void redundantNextPreviousError(const Token* tok, const std::string& func1, const std::string& func2);
8084
void orInComplexPattern(const Token *tok, const std::string &pattern, const std::string &funcname);
85+
void extraWhitespaceError(const Token *tok, const std::string &pattern, const std::string &funcname);
8186

8287
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const {
8388
CheckInternal c(0, settings, errorLogger);
@@ -88,6 +93,7 @@ class CPPCHECKLIB CheckInternal : public Check {
8893
c.unknownPatternError(0, "%typ");
8994
c.redundantNextPreviousError(0, "previous", "next");
9095
c.orInComplexPattern(0, "||", "Match");
96+
c.extraWhitespaceError(0, "%str% ", "Match");
9197
}
9298

9399
static std::string myName() {

test/testinternal.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class TestInternal : public TestFixture {
4242
TEST_CASE(internalError)
4343
TEST_CASE(invalidMultiCompare);
4444
TEST_CASE(orInComplexPattern);
45+
TEST_CASE(extraWhitespace);
4546
}
4647

4748
void check(const char code[]) {
@@ -375,6 +376,50 @@ class TestInternal : public TestFixture {
375376
"}");
376377
ASSERT_EQUALS("", errout.str());
377378
}
379+
380+
void extraWhitespace() {
381+
// whitespace at the end
382+
check("void f() {\n"
383+
" const Token *tok;\n"
384+
" Token::Match(tok, \"%str% \");\n"
385+
"}");
386+
ASSERT_EQUALS("[test.cpp:3]: (warning) Found extra whitespace inside Token::Match() call: \"%str% \"\n", errout.str());
387+
388+
// whitespace at the begin
389+
check("void f() {\n"
390+
" const Token *tok;\n"
391+
" Token::Match(tok, \" %str%\");\n"
392+
"}");
393+
ASSERT_EQUALS("[test.cpp:3]: (warning) Found extra whitespace inside Token::Match() call: \" %str%\"\n", errout.str());
394+
395+
// two whitespaces or more
396+
check("void f() {\n"
397+
" const Token *tok;\n"
398+
" Token::Match(tok, \"%str% bar\");\n"
399+
"}");
400+
ASSERT_EQUALS("[test.cpp:3]: (warning) Found extra whitespace inside Token::Match() call: \"%str% bar\"\n", errout.str());
401+
402+
// test simpleMatch
403+
check("void f() {\n"
404+
" const Token *tok;\n"
405+
" Token::simpleMatch(tok, \"foobar \");\n"
406+
"}");
407+
ASSERT_EQUALS("[test.cpp:3]: (warning) Found extra whitespace inside Token::simpleMatch() call: \"foobar \"\n", errout.str());
408+
409+
// test findmatch
410+
check("void f() {\n"
411+
" const Token *tok;\n"
412+
" Token::findmatch(tok, \"%str% \");\n"
413+
"}");
414+
ASSERT_EQUALS("[test.cpp:3]: (warning) Found extra whitespace inside Token::findmatch() call: \"%str% \"\n", errout.str());
415+
416+
// test findsimplematch
417+
check("void f() {\n"
418+
" const Token *tok;\n"
419+
" Token::findsimplematch(tok, \"foobar \");\n"
420+
"}");
421+
ASSERT_EQUALS("[test.cpp:3]: (warning) Found extra whitespace inside Token::findsimplematch() call: \"foobar \"\n", errout.str());
422+
}
378423
};
379424

380425
REGISTER_TEST(TestInternal)

0 commit comments

Comments
 (0)