2011-10-28 22:39:46 +02:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2019-02-09 07:24:06 +01:00
* Copyright ( C ) 2007 - 2019 Cppcheck team .
2011-10-28 22:39:46 +02:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2014-05-18 19:48:43 +02:00
# ifdef CHECK_INTERNAL
2011-10-29 12:47:12 +02:00
2011-10-28 22:39:46 +02:00
# include "checkinternal.h"
2017-05-27 04:33:47 +02:00
# include "astutils.h"
2020-04-13 13:44:48 +02:00
# include "errorlogger.h"
2011-10-28 22:39:46 +02:00
# include "symboldatabase.h"
2020-04-13 13:44:48 +02:00
# include "token.h"
# include "tokenize.h"
2017-05-27 04:33:47 +02:00
2011-10-28 22:39:46 +02:00
# include <set>
2014-01-05 21:15:41 +01:00
# include <cstring>
2011-10-28 22:39:46 +02:00
2011-10-29 12:47:12 +02:00
// Register this check class (by creating a static instance of it).
// Disabled in release builds
2011-10-28 22:39:46 +02:00
namespace {
CheckInternal instance ;
}
void CheckInternal : : checkTokenMatchPatterns ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2016-07-24 11:45:28 +02:00
for ( std : : size_t i = 0 ; i < symbolDatabase - > functionScopes . size ( ) ; + + i ) {
const Scope * scope = symbolDatabase - > functionScopes [ i ] ;
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2016-07-24 11:45:28 +02:00
if ( ! Token : : simpleMatch ( tok , " Token :: Match ( " ) & & ! Token : : simpleMatch ( tok , " Token :: findmatch ( " ) )
continue ;
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
const std : : string & funcname = tok - > strAt ( 2 ) ;
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
// Get pattern string
2016-07-25 16:04:18 +02:00
const Token * patternTok = tok - > tokAt ( 4 ) - > nextArgument ( ) ;
if ( ! patternTok | | patternTok - > tokType ( ) ! = Token : : eString )
2016-07-24 11:45:28 +02:00
continue ;
2011-10-28 22:39:46 +02:00
2016-07-25 16:04:18 +02:00
const std : : string pattern = patternTok - > strValue ( ) ;
2016-07-24 11:45:28 +02:00
if ( pattern . empty ( ) ) {
simplePatternError ( tok , pattern , funcname ) ;
continue ;
2015-01-28 19:48:36 +01:00
}
2016-07-24 11:45:28 +02:00
if ( pattern . find ( " || " ) ! = std : : string : : npos | | pattern . find ( " | " ) ! = std : : string : : npos | | pattern [ 0 ] = = ' | ' | | ( pattern [ pattern . length ( ) - 1 ] = = ' | ' & & pattern [ pattern . length ( ) - 2 ] = = ' ' ) )
orInComplexPattern ( tok , pattern , funcname ) ;
// Check for signs of complex patterns
if ( pattern . find_first_of ( " [| " ) ! = std : : string : : npos )
continue ;
else if ( pattern . find ( " !! " ) ! = std : : string : : npos )
continue ;
bool complex = false ;
size_t index = pattern . find ( ' % ' ) ;
while ( index ! = std : : string : : npos ) {
if ( pattern . length ( ) < = index + 2 ) {
complex = true ;
break ;
}
if ( pattern [ index + 1 ] = = ' o ' & & pattern [ index + 2 ] = = ' r ' ) // %or% or %oror%
index = pattern . find ( ' % ' , index + 1 ) ;
else {
complex = true ;
break ;
}
2015-01-28 19:48:36 +01:00
index = pattern . find ( ' % ' , index + 1 ) ;
}
2016-07-24 11:45:28 +02:00
if ( ! complex )
simplePatternError ( tok , pattern , funcname ) ;
2015-01-28 19:48:36 +01:00
}
2011-10-28 22:39:46 +02:00
}
}
2017-05-18 15:21:29 +02:00
void CheckInternal : : checkRedundantTokCheck ( )
{
2018-06-16 16:10:28 +02:00
for ( const Token * tok = mTokenizer - > tokens ( ) ; tok ; tok = tok - > next ( ) ) {
2018-01-01 05:04:59 +01:00
if ( Token : : Match ( tok , " && Token :: simpleMatch|Match|findsimplematch|findmatch ( " ) ) {
// in code like
// if (tok->previous() && Token::match(tok->previous(), "bla")) {}
// the first tok->previous() check is redundant
const Token * astOp1 = tok - > astOperand1 ( ) ;
const Token * astOp2 = getArguments ( tok - > tokAt ( 3 ) ) [ 0 ] ;
2019-04-06 07:44:44 +02:00
if ( Token : : simpleMatch ( astOp1 , " && " ) ) {
astOp1 = astOp1 - > astOperand2 ( ) ;
}
2018-01-01 04:19:26 +01:00
if ( astOp1 - > expressionString ( ) = = astOp2 - > expressionString ( ) ) {
checkRedundantTokCheckError ( astOp2 ) ;
}
2018-01-01 05:04:59 +01:00
// if (!tok || !Token::match(tok, "foo"))
} else if ( Token : : Match ( tok , " %oror% ! Token :: simpleMatch|Match|findsimplematch|findmatch ( " ) ) {
const Token * negTok = tok - > next ( ) - > astParent ( ) - > astOperand1 ( ) ;
2019-04-06 07:44:44 +02:00
if ( Token : : simpleMatch ( negTok , " || " ) ) {
negTok = negTok - > astOperand2 ( ) ;
}
2018-01-01 05:04:59 +01:00
// the first tok condition is negated
if ( Token : : simpleMatch ( negTok , " ! " ) ) {
const Token * astOp1 = negTok - > astOperand1 ( ) ;
const Token * astOp2 = getArguments ( tok - > tokAt ( 4 ) ) [ 0 ] ;
if ( astOp1 - > expressionString ( ) = = astOp2 - > expressionString ( ) ) {
checkRedundantTokCheckError ( astOp2 ) ;
}
}
2017-05-18 15:21:29 +02:00
}
}
2018-01-01 05:04:59 +01:00
}
2018-01-01 04:19:26 +01:00
2017-05-18 15:21:29 +02:00
void CheckInternal : : checkRedundantTokCheckError ( const Token * tok )
{
reportError ( tok , Severity : : style , " redundantTokCheck " ,
2017-05-30 07:03:15 +02:00
" Unnecessary check of \" " + ( tok ? tok - > expressionString ( ) : emptyString ) + " \" , match-function already checks if it is null. " ) ;
2017-05-18 15:21:29 +02:00
}
2011-10-28 22:39:46 +02:00
void CheckInternal : : checkTokenSimpleMatchPatterns ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2016-07-24 11:45:28 +02:00
for ( std : : size_t i = 0 ; i < symbolDatabase - > functionScopes . size ( ) ; + + i ) {
const Scope * scope = symbolDatabase - > functionScopes [ i ] ;
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2016-07-24 11:45:28 +02:00
if ( ! Token : : simpleMatch ( tok , " Token :: simpleMatch ( " ) & & ! Token : : simpleMatch ( tok , " Token :: findsimplematch ( " ) )
continue ;
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
const std : : string & funcname = tok - > strAt ( 2 ) ;
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
// Get pattern string
2016-07-26 08:46:50 +02:00
const Token * patternTok = tok - > tokAt ( 4 ) - > nextArgument ( ) ;
if ( ! patternTok | | patternTok - > tokType ( ) ! = Token : : eString )
2016-07-24 11:45:28 +02:00
continue ;
2011-10-28 22:39:46 +02:00
2016-07-26 08:46:50 +02:00
const std : : string pattern = patternTok - > strValue ( ) ;
2016-07-24 11:45:28 +02:00
if ( pattern . empty ( ) ) {
complexPatternError ( tok , pattern , funcname ) ;
continue ;
}
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
// Check for [xyz] usage - but exclude standalone square brackets
unsigned int char_count = 0 ;
for ( std : : string : : size_type pos = 0 ; pos < pattern . size ( ) ; + + pos ) {
char c = pattern [ pos ] ;
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
if ( c = = ' ' ) {
char_count = 0 ;
} else if ( c = = ' ] ' ) {
if ( char_count > 0 ) {
complexPatternError ( tok , pattern , funcname ) ;
continue ;
}
} else {
+ + char_count ;
2011-10-28 22:39:46 +02:00
}
}
2016-07-24 11:45:28 +02:00
// Check | usage: Count characters before the symbol
char_count = 0 ;
for ( std : : string : : size_type pos = 0 ; pos < pattern . size ( ) ; + + pos ) {
const char c = pattern [ pos ] ;
2011-10-28 22:39:46 +02:00
2016-07-24 11:45:28 +02:00
if ( c = = ' ' ) {
char_count = 0 ;
} else if ( c = = ' | ' ) {
if ( char_count > 0 ) {
complexPatternError ( tok , pattern , funcname ) ;
continue ;
}
} else {
+ + char_count ;
2011-10-28 22:39:46 +02:00
}
}
2016-07-24 11:45:28 +02:00
// Check for real errors
if ( pattern . length ( ) > 1 ) {
for ( size_t j = 0 ; j < pattern . length ( ) - 1 ; j + + ) {
if ( pattern [ j ] = = ' % ' & & pattern [ j + 1 ] ! = ' ' )
complexPatternError ( tok , pattern , funcname ) ;
else if ( pattern [ j ] = = ' ! ' & & pattern [ j + 1 ] = = ' ! ' )
complexPatternError ( tok , pattern , funcname ) ;
}
2014-05-18 20:39:52 +02:00
}
}
2011-10-28 22:39:46 +02:00
}
}
2015-06-17 21:25:15 +02:00
namespace {
2018-04-08 22:54:10 +02:00
const std : : set < std : : string > knownPatterns = {
" %any% "
, " %assign% "
, " %bool% "
, " %char% "
, " %comp% "
, " %num% "
, " %op% "
, " %cop% "
, " %or% "
, " %oror% "
, " %str% "
, " %type% "
, " %name% "
, " %var% "
, " %varid% "
} ;
2015-06-17 21:25:15 +02:00
}
2011-10-29 12:13:46 +02:00
void CheckInternal : : checkMissingPercentCharacter ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2016-07-24 11:45:28 +02:00
for ( std : : size_t i = 0 ; i < symbolDatabase - > functionScopes . size ( ) ; + + i ) {
const Scope * scope = symbolDatabase - > functionScopes [ i ] ;
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2016-07-24 11:45:28 +02:00
if ( ! Token : : simpleMatch ( tok , " Token :: Match ( " ) & & ! Token : : simpleMatch ( tok , " Token :: findmatch ( " ) )
continue ;
const std : : string & funcname = tok - > strAt ( 2 ) ;
// Get pattern string
2016-07-26 08:46:50 +02:00
const Token * patternTok = tok - > tokAt ( 4 ) - > nextArgument ( ) ;
if ( ! patternTok | | patternTok - > tokType ( ) ! = Token : : eString )
2016-07-24 11:45:28 +02:00
continue ;
2016-07-26 08:46:50 +02:00
const std : : string pattern = patternTok - > strValue ( ) ;
2016-07-24 11:45:28 +02:00
2016-07-26 15:42:17 +02:00
std : : set < std : : string > : : const_iterator knownPattern , knownPatternsEnd = knownPatterns . end ( ) ;
for ( knownPattern = knownPatterns . begin ( ) ; knownPattern ! = knownPatternsEnd ; + + knownPattern ) {
const std : : string brokenPattern = ( * knownPattern ) . substr ( 0 , ( * knownPattern ) . size ( ) - 1 ) ;
2016-07-24 11:45:28 +02:00
std : : string : : size_type pos = 0 ;
2016-07-26 15:42:17 +02:00
while ( ( pos = pattern . find ( brokenPattern , pos ) ) ! = std : : string : : npos ) {
2016-07-24 11:45:28 +02:00
// Check if it's the full pattern
2016-07-26 15:42:17 +02:00
if ( pattern . find ( * knownPattern , pos ) ! = pos ) {
2016-07-24 11:45:28 +02:00
// Known whitelist of substrings
2016-07-26 15:42:17 +02:00
if ( ( brokenPattern = = " %var " & & pattern . find ( " %varid% " , pos ) = = pos ) | |
( brokenPattern = = " %or " & & pattern . find ( " %oror% " , pos ) = = pos ) ) {
2016-07-24 11:45:28 +02:00
+ + pos ;
continue ;
}
missingPercentCharacterError ( tok , pattern , funcname ) ;
2011-10-29 12:13:46 +02:00
}
2016-07-24 11:45:28 +02:00
+ + pos ;
2011-10-29 12:13:46 +02:00
}
}
}
}
}
2012-07-11 17:45:16 +02:00
void CheckInternal : : checkUnknownPattern ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2016-07-24 11:45:28 +02:00
for ( std : : size_t i = 0 ; i < symbolDatabase - > functionScopes . size ( ) ; + + i ) {
const Scope * scope = symbolDatabase - > functionScopes [ i ] ;
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2016-07-24 11:45:28 +02:00
if ( ! Token : : simpleMatch ( tok , " Token :: Match ( " ) & & ! Token : : simpleMatch ( tok , " Token :: findmatch ( " ) )
continue ;
// Get pattern string
2016-07-26 08:46:50 +02:00
const Token * patternTok = tok - > tokAt ( 4 ) - > nextArgument ( ) ;
if ( ! patternTok | | patternTok - > tokType ( ) ! = Token : : eString )
2016-07-24 11:45:28 +02:00
continue ;
2016-07-26 08:46:50 +02:00
const std : : string pattern = patternTok - > strValue ( ) ;
2016-07-24 11:45:28 +02:00
bool inBrackets = false ;
for ( std : : string : : size_type j = 0 ; j < pattern . length ( ) - 1 ; j + + ) {
if ( pattern [ j ] = = ' [ ' & & ( j = = 0 | | pattern [ j - 1 ] = = ' ' ) )
inBrackets = true ;
else if ( pattern [ j ] = = ' ] ' )
inBrackets = false ;
else if ( pattern [ j ] = = ' % ' & & pattern [ j + 1 ] ! = ' ' & & pattern [ j + 1 ] ! = ' | ' & & ! inBrackets ) {
const std : : string : : size_type end = pattern . find ( ' % ' , j + 1 ) ;
if ( end ! = std : : string : : npos ) {
const std : : string s = pattern . substr ( j , end - j + 1 ) ;
if ( knownPatterns . find ( s ) = = knownPatterns . end ( ) )
unknownPatternError ( tok , s ) ;
}
2012-07-11 17:45:16 +02:00
}
}
}
}
}
2012-09-07 12:36:40 +02:00
void CheckInternal : : checkRedundantNextPrevious ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2016-07-24 11:45:28 +02:00
for ( std : : size_t i = 0 ; i < symbolDatabase - > functionScopes . size ( ) ; + + i ) {
const Scope * scope = symbolDatabase - > functionScopes [ i ] ;
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2016-07-24 11:45:28 +02:00
if ( tok - > str ( ) ! = " . " )
2012-09-07 12:36:40 +02:00
continue ;
2016-07-24 11:45:28 +02:00
tok = tok - > next ( ) ;
2012-09-07 12:36:40 +02:00
2016-07-24 11:45:28 +02:00
if ( Token : : Match ( tok , " previous ( ) . next|tokAt|strAt|linkAt ( " ) | | Token : : Match ( tok , " next ( ) . previous|tokAt|strAt|linkAt ( " ) | |
( Token : : simpleMatch ( tok , " tokAt ( " ) & & Token : : Match ( tok - > linkAt ( 1 ) , " ) . previous|next|tokAt|strAt|linkAt|str|link ( " ) ) ) {
const std : : string & func1 = tok - > str ( ) ;
const std : : string & func2 = tok - > linkAt ( 1 ) - > strAt ( 2 ) ;
2012-09-07 12:36:40 +02:00
2016-07-24 11:45:28 +02:00
if ( ( func2 = = " previous " | | func2 = = " next " | | func2 = = " str " | | func2 = = " link " ) & & tok - > linkAt ( 1 ) - > strAt ( 4 ) ! = " ) " )
continue ;
2012-09-07 12:36:40 +02:00
2016-07-24 11:45:28 +02:00
redundantNextPreviousError ( tok , func1 , func2 ) ;
} else if ( Token : : Match ( tok , " next|previous ( ) . next | previous ( ) . next | previous | linkAt | strAt | link | str ( " )) {
const std : : string & func1 = tok - > str ( ) ;
const std : : string & func2 = tok - > strAt ( 8 ) ;
if ( ( func2 = = " previous " | | func2 = = " next " | | func2 = = " str " | | func2 = = " link " ) & & tok - > strAt ( 10 ) ! = " ) " )
continue ;
redundantNextPreviousError ( tok , func1 , func2 ) ;
}
2012-09-07 12:36:40 +02:00
}
}
}
2014-12-30 14:21:18 +01:00
void CheckInternal : : checkExtraWhitespace ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2016-07-24 11:45:28 +02:00
for ( std : : size_t i = 0 ; i < symbolDatabase - > functionScopes . size ( ) ; + + i ) {
const Scope * scope = symbolDatabase - > functionScopes [ i ] ;
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2016-07-24 11:45:28 +02:00
if ( ! Token : : Match ( tok , " Token :: simpleMatch|findsimplematch|Match|findmatch ( " ) )
continue ;
const std : : string & funcname = tok - > strAt ( 2 ) ;
// Get pattern string
2016-07-26 08:46:50 +02:00
const Token * patternTok = tok - > tokAt ( 4 ) - > nextArgument ( ) ;
if ( ! patternTok | | patternTok - > tokType ( ) ! = Token : : eString )
2016-07-24 11:45:28 +02:00
continue ;
2016-07-26 08:46:50 +02:00
const std : : string pattern = patternTok - > strValue ( ) ;
2016-07-24 11:45:28 +02:00
if ( ! pattern . empty ( ) & & ( pattern [ 0 ] = = ' ' | | * pattern . rbegin ( ) = = ' ' ) )
extraWhitespaceError ( tok , pattern , funcname ) ;
// two whitespaces or more
if ( pattern . find ( " " ) ! = std : : string : : npos )
extraWhitespaceError ( tok , pattern , funcname ) ;
}
2014-12-30 14:21:18 +01:00
}
}
2018-04-14 19:43:57 +02:00
void CheckInternal : : checkStlUsage ( )
{
2018-06-16 16:10:28 +02:00
const SymbolDatabase * symbolDatabase = mTokenizer - > getSymbolDatabase ( ) ;
2018-04-14 19:43:57 +02:00
for ( const Scope * scope : symbolDatabase - > functionScopes ) {
2018-04-27 22:36:30 +02:00
for ( const Token * tok = scope - > bodyStart - > next ( ) ; tok ! = scope - > bodyEnd ; tok = tok - > next ( ) ) {
2018-04-14 19:43:57 +02:00
if ( Token : : simpleMatch ( tok , " . emplace ( " ) )
2019-01-13 12:12:07 +01:00
reportError ( tok , Severity : : error , " internalStlUsage " , " The 'emplace' function shall be avoided for now. It is not available e.g. in Slackware 14.0. 'emplace_back' is fine. " ) ;
2018-04-14 19:43:57 +02:00
//if (Token::simpleMatch(tok, ". back ( )") && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->container && Token::simpleMatch(tok->astOperand1()->valueType()->container, "std :: string"))
// reportError(tok, Severity::error, "internalStlUsage", "The 'std::string::back()' function shall be avoided for now.");
}
}
}
2014-01-05 21:15:41 +01:00
void CheckInternal : : multiComparePatternError ( const Token * tok , const std : : string & pattern , const std : : string & funcname )
{
reportError ( tok , Severity : : error , " multiComparePatternError " ,
2015-01-31 10:50:39 +01:00
" Bad multicompare pattern (a %cmd% must be first unless it is %or%,%op%,%cop%,%name%,%oror%) inside Token:: " + funcname + " () call: \" " + pattern + " \" "
2014-01-05 21:15:41 +01:00
) ;
}
2011-11-07 00:50:45 +01:00
void CheckInternal : : simplePatternError ( const Token * tok , const std : : string & pattern , const std : : string & funcname )
2011-10-28 22:39:46 +02:00
{
reportError ( tok , Severity : : warning , " simplePatternError " ,
" Found simple pattern inside Token:: " + funcname + " () call: \" " + pattern + " \" "
) ;
}
2011-11-07 00:50:45 +01:00
void CheckInternal : : complexPatternError ( const Token * tok , const std : : string & pattern , const std : : string & funcname )
2011-10-28 22:39:46 +02:00
{
reportError ( tok , Severity : : error , " complexPatternError " ,
" Found complex pattern inside Token:: " + funcname + " () call: \" " + pattern + " \" "
) ;
}
2011-10-29 12:13:46 +02:00
void CheckInternal : : missingPercentCharacterError ( const Token * tok , const std : : string & pattern , const std : : string & funcname )
{
reportError ( tok , Severity : : error , " missingPercentCharacter " ,
" Missing percent end character in Token:: " + funcname + " () pattern: \" " + pattern + " \" "
) ;
}
2011-10-29 12:47:12 +02:00
2012-07-11 17:45:16 +02:00
void CheckInternal : : unknownPatternError ( const Token * tok , const std : : string & pattern )
{
2012-07-21 15:54:04 +02:00
reportError ( tok , Severity : : error , " unknownPattern " ,
" Unknown pattern used: \" " + pattern + " \" " ) ;
2012-07-11 17:45:16 +02:00
}
2012-09-07 12:36:40 +02:00
void CheckInternal : : redundantNextPreviousError ( const Token * tok , const std : : string & func1 , const std : : string & func2 )
{
reportError ( tok , Severity : : style , " redundantNextPrevious " ,
" Call to 'Token:: " + func1 + " ()' followed by 'Token:: " + func2 + " ()' can be simplified. " ) ;
}
2014-07-02 15:50:49 +02:00
void CheckInternal : : orInComplexPattern ( const Token * tok , const std : : string & pattern , const std : : string & funcname )
{
reportError ( tok , Severity : : error , " orInComplexPattern " ,
" Token:: " + funcname + " () pattern \" " + pattern + " \" contains \" || \" or \" | \" . Replace it by \" %oror% \" or \" %or% \" . " ) ;
}
2014-12-30 14:21:18 +01:00
void CheckInternal : : extraWhitespaceError ( const Token * tok , const std : : string & pattern , const std : : string & funcname )
{
reportError ( tok , Severity : : warning , " extraWhitespaceError " ,
" Found extra whitespace inside Token:: " + funcname + " () call: \" " + pattern + " \" "
) ;
}
2014-05-18 19:48:43 +02:00
# endif // #ifdef CHECK_INTERNAL