diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 18e31d586..97c3c27c4 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -44,6 +44,11 @@ std::string Preprocessor::read(std::istream &istr) // For the error report int lineno = 1; + // handling + // when this is encountered the will be "skipped". + // on the next , extra newlines will be added + unsigned int newlines = 0; + std::ostringstream code; for (char ch = (char)istr.get(); istr.good(); ch = (char)istr.get()) { @@ -101,7 +106,6 @@ std::string Preprocessor::read(std::istream &istr) // String constants.. else if (ch == '\"') { - int newlines = 0; code << "\""; do { @@ -121,9 +125,6 @@ std::string Preprocessor::read(std::istream &istr) code << std::string(1, ch); } while (istr.good() && ch != '\"'); - - // Insert extra newlines after the string in case the string contained \newline sequences - code << std::string(newlines, '\n'); } // char constants.. @@ -141,10 +142,30 @@ std::string Preprocessor::read(std::istream &istr) code << "\'"; } + // .. + else if (ch == '\\') + { + char chNext = (char)istr.peek(); + if (chNext == '\n') + { + ++newlines; + (void)istr.get(); // Skip the "" + } + else + code << "\\"; + } + // Just some code.. else { code << std::string(1, ch); + + // if there has been sequences, add extra newlines.. + if ( ch == '\n' && newlines > 0 ) + { + code << std::string(newlines, '\n'); + newlines = 0; + } } } @@ -219,17 +240,6 @@ void Preprocessor::preprocess(std::istream &istr, std::string &processedFile, st // Remove space characters that are after or before new line character processedFile = removeSpaceNearNL(processedFile); - // Using the backslash at the end of a line.. - std::string::size_type loc = 0; - while ((loc = processedFile.rfind("\\\n")) != std::string::npos) - { - processedFile.erase(loc, 2); - if (loc > 0 && processedFile[loc-1] != ' ') - processedFile.insert(loc, " "); - if ((loc = processedFile.find("\n", loc)) != std::string::npos) - processedFile.insert(loc, "\n"); - } - processedFile = replaceIfDefined(processedFile); processedFile = expandMacros(processedFile); @@ -436,8 +446,6 @@ std::string Preprocessor::expandMacros(std::string code) // Get macro.. std::string::size_type endpos = code.find("\n", defpos + 6); - while (endpos != std::string::npos && code[endpos-1] == '\\') - endpos = code.find("\n", endpos + 1); if (endpos == std::string::npos) { code.erase(defpos); @@ -448,14 +456,6 @@ std::string Preprocessor::expandMacros(std::string code) std::string macro(code.substr(defpos + 8, endpos - defpos - 7)); code.erase(defpos, endpos - defpos); - // Remove "\\\n" from the macro - while (macro.find("\\\n") != std::string::npos) - { - macro.erase(macro.find("\\\n"), 2); - code.insert(defpos, "\n"); - ++defpos; - } - // Tokenize the macro to make it easier to handle Tokenizer tokenizer; std::istringstream istr(macro.c_str()); diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index b8af8eeb0..6ea81ca35 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -61,7 +61,8 @@ private: TEST_CASE(if_cond1); - TEST_CASE(multiline); + TEST_CASE(multiline1); + TEST_CASE(multiline2); TEST_CASE(if_defined); // "#if defined(AAA)" => "#ifdef AAA" @@ -69,7 +70,6 @@ private: TEST_CASE(macro_simple1); TEST_CASE(macro_simple2); TEST_CASE(macro_mismatch); - TEST_CASE(macro_multiline); TEST_CASE(preprocessor_inside_string); } @@ -375,21 +375,29 @@ private: } - void multiline() + void multiline1() { - const char filedata[] = "#define str \"abc\" \\ \n" + const char filedata[] = "#define str \"abc\" \\\n" " \"def\" \n" "abcdef = str;\n"; // Preprocess => actual result.. std::istringstream istr(filedata); - std::map actual; Preprocessor preprocessor; - preprocessor.preprocess(istr, actual); + ASSERT_EQUALS("#define str \"abc\" \"def\" \n\nabcdef = str;\n", preprocessor.read(istr)); + } - // Compare results.. - ASSERT_EQUALS("\n\nabcdef = \"abc\"\"def\"\n", actual[""]); - ASSERT_EQUALS(1, actual.size()); + + void multiline2() + { + const char filedata[] = "#define sqr(aa) aa * \\\n" + " aa\n" + "sqr(5);\n"; + + // Preprocess => actual result.. + std::istringstream istr(filedata); + Preprocessor preprocessor; + ASSERT_EQUALS("#define sqr(aa) aa * aa\n\nsqr(5);\n", preprocessor.read(istr)); } @@ -398,6 +406,7 @@ private: const char filedata[] = "#if defined(AAA)\n" "#endif\n"; + // Expected result.. std::string expected("#ifdef AAA\n#endif\n"); @@ -427,14 +436,6 @@ private: ASSERT_EQUALS("\nAAA(5);\n", Preprocessor::expandMacros(filedata)); } - void macro_multiline() - { - const char filedata[] = "#define sqr(aa) aa * \\\n" - " aa\n" - "sqr(5);\n"; - ASSERT_EQUALS("\n\n5*5;\n", Preprocessor::expandMacros(filedata)); - } - void preprocessor_inside_string() { const char filedata[] = "int main()"