Properly implement %op% for Token::multiCompare
Use tok->isOp() instead of doing it "manually". This fixes false positives for the C++ template case since the brackets in "template < something >" are not comparison operators. Profiling showed using tok->isOp() is actually faster than before (-O2).
This commit is contained in:
parent
8b2adf1391
commit
7dd07d8e77
|
@ -296,26 +296,7 @@ const std::string &Token::strAt(int index) const
|
|||
return tok ? tok->_str : empty_str;
|
||||
}
|
||||
|
||||
static bool strisop(const char str[])
|
||||
{
|
||||
if (str[1] == 0) {
|
||||
if (std::strchr("+-*/%&|^~!<>", *str))
|
||||
return true;
|
||||
} else if (str[2] == 0) {
|
||||
if ((str[0] == '&' && str[1] == '&') ||
|
||||
(str[0] == '|' && str[1] == '|') ||
|
||||
(str[0] == '=' && str[1] == '=') ||
|
||||
(str[0] == '!' && str[1] == '=') ||
|
||||
(str[0] == '>' && str[1] == '=') ||
|
||||
(str[0] == '<' && str[1] == '=') ||
|
||||
(str[0] == '>' && str[1] == '>') ||
|
||||
(str[0] == '<' && str[1] == '<'))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int multiComparePercent(const char * * haystack_p,
|
||||
static int multiComparePercent(const Token *tok, const char * * haystack_p,
|
||||
const char * needle,
|
||||
bool emptyStringFound)
|
||||
{
|
||||
|
@ -325,7 +306,7 @@ static int multiComparePercent(const char * * haystack_p,
|
|||
if (haystack[1] == 'o' && // "%op%"
|
||||
haystack[2] == 'p' &&
|
||||
haystack[3] == '%') {
|
||||
if (strisop(needle))
|
||||
if (tok->isOp())
|
||||
return 1;
|
||||
*haystack_p = haystack = haystack + 4;
|
||||
} else if (haystack[1] == 'o' && // "%or%"
|
||||
|
@ -355,14 +336,14 @@ static int multiComparePercent(const char * * haystack_p,
|
|||
return 0xFFFF;
|
||||
}
|
||||
|
||||
int Token::multiCompare(const char *haystack, const char *needle)
|
||||
int Token::multiCompare(const Token *tok, const char *haystack, const char *needle)
|
||||
{
|
||||
if (haystack[0] == '%' && haystack[1] == 'o') {
|
||||
if (haystack[2] == 'p' && // "%op%|"
|
||||
haystack[3] == '%' &&
|
||||
haystack[4] == '|') {
|
||||
haystack = haystack + 5;
|
||||
if (strisop(needle))
|
||||
if (tok->isOp())
|
||||
return 1;
|
||||
} else if (haystack[2] == 'r' && // "%or%|"
|
||||
haystack[3] == '%' &&
|
||||
|
@ -402,7 +383,7 @@ int Token::multiCompare(const char *haystack, const char *needle)
|
|||
needlePointer = needle;
|
||||
++haystack;
|
||||
|
||||
int ret = multiComparePercent(&haystack, needle, emptyStringFound);
|
||||
int ret = multiComparePercent(tok, &haystack, needle, emptyStringFound);
|
||||
if (ret < 2)
|
||||
return ret;
|
||||
} else if (*haystack == ' ' || *haystack == '\0') {
|
||||
|
@ -425,7 +406,7 @@ int Token::multiCompare(const char *haystack, const char *needle)
|
|||
|
||||
++haystack;
|
||||
|
||||
int ret = multiComparePercent(&haystack, needle, emptyStringFound);
|
||||
int ret = multiComparePercent(tok, &haystack, needle, emptyStringFound);
|
||||
if (ret < 2)
|
||||
return ret;
|
||||
}
|
||||
|
@ -711,7 +692,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
|||
|
||||
// Parse multi options, such as void|int|char (accept token which is one of these 3)
|
||||
else if (chrInFirstWord(p, '|') && (p[0] != '|' || firstWordLen(p) > 2)) {
|
||||
int res = multiCompare(p, tok->_str.c_str());
|
||||
int res = multiCompare(tok, p, tok->_str.c_str());
|
||||
if (res == 0) {
|
||||
// Empty alternative matches, use the same token on next round
|
||||
while (*p && *p != ' ')
|
||||
|
|
|
@ -279,13 +279,14 @@ public:
|
|||
* string, return value is 0. If needle was not found, return
|
||||
* value is -1.
|
||||
*
|
||||
* @param tok Current token
|
||||
* @param haystack e.g. "one|two" or "|one|two"
|
||||
* @param needle e.g. "one", "two" or "invalid"
|
||||
* @return 1 if needle is found from the haystack
|
||||
* 0 if needle was empty string
|
||||
* -1 if needle was not found
|
||||
*/
|
||||
static int multiCompare(const char *haystack, const char *needle);
|
||||
static int multiCompare(const Token *tok, const char *haystack, const char *needle);
|
||||
|
||||
unsigned int linenr() const {
|
||||
return _linenr;
|
||||
|
|
|
@ -120,28 +120,54 @@ private:
|
|||
|
||||
void multiCompare() {
|
||||
// Test for found
|
||||
ASSERT_EQUALS(1, Token::multiCompare("one|two", "one"));
|
||||
ASSERT_EQUALS(1, Token::multiCompare("one|two", "two"));
|
||||
ASSERT_EQUALS(1, Token::multiCompare("verybig|two|", "two"));
|
||||
Token *one = new Token(0);
|
||||
one->str("one");
|
||||
ASSERT_EQUALS(1, Token::multiCompare(one, "one|two", "one"));
|
||||
|
||||
Token *two = new Token(0);
|
||||
two->str("two");
|
||||
ASSERT_EQUALS(1, Token::multiCompare(two, "one|two", "two"));
|
||||
ASSERT_EQUALS(1, Token::multiCompare(two, "verybig|two|", "two"));
|
||||
|
||||
// Test for empty string found
|
||||
ASSERT_EQUALS(0, Token::multiCompare("|one|two", "notfound"));
|
||||
ASSERT_EQUALS(0, Token::multiCompare("one||two", "notfound"));
|
||||
ASSERT_EQUALS(0, Token::multiCompare("one|two|", "notfound"));
|
||||
Token *notfound = new Token(0);
|
||||
notfound->str("notfound");
|
||||
ASSERT_EQUALS(0, Token::multiCompare(notfound, "|one|two", "notfound"));
|
||||
ASSERT_EQUALS(0, Token::multiCompare(notfound, "one||two", "notfound"));
|
||||
ASSERT_EQUALS(0, Token::multiCompare(notfound, "one|two|", "notfound"));
|
||||
|
||||
// Test for not found
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare("one|two", "notfound")));
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare("verybig|two", "s")));
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare("one|two", "ne")));
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare("abc|def", "a")));
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare("abc|def", "abcd")));
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare("abc|def", "default")));
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(notfound, "one|two", "notfound")));
|
||||
|
||||
Token *s = new Token(0);
|
||||
s->str("s");
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(s, "verybig|two", "s")));
|
||||
|
||||
Token *ne = new Token(0);
|
||||
ne->str("ne");
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(ne, "one|two", "ne")));
|
||||
|
||||
Token *a = new Token(0);
|
||||
a->str("a");
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(a, "abc|def", "a")));
|
||||
|
||||
Token *abcd = new Token(0);
|
||||
abcd->str("abcd");
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(abcd, "abc|def", "abcd")));
|
||||
|
||||
Token *def = new Token(0);
|
||||
def->str("default");
|
||||
ASSERT_EQUALS(static_cast<unsigned int>(-1), static_cast<unsigned int>(Token::multiCompare(def, "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"));
|
||||
Token *plus = new Token(0);
|
||||
plus->str("+");
|
||||
ASSERT_EQUALS(1, Token::multiCompare(plus, "one|%op%", "+"));
|
||||
ASSERT_EQUALS(1, Token::multiCompare(plus, "%op%|two", "+"));
|
||||
Token *x = new Token(0);
|
||||
x->str("x");
|
||||
ASSERT_EQUALS(-1, Token::multiCompare(x, "one|%op%", "x"));
|
||||
ASSERT_EQUALS(-1, Token::multiCompare(x, "%op%|two", "x"));
|
||||
}
|
||||
|
||||
void multiCompare2() { // #3294
|
||||
|
@ -209,7 +235,8 @@ private:
|
|||
ASSERT_EQUALS(Token::eBracket, var.tokens()->tokAt(5)->type());
|
||||
|
||||
ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue %op%"));
|
||||
TODO_ASSERT_EQUALS(false, true, Token::Match(var.tokens(), "std :: queue x|%op%"));
|
||||
ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue x|%op%"));
|
||||
ASSERT_EQUALS(false, Token::Match(var.tokens(), "std :: queue %op%|x"));
|
||||
}
|
||||
|
||||
void getStrLength() {
|
||||
|
|
Loading…
Reference in New Issue