Fixed #3536 (Preprocessor #if fails to correctly compare two #defined values)
This commit is contained in:
parent
813a193bb6
commit
fc84f55f80
|
@ -876,7 +876,25 @@ std::string Preprocessor::getdef(std::string line, bool def)
|
|||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplifies the variable map. For example if the map contains A=>B, B=>1, then A=>B is simplified to A=>1.
|
||||
* @param [in,out] variables - a map of variable name to variable value. This map will be modified.
|
||||
*/
|
||||
static void simplifyVarMap(std::map<std::string, std::string> &variables)
|
||||
{
|
||||
for (std::map<std::string, std::string>::iterator i = variables.begin(); i != variables.end(); ++i) {
|
||||
std::string& varValue = i->second;
|
||||
|
||||
// TODO: 1. tokenize the value, replace each token like this.
|
||||
// TODO: 2. handle function-macros too.
|
||||
|
||||
std::map<std::string, std::string>::iterator it = variables.find(varValue);
|
||||
while (it != variables.end() && it != i) {
|
||||
varValue = it->second;
|
||||
it = variables.find(varValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const std::string &filename)
|
||||
{
|
||||
|
@ -998,6 +1016,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
|
|||
varmap[varname] = value;
|
||||
}
|
||||
|
||||
simplifyVarMap(varmap);
|
||||
simplifyCondition(varmap, def, false);
|
||||
}
|
||||
|
||||
|
@ -1386,7 +1405,7 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &c
|
|||
condition = "0";
|
||||
}
|
||||
|
||||
bool Preprocessor::match_cfg_def(const std::map<std::string, std::string> &cfg, std::string def)
|
||||
bool Preprocessor::match_cfg_def(std::map<std::string, std::string> cfg, std::string def)
|
||||
{
|
||||
/*
|
||||
std::cout << "cfg: \"";
|
||||
|
@ -1401,6 +1420,7 @@ bool Preprocessor::match_cfg_def(const std::map<std::string, std::string> &cfg,
|
|||
std::cout << "def: \"" << def << "\"\n";
|
||||
*/
|
||||
|
||||
simplifyVarMap(cfg);
|
||||
simplifyCondition(cfg, def, true);
|
||||
|
||||
if (cfg.find(def) != cfg.end())
|
||||
|
|
|
@ -206,7 +206,7 @@ public:
|
|||
* @param def condition
|
||||
* @return result when evaluating the condition
|
||||
*/
|
||||
bool match_cfg_def(const std::map<std::string, std::string> &cfg, std::string def);
|
||||
bool match_cfg_def(std::map<std::string, std::string> cfg, std::string def);
|
||||
|
||||
static void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings);
|
||||
|
||||
|
|
|
@ -128,6 +128,8 @@ private:
|
|||
TEST_CASE(if_or_1);
|
||||
TEST_CASE(if_or_2);
|
||||
|
||||
TEST_CASE(if_macro_eq_macro); // #3536
|
||||
|
||||
TEST_CASE(multiline1);
|
||||
TEST_CASE(multiline2);
|
||||
TEST_CASE(multiline3);
|
||||
|
@ -1501,6 +1503,23 @@ private:
|
|||
ASSERT_EQUALS("\na1;\n\n", preprocessor.getcode(code, "Y", "test.c"));
|
||||
}
|
||||
|
||||
void if_macro_eq_macro() {
|
||||
const std::string code("#define A B\n"
|
||||
"#define B 1\n"
|
||||
"#define C 1\n"
|
||||
"#if A == C\n"
|
||||
"Wilma\n"
|
||||
"#else\n"
|
||||
"Betty\n"
|
||||
"#endif\n");
|
||||
Settings settings;
|
||||
Preprocessor preprocessor(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
std::map<std::string, std::string> actual;
|
||||
preprocessor.preprocess(istr, actual, "file.c");
|
||||
|
||||
ASSERT_EQUALS("\n\n\n\nWilma\n\n\n\n", actual[""]);
|
||||
}
|
||||
|
||||
void multiline1() {
|
||||
const char filedata[] = "#define str \"abc\" \\\n"
|
||||
|
|
Loading…
Reference in New Issue