Partially fixed #4288 (handle %var%|%num% patterns).
This commit is contained in:
parent
6b8e83a181
commit
9d0a295b85
114
lib/token.cpp
114
lib/token.cpp
|
@ -530,10 +530,30 @@ int Token::firstWordLen(const char *str)
|
|||
return len;
|
||||
}
|
||||
|
||||
#define multicompare(p,cond,ismulticomp) \
|
||||
{ \
|
||||
if ((p)[0] != '|') { \
|
||||
if (!(cond)) \
|
||||
return false; \
|
||||
ismulticomp = false; \
|
||||
} else { \
|
||||
if (cond) { \
|
||||
while (*(p) && *(p) != ' ') \
|
||||
++(p); \
|
||||
ismulticomp = false; \
|
||||
} else { \
|
||||
(p) += 1; \
|
||||
ismulticomp = (*(p) && *(p) != ' '); \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
||||
{
|
||||
const char *p = pattern;
|
||||
bool firstpattern = true;
|
||||
bool ismulticomp = false;
|
||||
while (*p) {
|
||||
// Skip spaces in pattern..
|
||||
while (*p == ' ')
|
||||
|
@ -573,9 +593,8 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
|||
// work, before that change can be made.
|
||||
// Any symbolname..
|
||||
if (p[4] == '%') { // %var%
|
||||
if (!tok->isName())
|
||||
return false;
|
||||
p += 5;
|
||||
multicompare(p,tok->isName(),ismulticomp);
|
||||
patternUnderstood = true;
|
||||
} else { // %varid%
|
||||
if (varid == 0) {
|
||||
|
@ -592,16 +611,8 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
|||
case 't':
|
||||
// Type (%type%)
|
||||
{
|
||||
if (!tok->isName())
|
||||
return false;
|
||||
|
||||
if (tok->varId() != 0)
|
||||
return false;
|
||||
|
||||
if (tok->str() == "delete")
|
||||
return false;
|
||||
|
||||
p += 6;
|
||||
multicompare(p,tok->isName() && tok->varId() == 0 && tok->str() != "delete",ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
|
@ -609,98 +620,75 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
|||
// Accept any token (%any%)
|
||||
{
|
||||
p += 5;
|
||||
if (p[0] == '|')
|
||||
while (*p && *p != ' ')
|
||||
++p;
|
||||
ismulticomp = false;
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
// Number (%num%)
|
||||
{
|
||||
if (!tok->isNumber())
|
||||
return false;
|
||||
p += 5;
|
||||
multicompare(p,tok->isNumber(),ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
// Character (%char%)
|
||||
{
|
||||
if (tok->_type != eChar)
|
||||
return false;
|
||||
p += 6;
|
||||
multicompare(p,tok->_type == eChar,ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
// String (%str%)
|
||||
{
|
||||
if (tok->_str[0] != '\"')
|
||||
return false;
|
||||
p += 5;
|
||||
multicompare(p,tok->_type == eString,ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
// Bool (%bool%)
|
||||
{
|
||||
if (!tok->isBoolean())
|
||||
return false;
|
||||
p += 6;
|
||||
multicompare(p,tok->isBoolean(),ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
// Or (%or%) and Op (%op%)
|
||||
if (p[3] == '%') {
|
||||
patternUnderstood = true;
|
||||
|
||||
// multicompare..
|
||||
if (p[4] == '|') {
|
||||
int result = multiCompare(p, tok->str().c_str());
|
||||
if (result == -1)
|
||||
return false; // No match
|
||||
|
||||
while (*p && *p != ' ')
|
||||
p++;
|
||||
p += 2;
|
||||
// Or (%or%)
|
||||
if (p[0] == 'r') {
|
||||
p += 2;
|
||||
multicompare(p,tok->str() == "|",ismulticomp)
|
||||
patternUnderstood = true;
|
||||
// Op (%op%)
|
||||
} else if (p[0] == 'p') {
|
||||
p += 2;
|
||||
multicompare(p,tok->isOp(),ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
|
||||
// single compare..
|
||||
else if (p[2] == 'r') {
|
||||
if (tok->str() != "|")
|
||||
return false;
|
||||
p += 4;
|
||||
} else if (p[2] == 'p') {
|
||||
if (!tok->isOp())
|
||||
return false;
|
||||
p += 4;
|
||||
} else
|
||||
patternUnderstood = false;
|
||||
}
|
||||
|
||||
// Oror (%oror%)
|
||||
else if (p[5] == '%') {
|
||||
// multicompare..
|
||||
if (p[6] == '|') {
|
||||
int result = multiCompare(p, tok->str().c_str());
|
||||
if (result == -1)
|
||||
return false; // No match
|
||||
|
||||
while (*p && *p != ' ')
|
||||
p++;
|
||||
}
|
||||
|
||||
// single compare..
|
||||
else if (tok->str() != "||")
|
||||
return false;
|
||||
|
||||
else
|
||||
p += 6;
|
||||
|
||||
p += 6;
|
||||
multicompare(p,tok->str() == "||",ismulticomp);
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (firstWordEquals(p, tok->_str.c_str())) {
|
||||
p += tok->_str.length();
|
||||
if (p[0] == '|') {
|
||||
while (*p && *p != ' ')
|
||||
p++;
|
||||
}
|
||||
patternUnderstood = true;
|
||||
}
|
||||
break;
|
||||
|
@ -710,13 +698,15 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
|||
return false;
|
||||
}
|
||||
|
||||
// debugging: assert that this is not part of a multicompare pattern..
|
||||
assert(*p != '|');
|
||||
|
||||
tok = tok->next();
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (ismulticomp) {
|
||||
ismulticomp = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// [.. => search for a one-character token..
|
||||
else if (p[0] == '[' && chrInFirstWord(p, ']')) {
|
||||
if (tok->_str.length() != 1)
|
||||
|
|
|
@ -137,14 +137,15 @@ public:
|
|||
* 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.
|
||||
*
|
||||
* It's possible to use multi-compare patterns with just %cmds%, except for %varid%.
|
||||
* For example: "%var%|%num%| " means yes to a variable, a number or empty string.
|
||||
*
|
||||
* 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
|
||||
* "const" or "void" and token after that is '{'. If even one of the tokens does not
|
||||
* match its pattern, false is returned.
|
||||
*
|
||||
* @todo pattern "%type%|%num%" should mean either a type or a num.
|
||||
*
|
||||
* @param tok List of tokens to be compared to the pattern
|
||||
* @param pattern The pattern against which the tokens are compared,
|
||||
* e.g. "const" or ") const|volatile| {".
|
||||
|
|
|
@ -172,6 +172,32 @@ private:
|
|||
ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%var% >>|<<|&|%or%|^|% %var% ;"));
|
||||
ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%var% %|>>|<<|&|%or%|^ %var% ;"));
|
||||
ASSERT_EQUALS(true, Token::Match(toks4.tokens(), "%var% >>|<<|&|%or%|%|^ %var% ;"));
|
||||
|
||||
//%var%|%num% support
|
||||
givenACodeSampleToTokenize num("100", true);
|
||||
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%num%|%var%"));
|
||||
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%var%|%num%"));
|
||||
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%var%|%num%|%bool%"));
|
||||
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%var%|%bool%|%num%"));
|
||||
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%var%|%bool%|%str%|%num%"));
|
||||
ASSERT_EQUALS(false, Token::Match(num.tokens(), "%bool%|%var%"));
|
||||
ASSERT_EQUALS(false, Token::Match(num.tokens(), "%type%|%bool%|%char%"));
|
||||
ASSERT_EQUALS(true, Token::Match(num.tokens(), "%type%|%bool%|100"));
|
||||
|
||||
givenACodeSampleToTokenize numparen("( 100 )", true);
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %num%|%var% )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %var%|%num% )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %var%|%num%|%bool% )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %var%|%bool%|%num% )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| %var%|%bool%|%str%|%num% )|"));
|
||||
ASSERT_EQUALS(false, Token::Match(numparen.tokens(), "(| %bool%|%var% )|"));
|
||||
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %num%|%var%| )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %var%|%num%| )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %var%|%num%|%bool%| )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %var%|%bool%|%num%| )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %var%|%bool%|%str%|%num%| )|"));
|
||||
ASSERT_EQUALS(true, Token::Match(numparen.tokens(), "(| 100 %bool%|%var%| )|"));
|
||||
}
|
||||
|
||||
void getStrLength() {
|
||||
|
|
Loading…
Reference in New Issue