diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 6771858fd..ac5b8c721 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1673,6 +1673,9 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string } } + std::stack filenames; + filenames.push(filename); + std::stack lineNumbers; std::istringstream istr(filedata); std::string line; while (getline(istr, line)) @@ -1811,7 +1814,7 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string { Settings settings2(*settings); Preprocessor preprocessor(&settings2, errorLogger); - preprocessor.error(filename, lineno, line); + preprocessor.error(filenames.top(), lineno, line); } return ""; } @@ -1829,6 +1832,25 @@ std::string Preprocessor::getcode(const std::string &filedata, const std::string { // We must not remove #file tags or line numbers // are corrupted. File tags are removed by the tokenizer. + + // Keep location info updated + if (line.compare(0, 7, "#file \"") == 0) + { + filenames.push(line.substr(7, line.size() - 8)); + lineNumbers.push(lineno); + lineno = 0; + } + else if (line.compare(0, 8, "#endfile") == 0) + { + if (filenames.size() > 1U) + filenames.pop(); + + if (!lineNumbers.empty()) + { + lineno = lineNumbers.top(); + lineNumbers.pop(); + } + } } else if (!match || line.compare(0, 1, "#") == 0) { diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 87b7994ab..790d0d97b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -91,6 +91,7 @@ private: TEST_CASE(error2); TEST_CASE(error3); + TEST_CASE(error4); // #2919 - wrong filename is reported TEST_CASE(if0_exclude); TEST_CASE(if0_whitespace); @@ -639,6 +640,8 @@ private: void error2() { + errout.str(""); + const char filedata[] = "#error ê\n" "#warning ê\n" "123"; @@ -653,6 +656,7 @@ private: void error3() { + errout.str(""); Settings settings; settings.userDefines = "__cplusplus"; const std::string code("#error hello world!\n"); @@ -660,6 +664,30 @@ private: ASSERT_EQUALS("[test.c:1]: (error) #error hello world!\n", errout.str()); } + // Ticket #2919 - wrong filename reported for #error + void error4() + { + // In included file + { + errout.str(""); + Settings settings; + settings.userDefines = "TEST"; + const std::string code("#file \"ab.h\"\n#error hello world!\n#endfile"); + Preprocessor::getcode(code, "TEST", "test.c", &settings, this); + ASSERT_EQUALS("[ab.h:1]: (error) #error hello world!\n", errout.str()); + } + + // After including a file + { + errout.str(""); + Settings settings; + settings.userDefines = "TEST"; + const std::string code("#file \"ab.h\"\n\n#endfile\n#error aaa"); + Preprocessor::getcode(code, "TEST", "test.c", &settings, this); + ASSERT_EQUALS("[test.c:2]: (error) #error aaa\n", errout.str()); + } + } + void if0_exclude() { Settings settings;