Handle "#endif !defined" conditionals

This commit is contained in:
Raphael Geissert 2011-01-30 17:33:44 -06:00
parent b944168bdc
commit 66253af1e5
2 changed files with 56 additions and 2 deletions

View File

@ -714,13 +714,14 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
std::string Preprocessor::getdef(std::string line, bool def)
{
// If def is true, the line must start with "#ifdef"
if (def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0 && line.find("#if defined ") != 0)
if (def && line.find("#ifdef ") != 0 && line.find("#if ") != 0
&& (line.find("#elif ") != 0 || line.find("#elif !") == 0))
{
return "";
}
// If def is false, the line must start with "#ifndef"
if (!def && line.find("#ifndef ") != 0)
if (!def && line.find("#ifndef ") != 0 && line.find("#elif !") != 0)
{
return "";
}
@ -728,6 +729,17 @@ std::string Preprocessor::getdef(std::string line, bool def)
// Remove the "#ifdef" or "#ifndef"
if (line.find("#if defined ") == 0)
line.erase(0, 11);
else if (line.find("#elif !defined(") == 0)
{
std::string::size_type pos = 0;
line.erase(0, 15);
pos = line.find(")");
// if pos == ::npos then another part of the code will complain
// about the mismatch
if (pos != std::string::npos)
line.erase(pos, 1);
}
else
line.erase(0, line.find(" "));
@ -1360,6 +1372,22 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg,
}
}
else if (line.find("#elif !") == 0)
{
if (matched_ifdef.back())
{
matching_ifdef.back() = false;
}
else
{
if (!match_cfg_def(cfgmap, ndef))
{
matching_ifdef.back() = true;
matched_ifdef.back() = true;
}
}
}
else if (line.find("#elif ") == 0)
{
if (matched_ifdef.back())

View File

@ -911,6 +911,7 @@ private:
if_cond2b();
if_cond2c();
if_cond2d();
if_cond2e();
}
void if_cond2b()
@ -998,6 +999,31 @@ private:
ASSERT_EQUALS("\n!a\n\nb\n\n\n\n\n\n\n\n\n\n\n\n", actual["B"]);
}
void if_cond2e()
{
const char filedata[] = "#if !defined(A)\n"
"!a\n"
"#elif !defined(B)\n"
"!b\n"
"#endif\n";
// Preprocess => actual result..
errout.str("");
std::istringstream istr(filedata);
std::map<std::string, std::string> actual;
Settings settings;
settings.debug = settings.debugwarnings = true;
Preprocessor preprocessor(&settings, this);
preprocessor.preprocess(istr, actual, "file.c");
// Compare results..
ASSERT_EQUALS(3, static_cast<unsigned int>(actual.size()));
ASSERT_EQUALS("\n!a\n\n\n\n", actual[""]);
ASSERT_EQUALS("\n\n\n!b\n\n", actual["A"]);
TODO_ASSERT_EQUALS("\n\n\n\n\n", "", actual["A;B"]);
ASSERT_EQUALS("", errout.str());
}
void if_cond3()
{
const char filedata[] = "#ifdef A\n"