From 8876f0ee57759f72560dd82632e5d01be6c02645 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sat, 30 May 2009 00:04:01 +0300 Subject: [PATCH] Fix ticket #342 (Simplify "if( (true) == true )") http://apps.sourceforge.net/trac/cppcheck/ticket/342 --- src/tokenize.cpp | 112 ++++++++++++++++++++++++++---------------- test/testtokenize.cpp | 47 +++++++++++++----- 2 files changed, 105 insertions(+), 54 deletions(-) diff --git a/src/tokenize.cpp b/src/tokenize.cpp index 1be7ccf04..c1ec79a26 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -1744,28 +1744,54 @@ bool Tokenizer::simplifyConditions() if (! tok4) break; if ((tok->str() == "&&" || tok->str() == "||" || tok->str() == "(") && - Token::Match(tok->tokAt(1), "%num% %any% %num%") && + (Token::Match(tok->tokAt(1), "%num% %any% %num%") || + Token::Match(tok->tokAt(1), "%bool% %any% %bool%")) && (tok4->str() == "&&" || tok4->str() == "||" || tok4->str() == ")")) { - double op1 = (strstr(tok->strAt(1), "0x")) ? std::strtol(tok->strAt(1), 0, 16) : std::atof(tok->strAt(1)); - double op2 = (strstr(tok->strAt(3), "0x")) ? std::strtol(tok->strAt(3), 0, 16) : std::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); + if (Token::Match(tok->tokAt(1), "%num%")) + { + // Compare numbers + double op1 = (strstr(tok->strAt(1), "0x")) ? std::strtol(tok->strAt(1), 0, 16) : std::atof(tok->strAt(1)); + double op2 = (strstr(tok->strAt(3), "0x")) ? std::strtol(tok->strAt(3), 0, 16) : std::atof(tok->strAt(3)); + + 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 = ""; + } else - cmp = ""; + { + // Compare boolean + bool op1 = (tok->strAt(1) == std::string("true")); + bool op2 = (tok->strAt(3) == std::string("true")); + + 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()) { @@ -2387,36 +2413,40 @@ bool Tokenizer::elseif() bool Tokenizer::simplifyRedundantParanthesis() { + if (!createLinks()) + return false; + bool ret = false; for (Token *tok = _tokens; tok; tok = tok->next()) { - bool foundSomething = true; - while (foundSomething && Token::simpleMatch(tok, "( (")) + if (tok->str() != "(") + continue; + + while (Token::simpleMatch(tok, "( (") && + tok->link()->previous() == tok->next()->link()) { - foundSomething = false; - int parlevel = 0; + // We have "(( *something* ))", remove the inner + // paranthesis + tok->deleteNext(); + tok->link()->previous()->previous()->deleteNext(); + ret = true; + } - for (Token *tok2 = tok; tok2; tok2 = tok2->next()) - { - if (tok2->str() == "(") - ++parlevel; + if (Token::Match(tok, "( ( %bool% )") || + Token::Match(tok, "( ( %num% )")) + { + tok->tokAt(2)->deleteNext(); + tok->deleteNext(); + ret = true; + } - else if (tok2->str() == ")") - { - --parlevel; - if (parlevel == 1) - { - if (Token::simpleMatch(tok2, ") )")) - { - tok->deleteNext(); - tok2->deleteNext(); - ret = true; - foundSomething = true; - } - break; - } - } - } + if (Token::Match(tok, "( %bool% ) )") || + Token::Match(tok, "( %num% ) )")) + { + tok = tok->next(); + tok->deleteNext(); + tok->previous()->deleteThis(); + ret = true; } } return ret; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 2e7c66af0..300f4bc07 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1616,22 +1616,43 @@ private: void removeParantheses3() { - const char code[] = "void foo()\n" - "{\n" - " if (( true )==true){}\n" - "}"; + { + const char code[] = "void foo()\n" + "{\n" + " if (( true )==(true)){}\n" + "}"; - // tokenize.. - Tokenizer tokenizer; - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); + // tokenize.. + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); - tokenizer.simplifyTokenList(); + tokenizer.simplifyTokenList(); - std::ostringstream ostr; - for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) - ostr << " " << tok->str(); - TODO_ASSERT_EQUALS(std::string(" void foo ( ) { { } }"), ostr.str()); + std::ostringstream ostr; + for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) + ostr << " " << tok->str(); + ASSERT_EQUALS(std::string(" void foo ( ) { { } }"), ostr.str()); + } + + { + const char code[] = "void foo()\n" + "{\n" + " if (( 2 )==(2)){}\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 foo ( ) { { } }"), ostr.str()); + } } void simplify_numeric_condition()