diff --git a/src/tokenize.cpp b/src/tokenize.cpp index d1dfe0f71..507c8d508 100644 --- a/src/tokenize.cpp +++ b/src/tokenize.cpp @@ -484,6 +484,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[]) // Handle templates.. simplifyTemplates(); + // Simplify the operator "?:" + simplifyConditionOperator(); + // change array to pointer.. for (Token *tok = _tokens; tok; tok = tok->next()) { @@ -1753,6 +1756,47 @@ bool Tokenizer::simplifyIfAddBraces() return ret; } +bool Tokenizer::simplifyConditionOperator() +{ + bool ret = false; + int parlevel = 0; + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (tok->str() == "(") + ++parlevel; + else if (tok->str() == ")") + --parlevel; + else if (parlevel == 0 && Token::Match(tok, "; %var% = %var% ? %var% : %var% ;")) + { + const std::string var(tok->strAt(1)); + const std::string condition(tok->strAt(3)); + const std::string value1(tok->strAt(5)); + const std::string value2(tok->strAt(7)); + + Token::eraseTokens(tok, tok->tokAt(8)); + + std::string str("if ( " + condition + " ) " + var + " = " + value1 + " ; else " + var + " = " + value2); + std::string::size_type pos1 = 0; + while (pos1 != std::string::npos) + { + std::string::size_type pos2 = str.find(" ", pos1); + if (pos2 == std::string::npos) + { + tok->insertToken(str.substr(pos1).c_str()); + pos1 = pos2; + } + else + { + tok->insertToken(str.substr(pos1, pos2-pos1).c_str()); + pos1 = pos2 + 1; + } + tok = tok->next(); + } + } + } + return ret; +} + bool Tokenizer::simplifyConditions() { bool ret = false; diff --git a/src/tokenize.h b/src/tokenize.h index 9f3707063..1e77536d9 100644 --- a/src/tokenize.h +++ b/src/tokenize.h @@ -200,6 +200,13 @@ private: void addtoken(const char str[], const unsigned int lineno, const unsigned int fileno); + /** + * Simplify the operator "?:" + * @return true if something is modified + * false if nothing is done. + */ + bool simplifyConditionOperator(); + /** Simplify conditions * @return true if something is modified * false if nothing is done. diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index c3b13c630..aaa7015df 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -111,6 +111,9 @@ private: TEST_CASE(not1); TEST_CASE(comma_keyword); TEST_CASE(remove_comma); + + // Simplify "?:" + TEST_CASE(conditionOperator); } std::string tok(const char code[]) @@ -1045,6 +1048,12 @@ private: ASSERT_EQUALS(" void f ( ) { A a ; A b ; if ( a . f ) { a . f = b . f ; a . g = b . g ; } }", sizeof_(code)); } } + + void conditionOperator() + { + const char code[] = "; x = a ? b : c;"; + ASSERT_EQUALS("; if ( a ) { x = b ; } else { x = c ; }", tok(code)); + } }; REGISTER_TEST(TestSimplifyTokens)