TOKEN: Match() function improved, %any% and const|volatile kind of patterns are now accepted. Simplified comparing on tokenize.cpp.

This commit is contained in:
Reijo Tomperi 2008-12-04 21:48:15 +00:00
parent 3820a26e1c
commit c958482196
4 changed files with 126 additions and 21 deletions

View File

@ -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 )

View File

@ -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
View File

@ -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;

View File

@ -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;