diff options
author | Paul Phillips <paulp@improving.org> | 2011-05-20 17:53:03 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-05-20 17:53:03 +0000 |
commit | 2beeb23cc71273a2b6a262317a95a06df3491fbf (patch) | |
tree | 126f7b1701af7a0ab6768c28e3b8b5ea75d26060 | |
parent | be355453547d9a8436d58af7f6ab2a737cc0d376 (diff) | |
download | scala-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.scala | 6 | ||||
-rw-r--r-- | src/library/scala/xml/parsing/MarkupParser.scala | 65 | ||||
-rw-r--r-- | src/library/scala/xml/parsing/MarkupParserCommon.scala | 2 |
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 |