tokenizer: simplifyConditions tries to simplify conditions.. those that are always true to '( true )' and those that are always false to '( false )'

This commit is contained in:
Daniel Marjamäki 2008-11-22 17:53:22 +00:00
parent e33985dbf0
commit d68e2ae966
4 changed files with 52 additions and 64 deletions

View File

@ -382,11 +382,11 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
{
addtoken("if(!var)");
}
else if ( Tokenizer::Match(tok, "if (") && _tokenizer->alwaysTrue(tok->next) )
else if ( Tokenizer::Match(tok, "if ( true )") )
{
addtoken("if(true)");
}
else if ( Tokenizer::Match(tok, "if (") && _tokenizer->alwaysTrue(tok->next) )
else if ( Tokenizer::Match(tok, "if ( false )") )
{
addtoken("if(false)");
}

View File

@ -43,8 +43,7 @@ private:
TEST_CASE( dupfuncname );
TEST_CASE( alwaysTrue );
TEST_CASE( alwaysFalse );
TEST_CASE( simplifyConditions );
}
@ -154,45 +153,10 @@ private:
ASSERT_EQUALS( std::string("b"), tokenizer.FunctionList[0]->str );
}
bool alwaysTrueCheck(const char condition[])
void simplifyConditions()
{
// tokenize..
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(condition);
tokenizer.TokenizeCode(istr, 0);
// TODO Simplify various conditions..
// check..
return tokenizer.alwaysTrue( tokenizer.tokens() );
}
void alwaysTrue()
{
ASSERT_EQUALS(true, alwaysTrueCheck("(1)"));
ASSERT_EQUALS(true, alwaysTrueCheck("(true)"));
ASSERT_EQUALS(true, alwaysTrueCheck("(true || false)"));
ASSERT_EQUALS(false, alwaysTrueCheck("(true && false)"));
}
bool alwaysFalseCheck(const char condition[])
{
// tokenize..
Tokenizer tokenizer( this );
tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(condition);
tokenizer.TokenizeCode(istr, 0);
// check..
return tokenizer.alwaysFalse( tokenizer.tokens() );
}
void alwaysFalse()
{
ASSERT_EQUALS(true, alwaysFalseCheck("(0)"));
ASSERT_EQUALS(true, alwaysFalseCheck("(false)"));
ASSERT_EQUALS(true, alwaysFalseCheck("(false && true)"));
ASSERT_EQUALS(false, alwaysFalseCheck("(false || true)"));
}
};

View File

@ -820,12 +820,8 @@ void Tokenizer::SimplifyTokenList()
// Simple calculations..
bool done = false;
while (!done)
for ( bool done = false; !done; done = true )
{
done = true;
for (TOKEN *tok = _tokens; tok; tok = tok->next)
{
if (Tokenizer::Match(tok->next, "* 1") || Tokenizer::Match(tok->next, "1 *"))
@ -1037,10 +1033,52 @@ void Tokenizer::SimplifyTokenList()
DeleteNextToken(tok);
}
}
for ( bool done = false; !done; done = true)
{
done &= simplifyConditions();
};
}
//---------------------------------------------------------------------------
bool Tokenizer::simplifyConditions()
{
bool ret = true;
for ( TOKEN *tok = _tokens; tok; tok = tok->next )
{
if (Match(tok, "( true &&") || Match(tok, "&& true &&") || Match(tok->next, "&& true )"))
{
DeleteNextToken( tok );
DeleteNextToken( tok );
ret = false;
}
else if (Match(tok, "( false ||") || Match(tok, "|| false ||") || Match(tok->next, "|| false )"))
{
DeleteNextToken( tok );
DeleteNextToken( tok );
ret = false;
}
// Change numeric constant in condition to "true" or "false"
const TOKEN *tok2 = gettok(tok, 2);
if ((Match(tok, "(") || Match(tok, "&&") || Match(tok, "||")) &&
Match(tok->next, "%num%") &&
(Match(tok2, ")") || Match(tok2, "&&") || Match(tok2, "||")) )
{
tok->next->setstr((strcmp(tok->next->str, "0")!=0) ? "true" : "false");
ret = false;
}
}
return ret;
}
@ -1518,16 +1556,3 @@ bool Tokenizer::IsStandardType(const char str[])
return Ret;
}
//---------------------------------------------------------------------------
bool Tokenizer::alwaysTrue( const TOKEN *tok )
{
return (Match(tok,"( 1 [|)]") | Match(tok,"( 1 ||") |
Match(tok,"( true [|)]") | Match(tok,"( true ||"));
}
//---------------------------------------------------------------------------
bool Tokenizer::alwaysFalse( const TOKEN *tok )
{
return (Match(tok,"( 0 [&)]") | Match(tok,"( 0 &&") |
Match(tok,"( false [&)]") | Match(tok,"( false &&"));
}
//---------------------------------------------------------------------------

View File

@ -90,9 +90,6 @@ public:
static bool IsNumber(const char str[]);
static bool IsStandardType(const char str[]);
bool alwaysTrue( const TOKEN *tok );
bool alwaysFalse( const TOKEN *tok );
std::string fileLine( const TOKEN *tok );
// Return size.
@ -148,6 +145,8 @@ private:
void DeleteNextToken(TOKEN *tok);
bool simplifyConditions();
TOKEN *_gettok(TOKEN *tok, int index);
void InsertTokens(TOKEN *dest, TOKEN *src, unsigned int n);