From 2def7a3218c73a13e03a6beb375a7a22f79c3c18 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 3 Nov 2014 14:09:47 +0000 Subject: [PATCH] Add CRLF support to LineIterator. The MRI scripts have to work with CRLF, and in general it is probably a good idea to support this in a core utility like LineIterator. llvm-svn: 221153 --- lib/Support/LineIterator.cpp | 46 +++++++++++++++++++++------------ test/Object/Inputs/mri-crlf.mri | 2 ++ test/Object/mri-crlf.test | 1 + 3 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 test/Object/Inputs/mri-crlf.mri create mode 100644 test/Object/mri-crlf.test diff --git a/lib/Support/LineIterator.cpp b/lib/Support/LineIterator.cpp index 573e21a3cba..5baa1a37f38 100644 --- a/lib/Support/LineIterator.cpp +++ b/lib/Support/LineIterator.cpp @@ -12,6 +12,26 @@ using namespace llvm; +static bool isAtLineEnd(const char *P) { + if (*P == '\n') + return true; + if (*P == '\r' && *(P + 1) == '\n') + return true; + return false; +} + +static bool skipIfAtLineEnd(const char *&P) { + if (*P == '\n') { + ++P; + return true; + } + if (*P == '\r' && *(P + 1) == '\n') { + P += 2; + return true; + } + return false; +} + line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks, char CommentMarker) : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr), @@ -23,7 +43,7 @@ line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks, if (Buffer.getBufferSize()) { assert(Buffer.getBufferEnd()[0] == '\0'); // Make sure we don't skip a leading newline if we're keeping blanks - if (SkipBlanks || *Buffer.getBufferStart() != '\n') + if (SkipBlanks || !isAtLineEnd(Buffer.getBufferStart())) advance(); } } @@ -32,33 +52,27 @@ void line_iterator::advance() { assert(Buffer && "Cannot advance past the end!"); const char *Pos = CurrentLine.end(); - assert(Pos == Buffer->getBufferStart() || *Pos == '\n' || *Pos == '\0'); + assert(Pos == Buffer->getBufferStart() || isAtLineEnd(Pos) || *Pos == '\0'); - if (*Pos == '\n') { - ++Pos; + if (skipIfAtLineEnd(Pos)) ++LineNumber; - } - if (!SkipBlanks && *Pos == '\n') { + if (!SkipBlanks && isAtLineEnd(Pos)) { // Nothing to do for a blank line. } else if (CommentMarker == '\0') { // If we're not stripping comments, this is simpler. - size_t Blanks = 0; - while (Pos[Blanks] == '\n') - ++Blanks; - Pos += Blanks; - LineNumber += Blanks; + while (skipIfAtLineEnd(Pos)) + ++LineNumber; } else { // Skip comments and count line numbers, which is a bit more complex. for (;;) { - if (*Pos == '\n' && !SkipBlanks) + if (isAtLineEnd(Pos) && !SkipBlanks) break; if (*Pos == CommentMarker) do { ++Pos; - } while (*Pos != '\0' && *Pos != '\n'); - if (*Pos != '\n') + } while (*Pos != '\0' && !isAtLineEnd(Pos)); + if (!skipIfAtLineEnd(Pos)) break; - ++Pos; ++LineNumber; } } @@ -72,7 +86,7 @@ void line_iterator::advance() { // Measure the line. size_t Length = 0; - while (Pos[Length] != '\0' && Pos[Length] != '\n') { + while (Pos[Length] != '\0' && !isAtLineEnd(&Pos[Length])) { ++Length; } diff --git a/test/Object/Inputs/mri-crlf.mri b/test/Object/Inputs/mri-crlf.mri new file mode 100644 index 00000000000..b8540304f2e --- /dev/null +++ b/test/Object/Inputs/mri-crlf.mri @@ -0,0 +1,2 @@ +; this file intentionally has crlf line endings +end diff --git a/test/Object/mri-crlf.test b/test/Object/mri-crlf.test new file mode 100644 index 00000000000..3411b55095e --- /dev/null +++ b/test/Object/mri-crlf.test @@ -0,0 +1 @@ +; RUN: llvm-ar -M < %S/Inputs/mri-crlf.mri