Preprocessor: fix handling of (1&&2) condition
This commit is contained in:
parent
274fd2b985
commit
07a1222ac6
|
@ -1446,7 +1446,7 @@ std::list<std::string> Preprocessor::getcfgs(const std::string &filedata, const
|
|||
}
|
||||
|
||||
|
||||
void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &variables, std::string &condition, bool match)
|
||||
void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &cfg, std::string &condition, bool match)
|
||||
{
|
||||
Settings settings;
|
||||
Tokenizer tokenizer(&settings, NULL);
|
||||
|
@ -1455,8 +1455,8 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
|
||||
if (Token::Match(tokenizer.tokens(), "( %var% )"))
|
||||
{
|
||||
std::map<std::string,std::string>::const_iterator var = variables.find(tokenizer.tokens()->strAt(1));
|
||||
if (var != variables.end())
|
||||
std::map<std::string,std::string>::const_iterator var = cfg.find(tokenizer.tokens()->strAt(1));
|
||||
if (var != cfg.end())
|
||||
{
|
||||
const std::string &value = (*var).second;
|
||||
condition = (value == "0") ? "0" : "1";
|
||||
|
@ -1468,7 +1468,7 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
|
||||
if (Token::Match(tokenizer.tokens(), "( ! %var% )"))
|
||||
{
|
||||
if (variables.find(tokenizer.tokens()->strAt(2)) == variables.end())
|
||||
if (cfg.find(tokenizer.tokens()->strAt(2)) == cfg.end())
|
||||
condition = "1";
|
||||
else if (match)
|
||||
condition = "0";
|
||||
|
@ -1483,7 +1483,7 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
|
||||
if (Token::Match(tok, "defined ( %var% )"))
|
||||
{
|
||||
if (variables.find(tok->strAt(2)) != variables.end())
|
||||
if (cfg.find(tok->strAt(2)) != cfg.end())
|
||||
tok->str("1");
|
||||
else if (match)
|
||||
tok->str("0");
|
||||
|
@ -1497,7 +1497,7 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
|
||||
if (Token::Match(tok, "defined %var%"))
|
||||
{
|
||||
if (variables.find(tok->strAt(1)) != variables.end())
|
||||
if (cfg.find(tok->strAt(1)) != cfg.end())
|
||||
tok->str("1");
|
||||
else if (match)
|
||||
tok->str("0");
|
||||
|
@ -1507,8 +1507,8 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
continue;
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string>::const_iterator it = variables.find(tok->str());
|
||||
if (it != variables.end())
|
||||
const std::map<std::string, std::string>::const_iterator it = cfg.find(tok->str());
|
||||
if (it != cfg.end())
|
||||
{
|
||||
if (!it->second.empty())
|
||||
{
|
||||
|
@ -1563,6 +1563,17 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
}
|
||||
}
|
||||
|
||||
for (Token *tok = const_cast<Token *>(tokenizer.tokens()); tok; tok = tok->next())
|
||||
{
|
||||
if (Token::Match(tok, "(|%oror%|&& %num% &&|%oror%|)"))
|
||||
{
|
||||
if (tok->next()->str() != "0")
|
||||
{
|
||||
tok->next()->str("1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Token *tok = const_cast<Token *>(tokenizer.tokens()); tok; tok = tok->next())
|
||||
{
|
||||
while (Token::Match(tok, "(|%oror% %any% %oror% 1"))
|
||||
|
@ -1583,8 +1594,18 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
|||
|
||||
bool Preprocessor::match_cfg_def(const std::map<std::string, std::string> &cfg, std::string def)
|
||||
{
|
||||
//std::cout << "cfg: \"" << cfg << "\" ";
|
||||
//std::cout << "def: \"" << def << "\"";
|
||||
/*
|
||||
std::cout << "cfg: \"";
|
||||
for (std::map<std::string, std::string>::const_iterator it = cfg.begin(); it != cfg.end(); ++it)
|
||||
{
|
||||
std::cout << it->first;
|
||||
if (!it->second.empty())
|
||||
std::cout << "=" << it->second;
|
||||
std::cout << ";";
|
||||
}
|
||||
std::cout << "\" ";
|
||||
std::cout << "def: \"" << def << "\"\n";
|
||||
*/
|
||||
|
||||
simplifyCondition(cfg, def, true);
|
||||
|
||||
|
@ -1601,7 +1622,7 @@ bool Preprocessor::match_cfg_def(const std::map<std::string, std::string> &cfg,
|
|||
}
|
||||
|
||||
|
||||
std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, const std::string &filename, const Settings *settings, ErrorLogger *errorLogger)
|
||||
std::string Preprocessor::getcode(const std::string &filedata, const std::string &cfg, const std::string &filename, const Settings *settings, ErrorLogger *errorLogger)
|
||||
{
|
||||
// For the error report
|
||||
unsigned int lineno = 0;
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
/**
|
||||
* Get preprocessed code for a given configuration
|
||||
*/
|
||||
static std::string getcode(const std::string &filedata, std::string cfg, const std::string &filename, const Settings *settings, ErrorLogger *errorLogger);
|
||||
static std::string getcode(const std::string &filedata, const std::string &cfg, const std::string &filename, const Settings *settings, ErrorLogger *errorLogger);
|
||||
|
||||
/**
|
||||
* simplify condition
|
||||
|
|
|
@ -221,6 +221,10 @@ private:
|
|||
|
||||
// inline suppression, missingInclude
|
||||
TEST_CASE(inline_suppression_for_missing_include);
|
||||
|
||||
// Using -D to predefine symbols
|
||||
TEST_CASE(predefine1);
|
||||
TEST_CASE(predefine2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2853,6 +2857,38 @@ private:
|
|||
preprocessor.preprocess(src, processedFile, cfg, "test.c", paths);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void predefine1()
|
||||
{
|
||||
Settings settings;
|
||||
|
||||
const std::string src("#ifdef X || Y\n"
|
||||
"Fred & Wilma\n"
|
||||
"#endif\n");
|
||||
|
||||
std::string actual = Preprocessor::getcode(src, "X=1", "test.c", &settings, this);
|
||||
|
||||
ASSERT_EQUALS("\nFred & Wilma\n\n", actual);
|
||||
}
|
||||
|
||||
void predefine2()
|
||||
{
|
||||
Settings settings;
|
||||
|
||||
const std::string src("#ifdef X && Y\n"
|
||||
"Fred & Wilma\n"
|
||||
"#endif\n");
|
||||
{
|
||||
std::string actual = Preprocessor::getcode(src, "X=1", "test.c", &settings, this);
|
||||
ASSERT_EQUALS("\n\n\n", actual);
|
||||
}
|
||||
|
||||
{
|
||||
std::string actual = Preprocessor::getcode(src, "X=1;Y=2", "test.c", &settings, this);
|
||||
ASSERT_EQUALS("\nFred & Wilma\n\n", actual);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestPreprocessor)
|
||||
|
|
Loading…
Reference in New Issue