Merge branch 'ref'
This commit is contained in:
commit
01c39daa13
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue