Fix #795 (Preprocessor: Incorrect handling of #if (A) || (B))
http://sourceforge.net/apps/trac/cppcheck/ticket/795
This commit is contained in:
parent
0a7da96cb6
commit
272f0d3be5
|
@ -444,7 +444,7 @@ std::string Preprocessor::removeComments(const std::string &str)
|
||||||
|
|
||||||
std::string Preprocessor::removeParantheses(const std::string &str)
|
std::string Preprocessor::removeParantheses(const std::string &str)
|
||||||
{
|
{
|
||||||
if (str.find("\n#if") == std::string::npos)
|
if (str.find("\n#if") == std::string::npos && str.compare(0, 3, "#if") != 0)
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
std::istringstream istr(str.c_str());
|
std::istringstream istr(str.c_str());
|
||||||
|
@ -481,14 +481,38 @@ std::string Preprocessor::removeParantheses(const std::string &str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.compare(0, 4, "#if(") == 0 && line.find(")") == line.length() - 1)
|
// "#if(A) => #if A", but avoid "#if (defined A) || defined (B)"
|
||||||
|
if (line.compare(0, 4, "#if(") == 0 && line[line.length() - 1] == ')')
|
||||||
|
{
|
||||||
|
int ind = 0;
|
||||||
|
for (std::string::size_type i = 0; i < line.length(); ++i)
|
||||||
|
{
|
||||||
|
if (line[i] == '(')
|
||||||
|
++ind;
|
||||||
|
else if (line[i] == ')')
|
||||||
|
{
|
||||||
|
--ind;
|
||||||
|
if (ind == 0)
|
||||||
|
{
|
||||||
|
if (i == line.length() - 1)
|
||||||
{
|
{
|
||||||
line[3] = ' ';
|
line[3] = ' ';
|
||||||
line.erase(line.length() - 1);
|
line.erase(line.length() - 1);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.compare(0, 4, "#if(") == 0)
|
||||||
|
line.insert(3, " ");
|
||||||
|
else if (line.compare(0, 4, "#elif(") == 0)
|
||||||
|
line.insert(5, " ");
|
||||||
}
|
}
|
||||||
ret << line << "\n";
|
ret << line << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret.str();
|
return ret.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -650,6 +650,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void if_cond4()
|
void if_cond4()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
const char filedata[] = "#define A\n"
|
const char filedata[] = "#define A\n"
|
||||||
"#define B\n"
|
"#define B\n"
|
||||||
|
@ -668,6 +669,64 @@ private:
|
||||||
ASSERT_EQUALS("\n\n\nab\n\n", actual[""]);
|
ASSERT_EQUALS("\n\n\nab\n\n", actual[""]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char filedata[] = "#if A\n"
|
||||||
|
"{\n"
|
||||||
|
"#if (defined(B))\n"
|
||||||
|
"foo();\n"
|
||||||
|
"#endif\n"
|
||||||
|
"}\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(3, static_cast<unsigned int>(actual.size()));
|
||||||
|
ASSERT_EQUALS("\n\n\n\n\n\n\n", actual[""]);
|
||||||
|
ASSERT_EQUALS("\n{\n\n\n\n}\n\n", actual["A"]);
|
||||||
|
ASSERT_EQUALS("\n{\n\nfoo();\n\n}\n\n", actual["A;B"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char filedata[] = "#define A\n"
|
||||||
|
"#define B\n"
|
||||||
|
"#if (defined A) || defined (B)\n"
|
||||||
|
"ab\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(1, static_cast<unsigned int>(actual.size()));
|
||||||
|
ASSERT_EQUALS("\n\n\nab\n\n", actual[""]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char filedata[] = "#if (A)\n"
|
||||||
|
"foo();\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\n", actual[""]);
|
||||||
|
ASSERT_EQUALS("\nfoo();\n\n", actual["A"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void if_cond5()
|
void if_cond5()
|
||||||
{
|
{
|
||||||
const char filedata[] = "#if defined(A) && defined(B)\n"
|
const char filedata[] = "#if defined(A) && defined(B)\n"
|
||||||
|
|
Loading…
Reference in New Issue