Merge branch 'ref'

This commit is contained in:
Daniel Marjamäki 2009-03-13 22:39:47 +01:00
commit 01c39daa13
5 changed files with 129 additions and 88 deletions

View File

@ -115,90 +115,6 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1)
}
//---------------------------------------------------------------------------
const Token * CheckClass::FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel)
{
if (indentlevel < 0 || tok == NULL)
return NULL;
std::ostringstream classPattern;
classPattern << "class " << classname << " :|{";
std::ostringstream internalPattern;
internalPattern << funcname << " (";
std::ostringstream externalPattern;
externalPattern << classname << " :: " << funcname << " (";
for (;tok; tok = tok->next())
{
if (indentlevel == 0 && Token::Match(tok, classPattern.str().c_str()))
{
while (tok && tok->str() != "{")
tok = tok->next();
if (tok)
tok = tok->next();
if (! tok)
break;
indentlevel = 1;
}
if (tok->str() == "{")
{
// If indentlevel==0 don't go to indentlevel 1. Skip the block.
if (indentlevel > 0)
++indentlevel;
else
{
for (; tok; tok = tok->next())
{
if (tok->str() == "{")
++indentlevel;
else if (tok->str() == "}")
{
--indentlevel;
if (indentlevel <= 0)
break;
}
}
if (tok == NULL)
return NULL;
continue;
}
}
if (tok->str() == "}")
{
--indentlevel;
if (indentlevel < 0)
return NULL;
}
if (indentlevel == 1)
{
// Member function implemented in the class declaration?
if (tok->str() != "~" && Token::Match(tok->next(), internalPattern.str().c_str()))
{
const Token *tok2 = tok->next();
while (tok2 && tok2->str() != "{" && tok2->str() != ";")
tok2 = tok2->next();
if (tok2 && tok2->str() == "{")
return tok->next();
}
}
else if (indentlevel == 0 && Token::Match(tok, externalPattern.str().c_str()))
{
return tok;
}
}
// Not found
return NULL;
}
//---------------------------------------------------------------------------
void CheckClass::InitVar(struct VAR *varlist, const char varname[])
{
for (struct VAR *var = varlist; var; var = var->next)
@ -295,7 +211,7 @@ void CheckClass::ClassChecking_VarList_Initialize(const Token *tok1, const Token
{
callstack.push_back(ftok->str());
int i = 0;
const Token *ftok2 = FindClassFunction(tok1, classname, ftok->aaaa(), i);
const Token *ftok2 = Tokenizer::FindClassFunction(tok1, classname, ftok->aaaa(), i);
ClassChecking_VarList_Initialize(tok1, ftok2, varlist, classname, callstack);
}
}
@ -438,7 +354,7 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
const char * const className = tok1->strAt(1);
int indentlevel = 0;
const Token *constructor_token = FindClassFunction(tok1, className, funcname, indentlevel);
const Token *constructor_token = Tokenizer::FindClassFunction(tok1, className, funcname, indentlevel);
std::list<std::string> callstack;
ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack);
while (constructor_token)
@ -462,7 +378,7 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
for (struct VAR *var = varlist; var; var = var->next)
var->init = false;
constructor_token = FindClassFunction(constructor_token->next(), className, funcname, indentlevel);
constructor_token = Tokenizer::FindClassFunction(constructor_token->next(), className, funcname, indentlevel);
callstack.clear();
ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack);
}

View File

@ -60,7 +60,6 @@ private:
void ClassChecking_VarList_Initialize(const Token *tok1, const Token *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack);
void InitVar(struct VAR *varlist, const char varname[]);
const Token *FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
struct VAR *ClassChecking_GetVarList(const Token *tok1);
// Check constructors for a specified class

View File

@ -2104,3 +2104,90 @@ std::string Tokenizer::file(const Token *tok) const
}
//---------------------------------------------------------------------------
const Token * Tokenizer::FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel)
{
if (indentlevel < 0 || tok == NULL)
return NULL;
std::ostringstream classPattern;
classPattern << "class " << classname << " :|{";
std::ostringstream internalPattern;
internalPattern << funcname << " (";
std::ostringstream externalPattern;
externalPattern << classname << " :: " << funcname << " (";
for (;tok; tok = tok->next())
{
if (indentlevel == 0 && Token::Match(tok, classPattern.str().c_str()))
{
while (tok && tok->str() != "{")
tok = tok->next();
if (tok)
tok = tok->next();
if (! tok)
break;
indentlevel = 1;
}
if (tok->str() == "{")
{
// If indentlevel==0 don't go to indentlevel 1. Skip the block.
if (indentlevel > 0)
++indentlevel;
else
{
for (; tok; tok = tok->next())
{
if (tok->str() == "{")
++indentlevel;
else if (tok->str() == "}")
{
--indentlevel;
if (indentlevel <= 0)
break;
}
}
if (tok == NULL)
return NULL;
continue;
}
}
if (tok->str() == "}")
{
--indentlevel;
if (indentlevel < 0)
return NULL;
}
if (indentlevel == 1)
{
// Member function implemented in the class declaration?
if (tok->str() != "~" && Token::Match(tok->next(), internalPattern.str().c_str()))
{
const Token *tok2 = tok->next();
while (tok2 && tok2->str() != "{" && tok2->str() != ";")
tok2 = tok2->next();
if (tok2 && tok2->str() == "{")
return tok->next();
}
}
else if (indentlevel == 0 && Token::Match(tok, externalPattern.str().c_str()))
{
return tok;
}
}
// Not found
return NULL;
}
//---------------------------------------------------------------------------

View File

@ -77,6 +77,17 @@ public:
std::string file(const Token *tok) const;
/**
* Find a class member function
* @param tok where to begin the search
* @param classname name of class
* @param funcname name of function ("~ Fred" => destructor for fred, "%var%" => any function)
* @param indentlevel Just an integer that you initialize to 0 before the first call.
* @return First matching token or NULL.
*/
static const Token *FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
protected:
/** Add braces to an if-block

View File

@ -119,6 +119,8 @@ private:
TEST_CASE(tokenize_strings);
TEST_CASE(simplify_constants);
TEST_CASE(simplify_constants2);
TEST_CASE(findClassFunction1);
}
@ -1258,6 +1260,32 @@ private:
oss << " void f ( Foo & foo , Foo * foo2 ) { const int a = 45 ; foo . a = 90 ; foo2 . a = 45 ; }";
ASSERT_EQUALS(oss.str(), ostr.str());
}
void findClassFunction1()
{
const char code[] =
"class Fred"
"{\n"
"public:\n"
" Fred()\n"
" { }\n"
"};\n";
// tokenize..
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
int i;
i = 0;
const Token *tok = Tokenizer::FindClassFunction(tokenizer.tokens(), "Fred", "%var%", i);
ASSERT_EQUALS(true, Token::simpleMatch(tok, "Fred ( ) {"));
tok = Tokenizer::FindClassFunction(tok->next(), "Fred", "%var%", i);
ASSERT_EQUALS(0, (int)tok);
}
};
REGISTER_TEST(TestTokenizer)