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;
|
Settings settings;
|
||||||
Tokenizer tokenizer(&settings, NULL);
|
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% )"))
|
if (Token::Match(tokenizer.tokens(), "( %var% )"))
|
||||||
{
|
{
|
||||||
std::map<std::string,std::string>::const_iterator var = variables.find(tokenizer.tokens()->strAt(1));
|
std::map<std::string,std::string>::const_iterator var = cfg.find(tokenizer.tokens()->strAt(1));
|
||||||
if (var != variables.end())
|
if (var != cfg.end())
|
||||||
{
|
{
|
||||||
const std::string &value = (*var).second;
|
const std::string &value = (*var).second;
|
||||||
condition = (value == "0") ? "0" : "1";
|
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 (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";
|
condition = "1";
|
||||||
else if (match)
|
else if (match)
|
||||||
condition = "0";
|
condition = "0";
|
||||||
|
@ -1483,7 +1483,7 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
||||||
|
|
||||||
if (Token::Match(tok, "defined ( %var% )"))
|
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");
|
tok->str("1");
|
||||||
else if (match)
|
else if (match)
|
||||||
tok->str("0");
|
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 (Token::Match(tok, "defined %var%"))
|
||||||
{
|
{
|
||||||
if (variables.find(tok->strAt(1)) != variables.end())
|
if (cfg.find(tok->strAt(1)) != cfg.end())
|
||||||
tok->str("1");
|
tok->str("1");
|
||||||
else if (match)
|
else if (match)
|
||||||
tok->str("0");
|
tok->str("0");
|
||||||
|
@ -1507,8 +1507,8 @@ void Preprocessor::simplifyCondition(const std::map<std::string, std::string> &v
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, std::string>::const_iterator it = variables.find(tok->str());
|
const std::map<std::string, std::string>::const_iterator it = cfg.find(tok->str());
|
||||||
if (it != variables.end())
|
if (it != cfg.end())
|
||||||
{
|
{
|
||||||
if (!it->second.empty())
|
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())
|
for (Token *tok = const_cast<Token *>(tokenizer.tokens()); tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
while (Token::Match(tok, "(|%oror% %any% %oror% 1"))
|
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)
|
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);
|
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
|
// For the error report
|
||||||
unsigned int lineno = 0;
|
unsigned int lineno = 0;
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Get preprocessed code for a given configuration
|
* 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
|
* simplify condition
|
||||||
|
|
|
@ -221,6 +221,10 @@ private:
|
||||||
|
|
||||||
// inline suppression, missingInclude
|
// inline suppression, missingInclude
|
||||||
TEST_CASE(inline_suppression_for_missing_include);
|
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);
|
preprocessor.preprocess(src, processedFile, cfg, "test.c", paths);
|
||||||
ASSERT_EQUALS("", errout.str());
|
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)
|
REGISTER_TEST(TestPreprocessor)
|
||||||
|
|
Loading…
Reference in New Issue