Fixed #3834 (Preprocessor: -U doesn't work)

This commit is contained in:
Daniel Marjamäki 2012-07-18 20:57:00 +02:00
parent 17c27f51ff
commit dc6c3228d7
3 changed files with 90 additions and 4 deletions

View File

@ -810,7 +810,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = ostr.str();
}
if (_settings && (!_settings->userDefines.empty() || !_settings->userUndefs.empty())) {
if (_settings && !_settings->userDefines.empty()) {
std::map<std::string, std::string> defs;
// TODO: break out this code. There is other similar code.
@ -849,12 +849,41 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
processedFile = replaceIfDefined(processedFile);
// Get all possible configurations..
if (!_settings || (_settings && _settings->userDefines.empty()))
resultConfigurations = getcfgs(processedFile, filename);
resultConfigurations = getcfgs(processedFile, filename);
// Remove configurations that are disabled by -U
handleUndef(resultConfigurations);
}
}
void Preprocessor::handleUndef(std::list<std::string> &configurations) const
{
if (_settings && !_settings->userUndefs.empty()) {
for (std::list<std::string>::iterator cfg = configurations.begin(); cfg != configurations.end();) {
const std::string strcfg(*cfg);
bool undef = false;
for (std::set<std::string>::const_iterator it = _settings->userUndefs.begin(); it != _settings->userUndefs.end(); ++it) {
if (*it == *cfg)
undef = true;
else if (cfg->compare(0,it->length(),*it)==0 && cfg->find_first_of(";=") == it->length())
undef = true;
else if (cfg->find(";" + *it) == std::string::npos)
;
else if (cfg->find(";" + *it + ";") != std::string::npos)
undef = true;
else if (cfg->find(";" + *it + "=") != std::string::npos)
undef = true;
else if (cfg->find(";" + *it) + it->size() + 1U == cfg->size())
undef = true;
}
if (undef)
configurations.erase(cfg++);
else
cfg++;
}
}
}
// Get the DEF in this line: "#ifdef DEF"
std::string Preprocessor::getdef(std::string line, bool def)

View File

@ -124,6 +124,8 @@ public:
bool validateCfg(const std::string &code, const std::string &cfg);
void validateCfgError(const std::string &cfg);
void handleUndef(std::list<std::string> &configurations) const;
protected:
/**

View File

@ -268,6 +268,9 @@ private:
TEST_CASE(undef7);
TEST_CASE(undef8);
TEST_CASE(undef9);
TEST_CASE(undef10);
TEST_CASE(handleUndef);
TEST_CASE(macroChar);
@ -3502,7 +3505,7 @@ private:
preprocessor.preprocess(istr, actual, "file.c");
// Compare results..
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[file.c:2]: (information) Include file: \"config.h\" not found.\n", errout.str());
ASSERT_EQUALS("\n\n\n\nvoid foo();\n", actual[""]);
}
@ -3529,6 +3532,58 @@ private:
ASSERT_EQUALS("\n\nFred & Wilma\n\n\n\n", actual[""]);
}
void undef10() {
Settings settings;
const char filedata[] = "#ifndef X\n"
"#endif\n"
"#ifndef Y\n"
"#endif\n";
// Preprocess => actual result..
std::istringstream istr(filedata);
settings.userUndefs.insert("X"); // User undefs should override internal defines
Preprocessor preprocessor(&settings, this);
std::string processedFile;
std::list<std::string> resultConfigurations;
const std::list<std::string> includePaths;
preprocessor.preprocess(istr, processedFile, resultConfigurations, "file.c", includePaths);
// Compare results. Two configurations "" and "Y". No "X".
ASSERT_EQUALS(2U, resultConfigurations.size());
ASSERT_EQUALS("", resultConfigurations.front());
ASSERT_EQUALS("Y", resultConfigurations.back());
}
void handleUndef() {
Settings settings;
settings.userUndefs.insert("X");
const Preprocessor preprocessor(&settings, this);
std::list<std::string> configurations;
// configurations to keep
configurations.clear();
configurations.push_back("XY;");
configurations.push_back("AX;");
configurations.push_back("A;XY");
preprocessor.handleUndef(configurations);
ASSERT_EQUALS(3U, configurations.size());
// configurations to remove
configurations.clear();
configurations.push_back("X;Y");
configurations.push_back("X=1;Y");
configurations.push_back("A;X;B");
configurations.push_back("A;X=1;B");
configurations.push_back("A;X");
configurations.push_back("A;X=1");
preprocessor.handleUndef(configurations);
ASSERT_EQUALS(0U, configurations.size());
}
void macroChar() {
const char filedata[] = "#define X 1\nX\n";
ASSERT_EQUALS("\n$1\n", OurPreprocessor::expandMacros(filedata,NULL));