TOKEN: Match() function improved, %any% and const|volatile kind of patterns are now accepted. Simplified comparing on tokenize.cpp.
This commit is contained in:
parent
3820a26e1c
commit
c958482196
|
@ -47,6 +47,8 @@ private:
|
|||
TEST_CASE( const_and_volatile_functions );
|
||||
|
||||
TEST_CASE( numeric_true_condition );
|
||||
|
||||
TEST_CASE( multi_compare );
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,6 +210,23 @@ private:
|
|||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS( std::string(" void f ( ) { if ( true ) ; }"), ostr.str() );
|
||||
}
|
||||
|
||||
void multi_compare()
|
||||
{
|
||||
// Test for found
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "one|two", "one" ), 1 );
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "one|two", "two" ), 1 );
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "verybig|two|", "two" ), 1 );
|
||||
|
||||
// Test for empty string found
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "|one|two", "notfound" ), 0 );
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "one||two", "notfound" ), 0 );
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "one|two|", "notfound" ), 0 );
|
||||
|
||||
// Test for not found
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "one|two", "notfound" ), -1 );
|
||||
ASSERT_EQUALS( TOKEN::multiCompare( "verybig|two", "s" ), -1 );
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST( TestTokenizer )
|
||||
|
|
53
token.cpp
53
token.cpp
|
@ -90,6 +90,37 @@ const char *TOKEN::strAt(int index) const
|
|||
return tok ? tok->_cstr : "";
|
||||
}
|
||||
|
||||
int TOKEN::multiCompare( const char *needle, const char *haystack )
|
||||
{
|
||||
bool emptyStringFound = false;
|
||||
bool findNextOr = false;
|
||||
for( ; *needle; ++needle )
|
||||
{
|
||||
if( *needle == '|' )
|
||||
{
|
||||
if( findNextOr )
|
||||
findNextOr = false;
|
||||
else
|
||||
emptyStringFound = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this part of needle equals to the haystack
|
||||
else if( strncmp( haystack, needle, strlen( haystack ) ) == 0 )
|
||||
return 1;
|
||||
else
|
||||
findNextOr = true;
|
||||
}
|
||||
|
||||
// If empty string was found or if last character in needle was '|'
|
||||
if( emptyStringFound || findNextOr == false )
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool TOKEN::Match(const TOKEN *tok, const char pattern[], const char *varname1[], const char *varname2[])
|
||||
{
|
||||
if (!tok)
|
||||
|
@ -124,6 +155,12 @@ bool TOKEN::Match(const TOKEN *tok, const char pattern[], const char *varname1[]
|
|||
return false;
|
||||
}
|
||||
|
||||
// Accept any token
|
||||
else if (strcmp(str,"%any%")==0 )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Variable name..
|
||||
else if (strcmp(str,"%var1%")==0 || strcmp(str,"%var2%")==0)
|
||||
{
|
||||
|
@ -171,6 +208,22 @@ bool TOKEN::Match(const TOKEN *tok, const char pattern[], const char *varname1[]
|
|||
return false;
|
||||
}
|
||||
|
||||
// Parse multi options, such as void|int|char (accept token which is one of these 3)
|
||||
else if ( strchr(str, '|') && strlen( str ) > 2 )
|
||||
{
|
||||
int res = multiCompare( str, tok->_cstr );
|
||||
if( res == 0 )
|
||||
{
|
||||
// Empty alternative matches, use the same token on next round
|
||||
continue;
|
||||
}
|
||||
else if( res == 2 )
|
||||
{
|
||||
// No match
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else if (str != tok->_str)
|
||||
return false;
|
||||
|
||||
|
|
43
token.h
43
token.h
|
@ -61,13 +61,56 @@ public:
|
|||
|
||||
const char *strAt(int index) const;
|
||||
|
||||
/**
|
||||
* Match given token (or list of tokens) to a pattern list.
|
||||
*
|
||||
* Possible patterns
|
||||
* "%any%" any token
|
||||
* "%var%" any token which is a name or type e.g. "hello" or "int"
|
||||
* "%num%" Any numeric token, e.g. "23"
|
||||
* "%str%" Any token starting with "-character (C-string).
|
||||
* "[abc]" Any of the characters 'a' or 'b' or 'c'
|
||||
* "int|void|char" Any of the strings, int, void or char
|
||||
* "int|void|char|" Any of the strings, int, void or char or empty string
|
||||
* "someRandomText" If token contains "someRandomText".
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param tok List of tokens to be compared to the pattern
|
||||
* @param pattern The pattern where tokens are compared, e.g. "const"
|
||||
* or ") const|volatile| {".
|
||||
* @param varname1 Used with pattern "%var1%" and "%var2%"
|
||||
* @param varname2 Used with pattern "%var1%" and "%var2%"
|
||||
* @return true if given token matches with given pattern
|
||||
* false if given token does not match with given pattern
|
||||
*/
|
||||
static bool Match(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
|
||||
bool isName() const;
|
||||
bool isNumber() const;
|
||||
bool isStandardType() const;
|
||||
static const TOKEN *findmatch(const TOKEN *tok, const char pattern[], const char *varname1[]=0, const char *varname2[]=0);
|
||||
static const TOKEN *findtoken(const TOKEN *tok1, const char *tokenstr[]);
|
||||
|
||||
/**
|
||||
* Needle is build from multiple alternatives. If one of
|
||||
* them is equal to haystack, return value is 1. If there
|
||||
* are no matches, but one alternative to needle is empty
|
||||
* string, return value is 0. If needle was not found, return
|
||||
* value is -1.
|
||||
*
|
||||
* @param needle e.g. "one|two" or "|one|two"
|
||||
* @param haystack 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 *needle, const char *haystack );
|
||||
|
||||
unsigned int FileIndex;
|
||||
unsigned int linenr;
|
||||
TOKEN *next;
|
||||
|
|
12
tokenize.cpp
12
tokenize.cpp
|
@ -1117,17 +1117,7 @@ void Tokenizer::fillFunctionList()
|
|||
|
||||
else if ( tok2->aaaa0() == ')' )
|
||||
{
|
||||
if ( TOKEN::Match(tok2, ") {") )
|
||||
{
|
||||
_functionList.push_back( tok );
|
||||
tok = tok2;
|
||||
}
|
||||
else if ( TOKEN::Match(tok2, ") const {") )
|
||||
{
|
||||
_functionList.push_back( tok );
|
||||
tok = tok2;
|
||||
}
|
||||
else if ( TOKEN::Match(tok2, ") volatile {") )
|
||||
if ( TOKEN::Match(tok2, ") const|volatile| {") )
|
||||
{
|
||||
_functionList.push_back( tok );
|
||||
tok = tok2;
|
||||
|
|
Loading…
Reference in New Issue