Skip to content

Commit

Permalink
Fixed danmar#1326 (remove simplified enum definitions)
Browse files Browse the repository at this point in the history
  • Loading branch information
IOBYTE authored and Daniel Marjamäki committed Jan 29, 2010
1 parent 9d11492 commit fc54ed1
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 8 deletions.
89 changes: 89 additions & 0 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// typedef..
simplifyTypedef();

// enum..
simplifyEnum();

// Remove __asm..
Expand Down Expand Up @@ -4702,12 +4703,17 @@ void Tokenizer::simplifyEnum()
Token::Match(tok, "enum %type% {"))
{
Token * tok1;
Token * start = tok;
Token * end;
Token * enumType = 0;

if (tok->tokAt(1)->str() == "{")
tok1 = tok->tokAt(2);
else
{
enumType = tok->tokAt(1);
tok1 = tok->tokAt(3);
}

end = tok1->tokAt(-1)->link();

Expand Down Expand Up @@ -4743,6 +4749,7 @@ void Tokenizer::simplifyEnum()
bool exitThisScope = false;
int exitScope = 0;
bool simplifyEnum = false;
bool hasClass = false;
for (Token *tok2 = end->next(); tok2; tok2 = tok2->next())
{
if (tok2->str() == "}")
Expand All @@ -4762,6 +4769,7 @@ void Tokenizer::simplifyEnum()
else if (!pattern.empty() && Token::Match(tok2, pattern.c_str()))
{
simplifyEnum = true;
hasClass = true;
}
else if (inScope && !exitThisScope && tok2->str() == enumName->str())
{
Expand All @@ -4770,18 +4778,99 @@ void Tokenizer::simplifyEnum()
// Don't replace this enum if it's preceded by "::"
}
else
{
simplifyEnum = true;
hasClass = false;
}
}

if (simplifyEnum)
{
tok2->str(enumValue->strAt(0));

if (hasClass)
{
tok2->deleteNext();
tok2->deleteNext();
}

simplifyEnum = false;
}
}
}
}

if (enumType)
{
const std::string pattern(className.empty() ? "" : (className + " :: " + enumType->str()).c_str());
int level = 0;
bool inScope = true;

bool exitThisScope = false;
int exitScope = 0;
bool simplifyEnum = false;
bool hasClass = false;
for (Token *tok2 = end->next(); tok2; tok2 = tok2->next())
{
if (tok2->str() == "}")
{
--level;
if (level < 0)
inScope = false;

if (exitThisScope)
{
if (level < exitScope)
exitThisScope = false;
}
}
else if (tok2->str() == "{")
++level;
else if (!pattern.empty() && ((Token::Match(tok2, "enum") && Token::Match(tok2->next(), pattern.c_str())) || Token::Match(tok2, pattern.c_str())))
{
simplifyEnum = true;
hasClass = true;
}
else if (inScope && !exitThisScope && (tok2->str() == enumType->str() || (tok2->str() == "enum" && tok2->next()->str() == enumType->str())))
{
if (Token::simpleMatch(tok2->previous(), "::"))
{
// Don't replace this enum if it's preceded by "::"
}
else
{
simplifyEnum = true;
hasClass = false;
}
}

if (simplifyEnum)
{
if (tok2->str() == "enum")
tok2->deleteNext();
tok2->str("int");

if (hasClass)
{
tok2->deleteNext();
tok2->deleteNext();
}

simplifyEnum = false;
}
}
}

tok1 = start;
while (tok1->next() && tok1->next() != end->next())
tok1->deleteNext();
if (start != _tokens)
{
tok1 = start->previous();
tok1->deleteNext();
}
else
_tokens->deleteThis();
}
}
}
Expand Down
44 changes: 36 additions & 8 deletions test/testsimplifytokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ class TestSimplifyTokens : public TestFixture
TEST_CASE(enum1);
TEST_CASE(enum2);
TEST_CASE(enum3);
TEST_CASE(enum4);

// remove "std::" on some standard functions
TEST_CASE(removestd);
Expand Down Expand Up @@ -2474,10 +2475,10 @@ class TestSimplifyTokens : public TestFixture
"XYZ e2;";

const char expected[] =
"enum abc { a = 0 , b = 1 , c = 2 } ; ; "
"enum xyz { x = 0 , y = 1 , z = 2 } ; ; "
"enum abc e1 ; "
"enum xyz e2 ;";
"; ; "
"; ; "
"int e1 ; "
"int e2 ;";

ASSERT_EQUALS(expected, tok(code, false));
}
Expand Down Expand Up @@ -3145,24 +3146,51 @@ class TestSimplifyTokens : public TestFixture

void enum1()
{
const char code[] = "enum A { a, b, c };";
const char expected[] = "enum A { a = 0 , b = 1 , c = 2 } ;";
const char code[] = "enum A { a, b, c }; A c1 = c;";
const char expected[] = "; int c1 ; c1 = 2 ;";

ASSERT_EQUALS(expected, tok(code, false));
}

void enum2()
{
const char code[] = "enum A { a, }; int array[a];";
const char expected[] = "enum A { a = 0 , } ; int array [ 0 ] ;";
const char expected[] = "; int array [ 0 ] ;";

ASSERT_EQUALS(expected, tok(code, false));
}

void enum3()
{
const char code[] = "enum { a, }; int array[a];";
const char expected[] = "enum { a = 0 , } ; int array [ 0 ] ;";
const char expected[] = "; int array [ 0 ] ;";

ASSERT_EQUALS(expected, tok(code, false));
}

void enum4()
{
const char code[] = "class A {\n"
"public:\n"
" enum EA { a1, a2, a3 };\n"
" EA get() const;\n"
" void put(EA a) { ea = a; ea = a1; }\n"
"private:\n"
" EA ea;\n"
"};\n"
"A::EA A::get() const { return ea; }\n"
"A::EA e = A::a1;";

const char expected[] = "class A { "
"public: "
"; "
"int get ( ) const ; "
"void put ( int a ) { ea = a ; ea = 0 ; } "
"private: "
"int ea ; "
"} ; "
"int A :: get ( ) const { return ea ; } "
"int e ; e = 0 ;";

ASSERT_EQUALS(expected, tok(code, false));
}
Expand Down

0 comments on commit fc54ed1

Please sign in to comment.