Fixed #3294 (Token::Match multi compare false negative)
This commit is contained in:
parent
580fef6951
commit
5edf153602
|
@ -225,6 +225,46 @@ static bool strisop(const char str[])
|
|||
return false;
|
||||
}
|
||||
|
||||
static int multiComparePercent(const char * * haystack_p,
|
||||
const char * needle,
|
||||
bool emptyStringFound)
|
||||
{
|
||||
const char *haystack = *haystack_p;
|
||||
|
||||
if (haystack[0] == '%' && haystack[1] != '|') {
|
||||
if (haystack[1] == 'o' && // "%op%"
|
||||
haystack[2] == 'p' &&
|
||||
haystack[3] == '%') {
|
||||
if (strisop(needle))
|
||||
return 1;
|
||||
*haystack_p = haystack = haystack + 4;
|
||||
} else if (haystack[1] == 'o' && // "%or%"
|
||||
haystack[2] == 'r' &&
|
||||
haystack[3] == '%') {
|
||||
if (*needle == '|')
|
||||
return 1;
|
||||
*haystack_p = haystack = haystack + 4;
|
||||
} else if (haystack[1] == 'o' && // "%oror%"
|
||||
haystack[2] == 'r' &&
|
||||
haystack[3] == 'o' &&
|
||||
haystack[4] == 'r' &&
|
||||
haystack[5] == '%') {
|
||||
if (needle[0] == '|' && needle[1] == '|')
|
||||
return 1;
|
||||
*haystack_p = haystack = haystack + 6;
|
||||
}
|
||||
|
||||
if (*haystack == '|')
|
||||
*haystack_p = haystack = haystack + 1;
|
||||
else if (*haystack == ' ' || *haystack == '\0')
|
||||
return emptyStringFound ? 0 : -1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
int Token::multiCompare(const char *haystack, const char *needle)
|
||||
{
|
||||
if (haystack[0] == '%' && haystack[1] == 'o') {
|
||||
|
@ -271,6 +311,10 @@ int Token::multiCompare(const char *haystack, const char *needle)
|
|||
|
||||
needlePointer = needle;
|
||||
++haystack;
|
||||
|
||||
int ret = multiComparePercent(&haystack, needle, emptyStringFound);
|
||||
if (ret < 2)
|
||||
return ret;
|
||||
} else if (*haystack == ' ' || *haystack == '\0') {
|
||||
if (needlePointer == needle)
|
||||
return 0;
|
||||
|
@ -291,36 +335,9 @@ int Token::multiCompare(const char *haystack, const char *needle)
|
|||
|
||||
++haystack;
|
||||
|
||||
if (haystack[0] == '%' && haystack[1] != '|') {
|
||||
if (haystack[1] == 'o' && // "%op%"
|
||||
haystack[2] == 'p' &&
|
||||
haystack[3] == '%') {
|
||||
if (strisop(needle))
|
||||
return 1;
|
||||
haystack = haystack + 4;
|
||||
} else if (haystack[1] == 'o' && // "%or%"
|
||||
haystack[2] == 'r' &&
|
||||
haystack[3] == '%') {
|
||||
if (*needle == '|')
|
||||
return 1;
|
||||
haystack = haystack + 4;
|
||||
} else if (haystack[1] == 'o' && // "%oror%"
|
||||
haystack[2] == 'r' &&
|
||||
haystack[3] == 'o' &&
|
||||
haystack[4] == 'r' &&
|
||||
haystack[5] == '%') {
|
||||
if (needle[0] == '|' && needle[1] == '|')
|
||||
return 1;
|
||||
haystack = haystack + 6;
|
||||
}
|
||||
|
||||
if (*haystack == '|')
|
||||
haystack++;
|
||||
else if (*haystack == ' ' || *haystack == '\0')
|
||||
return emptyStringFound ? 0 : -1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
int ret = multiComparePercent(&haystack, needle, emptyStringFound);
|
||||
if (ret < 2)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,9 @@ public:
|
|||
* - "!!else" No tokens or any token that is not "else".
|
||||
* - "someRandomText" If token contains "someRandomText".
|
||||
*
|
||||
* multi-compare patterns such as "int|void|char" can contain %or%, %oror% and %op%
|
||||
* but it is not recommended to put such an %cmd% as the first pattern.
|
||||
*
|
||||
* The patterns can be also combined to compare to multiple tokens at once
|
||||
* by separating tokens with a space, e.g.
|
||||
* ") const|void {" will return true if first token is ')' next token is either
|
||||
|
|
|
@ -1869,7 +1869,10 @@ bool Tokenizer::tokenize(std::istream &code,
|
|||
|
||||
// token concatenation
|
||||
for (Token *tok = _tokens; tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "%var%|%num% ## %var%|%num%")) {
|
||||
// TODO: pattern should be "%var%|%num% ## %var%|%num%"
|
||||
if (Token::Match(tok, "%any% ## %any%") &&
|
||||
(tok->isName() || tok->isNumber()) &&
|
||||
(tok->tokAt(2)->isName() || tok->tokAt(2)->isNumber())) {
|
||||
tok->str(tok->str() + tok->strAt(2));
|
||||
tok->deleteNext();
|
||||
tok->deleteNext();
|
||||
|
|
|
@ -107,8 +107,7 @@ private:
|
|||
void multiCompare2() { // #3294
|
||||
// Original pattern that failed: [[,(=<>+-*|&^] %num% [+-*/] %num% ]|,|)|;|=|%op%
|
||||
givenACodeSampleToTokenize toks("a == 1");
|
||||
// FIXME: Result should be true
|
||||
ASSERT_EQUALS(false, Token::Match(toks.tokens(), "a =|%op%"));
|
||||
ASSERT_EQUALS(true, Token::Match(toks.tokens(), "a =|%op%"));
|
||||
}
|
||||
|
||||
void getStrLength() {
|
||||
|
|
Loading…
Reference in New Issue