From 96359b14ffb8580939a91e57bdc4e4e74b71ee51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 20 Jan 2010 21:19:06 +0100 Subject: [PATCH] Simplify function pointers --- lib/checkclass.cpp | 1 + lib/tokenize.cpp | 33 +++++++++++++++++++++++++++++++++ lib/tokenize.h | 3 +++ test/testsimplifytokens.cpp | 6 +++--- test/testtokenize.cpp | 22 ++++++++++++++++++++++ 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index c5d5490a7..304048066 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -579,6 +579,7 @@ void CheckClass::privateFunctions() tok = tok->tokAt(2)->link(); else if (Token::Match(tok, "%var% (") && + !Token::simpleMatch(tok->next()->link(), ") (") && !Token::Match(tok, classname.c_str())) { FuncList.push_back(tok); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b26ca62be..eba6ea2fc 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -941,6 +941,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[]) // remove exception specifications.. removeExceptionSpecifications(_tokens); + // simplify function pointers + simplifyFunctionPointers(); + setVarId(); if (!validate()) return false; @@ -3291,6 +3294,36 @@ void Tokenizer::simplifyFunctionParameters() } +void Tokenizer:: simplifyFunctionPointers() +{ + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (tok->previous() && !Token::Match(tok->previous(), "[{};]")) + continue; + + if (Token::Match(tok, "%type% *| *| ( * %var% ) (")) + ; + else if (Token::Match(tok, "%type% %type% *| *| ( * %var% ) (")) + tok = tok->next(); + else + continue; + + while (tok->next()->str() == "*") + tok = tok->next(); + + // check that the declaration ends with ; + if (!Token::simpleMatch(tok->tokAt(5)->link(), ") ;")) + continue; + + // ok simplify this function pointer to an ordinary pointer + tok->deleteNext(); + tok->tokAt(2)->deleteNext(); + const Token *tok2 = tok->tokAt(3)->link(); + Token::eraseTokens(tok->tokAt(2), tok2 ? tok2->next() : 0); + } +} + + bool Tokenizer::simplifyFunctionReturn() { bool ret = false; diff --git a/lib/tokenize.h b/lib/tokenize.h index 9f7ea025a..a2bff13e7 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -336,6 +336,9 @@ private: */ void simplifyStd(); + /** Simplify function pointers */ + void simplifyFunctionPointers(); + /** * Remove exception specifications. This function calls itself recursively. * @param tok First token in scope to cleanup diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 82d76d075..ad320b0fa 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -135,7 +135,7 @@ private: TEST_CASE(simplifyAtol) TEST_CASE(simplifyHexInString) - TEST_CASE(simplifyTypedef) + TEST_CASE(simplifyTypedef1) TEST_CASE(simplifyTypedef2) TEST_CASE(simplifyTypedef3) TEST_CASE(simplifyTypedef4) @@ -2158,7 +2158,7 @@ private: ASSERT_EQUALS("\"a\"", tok("\"\\177\"")); } - void simplifyTypedef() + void simplifyTypedef1() { const char code[] = "class A\n" "{\n" @@ -2652,7 +2652,7 @@ private: "void ( * pf ) ( ) ; " "void * ( * pfv ) ( void * ) ;"; - ASSERT_EQUALS(expected, tok(code, false)); + ASSERT_EQUALS(tok(expected), tok(code)); } void simplifyTypedef22() diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 6580b0355..e50efc735 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -176,6 +176,8 @@ private: TEST_CASE(simplifyString); TEST_CASE(simplifyConst); TEST_CASE(switchCase); + + TEST_CASE(functionpointer); } @@ -2808,6 +2810,26 @@ private: ASSERT_EQUALS("void foo ( int i ) { switch ( i ) { case -1 : break ; } }", tokenizeAndStringify("void foo (int i) { switch(i) { case -1: break; } }")); } + + std::string simplifyFunctionPointers(const char code[]) + { + Tokenizer tokenizer; + std::istringstream istr(code); + tokenizer.tokenize(istr, "test.cpp"); + tokenizer.simplifyFunctionPointers(); + std::ostringstream ostr; + for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) + ostr << (tok->isName() ? " " : "") << tok->str(); + return ostr.str(); + } + + void functionpointer() + { + ASSERT_EQUALS(" void* f;", simplifyFunctionPointers("void (*f)();")); + ASSERT_EQUALS(" void** f;", simplifyFunctionPointers("void *(*f)();")); + ASSERT_EQUALS(" unsigned int* f;", simplifyFunctionPointers("unsigned int (*f)();")); + ASSERT_EQUALS(" unsigned int** f;", simplifyFunctionPointers("unsigned int * (*f)();")); + } }; REGISTER_TEST(TestTokenizer)