Preprocessor: Better evaluation of conditions such as '#if defined A || defined B' (#469)
This commit is contained in:
parent
62f681094f
commit
9b2dd8c7eb
|
@ -519,6 +519,31 @@ void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, st
|
||||||
// Remove space characters that are after or before new line character
|
// Remove space characters that are after or before new line character
|
||||||
processedFile = removeSpaceNearNL(processedFile);
|
processedFile = removeSpaceNearNL(processedFile);
|
||||||
|
|
||||||
|
// Replace "defined A" with "defined(A)"
|
||||||
|
{
|
||||||
|
std::istringstream istr(processedFile.c_str());
|
||||||
|
std::ostringstream ostr;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(istr, line))
|
||||||
|
{
|
||||||
|
if (line.substr(0, 4) == "#if " || line.substr(0, 6) == "#elif ")
|
||||||
|
{
|
||||||
|
std::string::size_type pos = 0;
|
||||||
|
while ((pos = line.find(" defined ")) != std::string::npos)
|
||||||
|
{
|
||||||
|
line[pos+8] = '(';
|
||||||
|
pos = line.find_first_of(" |&", pos + 8);
|
||||||
|
if (pos == std::string::npos)
|
||||||
|
line += ")";
|
||||||
|
else
|
||||||
|
line.insert(pos, ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ostr << line << "\n";
|
||||||
|
}
|
||||||
|
processedFile = ostr.str();
|
||||||
|
}
|
||||||
|
|
||||||
handleIncludes(processedFile, filename, includePaths);
|
handleIncludes(processedFile, filename, includePaths);
|
||||||
|
|
||||||
processedFile = replaceIfDefined(processedFile);
|
processedFile = replaceIfDefined(processedFile);
|
||||||
|
@ -771,6 +796,9 @@ bool Preprocessor::match_cfg_def(std::string cfg, std::string def)
|
||||||
def.insert(pos, isdefined ? "1" : "0");
|
def.insert(pos, isdefined ? "1" : "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def.find("1||") != std::string::npos || def.find("||1") != std::string::npos)
|
||||||
|
return true;
|
||||||
|
|
||||||
while (def.find("1&&") != std::string::npos)
|
while (def.find("1&&") != std::string::npos)
|
||||||
{
|
{
|
||||||
def.erase(def.find("1&&"), 3);
|
def.erase(def.find("1&&"), 3);
|
||||||
|
|
|
@ -89,6 +89,7 @@ private:
|
||||||
TEST_CASE(if_cond1);
|
TEST_CASE(if_cond1);
|
||||||
TEST_CASE(if_cond2);
|
TEST_CASE(if_cond2);
|
||||||
TEST_CASE(if_cond3);
|
TEST_CASE(if_cond3);
|
||||||
|
TEST_CASE(if_cond4);
|
||||||
|
|
||||||
TEST_CASE(multiline1);
|
TEST_CASE(multiline1);
|
||||||
TEST_CASE(multiline2);
|
TEST_CASE(multiline2);
|
||||||
|
@ -582,6 +583,24 @@ private:
|
||||||
ASSERT_EQUALS("\na\n\nabc\n\n\n", actual["A;B;C"]);
|
ASSERT_EQUALS("\na\n\nabc\n\n\n", actual["A;B;C"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void if_cond4()
|
||||||
|
{
|
||||||
|
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[""]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue