Tokenizer: Simplify numeric comparisons

This commit is contained in:
Daniel Marjamäki 2008-12-04 19:32:26 +00:00
parent c6ed868009
commit 3820a26e1c
2 changed files with 61 additions and 1 deletions

View File

@ -44,7 +44,9 @@ private:
TEST_CASE( dupfuncname );
TEST_CASE( const_and_volatile_functions );
TEST_CASE( const_and_volatile_functions );
TEST_CASE( numeric_true_condition );
}
@ -184,6 +186,27 @@ private:
ASSERT_EQUALS( std::string("b"), tokenizer._functionList[1]->str() );
ASSERT_EQUALS( std::string("c"), tokenizer._functionList[2]->str() );
}
}
void numeric_true_condition()
{
const char code[] = "void f()\n"
"{\n"
" if (5==5);\n"
"}\n";
// tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList();
std::ostringstream ostr;
for (const TOKEN *tok = tokenizer.tokens(); tok; tok = tok->next)
ostr << " " << tok->str();
ASSERT_EQUALS( std::string(" void f ( ) { if ( true ) ; }"), ostr.str() );
}
};

View File

@ -1004,6 +1004,43 @@ bool Tokenizer::simplifyConditions()
{
tok->next->setstr((strcmp(tok->next->aaaa(), "0")!=0) ? "true" : "false");
ret = false;
}
// Reduce "(%num% == %num%)" => "(true)"/"(false)"
if ( (TOKEN::Match(tok, "&&") || TOKEN::Match(tok, "||") || TOKEN::Match(tok, "(")) &&
TOKEN::Match(tok->tokAt(1), "%num%") &&
TOKEN::Match(tok->tokAt(3), "%num%") &&
(TOKEN::Match(tok->tokAt(4), "&&") || TOKEN::Match(tok->tokAt(4), "||") || TOKEN::Match(tok->tokAt(4), ")")) )
{
double op1 = (strstr(tok->strAt(1), "0x")) ? strtol(tok->strAt(1),0,16) : atof( tok->strAt(1) );
double op2 = (strstr(tok->strAt(3), "0x")) ? strtol(tok->strAt(3),0,16) : atof( tok->strAt(3) );
std::string cmp = tok->strAt(2);
bool result = false;
if ( cmp == "==" )
result = (op1 == op2);
else if ( cmp == "!=" )
result = (op1 != op2);
else if ( cmp == ">=" )
result = (op1 >= op2);
else if ( cmp == ">" )
result = (op1 > op2);
else if ( cmp == "<=" )
result = (op1 <= op2);
else if ( cmp == "<" )
result = (op1 < op2);
else
cmp = "";
if ( ! cmp.empty() )
{
tok = tok->next;
tok->deleteNext();
tok->deleteNext();
tok->setstr( result ? "true" : "false" );
ret = false;
}
}
}