diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 6c37e43a1..bdce31069 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1380,19 +1380,13 @@ bool Preprocessor::match_cfg_def(const std::map &cfg, } -std::string Preprocessor::getcode(const std::string &filedata, const std::string &cfg, const std::string &filename) +/** + * Get cfgmap - a map of macro names and values + */ +static std::map getcfgmap(const std::string &cfg) { - // For the error report - unsigned int lineno = 0; - - std::ostringstream ret; - - bool match = true; - std::list matching_ifdef; - std::list matched_ifdef; - - // Create a map for the cfg for faster access to defines std::map cfgmap; + if (!cfg.empty()) { std::string::size_type pos = 0; for (;;) { @@ -1417,6 +1411,24 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string } } + return cfgmap; +} + + +std::string Preprocessor::getcode(const std::string &filedata, const std::string &cfg, const std::string &filename) +{ + // For the error report + unsigned int lineno = 0; + + std::ostringstream ret; + + bool match = true; + std::list matching_ifdef; + std::list matched_ifdef; + + // Create a map for the cfg for faster access to defines + std::map cfgmap(getcfgmap(cfg)); + std::stack filenames; filenames.push(filename); std::stack lineNumbers; @@ -1596,7 +1608,7 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string ret << line << "\n"; } - return expandMacros(ret.str(), filename, _errorLogger); + return expandMacros(ret.str(), filename, cfg, _errorLogger); } void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg) @@ -2445,7 +2457,7 @@ static bool getlines(std::istream &istr, std::string &line) return true; } -std::string Preprocessor::expandMacros(const std::string &code, std::string filename, ErrorLogger *errorLogger) +std::string Preprocessor::expandMacros(const std::string &code, std::string filename, const std::string &cfg, ErrorLogger *errorLogger) { // Search for macros and expand them.. // -------------------------------------------- @@ -2453,6 +2465,19 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file // Available macros (key=macroname, value=macro). std::map macros; + { + // fill up "macros" with user defined macros + const std::map cfgmap(getcfgmap(cfg)); + std::map::const_iterator it; + for (it = cfgmap.begin(); it != cfgmap.end(); ++it) { + std::string s = it->first; + if (!it->second.empty()) + s += " " + it->second; + PreprocessorMacro *macro = new PreprocessorMacro(s); + macros[it->first] = macro; + } + } + // Current line number unsigned int linenr = 1; diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 2e881c518..b30587e28 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -130,10 +130,11 @@ protected: * expand macros in code. ifdefs etc are ignored so the code must be a single configuration * @param code The input code * @param filename filename of source file + * @param cfg user given -D configuration * @param errorLogger Error logger to write errors to (if any) * @return the expanded string */ - static std::string expandMacros(const std::string &code, std::string filename, ErrorLogger *errorLogger); + static std::string expandMacros(const std::string &code, std::string filename, const std::string &cfg, ErrorLogger *errorLogger); /** * Remove comments from code. This should only be called from read(). diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 41842c189..dafef1de4 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -46,7 +46,7 @@ public: } static std::string expandMacros(std::string code, ErrorLogger *errorLogger = 0) { - return Preprocessor::expandMacros(code, "file.cpp", errorLogger); + return Preprocessor::expandMacros(code, "file.cpp", "", errorLogger); } static int getHeaderFileName(std::string &str) { @@ -227,6 +227,7 @@ private: TEST_CASE(predefine1); TEST_CASE(predefine2); TEST_CASE(predefine3); + TEST_CASE(predefine4); // Test Preprocessor::simplifyCondition TEST_CASE(simplifyCondition); @@ -2868,6 +2869,14 @@ private: ASSERT_EQUALS("\n\n\nFred & Wilma\n\n", actual); } + void predefine4() { + // #3577 + const char code[] = "char buf[X];\n"; + Preprocessor preprocessor(NULL,this); + const std::string actual = preprocessor.getcode(code, "X=123", "test.c"); + ASSERT_EQUALS("char buf[$123];\n", actual); + } + void simplifyCondition() { // Ticket #2794 std::map cfg;