diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 974485687..278b8196f 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1446,7 +1446,7 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const } -void Preprocessor::simplifyCondition(const std::map &variables, std::string &condition, bool match) +void Preprocessor::simplifyCondition(const std::map &cfg, std::string &condition, bool match) { Settings settings; Tokenizer tokenizer(&settings, NULL); @@ -1455,8 +1455,8 @@ void Preprocessor::simplifyCondition(const std::map &v if (Token::Match(tokenizer.tokens(), "( %var% )")) { - std::map::const_iterator var = variables.find(tokenizer.tokens()->strAt(1)); - if (var != variables.end()) + std::map::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 &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 &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 &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 &v continue; } - const std::map::const_iterator it = variables.find(tok->str()); - if (it != variables.end()) + const std::map::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 &v } } + for (Token *tok = const_cast(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(tokenizer.tokens()); tok; tok = tok->next()) { while (Token::Match(tok, "(|%oror% %any% %oror% 1")) @@ -1583,8 +1594,18 @@ void Preprocessor::simplifyCondition(const std::map &v bool Preprocessor::match_cfg_def(const std::map &cfg, std::string def) { - //std::cout << "cfg: \"" << cfg << "\" "; - //std::cout << "def: \"" << def << "\""; +/* + std::cout << "cfg: \""; + for (std::map::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 &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; diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 4f9eefd7f..d02dd5130 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -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 diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index a9e4e0f53..4e19324ef 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -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)