Fixed ticket #3389 '-U option doesn't supress include file handling for #include statements inside #ifdef code paths'
Signed-off-by: makulik <g-makulik@t-online.de>
This commit is contained in:
parent
8c04431b17
commit
0a777dcb52
|
@ -856,7 +856,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
|
||||||
processedFile = ostr.str();
|
processedFile = ostr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_settings && !_settings->userDefines.empty()) {
|
if (_settings && (!_settings->userDefines.empty() || !_settings->userUndefs.empty())) {
|
||||||
std::map<std::string, std::string> defs;
|
std::map<std::string, std::string> defs;
|
||||||
|
|
||||||
// TODO: break out this code. There is other similar code.
|
// TODO: break out this code. There is other similar code.
|
||||||
|
@ -885,7 +885,11 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
|
||||||
}
|
}
|
||||||
|
|
||||||
processedFile = handleIncludes(processedFile, filename, includePaths, defs);
|
processedFile = handleIncludes(processedFile, filename, includePaths, defs);
|
||||||
|
if (_settings->userDefines.empty())
|
||||||
|
resultConfigurations = getcfgs(processedFile, filename);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
handleIncludes(processedFile, filename, includePaths);
|
handleIncludes(processedFile, filename, includePaths);
|
||||||
|
|
||||||
processedFile = replaceIfDefined(processedFile);
|
processedFile = replaceIfDefined(processedFile);
|
||||||
|
@ -1768,31 +1772,48 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
|
||||||
|
|
||||||
unsigned int linenr = 0;
|
unsigned int linenr = 0;
|
||||||
|
|
||||||
|
std::set<std::string> undefs = _settings ? _settings->userUndefs : std::set<std::string>();
|
||||||
|
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
std::istringstream istr(code);
|
std::istringstream istr(code);
|
||||||
std::string line;
|
std::string line;
|
||||||
|
bool suppressCurrentCodePath = false;
|
||||||
while (std::getline(istr,line)) {
|
while (std::getline(istr,line)) {
|
||||||
++linenr;
|
++linenr;
|
||||||
|
|
||||||
if (line.compare(0,7,"#ifdef ") == 0) {
|
if (line.compare(0,7,"#ifdef ") == 0) {
|
||||||
if (indent == indentmatch && defs.find(getdef(line,true)) != defs.end()) {
|
if (indent == indentmatch) {
|
||||||
elseIsTrue = false;
|
std::string tag = getdef(line,true);
|
||||||
indentmatch++;
|
if (defs.find(tag) != defs.end()) {
|
||||||
|
elseIsTrue = false;
|
||||||
|
indentmatch++;
|
||||||
|
} else if (undefs.find(tag) != undefs.end()) {
|
||||||
|
elseIsTrue = true;
|
||||||
|
indentmatch++;
|
||||||
|
suppressCurrentCodePath = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++indent;
|
++indent;
|
||||||
|
|
||||||
if (indent == indentmatch + 1)
|
if (indent == indentmatch + 1)
|
||||||
elseIsTrue = true;
|
elseIsTrue = true;
|
||||||
} else if (line.compare(0,8,"#ifndef ") == 0) {
|
} else if (line.compare(0,8,"#ifndef ") == 0) {
|
||||||
if (indent == indentmatch && defs.find(getdef(line,false)) == defs.end()) {
|
if (indent == indentmatch) {
|
||||||
elseIsTrue = false;
|
std::string tag = getdef(line,false);
|
||||||
indentmatch++;
|
if (defs.find(tag) == defs.end()) {
|
||||||
}
|
elseIsTrue = false;
|
||||||
++indent;
|
indentmatch++;
|
||||||
|
} else if (undefs.find(tag) != undefs.end()) {
|
||||||
|
elseIsTrue = false;
|
||||||
|
indentmatch++;
|
||||||
|
suppressCurrentCodePath = false;
|
||||||
|
}
|
||||||
|
++indent;
|
||||||
|
|
||||||
if (indent == indentmatch + 1)
|
if (indent == indentmatch + 1)
|
||||||
elseIsTrue = true;
|
elseIsTrue = true;
|
||||||
} else if (line.compare(0,4,"#if ") == 0) {
|
}
|
||||||
|
} else if (!suppressCurrentCodePath && line.compare(0,4,"#if ") == 0) {
|
||||||
if (indent == indentmatch && match_cfg_def(defs, line.substr(4))) {
|
if (indent == indentmatch && match_cfg_def(defs, line.substr(4))) {
|
||||||
elseIsTrue = false;
|
elseIsTrue = false;
|
||||||
indentmatch++;
|
indentmatch++;
|
||||||
|
@ -1803,46 +1824,58 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
|
||||||
elseIsTrue = true;
|
elseIsTrue = true;
|
||||||
} else if (line.compare(0,6,"#elif ") == 0 || line.compare(0,5,"#else") == 0) {
|
} else if (line.compare(0,6,"#elif ") == 0 || line.compare(0,5,"#else") == 0) {
|
||||||
if (!elseIsTrue) {
|
if (!elseIsTrue) {
|
||||||
if (indentmatch == indent)
|
if (indentmatch == indent) {
|
||||||
indentmatch = indent - 1;
|
indentmatch = indent - 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (indentmatch == indent)
|
if (indentmatch == indent) {
|
||||||
indentmatch = indent - 1;
|
indentmatch = indent - 1;
|
||||||
else if (indentmatch == indent - 1) {
|
} else if (indentmatch == indent - 1) {
|
||||||
if (line.compare(0,5,"#else")==0 || match_cfg_def(defs,line.substr(6))) {
|
if (line.compare(0,5,"#else")==0 || match_cfg_def(defs,line.substr(6))) {
|
||||||
indentmatch = indent;
|
indentmatch = indent;
|
||||||
elseIsTrue = false;
|
elseIsTrue = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (suppressCurrentCodePath) {
|
||||||
|
suppressCurrentCodePath = false;
|
||||||
|
indentmatch = indent;
|
||||||
|
}
|
||||||
} else if (line == "#endif") {
|
} else if (line == "#endif") {
|
||||||
--indent;
|
--indent;
|
||||||
if (indentmatch > indent) {
|
if (indentmatch > indent) {
|
||||||
indentmatch = indent;
|
indentmatch = indent;
|
||||||
elseIsTrue = false;
|
elseIsTrue = false;
|
||||||
|
suppressCurrentCodePath = false;
|
||||||
}
|
}
|
||||||
} else if (indentmatch == indent) {
|
} else if (indentmatch == indent) {
|
||||||
if (line.compare(0,8,"#define ")==0) {
|
if (!suppressCurrentCodePath && line.compare(0,8,"#define ")==0) {
|
||||||
// no value
|
// no value
|
||||||
|
std::string tag = line.substr(8);
|
||||||
if (line.find_first_of("( ", 8) == std::string::npos)
|
if (line.find_first_of("( ", 8) == std::string::npos)
|
||||||
defs[line.substr(8)] = "";
|
defs[tag] = "";
|
||||||
|
|
||||||
// define value
|
// define value
|
||||||
else if (line.find("(") == std::string::npos) {
|
else if (line.find("(") == std::string::npos) {
|
||||||
const std::string::size_type pos = line.find(" ", 8);
|
const std::string::size_type pos = line.find(" ", 8);
|
||||||
defs[line.substr(8,pos-8)] = line.substr(pos+1);
|
tag = line.substr(8,pos-8);
|
||||||
|
defs[tag] = line.substr(pos+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (undefs.find(tag) != undefs.end()) {
|
||||||
|
defs.erase(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (line.compare(0,7,"#undef ") == 0) {
|
else if (!suppressCurrentCodePath && line.compare(0,7,"#undef ") == 0) {
|
||||||
defs.erase(line.substr(7));
|
defs.erase(line.substr(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (line.compare(0,7,"#error ") == 0) {
|
else if (!suppressCurrentCodePath && line.compare(0,7,"#error ") == 0) {
|
||||||
error(filePath, linenr, line.substr(7));
|
error(filePath, linenr, line.substr(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (line.compare(0,9,"#include ")==0) {
|
else if (!suppressCurrentCodePath && line.compare(0,9,"#include ")==0) {
|
||||||
std::string filename(line.substr(9));
|
std::string filename(line.substr(9));
|
||||||
|
|
||||||
const HeaderTypes headerType = getHeaderFileName(filename);
|
const HeaderTypes headerType = getHeaderFileName(filename);
|
||||||
|
@ -1883,7 +1916,8 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostr << line;
|
if (!suppressCurrentCodePath)
|
||||||
|
ostr << line;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A line has been read..
|
// A line has been read..
|
||||||
|
|
|
@ -244,6 +244,8 @@ private:
|
||||||
TEST_CASE(undef5);
|
TEST_CASE(undef5);
|
||||||
TEST_CASE(undef6);
|
TEST_CASE(undef6);
|
||||||
TEST_CASE(undef7);
|
TEST_CASE(undef7);
|
||||||
|
TEST_CASE(undef8);
|
||||||
|
TEST_CASE(undef9);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3151,7 +3153,7 @@ private:
|
||||||
const char filedata[] = "#define X Y\n"
|
const char filedata[] = "#define X Y\n"
|
||||||
"#ifdef X\n"
|
"#ifdef X\n"
|
||||||
"Fred & Wilma\n"
|
"Fred & Wilma\n"
|
||||||
"#else"
|
"#else\n"
|
||||||
"Barney & Betty\n"
|
"Barney & Betty\n"
|
||||||
"#endif\n";
|
"#endif\n";
|
||||||
|
|
||||||
|
@ -3165,7 +3167,7 @@ private:
|
||||||
|
|
||||||
// Compare results..
|
// Compare results..
|
||||||
ASSERT_EQUALS(1U, actual.size());
|
ASSERT_EQUALS(1U, actual.size());
|
||||||
TODO_ASSERT_EQUALS("\n\n\nBarney & Betty\n\n","\n\n\n\n\n", actual[""]);
|
ASSERT_EQUALS("\n\n\n\nBarney & Betty\n\n", actual[""]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void undef7() {
|
void undef7() {
|
||||||
|
@ -3186,6 +3188,53 @@ private:
|
||||||
ASSERT_EQUALS(1U, actual.size());
|
ASSERT_EQUALS(1U, actual.size());
|
||||||
TODO_ASSERT_EQUALS("\n;\n","\nXDefined;\n", actual[""]);
|
TODO_ASSERT_EQUALS("\n;\n","\nXDefined;\n", actual[""]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void undef8() {
|
||||||
|
Settings settings;
|
||||||
|
|
||||||
|
const char filedata[] = "#ifdef HAVE_CONFIG_H\n"
|
||||||
|
"#include \"config.h\"\n"
|
||||||
|
"#endif\n"
|
||||||
|
"\n"
|
||||||
|
"void foo();\n";
|
||||||
|
|
||||||
|
// Preprocess => actual result..
|
||||||
|
std::istringstream istr(filedata);
|
||||||
|
std::map<std::string, std::string> actual;
|
||||||
|
settings.userUndefs.insert("X"); // User undefs should override internal defines
|
||||||
|
settings.checkConfiguration = true;
|
||||||
|
errout.str("");
|
||||||
|
|
||||||
|
Preprocessor preprocessor(&settings, this);
|
||||||
|
preprocessor.preprocess(istr, actual, "file.c");
|
||||||
|
|
||||||
|
// Compare results..
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
ASSERT_EQUALS("\n\n\n\nvoid foo();\n", actual[""]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void undef9() {
|
||||||
|
Settings settings;
|
||||||
|
|
||||||
|
const char filedata[] = "#define X Y\n"
|
||||||
|
"#ifndef X\n"
|
||||||
|
"Fred & Wilma\n"
|
||||||
|
"#else\n"
|
||||||
|
"Barney & Betty\n"
|
||||||
|
"#endif\n";
|
||||||
|
|
||||||
|
// Preprocess => actual result..
|
||||||
|
std::istringstream istr(filedata);
|
||||||
|
std::map<std::string, std::string> actual;
|
||||||
|
settings.userUndefs.insert("X"); // User undefs should override internal defines
|
||||||
|
|
||||||
|
Preprocessor preprocessor(&settings, this);
|
||||||
|
preprocessor.preprocess(istr, actual, "file.c");
|
||||||
|
|
||||||
|
// Compare results..
|
||||||
|
ASSERT_EQUALS(1U, actual.size());
|
||||||
|
ASSERT_EQUALS("\n\nFred & Wilma\n\n\n\n", actual[""]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestPreprocessor)
|
REGISTER_TEST(TestPreprocessor)
|
||||||
|
|
Loading…
Reference in New Issue