diff --git a/src/preprocessor.cpp b/src/preprocessor.cpp index 414e42c41..584eceebe 100644 --- a/src/preprocessor.cpp +++ b/src/preprocessor.cpp @@ -789,33 +789,65 @@ std::string Preprocessor::expandMacros(std::string code, const std::string &file // String or char.. if (code[pos1] == '\"' || code[pos1] == '\'') { - //char ch = code[pos1]; + // Find the end of the string/char.. ++pos1; - while (code[pos1] != ch) + while (pos1 < code.size() && code[pos1] != ch && code[pos1] != '\n') { if (code[pos1] == '\\') ++pos1; ++pos1; - - if (!code[pos1]) - { - // End of file was reached without finding pair - if (errorLogger) - { - std::list locationList; - ErrorLogger::ErrorMessage::FileLocation loc; - loc.line = 0; - loc.file = filename; - locationList.push_back(loc); - errorLogger->reportErr( - ErrorLogger::ErrorMessage(locationList, - "error", - std::string("No pair for character (") + ch + "). Can't process file. File is either invalid or unicode, which is currently not supported.", - "noQuoteCharPair")); - } - return ""; - } } + + // End of line/file was reached without finding pair + if (pos1 >= code.size() || code[pos1] == '\n') + { + if (errorLogger) + { + std::string fname(filename); + int lineno = 0; + for (std::string::size_type p = pos1; p > 0; --p) + { + // newline.. + if (code[p-1] == '\n') + lineno++; + + // #file.. + else if (code[p-1] == '#') + { + // Previous char should be a newline.. + if (p == 1 || code[p-2] == '\n') + { + // #file.. + if (code.substr(p - 1, 6) == "#file ") + { + fname = code.substr(p + 5, code.find("\n", p) - p - 5); + break; + } + + else + ++lineno; + } + } + + // start of file.. + else if (p == 1) + ++lineno; + } + + std::list locationList; + ErrorLogger::ErrorMessage::FileLocation loc; + loc.line = lineno; + loc.file = fname; + locationList.push_back(loc); + errorLogger->reportErr( + ErrorLogger::ErrorMessage(locationList, + "error", + std::string("No pair for character (") + ch + "). Can't process file. File is either invalid or unicode, which is currently not supported.", + "noQuoteCharPair")); + } + return ""; + } + continue; } diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 3e1c645f6..5430c1374 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -822,17 +822,33 @@ private: void missing_doublequote() { - const char filedata[] = "#define a\n" - "#ifdef 1\n" - "\"\n" - "#endif\n"; + { + const char filedata[] = "#define a\n" + "#ifdef 1\n" + "\"\n" + "#endif\n"; - // expand macros.. - errout.str(""); - std::string actual = OurPreprocessor::expandMacros(filedata, this); + // expand macros.. + errout.str(""); + const std::string actual(OurPreprocessor::expandMacros(filedata, this)); - ASSERT_EQUALS("", actual); - ASSERT_EQUALS("[file.cpp:0]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported.\n", errout.str()); + ASSERT_EQUALS("", actual); + ASSERT_EQUALS("[file.cpp:3]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported.\n", errout.str()); + } + + { + const char filedata[] = "#file abc.h\n" + "#define a\n" + "\"\n" + "#endfile\n"; + + // expand macros.. + errout.str(""); + const std::string actual(OurPreprocessor::expandMacros(filedata, this)); + + ASSERT_EQUALS("", actual); + ASSERT_EQUALS("[abc.h:2]: (error) No pair for character (\"). Can't process file. File is either invalid or unicode, which is currently not supported.\n", errout.str()); + } } };