Skip to content

Commit

Permalink
Merge pull request #164 from Philippus/issue-5669
Browse files Browse the repository at this point in the history
Support '\r' and '\r\n' line endings, closes scala/bug#5669
  • Loading branch information
gourlaysama authored Nov 5, 2018
2 parents 0a8f96c + 7fe2897 commit c3f8797
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ case class OffsetPosition(source: CharSequence, offset: Int) extends Position {

private def genIndex: Array[Int] = {
val lineStarts = new ArrayBuffer[Int]
lineStarts += 0
for (i <- 0 until source.length)
if (source.charAt(i) == '\n') lineStarts += (i + 1)
lineStarts += source.length
lineStarts += 0 // first line
for (i <- 1 until source.length) {
if (source.charAt(i - 1) == '\n') // \n or \r\n
lineStarts += i
else if (source.charAt(i - 1) == '\r' && source.charAt(i) != '\n') // \r but not \r\n
lineStarts += i
}
lineStarts += source.length // eof
lineStarts.toArray
}

Expand All @@ -63,11 +67,14 @@ case class OffsetPosition(source: CharSequence, offset: Int) extends Position {
def lineContents: String = {
val lineStart = index(line - 1)
val lineEnd = index(line)
val endIndex = if ( lineStart < lineEnd && source.charAt(lineEnd - 1) == '\n') {
lineEnd - 1
} else {
lineEnd
}
val endIndex =
if (lineStart < lineEnd - 1 && source.charAt(lineEnd - 2) == '\r' && source.charAt(lineEnd - 1) == '\n') {
lineEnd - 2
} else if (lineStart < lineEnd && (source.charAt(lineEnd - 1) == '\r' || source.charAt(lineEnd - 1) == '\n')) {
lineEnd - 1
} else {
lineEnd
}
source.subSequence(lineStart, endIndex).toString
}

Expand Down
14 changes: 14 additions & 0 deletions shared/src/test/scala/scala/util/parsing/combinator/t5669.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package scala.util.parsing.combinator

import scala.util.parsing.input.OffsetPosition

import org.junit.Test
import org.junit.Assert.assertEquals

class t5669 {
@Test
def test: Unit = {
val op = new OffsetPosition("foo\rbar", 4)
assertEquals(2, op.line)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,44 @@ import org.junit.Assert.assertEquals

class OffsetPositionTest {
@Test
def printLineContentsWithTrailingNewLine: Unit = {
def lineContentsWithTrailingLF: Unit = {
val op = new OffsetPosition("\n", 1)
assertEquals(op.lineContents, "")
assertEquals("", op.lineContents)
}

@Test
def printLineContentsWithEmptySource: Unit = {
def lineContentsWithTrailingCR: Unit = {
val op = new OffsetPosition("\r", 1)
assertEquals("", op.lineContents)
}

@Test
def lineContentsWithTrailingCRLF: Unit = {
val op = new OffsetPosition("\r\n", 1)
assertEquals("", op.lineContents)
}

@Test
def lineContentsWithEmptySource: Unit = {
val op = new OffsetPosition("", 0)
assertEquals(op.lineContents, "")
assertEquals("", op.lineContents)
}

@Test
def linesWithLF: Unit = {
val op = new OffsetPosition("foo\nbar", 4)
assertEquals(2, op.line)
}

@Test
def linesWithCR: Unit = {
val op = new OffsetPosition("foo\rbar", 4)
assertEquals(2, op.line)
}

@Test
def linesWithCRLF: Unit = {
val op = new OffsetPosition("foo\r\nbar", 5)
assertEquals(2, op.line)
}
}

0 comments on commit c3f8797

Please sign in to comment.