Handle "#endif !defined" conditionals
This commit is contained in:
parent
b944168bdc
commit
66253af1e5
|
@ -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())
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue