diff --git a/simplecpp.cpp b/simplecpp.cpp index 27108a4a..2223d431 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1364,7 +1364,9 @@ void simplecpp::TokenList::combineOperators() if (tok->next && tok->next->op == '.' && tok->next->location.col == (tok->location.col + 1) && tok->next->next && tok->next->next->op == '.' && tok->next->next->location.col == (tok->location.col + 2)) { tok->setstr("..."); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); continue; } @@ -1374,11 +1376,13 @@ void simplecpp::TokenList::combineOperators() deleteToken(tok->previous); if (sameline(tok, tok->next) && (isFloatSuffix(tok->next) || (tok->next && tok->next->startsWithOneOf("AaBbCcDdEeFfPp") && !isAlternativeAndBitandBitor(tok->next)))) { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } } if (tok->next && tok->next->number) { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } } @@ -1389,7 +1393,9 @@ void simplecpp::TokenList::combineOperators() (isHex(tok->str()) && (lastChar == 'P' || lastChar == 'p'))) && tok->next && tok->next->isOneOf("+-") && tok->next->next && tok->next->next->number) { tok->setstr(tok->str() + tok->next->op + tok->next->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } @@ -1406,21 +1412,27 @@ void simplecpp::TokenList::combineOperators() if (tok->op == '&' && !executableScope.top() && isAnonymousReferenceParameter(tok)) continue; tok->setstr(tok->str() + "="); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } else if ((tok->op == '|' || tok->op == '&') && tok->op == tok->next->op) { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } else if (tok->op == ':' && tok->next->op == ':') { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } else if (tok->op == '-' && tok->next->op == '>') { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } else if ((tok->op == '<' || tok->op == '>') && tok->op == tok->next->op) { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); if (tok->next && tok->next->op == '=' && tok->next->next && tok->next->next->op != '=') { tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } } else if ((tok->op == '+' || tok->op == '-') && tok->op == tok->next->op) { @@ -1431,6 +1443,7 @@ void simplecpp::TokenList::combineOperators() if (tok->next->next && tok->next->next->number) continue; tok->setstr(tok->str() + tok->next->str()); + tok->whitespaceahead = tok->next->whitespaceahead; deleteToken(tok->next); } } diff --git a/test.cpp b/test.cpp index 5bb980e1..3f996167 100644 --- a/test.cpp +++ b/test.cpp @@ -1911,6 +1911,14 @@ static void hashMacroTrailingWhitespace() "\"a b\"", preprocess(code, dui)); } +static void hashCombinedOperator() +{ + // the whitespace after an operator of two characters is kept + const char code[] = "#define str(x) #x\n" + "str(a == 0) str(a -> b) str(x... y)\n"; + ASSERT_EQUALS("\n\"a == 0\" \"a -> b\" \"x... y\"", preprocess(code)); +} + static void hashEscapeTrailingBackslash() { // an odd number of trailing backslashes would escape the closing quote, @@ -2427,38 +2435,22 @@ static void macro_c11_example4() // C11 6.10.3.5 EXAMPLE 4 // the comments are removed before preprocessing, like cppcheck and the simplecpp program do simplecpp::DUI dui; dui.removeComments = true; - // TODO: the space before == is lost after the comment and newline in the # argument - TODO_ASSERT_EQUALS("\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "printf ( \"x\" \"1\" \"= %d, x\" \"2\" \"= %s\" , x1 , x2 ) ;\n" - "fputs ( \"strncmp(\\\"abc\\\\0d\\\", \\\"abc\\\", '\\\\4') == 0\"\n" - "\": @\\n\" , s ) ;\n" - "\"vers2.h\"\n" - "\"hello\" ;\n" - "\"hello\" \", world\"", - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "printf ( \"x\" \"1\" \"= %d, x\" \"2\" \"= %s\" , x1 , x2 ) ;\n" - "fputs ( \"strncmp(\\\"abc\\\\0d\\\", \\\"abc\\\", '\\\\4') ==0\"\n" - "\": @\\n\" , s ) ;\n" - "\"vers2.h\"\n" - "\"hello\" ;\n" - "\"hello\" \", world\"", - preprocess(code, dui)); + ASSERT_EQUALS("\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "printf ( \"x\" \"1\" \"= %d, x\" \"2\" \"= %s\" , x1 , x2 ) ;\n" + "fputs ( \"strncmp(\\\"abc\\\\0d\\\", \\\"abc\\\", '\\\\4') == 0\"\n" + "\": @\\n\" , s ) ;\n" + "\"vers2.h\"\n" + "\"hello\" ;\n" + "\"hello\" \", world\"", + preprocess(code, dui)); } static void macro_c11_example5() // C11 6.10.3.5 EXAMPLE 5 @@ -5660,6 +5652,7 @@ static void runTests(int argc, char **argv, Input input) TEST_CASE(hashEscape); TEST_CASE(hashComment); TEST_CASE(hashMacroTrailingWhitespace); + TEST_CASE(hashCombinedOperator); TEST_CASE(hashEscapeTrailingBackslash); TEST_CASE(hashhash1); TEST_CASE(hashhash2);