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:
parent
fc343b3e9e
commit
e1cdbf3c5a
|
@ -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();)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue