diff --git a/lib/token.cpp b/lib/token.cpp index 940bb7f09..7dc9abc7b 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -200,8 +200,37 @@ std::string Token::strAt(int index) const return tok ? tok->_str.c_str() : ""; } +static bool strisop(const char str[]) +{ + if (str[1] == 0) + { + if (strchr("+-*/%&|^~!<>", *str)) + return true; + } + else if (str[2] == 0) + { + if (strcmp(str, "&&")==0 || + strcmp(str, "||")==0 || + strcmp(str, "==")==0 || + strcmp(str, "!=")==0 || + strcmp(str, ">=")==0 || + strcmp(str, "<=")==0 || + strcmp(str, ">>")==0 || + strcmp(str, "<<")==0) + return true; + } + return false; +} + int Token::multiCompare(const char *haystack, const char *needle) { + if (strncmp(haystack, "%op%|", 5) == 0) + { + haystack = haystack + 5; + if (strisop(needle)) + return 1; + } + bool emptyStringFound = false; const char *needlePointer = needle; while (true) @@ -254,6 +283,19 @@ int Token::multiCompare(const char *haystack, const char *needle) } ++haystack; + + if (strncmp(haystack, "%op%", 4) == 0) + { + if (strisop(needle)) + return 1; + haystack = haystack + 4; + if (*haystack == '|') + haystack++; + else if (*haystack == ' ' || *haystack == '\0') + return emptyStringFound ? 0 : -1; + else + return -1; + } } } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 073030c79..632f6a0ce 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2075,7 +2075,7 @@ bool Tokenizer::tokenize(std::istream &code, // Combine "- %num%" .. for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "%any% - %num%") && (tok->isOp() || Token::Match(tok, "?|:|,|(|[|=|return|case"))) + if (Token::Match(tok, "?|:|,|(|[|=|return|case|%op% - %num%")) { tok->next()->str("-" + tok->strAt(2)); tok->next()->deleteNext(); @@ -5594,12 +5594,10 @@ bool Tokenizer::simplifyFunctionReturn() else if (indentlevel == 0 && Token::Match(tok, "%var% ( ) { return %num% ; }") && tok->str() != ")") { - const std::string pattern("%any% " + tok->str() + " ( ) %any%"); + const std::string pattern("(|[|=|%op% " + tok->str() + " ( ) ;|]|)|%op%"); for (Token *tok2 = _tokens; tok2; tok2 = tok2->next()) { - if (Token::Match(tok2, pattern.c_str()) && - (tok2->isOp() || Token::Match(tok2, "(|[|=")) && - (tok2->tokAt(4)->isOp() || Token::Match(tok2->tokAt(4), ";|]|)"))) + if (Token::Match(tok2, pattern.c_str())) { tok2 = tok2->next(); tok2->str(tok->strAt(5)); diff --git a/test/testtoken.cpp b/test/testtoken.cpp index 7be587ff3..8897cf7f5 100644 --- a/test/testtoken.cpp +++ b/test/testtoken.cpp @@ -89,6 +89,12 @@ private: ASSERT_EQUALS(static_cast(-1), static_cast(Token::multiCompare("abc|def", "a"))); ASSERT_EQUALS(static_cast(-1), static_cast(Token::multiCompare("abc|def", "abcd"))); ASSERT_EQUALS(static_cast(-1), static_cast(Token::multiCompare("abc|def", "default"))); + + // %op% + ASSERT_EQUALS(1, Token::multiCompare("one|%op%", "+")); + ASSERT_EQUALS(1, Token::multiCompare("%op%|two", "+")); + ASSERT_EQUALS(-1, Token::multiCompare("one|%op%", "x")); + ASSERT_EQUALS(-1, Token::multiCompare("%op%|two", "x")); } void getStrLength()