From 5be85d71a03073ace748c1b985301ee66a6f1f30 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Sun, 8 Mar 2009 09:45:53 +0200 Subject: [PATCH] Fix ticket #145 (Line numbers are invalid if file is included inside #ifdef) http://apps.sourceforge.net/trac/cppcheck/ticket/145 --- src/preprocessor.cpp | 11 ++++++++--- test/testpreprocessor.cpp | 30 +++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 87644fb05..3d0316beb 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -447,10 +447,15 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg) for (std::list::const_iterator it = matching_ifdef.begin(); it != matching_ifdef.end(); ++it) match &= bool(*it); } - if (! match) - line = ""; - if (line.find("#if") == 0 || + if (line.find("#file \"") == 0 || + line.find("#endfile") == 0 ) + { + // We must not remove #file tags or line numbers + // are corrupted. File tags are removed by the tokenizer. + } + else if (!match || + line.find("#if") == 0 || line.find("#else") == 0 || line.find("#elif") == 0 || line.find("#endif") == 0) diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index add71854b..349000bd7 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -24,7 +24,7 @@ #include "testsuite.h" #include "../src/preprocessor.h" - +#include "../src/tokenize.h" #include #include @@ -106,6 +106,7 @@ private: TEST_CASE(multi_character_character); TEST_CASE(stringify); + TEST_CASE(ifdefwithfile); } @@ -324,6 +325,33 @@ private: ASSERT_EQUALS(2, static_cast(actual.size())); } + void ifdefwithfile() + { + // Handling include guards.. + const char filedata[] = "#ifdef ABC\n" + "#file \"abc.h\"\n" + "class A{};/*\n\n\n\n\n\n\n*/\n" + "#endfile\n" + "#endif\n" + "int main() {}\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + std::map actual; + Preprocessor preprocessor; + preprocessor.preprocess(istr, actual, "file.c"); + + Tokenizer tok; + std::istringstream codeStream( actual[""] ); + tok.tokenize( codeStream, "main.cpp" ); + + ASSERT_EQUALS( "\n\n##file 0\n1:\n2:\n3:\n4: int main ( ) { }\n", tok.tokens()->stringifyList() ); + + // Expected configurations: "" and "ABC" + ASSERT_EQUALS(2, static_cast(actual.size())); + ASSERT_EQUALS("\n#file \"abc.h\"\n\n\n\n\n\n\n\n\n#endfile\n\nint main() {}\n", actual[""]); + ASSERT_EQUALS("\n#file \"abc.h\"\nclass A{};\n\n\n\n\n\n\n\n#endfile\n\nint main() {}\n", actual["ABC"]); + } void newlines() {