summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-05-20 17:53:03 +0000
committerPaul Phillips <paulp@improving.org>2011-05-20 17:53:03 +0000
commit2beeb23cc71273a2b6a262317a95a06df3491fbf (patch)
tree126f7b1701af7a0ab6768c28e3b8b5ea75d26060
parentbe355453547d9a8436d58af7f6ab2a737cc0d376 (diff)
downloadscala-2beeb23cc71273a2b6a262317a95a06df3491fbf.tar.gz
scala-2beeb23cc71273a2b6a262317a95a06df3491fbf.tar.bz2
scala-2beeb23cc71273a2b6a262317a95a06df3491fbf.zip
Fix #4599: XMLEventReader issue with input stream.
Makes MarkupParser.nextch lazy, only reaching out for the next char when calling ch or eof. To make it possible, nextch now returns Unit instead of Char. As it happens, that's how it is used almost everywhere. Contributed by Daniel Sobral, no review.
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala6
-rw-r--r--src/library/scala/xml/parsing/MarkupParser.scala65
-rw-r--r--src/library/scala/xml/parsing/MarkupParserCommon.scala2
3 files changed, 47 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index 6c025e8443..2cc2b598d3 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -76,8 +76,8 @@ trait MarkupParsers {
var tmppos : Position = NoPosition
def ch = input.ch
/** this method assign the next character to ch and advances in input */
- def nextch = { val result = input.ch; input.nextChar(); result }
- def ch_returning_nextch = nextch
+ def nextch() { input.nextChar() }
+ def ch_returning_nextch = { val result = ch; input.nextChar(); result }
def mkProcInstr(position: Position, name: String, text: String): Tree =
parser.symbXMLBuilder.procInstr(position, name, text)
@@ -398,7 +398,9 @@ trait MarkupParsers {
def reportSyntaxError(pos: Int, str: String) = parser.syntaxError(pos, str)
def reportSyntaxError(str: String) = {
reportSyntaxError(curOffset, "in XML literal: " + str)
+ val result = ch
nextch
+ result
}
/** '<' xPattern ::= Name [S] { xmlPattern | '{' pattern3 '}' } ETag
diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala
index d68b8b649b..f6cdb1d679 100644
--- a/src/library/scala/xml/parsing/MarkupParser.scala
+++ b/src/library/scala/xml/parsing/MarkupParser.scala
@@ -96,7 +96,29 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
var tmppos: Int = _
/** holds the next character */
- var ch: Char = _
+ var nextChNeeded: Boolean = false
+ var reachedEof: Boolean = false
+ var lastChRead: Char = _
+ def ch: Char = {
+ if (nextChNeeded) {
+ if (curInput.hasNext) {
+ lastChRead = curInput.next
+ pos = curInput.pos
+ } else {
+ val ilen = inpStack.length;
+ //Console.println(" ilen = "+ilen+ " extIndex = "+extIndex);
+ if ((ilen != extIndex) && (ilen > 0)) {
+ /** for external source, inpStack == Nil ! need notify of eof! */
+ pop()
+ } else {
+ reachedEof = true
+ lastChRead = 0.asInstanceOf[Char]
+ }
+ }
+ nextChNeeded = false
+ }
+ lastChRead
+ }
/** character buffer, for names */
protected val cbuf = new StringBuilder()
@@ -105,7 +127,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
protected var doc: Document = null
- var eof: Boolean = false
+ def eof: Boolean = { ch; reachedEof }
//
// methods
@@ -261,23 +283,13 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
if (isNameStart (ch)) xAttributes(pscope)
else (Null, pscope)
- /** this method assign the next character to ch and advances in input */
- def nextch = {
- if (curInput.hasNext) {
- ch = curInput.next
- pos = curInput.pos
- } else {
- val ilen = inpStack.length;
- //Console.println(" ilen = "+ilen+ " extIndex = "+extIndex);
- if ((ilen != extIndex) && (ilen > 0)) {
- /** for external source, inpStack == Nil ! need notify of eof! */
- pop()
- } else {
- eof = true
- ch = 0.asInstanceOf[Char]
- }
- }
+ /** this method tells ch to get the next character when next called */
+ def nextch() {
+ // Read current ch if needed
ch
+
+ // Mark next ch to be required
+ nextChNeeded = true
}
/** parse attribute and create namespace scope, metadata
@@ -412,14 +424,14 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
ch match {
case '<' => // another tag
- nextch match {
+ nextch; ch match {
case '/' => exit = true // end tag
case _ => content1(pscope, ts)
}
// postcond: xEmbeddedBlock == false!
case '&' => // EntityRef or CharRef
- nextch match {
+ nextch; ch match {
case '#' => // CharacterRef
nextch
val theChar = handle.text(tmppos, xCharRef(() => ch, () => nextch))
@@ -627,7 +639,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
xToken('['); while(']' != ch) markupDecl(); nextch // ']'
}
def doIgnore() = {
- xToken('['); while(']' != ch) nextch; nextch; // ']'
+ xToken('['); while(']' != ch) nextch; nextch // ']'
}
if ('?' == ch) {
nextch
@@ -881,6 +893,9 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
if (!eof)
inpStack = curInput :: inpStack
+ // can't push before getting next character if needed
+ ch
+
curInput = replacementText(entityName)
nextch
}
@@ -889,6 +904,9 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
if (!eof)
inpStack = curInput :: inpStack
+ // can't push before getting next character if needed
+ ch
+
curInput = externalSource(systemId)
nextch
}
@@ -896,8 +914,9 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
def pop() {
curInput = inpStack.head
inpStack = inpStack.tail
- ch = curInput.ch
+ lastChRead = curInput.ch
+ nextChNeeded = false
pos = curInput.pos
- eof = false // must be false, because of places where entity refs occur
+ reachedEof = false // must be false, because of places where entity refs occur
}
}
diff --git a/src/library/scala/xml/parsing/MarkupParserCommon.scala b/src/library/scala/xml/parsing/MarkupParserCommon.scala
index d9729e14e1..096b2c910d 100644
--- a/src/library/scala/xml/parsing/MarkupParserCommon.scala
+++ b/src/library/scala/xml/parsing/MarkupParserCommon.scala
@@ -175,7 +175,7 @@ private[scala] trait MarkupParserCommon extends TokenTests {
* temporarily abstract over the nextchs.
*/
def ch: Char
- def nextch: Char
+ def nextch(): Unit
def ch_returning_nextch: Char
def eof: Boolean