Fixed ticket 184 (Tokenizer - Simplification: Split up variable declarations)
This commit is contained in:
parent
2fb4c52728
commit
f37dd4f143
239
src/tokenize.cpp
239
src/tokenize.cpp
|
@ -478,6 +478,8 @@ void Tokenizer::tokenize(std::istream &code, const char FileName[])
|
|||
}
|
||||
}
|
||||
|
||||
simplifyVarDecl();
|
||||
|
||||
// Handle templates..
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
|
@ -1109,116 +1111,8 @@ void Tokenizer::simplifyTokenList()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Split up variable declarations if possible..
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
if (! Token::Match(tok, "[{};]"))
|
||||
continue;
|
||||
|
||||
Token *type0 = tok->next();
|
||||
if (!Token::Match(type0, "%type%"))
|
||||
continue;
|
||||
if (Token::Match(type0, "else|return"))
|
||||
continue;
|
||||
|
||||
Token *tok2 = NULL;
|
||||
unsigned int typelen = 0;
|
||||
|
||||
if (Token::Match(type0, "%type% %var% ,|="))
|
||||
{
|
||||
if (type0->next()->str() != "operator")
|
||||
{
|
||||
tok2 = type0->tokAt(2); // The ',' or '=' token
|
||||
typelen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (Token::Match(type0, "%type% * %var% ,|="))
|
||||
{
|
||||
if (type0->next()->next()->str() != "operator")
|
||||
{
|
||||
tok2 = type0->tokAt(3); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (Token::Match(type0, "%type% %var% [ %num% ] ,"))
|
||||
{
|
||||
tok2 = type0->tokAt(5); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if (Token::Match(type0, "%type% * %var% [ %num% ] ,"))
|
||||
{
|
||||
tok2 = type0->tokAt(6); // The ',' token
|
||||
typelen = 1;
|
||||
}
|
||||
|
||||
else if (Token::Match(type0, "struct %type% %var% ,|="))
|
||||
{
|
||||
tok2 = type0->tokAt(3);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
else if (Token::Match(type0, "struct %type% * %var% ,|="))
|
||||
{
|
||||
tok2 = type0->tokAt(4);
|
||||
typelen = 2;
|
||||
}
|
||||
|
||||
|
||||
if (tok2)
|
||||
{
|
||||
if (tok2->str() == ",")
|
||||
{
|
||||
tok2->str(";");
|
||||
InsertTokens(tok2, type0, typelen);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Token *eq = tok2;
|
||||
|
||||
int parlevel = 0;
|
||||
while (tok2)
|
||||
{
|
||||
if (strchr("{(", tok2->aaaa0()))
|
||||
{
|
||||
++parlevel;
|
||||
}
|
||||
|
||||
else if (strchr("})", tok2->aaaa0()))
|
||||
{
|
||||
if (parlevel < 0)
|
||||
break;
|
||||
--parlevel;
|
||||
}
|
||||
|
||||
else if (parlevel == 0 && strchr(";,", tok2->aaaa0()))
|
||||
{
|
||||
// "type var =" => "type var; var ="
|
||||
Token *VarTok = type0->tokAt(typelen);
|
||||
if (VarTok->aaaa0() == '*')
|
||||
VarTok = VarTok->next();
|
||||
InsertTokens(eq, VarTok, 2);
|
||||
eq->str(";");
|
||||
|
||||
// "= x, " => "= x; type "
|
||||
if (tok2->str() == ",")
|
||||
{
|
||||
tok2->str(";");
|
||||
InsertTokens(tok2, type0, typelen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Simplify variable declarations
|
||||
simplifyVarDecl();
|
||||
|
||||
// In case variable declarations have been updated...
|
||||
setVarId();
|
||||
|
@ -1787,6 +1681,131 @@ static void incdec(std::string &value, const std::string &op)
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool Tokenizer::simplifyVarDecl()
|
||||
{
|
||||
// Split up variable declarations..
|
||||
// "int a=4;" => "int a; a=4;"
|
||||
bool ret = false;
|
||||
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
if (tok->previous() && !Token::Match(tok->previous(), "[{};)]"))
|
||||
continue;
|
||||
|
||||
Token *type0 = tok;
|
||||
if (!Token::Match(type0, "%type%"))
|
||||
continue;
|
||||
if (Token::Match(type0, "else|return"))
|
||||
continue;
|
||||
|
||||
bool isconst = false;
|
||||
Token *tok2 = type0;
|
||||
unsigned int typelen = 1;
|
||||
|
||||
while (Token::Match(tok2, "%type% %type% *| %var%"))
|
||||
{
|
||||
if (tok2->str() == "const")
|
||||
isconst = true;
|
||||
|
||||
tok2 = tok2->next();
|
||||
++typelen;
|
||||
}
|
||||
|
||||
// Don't split up const declaration..
|
||||
if (isconst && Token::Match(tok2, "%type% %var% ="))
|
||||
continue;
|
||||
|
||||
if (Token::Match(tok2, "%type% %var% ,|="))
|
||||
{
|
||||
if (tok2->next()->str() != "operator")
|
||||
tok2 = tok2->tokAt(2); // The ',' or '=' token
|
||||
else
|
||||
tok2 = NULL;
|
||||
}
|
||||
|
||||
else if (Token::Match(tok2, "%type% * %var% ,|="))
|
||||
{
|
||||
if (tok2->next()->next()->str() != "operator")
|
||||
tok2 = tok2->tokAt(3); // The ',' token
|
||||
else
|
||||
tok2 = NULL;
|
||||
}
|
||||
|
||||
else if (Token::Match(tok2, "%type% %var% [ %num% ] ,"))
|
||||
{
|
||||
tok2 = tok2->tokAt(5); // The ',' token
|
||||
}
|
||||
|
||||
else if (Token::Match(tok2, "%type% * %var% [ %num% ] ,"))
|
||||
{
|
||||
tok2 = tok2->tokAt(6); // The ',' token
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tok2 = NULL;
|
||||
typelen = 0;
|
||||
}
|
||||
|
||||
|
||||
if (tok2)
|
||||
{
|
||||
ret = true;
|
||||
|
||||
if (tok2->str() == ",")
|
||||
{
|
||||
tok2->str(";");
|
||||
InsertTokens(tok2, type0, typelen);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Token *eq = tok2;
|
||||
|
||||
int parlevel = 0;
|
||||
while (tok2)
|
||||
{
|
||||
if (strchr("{(", tok2->aaaa0()))
|
||||
{
|
||||
++parlevel;
|
||||
}
|
||||
|
||||
else if (strchr("})", tok2->aaaa0()))
|
||||
{
|
||||
if (parlevel < 0)
|
||||
break;
|
||||
--parlevel;
|
||||
}
|
||||
|
||||
else if (parlevel == 0 && strchr(";,", tok2->aaaa0()))
|
||||
{
|
||||
// "type var =" => "type var; var ="
|
||||
Token *VarTok = type0->tokAt(typelen);
|
||||
if (VarTok->aaaa0() == '*')
|
||||
VarTok = VarTok->next();
|
||||
InsertTokens(eq, VarTok, 2);
|
||||
eq->str(";");
|
||||
|
||||
// "= x, " => "= x; type "
|
||||
if (tok2->str() == ",")
|
||||
{
|
||||
tok2->str(";");
|
||||
InsertTokens(tok2, type0, typelen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool Tokenizer::simplifyKnownVariables()
|
||||
{
|
||||
bool ret = false;
|
||||
|
|
|
@ -89,6 +89,12 @@ public:
|
|||
static const Token *FindClassFunction(const Token *tok, const char classname[], const char funcname[], int &indentlevel);
|
||||
|
||||
|
||||
/**
|
||||
* Simplify variable declarations
|
||||
*/
|
||||
bool simplifyVarDecl();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** Add braces to an if-block
|
||||
|
|
|
@ -125,8 +125,8 @@ private:
|
|||
|
||||
TEST_CASE(findClassFunction1);
|
||||
|
||||
// Ticket 184 TEST_CASE(vardecl1);
|
||||
// Ticket 184 TEST_CASE(vardecl2);
|
||||
TEST_CASE(vardecl1);
|
||||
TEST_CASE(vardecl2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,7 +409,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" char * foo ( ) { char * str = malloc ( 10 ) ; if ( somecondition ) { for ( ; ; ) { } } return str ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" char * foo ( ) { char * str ; str = malloc ( 10 ) ; if ( somecondition ) { for ( ; ; ) { } } return str ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void ifAddBraces5()
|
||||
|
@ -457,7 +457,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a = 10 ; if ( 10 ) ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a ; a = 10 ; if ( 10 ) ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables2()
|
||||
|
@ -480,7 +480,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a = 10 ; a = g ( ) ; if ( a ) ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a ; a = 10 ; a = g ( ) ; if ( a ) ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables3()
|
||||
|
@ -506,7 +506,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a = 4 ; while ( true ) { break ; a = 10 ; } if ( a ) ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a ; a = 4 ; while ( true ) { break ; a = 10 ; } if ( a ) ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables4()
|
||||
|
@ -528,7 +528,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a = 4 ; if ( g ( a ) ) ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a ; a = 4 ; if ( g ( a ) ) ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables5()
|
||||
|
@ -550,7 +550,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a = 4 ; if ( a = 5 ) ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { int a ; a = 4 ; if ( a = 5 ) ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables6()
|
||||
|
@ -573,7 +573,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { char str [ 2 ] ; int a = 4 ; str [ 4 ] = 0 ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { char str [ 2 ] ; int a ; a = 4 ; str [ 4 ] = 0 ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables7()
|
||||
|
@ -595,7 +595,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void foo ( ) { int i = 24 ; abc [ 22 ] = 1 ; abc [ 24 ] = 2 ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void foo ( ) { int i ; i = 24 ; abc [ 22 ] = 1 ; abc [ 24 ] = 2 ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplifyKnownVariables8()
|
||||
|
@ -617,7 +617,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void foo ( ) { int i = 23 ; ; abc [ 23 ] = 0 ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void foo ( ) { int i ; i = 23 ; ; abc [ 23 ] = 0 ; }"), ostr.str());
|
||||
}
|
||||
|
||||
|
||||
|
@ -779,10 +779,10 @@ private:
|
|||
// result..
|
||||
const std::string actual(tokenizer.tokens()->stringifyList(true));
|
||||
const std::string expected("\n\n##file 0\n"
|
||||
"1: static int i@1 = 1 ;\n"
|
||||
"1: static int i@1 ; i@1 = 1 ;\n"
|
||||
"2: void f ( )\n"
|
||||
"3: {\n"
|
||||
"4: int i@2 = 2 ;\n"
|
||||
"4: int i@2 ; i@2 = 2 ;\n"
|
||||
"5: for ( int i@3 = 0 ; i@3 < 10 ; ++ i@3 )\n"
|
||||
"6: i@3 = 3 ;\n"
|
||||
"7: i@2 = 4 ;\n"
|
||||
|
@ -1220,7 +1220,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { double a = 4.2 ; float b = 4.2f ; double c = 4.2e+10 ; double d = 4.2e-10 ; int e = 4 + 2 ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { double a ; a = 4.2 ; float b ; b = 4.2f ; double c ; c = 4.2e+10 ; double d ; d = 4.2e-10 ; int e ; e = 4 + 2 ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void tokenize_strings()
|
||||
|
@ -1244,7 +1244,7 @@ private:
|
|||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { const char * a = { \"hello more world\" } ; }"), ostr.str());
|
||||
ASSERT_EQUALS(std::string(" void f ( ) { const char * a ; a = { \"hello more world\" } ; }"), ostr.str());
|
||||
}
|
||||
|
||||
void simplify_constants()
|
||||
|
@ -1331,32 +1331,18 @@ private:
|
|||
{
|
||||
const char code[] = "unsigned int a, b;";
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const std::string actual(tokenizeAndStringify(code));
|
||||
|
||||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
|
||||
ASSERT_EQUALS(" unsigned int a ; unsigned int b ;", ostr.str());
|
||||
ASSERT_EQUALS("unsigned int a ; unsigned int b ;", actual);
|
||||
}
|
||||
|
||||
void vardecl2()
|
||||
{
|
||||
const char code[] = "void foo(a,b) unsigned int a, b; { }";
|
||||
|
||||
// tokenize..
|
||||
Tokenizer tokenizer;
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const std::string actual(tokenizeAndStringify(code));
|
||||
|
||||
std::ostringstream ostr;
|
||||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next())
|
||||
ostr << " " << tok->str();
|
||||
|
||||
ASSERT_EQUALS(" void foo ( a , b ) unsigned int a ; unsigned int b ; { }", ostr.str());
|
||||
ASSERT_EQUALS("void foo ( a , b ) unsigned int a ; unsigned int b ; { }", actual);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue