Fix ticket #611 (Preprocessor: the configurations "A;B" and "B;A" are the same)

http://sourceforge.net/apps/trac/cppcheck/ticket/611
This commit is contained in:
Reijo Tomperi 2009-08-30 00:00:54 +03:00
parent fc343b3e9e
commit e1cdbf3c5a
2 changed files with 49 additions and 19 deletions

View File

@ -706,20 +706,6 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
}
}
// Remove duplicates from the ret list..
for (std::list<std::string>::iterator it1 = ret.begin(); it1 != ret.end(); ++it1)
{
std::list<std::string>::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<std::string>::iterator it = ret.begin(); it != ret.end(); ++it)
{
@ -731,37 +717,60 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata)
std::istringstream istr(s.c_str());
tokenizer.tokenize(istr, "");
s = "";
const Token *tok = tokenizer.tokens();
std::list<std::string> 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<std::string>::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<std::string>::iterator it1 = ret.begin(); it1 != ret.end(); ++it1)
{
std::list<std::string>::iterator it2 = it1;
++it2;
while (it2 != ret.end())
{
if (*it1 == *it2)
ret.erase(it2++);
else
++it2;
}
}
// cleanup unhandled configurations..
for (std::list<std::string>::iterator it = ret.begin(); it != ret.end();)
{

View File

@ -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<std::string, std::string> actual;
Preprocessor preprocessor;
preprocessor.preprocess(istr, actual, "file.c");
// Compare results..
ASSERT_EQUALS(2, static_cast<unsigned int>(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()