[PATCH] Support for CR LF newlines.

Alexander Kornienko alexfh at google.com
Wed Sep 11 02:24:02 PDT 2013


  Apparently, Arcanist doesn't like our FormatTests.cpp, and truncates the diff on some line > 6000. Trying to add the diff manually.

Hi djasper,

http://llvm-reviews.chandlerc.com/D1643

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1643?vs=4189&id=4190#toc

Files:
  lib/Format/Format.cpp
  lib/Format/WhitespaceManager.cpp
  lib/Format/WhitespaceManager.h
  unittests/Format/FormatTest.cpp

Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -631,7 +631,9 @@
           ++FormatTok->NewlinesBefore;
           // FIXME: This is technically incorrect, as it could also
           // be a literal backslash at the end of the line.
-          if (i == 0 || FormatTok->TokenText[i - 1] != '\\')
+          if (i == 0 || (FormatTok->TokenText[i - 1] != '\\' &&
+                         (FormatTok->TokenText[i - 1] != '\r' || i == 1 ||
+                          FormatTok->TokenText[i - 2] != '\\')))
             FormatTok->HasUnescapedNewline = true;
           FormatTok->LastNewlineOffset = WhitespaceLength + i + 1;
           Column = 0;
@@ -745,8 +747,9 @@
   Formatter(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr,
             const std::vector<CharSourceRange> &Ranges)
       : Style(Style), Lex(Lex), SourceMgr(SourceMgr),
-        Whitespaces(SourceMgr, Style), Ranges(Ranges),
-        Encoding(encoding::detectEncoding(Lex.getBuffer())) {
+        Whitespaces(SourceMgr, Style, Lex.getBuffer().count('\r') * 2 >
+                                          Lex.getBuffer().count('\n')),
+        Ranges(Ranges), Encoding(encoding::detectEncoding(Lex.getBuffer())) {
     DEBUG(llvm::dbgs() << "File encoding: "
                        << (Encoding == encoding::Encoding_UTF8 ? "UTF8"
                                                                : "unknown")
Index: lib/Format/WhitespaceManager.cpp
===================================================================
--- lib/Format/WhitespaceManager.cpp
+++ lib/Format/WhitespaceManager.cpp
@@ -221,14 +221,14 @@
   for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
     const Change &C = Changes[i];
     if (C.CreateReplacement) {
-      std::string ReplacementText =
-          C.PreviousLinePostfix +
-          (C.ContinuesPPDirective
-               ? getNewlineText(C.NewlinesBefore, C.Spaces,
-                                C.PreviousEndOfTokenColumn,
-                                C.EscapedNewlineColumn)
-               : getNewlineText(C.NewlinesBefore, C.Spaces)) +
-          C.CurrentLinePrefix;
+      std::string ReplacementText = C.PreviousLinePostfix;
+      if (C.ContinuesPPDirective)
+        appendNewlineText(ReplacementText, C.NewlinesBefore,
+                          C.PreviousEndOfTokenColumn, C.EscapedNewlineColumn);
+      else
+        appendNewlineText(ReplacementText, C.NewlinesBefore);
+      appendIndentText(ReplacementText, C.Spaces);
+      ReplacementText.append(C.CurrentLinePrefix);
       storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
     }
   }
@@ -246,34 +246,33 @@
       SourceMgr, CharSourceRange::getCharRange(Range), Text));
 }
 
-std::string WhitespaceManager::getNewlineText(unsigned Newlines,
-                                              unsigned Spaces) {
-  return std::string(Newlines, '\n') + getIndentText(Spaces);
+void WhitespaceManager::appendNewlineText(std::string &Text,
+                                          unsigned Newlines) {
+  for (unsigned i = 0; i < Newlines; ++i)
+    Text.append(UseCRLF ? "\r\n" : "\n");
 }
 
-std::string WhitespaceManager::getNewlineText(unsigned Newlines,
-                                              unsigned Spaces,
-                                              unsigned PreviousEndOfTokenColumn,
-                                              unsigned EscapedNewlineColumn) {
-  std::string NewlineText;
+void WhitespaceManager::appendNewlineText(std::string &Text, unsigned Newlines,
+                                          unsigned PreviousEndOfTokenColumn,
+                                          unsigned EscapedNewlineColumn) {
   if (Newlines > 0) {
     unsigned Offset =
         std::min<int>(EscapedNewlineColumn - 1, PreviousEndOfTokenColumn);
     for (unsigned i = 0; i < Newlines; ++i) {
-      NewlineText += std::string(EscapedNewlineColumn - Offset - 1, ' ');
-      NewlineText += "\\\n";
+      Text.append(std::string(EscapedNewlineColumn - Offset - 1, ' '));
+      Text.append(UseCRLF ? "\\\r\n" : "\\\n");
       Offset = 0;
     }
   }
-  return NewlineText + getIndentText(Spaces);
 }
 
-std::string WhitespaceManager::getIndentText(unsigned Spaces) {
-  if (!Style.UseTab)
-    return std::string(Spaces, ' ');
-
-  return std::string(Spaces / Style.TabWidth, '\t') +
-         std::string(Spaces % Style.TabWidth, ' ');
+void WhitespaceManager::appendIndentText(std::string &Text, unsigned Spaces) {
+  if (!Style.UseTab) {
+    Text.append(std::string(Spaces, ' '));
+  } else {
+    Text.append(std::string(Spaces / Style.TabWidth, '\t'));
+    Text.append(std::string(Spaces % Style.TabWidth, ' '));
+  }
 }
 
 } // namespace format
Index: lib/Format/WhitespaceManager.h
===================================================================
--- lib/Format/WhitespaceManager.h
+++ lib/Format/WhitespaceManager.h
@@ -37,8 +37,9 @@
 /// There may be multiple calls to \c breakToken for a given token.
 class WhitespaceManager {
 public:
-  WhitespaceManager(SourceManager &SourceMgr, const FormatStyle &Style)
-      : SourceMgr(SourceMgr), Style(Style) {}
+  WhitespaceManager(SourceManager &SourceMgr, const FormatStyle &Style,
+                    bool UseCRLF)
+      : SourceMgr(SourceMgr), Style(Style), UseCRLF(UseCRLF) {}
 
   /// \brief Replaces the whitespace in front of \p Tok. Only call once for
   /// each \c AnnotatedToken.
@@ -152,16 +153,17 @@
 
   /// \brief Stores \p Text as the replacement for the whitespace in \p Range.
   void storeReplacement(const SourceRange &Range, StringRef Text);
-  std::string getNewlineText(unsigned Newlines, unsigned Spaces);
-  std::string getNewlineText(unsigned Newlines, unsigned Spaces,
-                             unsigned PreviousEndOfTokenColumn,
-                             unsigned EscapedNewlineColumn);
-  std::string getIndentText(unsigned Spaces);
+  void appendNewlineText(std::string &Text, unsigned Newlines);
+  void appendNewlineText(std::string &Text, unsigned Newlines,
+                         unsigned PreviousEndOfTokenColumn,
+                         unsigned EscapedNewlineColumn);
+  void appendIndentText(std::string &Text, unsigned Spaces);
 
   SmallVector<Change, 16> Changes;
   SourceManager &SourceMgr;
   tooling::Replacements Replaces;
   const FormatStyle &Style;
+  bool UseCRLF;
 };
 
 } // namespace format
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -116,7 +116,7 @@
 
 TEST_F(FormatTest, FormatsGlobalStatementsAt0) {
   EXPECT_EQ("int i;", format("  int i;"));
-  EXPECT_EQ("\nint i;", format(" \n\t \r  int i;"));
+  EXPECT_EQ("\nint i;", format(" \n\t \v \f  int i;"));
   EXPECT_EQ("int i;\nint j;", format("    int i; int j;"));
   EXPECT_EQ("int i;\nint j;", format("    int i;\n  int j;"));
 }
@@ -6479,5 +6479,40 @@
                "onOperationDone]; }] };");
 }
 
+TEST_F(FormatTest, SupportsCRLF) {
+  EXPECT_EQ("int a;\r\n"
+            "int b;\r\n"
+            "int c;\r\n",
+            format("int a;\r\n"
+                   "  int b;\r\n"
+                   "    int c;\r\n",
+                   getLLVMStyle()));
+  EXPECT_EQ("int a;\r\n"
+            "int b;\r\n"
+            "int c;\r\n",
+            format("int a;\r\n"
+                   "  int b;\n"
+                   "    int c;\r\n",
+                   getLLVMStyle()));
+  EXPECT_EQ("int a;\n"
+            "int b;\n"
+            "int c;\n",
+            format("int a;\r\n"
+                   "  int b;\n"
+                   "    int c;\n",
+                   getLLVMStyle()));
+  EXPECT_EQ("\"aaaaaaa \"\r\n"
+            "\"bbbbbbb\";\r\n",
+            format("\"aaaaaaa bbbbbbb\";\r\n", getLLVMStyleWithColumns(10)));
+  EXPECT_EQ("#define A \\\r\n"
+            "  b;      \\\r\n"
+            "  c;      \\\r\n"
+            "  d;\r\n",
+            format("#define A \\\r\n"
+                   "  b; \\\r\n"
+                   "  c; d; \r\n",
+                   getGoogleStyle()));
+}
+
 } // end namespace tooling
 } // end namespace clang
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1643.3.patch
Type: text/x-patch
Size: 8236 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130911/6efe3373/attachment.bin>


More information about the cfe-commits mailing list