[cfe-commits] r140435 - /cfe/trunk/lib/Frontend/FrontendActions.cpp

Douglas Gregor dgregor at apple.com
Fri Sep 23 16:43:36 PDT 2011


Author: dgregor
Date: Fri Sep 23 18:43:36 2011
New Revision: 140435

URL: http://llvm.org/viewvc/llvm-project?rev=140435&view=rev
Log:
Don't translate CRLF files into LF files. Fixes PR6870, from Aaron Ballman!

Modified:
    cfe/trunk/lib/Frontend/FrontendActions.cpp

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=140435&r1=140434&r2=140435&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Fri Sep 23 18:43:36 2011
@@ -22,6 +22,8 @@
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -181,9 +183,48 @@
 
 void PrintPreprocessedAction::ExecuteAction() {
   CompilerInstance &CI = getCompilerInstance();
-  // Output file needs to be set to 'Binary', to avoid converting Unix style
+  // Output file may need to be set to 'Binary', to avoid converting Unix style
   // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
-  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  //
+  // Look to see what type of line endings the file uses. If there's a
+  // CRLF, then we won't open the file up in binary mode. If there is
+  // just an LF or CR, then we will open the file up in binary mode.
+  // In this fashion, the output format should match the input format, unless
+  // the input format has inconsistent line endings.
+  //
+  // This should be a relatively fast operation since most files won't have
+  // all of their source code on a single line. However, that is still a 
+  // concern, so if we scan for too long, we'll just assume the file should
+  // be opened in binary mode.
+  bool BinaryMode = true;
+  bool InvalidFile = false;
+  const SourceManager& SM = CI.getSourceManager();
+  const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(), 
+                                                     &InvalidFile);
+  if (!InvalidFile) {
+    const char *cur = Buffer->getBufferStart();
+    const char *end = Buffer->getBufferEnd();
+    const char *next = (cur != end) ? cur + 1 : end;
+
+    // Limit ourselves to only scanning 256 characters into the source
+    // file.  This is mostly a sanity check in case the file has no 
+    // newlines whatsoever.
+    if (end - cur > 256) end = cur + 256;
+	  
+    while (next < end) {
+      if (*cur == 0x0D) {  // CR
+        if (*next == 0x0A)  // CRLF
+          BinaryMode = false;
+
+        break;
+      } else if (*cur == 0x0A)  // LF
+        break;
+
+      ++cur, ++next;
+    }
+  }
+
+  raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile());
   if (!OS) return;
 
   DoPrintPreprocessedInput(CI.getPreprocessor(), OS,





More information about the cfe-commits mailing list