preprocessor: Handle "<backslash><newline>" better
This commit is contained in:
parent
3d8791eebd
commit
94667320e8
|
@ -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());
|
||||
|
|
|
@ -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()"
|
||||
|
|
Loading…
Reference in New Issue