preprocessor: Handle "<backslash><newline>" better

This commit is contained in:
Daniel Marjamäki 2009-01-11 07:19:28 +00:00
parent 3d8791eebd
commit 94667320e8
2 changed files with 43 additions and 42 deletions

View File

@ -44,6 +44,11 @@ std::string Preprocessor::read(std::istream &istr)
// For the error report
int lineno = 1;
// handling <backspace><newline>
// when this is encountered the <backspace><newline> will be "skipped".
// on the next <newline>, 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 << "\'";
}
// <backspace><newline>..
else if (ch == '\\')
{
char chNext = (char)istr.peek();
if (chNext == '\n')
{
++newlines;
(void)istr.get(); // Skip the "<backspace><newline>"
}
else
code << "\\";
}
// Just some code..
else
{
code << std::string(1, ch);
// if there has been <backspace><newline> 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());

View File

@ -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<std::string, std::string> 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()"