From e1cdbf3c5a719af99c38bf7121067af6d996410b Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sun, 30 Aug 2009 00:00:54 +0300 Subject: [PATCH] Fix ticket #611 (Preprocessor: the configurations "A;B" and "B;A" are the same) http://sourceforge.net/apps/trac/cppcheck/ticket/611 --- src/preprocessor.cpp | 47 +++++++++++++++++++++++---------------- test/testpreprocessor.cpp | 21 +++++++++++++++++ 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 3e49809b9..4c32f770c 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -706,20 +706,6 @@ std::list Preprocessor::getcfgs(const std::string &filedata) } } - // Remove duplicates from the ret list.. - for (std::list::iterator it1 = ret.begin(); it1 != ret.end(); ++it1) - { - std::list::iterator it2 = it1; - ++it2; - while (it2 != ret.end()) - { - if (*it1 == *it2) - ret.erase(it2++); - else - ++it2; - } - } - // convert configurations: "defined(A) && defined(B)" => "A;B" for (std::list::iterator it = ret.begin(); it != ret.end(); ++it) { @@ -731,37 +717,60 @@ std::list Preprocessor::getcfgs(const std::string &filedata) std::istringstream istr(s.c_str()); tokenizer.tokenize(istr, ""); - s = ""; + const Token *tok = tokenizer.tokens(); + std::list varList; while (tok) { if (Token::Match(tok, "defined ( %var% )")) { - s = s + tok->strAt(2); + varList.push_back(tok->strAt(2)); tok = tok->tokAt(4); if (tok && tok->str() == "&&") { - s += ";"; tok = tok->next(); } } else if (Token::Match(tok, "%var% ;")) { - s += tok->str() + ";"; + varList.push_back(tok->str()); tok = tok->tokAt(2); } else { - s = ""; break; } } + varList.sort(); + s = ""; + for (std::list::iterator varIter = varList.begin(); varIter != varList.end(); ++varIter) + { + if (!s.empty()) + s += ";"; + + s += *varIter; + } + if (!s.empty()) *it = s; } } + // Remove duplicates from the ret list.. + for (std::list::iterator it1 = ret.begin(); it1 != ret.end(); ++it1) + { + std::list::iterator it2 = it1; + ++it2; + while (it2 != ret.end()) + { + if (*it1 == *it2) + ret.erase(it2++); + else + ++it2; + } + } + // cleanup unhandled configurations.. for (std::list::iterator it = ret.begin(); it != ret.end();) { diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index c51d9f7bf..19007f772 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -93,6 +93,7 @@ private: TEST_CASE(if_cond2); TEST_CASE(if_cond3); TEST_CASE(if_cond4); + TEST_CASE(if_cond5); TEST_CASE(multiline1); TEST_CASE(multiline2); @@ -662,7 +663,27 @@ private: ASSERT_EQUALS("\n\n\nab\n\n", actual[""]); } + void if_cond5() + { + const char filedata[] = "#if defined(A) && defined(B)\n" + "ab\n" + "#endif\n" + "cd\n" + "#if defined(B) && defined(A)\n" + "ef\n" + "#endif\n"; + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Preprocessor preprocessor; + preprocessor.preprocess(istr, actual, "file.c"); + + // Compare results.. + ASSERT_EQUALS(2, static_cast(actual.size())); + ASSERT_EQUALS("\n\n\ncd\n\n\n\n", actual[""]); + ASSERT_EQUALS("\nab\n\ncd\n\nef\n\n", actual["A;B"]); + } void multiline1()