}
}
-static const char *reverseOverSpaces(const char *First, const char *Last) {
+static const char *findLastNonSpace(const char *First, const char *Last) {
assert(First <= Last);
- const char *PrevLast = Last;
- while (First != Last && isHorizontalWhitespace(Last[-1])) {
- PrevLast = Last;
+ while (First != Last && isHorizontalWhitespace(Last[-1]))
--Last;
- }
- return PrevLast;
+ return Last;
+}
+
+static const char *findFirstTrailingSpace(const char *First,
+ const char *Last) {
+ const char *LastNonSpace = findLastNonSpace(First, Last);
+ if (Last == LastNonSpace)
+ return Last;
+ assert(isHorizontalWhitespace(LastNonSpace[0]));
+ return LastNonSpace + 1;
}
static void skipLineComment(const char *&First, const char *const End) {
}
// Deal with "//..." and "/*...*/".
- append(First, reverseOverSpaces(First, Last));
+ append(First, findFirstTrailingSpace(First, Last));
First = Last;
if (Last[1] == '/') {
} while (Last != End && !isVerticalWhitespace(*Last));
// Print out the string.
- if (Last == End || Last == First || Last[-1] != '\\') {
- append(First, reverseOverSpaces(First, Last));
+ const char *LastBeforeTrailingSpace = findLastNonSpace(First, Last);
+ if (Last == End || LastBeforeTrailingSpace == First ||
+ LastBeforeTrailingSpace[-1] != '\\') {
+ append(First, LastBeforeTrailingSpace);
First = Last;
skipNewline(First, End);
return;
}
- // Print up to the backslash, backing up over spaces.
- append(First, reverseOverSpaces(First, Last - 1));
+ // Print up to the backslash, backing up over spaces. Preserve at least one
+ // space, as the space matters when tokens are separated by a line
+ // continuation.
+ append(First, findFirstTrailingSpace(
+ First, LastBeforeTrailingSpace - 1));
First = Last;
skipNewline(First, End);
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO(\t)\tcon \t tent\t", Out));
- EXPECT_STREQ("#define MACRO() con \t tent\t\n", Out.data());
+ EXPECT_STREQ("#define MACRO() con \t tent\n", Out.data());
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO(\f)\fcon \f tent\f", Out));
- EXPECT_STREQ("#define MACRO() con \f tent\f\n", Out.data());
+ EXPECT_STREQ("#define MACRO() con \f tent\n", Out.data());
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO(\v)\vcon \v tent\v", Out));
- EXPECT_STREQ("#define MACRO() con \v tent\v\n", Out.data());
+ EXPECT_STREQ("#define MACRO() con \v tent\n", Out.data());
ASSERT_FALSE(minimizeSourceToDependencyDirectives(
"#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v", Out));
- EXPECT_STREQ("#define MACRO con\f\t\vtent\v\n", Out.data());
+ EXPECT_STREQ("#define MACRO con\f\t\vtent\n", Out.data());
}
TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) {
EXPECT_STREQ("#define GUA RD\n", Out.data());
}
+TEST(MinimizeSourceToDependencyDirectivesTest,
+ WhitespaceAfterLineContinuationSlash) {
+ SmallVector<char, 128> Out;
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
+ "2 + \\\t\n"
+ "3\n",
+ Out));
+ EXPECT_STREQ("#define A 1 + 2 + 3\n", Out.data());
+}
+
TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
SmallVector<char, 128> Out;