From 3bbb2e1d7f3965cb32012018173a65174c963f46 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Wed, 14 Apr 2010 19:04:16 +0200 Subject: [PATCH] Fixed #1601 (change simplifyInitVar to split declaration from initialization) --- lib/tokenize.cpp | 63 ++++++++++----- lib/tokenize.h | 1 + test/testtokenize.cpp | 178 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+), 19 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 3b793ec67..b3389686d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4765,32 +4765,57 @@ void Tokenizer::simplifyLogicalOperators() } } - +// int i(0); => int i; i = 0; void Tokenizer::simplifyInitVar() { for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "[{};] %type% *| %var% ( %num% ) ;")) - { - // call constructor of class => no simplification - if (!tok->next()->isStandardType() && tok->tokAt(2)->str() != "*") - continue; - - // goto variable name.. - tok = tok->tokAt(2); - if (tok->str() == "*") - tok = tok->next(); - - // insert '=' - tok->insertToken("="); - - // remove parantheses.. - tok->next()->deleteNext(); - tok->next()->next()->deleteNext(); - } + if (Token::Match(tok, "[{};] class|struct|union| %type% *| %var% ( &| %any% ) ;")) + tok = initVar(tok->next()); + else if (tok == _tokens && Token::Match(tok, "class|struct|union| %type% *| %var% ( &| %num% ) ;")) + tok = initVar(tok); } } +Token * Tokenizer::initVar(Token * tok) +{ + // call constructor of class => no simplification + if (Token::Match(tok, "class|struct|union")) + { + if (tok->tokAt(2)->str() != "*") + return tok; + + tok = tok->next(); + } + else if (!tok->isStandardType() && tok->tokAt(1)->str() != "*") + return tok; + + // goto variable name.. + tok = tok->next(); + if (tok->str() == "*") + tok = tok->next(); + + // check initializer.. + if (tok->tokAt(2)->isStandardType() || tok->tokAt(2)->str() == "void") + return tok; + + // insert '; var =' + tok->insertToken(";"); + tok->next()->insertToken(tok->str()); + tok = tok->tokAt(2); + tok->insertToken("="); + + // remove parantheses.. + tok = tok->next(); + tok->deleteNext(); + tok = tok->next(); + if (tok->str() == "&") + tok = tok->next(); + tok->deleteNext(); + + return tok; +} + bool Tokenizer::simplifyKnownVariables() { diff --git a/lib/tokenize.h b/lib/tokenize.h index 63d8c7208..f67a32e45 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -165,6 +165,7 @@ public: * ; int *p = 0; */ void simplifyInitVar(); + Token * initVar(Token * tok); /** * Colapse compound standard types into a single token. diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 5fbb5d413..46fca738e 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -206,6 +206,7 @@ private: TEST_CASE(arraySize); TEST_CASE(labels); + TEST_CASE(simplifyInitVar); } @@ -3072,6 +3073,183 @@ private: { ASSERT_EQUALS(" void f(){ ab:; a=0;}", labels_("void f() { ab: a=0; }")); } + + // Check simplifyInitVar + void checkSimplifyInitVar(const char code[]) + { + // Tokenize.. + Settings settings(Settings::testSettings()); + settings._checkCodingStyle = true; + Tokenizer tokenizer(&settings, this); + std::istringstream istr(code); + errout.str(""); + tokenizer.tokenize(istr, "test.cpp"); + } + + void simplifyInitVar() + { + { + const char code[] = "int i ; int p(0);"; + ASSERT_EQUALS("int i ; int p ; p = 0 ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int i; int *p(0);"; + ASSERT_EQUALS("int i ; int * p ; p = 0 ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int p(0);"; + ASSERT_EQUALS("int p ; p = 0 ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int *p(0);"; + ASSERT_EQUALS("int * p ; p = 0 ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int i ; int p(i);"; + ASSERT_EQUALS("int i ; int p ; p = i ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int i; int *p(&i);"; + ASSERT_EQUALS("int i ; int * p ; p = & i ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int i; void *p(&i);"; + ASSERT_EQUALS("int i ; void * p ; p = & i ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "struct S { }; struct S s; struct S *p(&s);"; + ASSERT_EQUALS("struct S { } ; struct S s ; struct S * p ; p = & s ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "struct S { }; S s; S *p(&s);"; + ASSERT_EQUALS("struct S { } ; S s ; S * p ; p = & s ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "union S { int i; float f; }; union S s; union S *p(&s);"; + ASSERT_EQUALS("union S { int i ; float f ; } ; union S s ; union S * p ; p = & s ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "union S { int i; float f; }; S s; S *p(&s);"; + ASSERT_EQUALS("union S { int i ; float f ; } ; S s ; S * p ; p = & s ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "class C { }; class C c; class C *p(&c);"; + ASSERT_EQUALS("class C { } ; class C c ; class C * p ; p = & c ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "class C { }; C c; C *p(&c);"; + ASSERT_EQUALS("class C { } ; C c ; C * p ; p = & c ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "struct S { }; struct S s; struct S s1(s);"; + ASSERT_EQUALS("struct S { } ; struct S s ; struct S s1 ( s ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "struct S { }; S s; S s1(s);"; + ASSERT_EQUALS("struct S { } ; S s ; S s1 ( s ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "struct S { }; struct S s; struct S s1(&s);"; + ASSERT_EQUALS("struct S { } ; struct S s ; struct S s1 ( & s ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "struct S { }; S s; S s1(&s);"; + ASSERT_EQUALS("struct S { } ; S s ; S s1 ( & s ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "class S { int function(void); };"; + ASSERT_EQUALS("class S { int function ( void ) ; } ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "class S { int function(int); };"; + ASSERT_EQUALS("class S { int function ( int ) ; } ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int function(void);"; + ASSERT_EQUALS("int function ( void ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int function(int);"; + ASSERT_EQUALS("int function ( int ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "extern int function(void);"; + ASSERT_EQUALS("extern int function ( void ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + { + const char code[] = "int function1(void); int function2(void);"; + ASSERT_EQUALS("int function1 ( void ) ; int function2 ( void ) ;", tokenizeAndStringify(code)); + checkSimplifyInitVar(code); + ASSERT_EQUALS("", errout.str()); + } + + } }; REGISTER_TEST(TestTokenizer)