summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala15
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala3
-rw-r--r--src/dotnet-library/scala/xml/NodeTraverser.scala1
-rw-r--r--src/dotnet-library/scala/xml/Parsing.scala1
-rw-r--r--src/library/scala/xml/MetaData.scala22
-rw-r--r--src/library/scala/xml/NodeTraverser.scala37
-rw-r--r--src/library/scala/xml/Null.scala17
-rw-r--r--src/library/scala/xml/Parsing.scala97
-rw-r--r--src/library/scala/xml/PrettyPrinter.scala32
-rw-r--r--src/library/scala/xml/include/sax/Main.scala140
-rw-r--r--src/library/scala/xml/include/sax/XIncludeFilter.scala23
-rw-r--r--src/library/scala/xml/parsing/ConstructingParser.scala15
-rw-r--r--src/library/scala/xml/parsing/MarkupParser.scala100
-rw-r--r--src/library/scala/xml/parsing/XhtmlParser.scala41
-rw-r--r--src/library/scala/xml/pull/XMLEventReader.scala2
-rw-r--r--test/files/jvm/unittest_xml.scala17
16 files changed, 133 insertions, 430 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index 030b2a4732..1e254f7e51 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -11,8 +11,9 @@ import scala.collection.mutable
import mutable.{ Buffer, ArrayBuffer, ListBuffer, HashMap }
import scala.util.control.ControlException
import scala.tools.nsc.util.{Position,NoPosition,SourceFile,CharArrayReader}
-import scala.xml.{Text, TextBuffer}
-import SourceFile.{SU,LF}
+import scala.xml.{ Text, TextBuffer }
+import scala.xml.Utility.{ isNameStart, isNameChar, isSpace }
+import SourceFile.{ SU, LF }
import scala.annotation.switch
// XXX/Note: many/most of the functions in here are almost direct cut and pastes
@@ -117,7 +118,7 @@ trait MarkupParsers
def xAttributes = {
val aMap = new HashMap[String, Tree]()
- while (xml.Parsing.isNameStart(ch)) {
+ while (isNameStart(ch)) {
val start = curOffset
val key = xName
xEQ
@@ -405,13 +406,13 @@ trait MarkupParsers
*/
def xName: String = {
if (ch == SU) throw TruncatedXML
- else if (!xml.Parsing.isNameStart(ch))
+ else if (!isNameStart(ch))
return errorAndResult("name expected, but char '%s' cannot start a name" format ch, "")
val buf = new StringBuilder
do buf append nextch
- while (xml.Parsing.isNameChar(ch))
+ while (isNameChar(ch))
if (buf.last == ':') {
reportSyntaxError( "name cannot end in ':'" )
@@ -424,11 +425,11 @@ trait MarkupParsers
def xEQ = { xSpaceOpt; xToken('='); xSpaceOpt }
/** skip optional space S? */
- def xSpaceOpt = { while (xml.Parsing.isSpace(ch)) { nextch }}
+ def xSpaceOpt = { while (isSpace(ch)) { nextch }}
/** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */
def xSpace =
- if (xml.Parsing.isSpace(ch)) { nextch; xSpaceOpt }
+ if (isSpace(ch)) { nextch; xSpaceOpt }
else if (ch == SU) throw TruncatedXML
else reportSyntaxError("whitespace expected")
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 345edb505e..01a7f31462 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -11,6 +11,7 @@ import SourceFile.{LF, FF, CR, SU}
import Tokens._
import scala.annotation.switch
import scala.collection.mutable.{ListBuffer, ArrayBuffer}
+import scala.xml.Utility.{ isNameStart }
trait Scanners {
val global : Global
@@ -264,7 +265,7 @@ trait Scanners {
val last = if (charOffset >= 2) buf(charOffset - 2) else ' '
nextChar()
last match {
- case ' '|'\t'|'\n'|'{'|'('|'>' if xml.Parsing.isNameStart(ch) || ch == '!' || ch == '?' =>
+ case ' '|'\t'|'\n'|'{'|'('|'>' if isNameStart(ch) || ch == '!' || ch == '?' =>
token = XMLSTART
case _ =>
// Console.println("found '<', but last is '"+in.last+"'"); // DEBUG
diff --git a/src/dotnet-library/scala/xml/NodeTraverser.scala b/src/dotnet-library/scala/xml/NodeTraverser.scala
deleted file mode 100644
index 87aca3a120..0000000000
--- a/src/dotnet-library/scala/xml/NodeTraverser.scala
+++ /dev/null
@@ -1 +0,0 @@
-/* NodeTraverser.scala does not exist for the dotnet target */
diff --git a/src/dotnet-library/scala/xml/Parsing.scala b/src/dotnet-library/scala/xml/Parsing.scala
deleted file mode 100644
index 510a535888..0000000000
--- a/src/dotnet-library/scala/xml/Parsing.scala
+++ /dev/null
@@ -1 +0,0 @@
-/* Parsing.scala does not exist for the dotnet target */
diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala
index 280f2b7871..f45da11211 100644
--- a/src/library/scala/xml/MetaData.scala
+++ b/src/library/scala/xml/MetaData.scala
@@ -139,7 +139,7 @@ abstract class MetaData extends Iterable[MetaData]
def isPrefixed: Boolean
- /** deep equals method */
+ /** deep equals method - XXX */
override def equals(that: Any) = that match {
case m: MetaData =>
(this.length == m.length) &&
@@ -156,9 +156,9 @@ abstract class MetaData extends Iterable[MetaData]
def equals1(that: MetaData): Boolean
/** filters this sequence of meta data */
- override def filter(f: MetaData => Boolean): MetaData = {
- if (f(this)) copy(next filter f) else next filter f
- }
+ override def filter(f: MetaData => Boolean): MetaData =
+ if (f(this)) copy(next filter f)
+ else next filter f
/** returns key of this MetaData item */
def key: String
@@ -167,7 +167,7 @@ abstract class MetaData extends Iterable[MetaData]
def value: Seq[Node]
/** maps this sequence of meta data */
- def map(f: MetaData => Text): List[Text] = f(this)::(next map f)
+ def map(f: MetaData => Text): List[Text] = (iterator map f).toList
/** returns Null or the next MetaData item */
def next: MetaData
@@ -178,16 +178,12 @@ abstract class MetaData extends Iterable[MetaData]
* @param key
* @return value in Some(Seq[Node]) if key is found, None otherwise
*/
- final def get(key: String): Option[Seq[Node]] = apply(key) match {
- case null => None
- case x => Some(x)
- }
+ final def get(key: String): Option[Seq[Node]] = Option(apply(key))
/** same as get(uri, owner.scope, key) */
final def get(uri: String, owner: Node, key: String): Option[Seq[Node]] =
get(uri, owner.scope, key)
-
/** gets value of qualified (prefixed) attribute with given key.
*
* @param uri namespace of key
@@ -196,10 +192,7 @@ abstract class MetaData extends Iterable[MetaData]
* @return value as Some[Seq[Node]] if key is found, None otherwise
*/
final def get(uri: String, scope: NamespaceBinding, key: String): Option[Seq[Node]] =
- apply(uri, scope, key) match {
- case null => None
- case x => Some(x)
- }
+ Option(apply(uri, scope, key))
override def hashCode(): Int
@@ -244,5 +237,4 @@ abstract class MetaData extends Iterable[MetaData]
*/
final def remove(namespace: String, owner: Node, key: String): MetaData =
remove(namespace, owner.scope, key)
-
}
diff --git a/src/library/scala/xml/NodeTraverser.scala b/src/library/scala/xml/NodeTraverser.scala
deleted file mode 100644
index cec5341073..0000000000
--- a/src/library/scala/xml/NodeTraverser.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-
-/** This class ...
- *
- * @author Burak Emir
- * @version 1.0
- */
-abstract class NodeTraverser extends parsing.MarkupHandler {
-
- def traverse(n: Node): Unit = n match {
- case x:ProcInstr =>
- procInstr(0, x.target, x.text)
- case x:Comment =>
- comment(0, x.text)
- case x:Text =>
- text(0, x.data)
- case x:EntityRef =>
- entityRef(0, x.entityName)
- case _ =>
- elemStart(0, n.prefix, n.label, n.attributes, n.scope)
- for (m <- n.child) traverse(m)
- elem(0, n.prefix, n.label, n.attributes, n.scope, NodeSeq.fromSeq(n.child))
- elemEnd(0, n.prefix, n.label)
- }
-
-}
diff --git a/src/library/scala/xml/Null.scala b/src/library/scala/xml/Null.scala
index 7718c61493..9cda330057 100644
--- a/src/library/scala/xml/Null.scala
+++ b/src/library/scala/xml/Null.scala
@@ -11,6 +11,8 @@
package scala.xml
+import Utility.{ isNameStart }
+
case object Null extends MetaData {
/** appends given MetaData items to this MetaData list */
@@ -25,18 +27,19 @@ case object Null extends MetaData {
override def filter(f: MetaData => Boolean): MetaData = this
- /** returns null */
def getNamespace(owner: Node) = null
final override def hasNext = false
+ def next = null
+ def key = null
+ def value = null
final override def length = 0
-
final override def length(i: Int) = i
def isPrefixed = false
- /** deep equals method */
+ /** deep equals method - XXX */
override def equals(that: Any) = that match {
case m: MetaData => m.length == 0
case _ => false
@@ -44,17 +47,11 @@ case object Null extends MetaData {
def equals1(that:MetaData) = that.length == 0
- def key = null
-
- def value = null
-
override def map(f: MetaData => Text): List[Text] = Nil
- def next = null
-
/** null */
def apply(key: String) = {
- if(!Parsing.isNameStart (key charAt 0))
+ if(!isNameStart(key charAt 0))
throw new IllegalArgumentException("not a valid attribute name '"+key+"', so can never match !")
null
}
diff --git a/src/library/scala/xml/Parsing.scala b/src/library/scala/xml/Parsing.scala
deleted file mode 100644
index 3f64ff63e2..0000000000
--- a/src/library/scala/xml/Parsing.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-
-
-/** The object <code>Parsing</code> ...
- *
- * @author Burak Emir
- * @version 1.0
- *
- * @deprecated use either <code>parsing.TokenTests</code> or
- * <code>Utilty</code> (helper functions for parsing XML fragments).
- */
-object Parsing {
-
- /** <pre>(#x20 | #x9 | #xD | #xA)</pre> */
- final def isSpace(ch: Char): Boolean = ch match {
- case '\u0009' | '\u000A' | '\u000D' | '\u0020' => true
- case _ => false
- }
-
- /** <pre>(#x20 | #x9 | #xD | #xA)+</pre> */
- final def isSpace(cs: Seq[Char]): Boolean = cs forall isSpace
-
- /** <pre>NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
- * | CombiningChar | Extender</pre>
- *
- * see [4] and Appendix B of XML 1.0 specification
- */
- private val nameCharTypeList = {
- import java.lang.Character._
- List(
- COMBINING_SPACING_MARK, // Mc
- ENCLOSING_MARK, // Me
- NON_SPACING_MARK, // Mn
- MODIFIER_LETTER, // Lm
- DECIMAL_DIGIT_NUMBER // Nd
- )
- }
- def isNameChar(ch: Char) =
- isNameStart(ch) || List('.', '-', ':').contains(ch) ||
- nameCharTypeList.contains(Character.getType(ch).asInstanceOf[Byte])
-
- /** <pre>NameStart ::= ( Letter | '_' )</pre>
- * where Letter means in one of the Unicode general
- * categories { Ll, Lu, Lo, Lt, Nl }
- *
- * We do not allow a name to start with ':'.
- * see [3] and Appendix B of XML 1.0 specification
- */
- def isNameStart(ch: Char) =
- java.lang.Character.getType(ch).asInstanceOf[Byte] match {
- case java.lang.Character.LOWERCASE_LETTER => true
- case java.lang.Character.UPPERCASE_LETTER => true
- case java.lang.Character.OTHER_LETTER => true
- case java.lang.Character.TITLECASE_LETTER => true
- case java.lang.Character.LETTER_NUMBER => true
- case _ => ch == '_'
- }
-
- /** <pre>Name ::= ( Letter | '_' ) (NameChar)*</pre>
- *
- * see [5] of XML 1.0 specification
- */
- def isName(s: String): Boolean =
- if (s.length() > 0) {
- val z: Seq[Char] = s
- val y = z.iterator
- if (isNameStart(y.next)) {
- while (y.hasNext && isNameChar(y.next)) {}
- !y.hasNext
- } else false
- } else false
-
- def isPubIDChar(c: Char) = c match {
- case '\u0020' | '\u000D' | '\u000A' => true
- case _ if
- ('0' < c && c < '9')||('a' < c && c < 'z')||('A' < c && c < 'Z') => true
- case '-' | '\''| '(' | ')' | '+' | ',' | '.' | '/' | ':' | '=' |
- '?' | ';' | '!' | '*' | '#' | '@' | '$' | '_' | '%' => true
- case _ => false
- }
-
- def checkSysID(s: String): Boolean =
- s.indexOf('"') == -1 || s.indexOf('\'') == -1
-
- def checkPubID(s: String): Boolean = s forall isPubIDChar
-}
diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala
index 1753860f50..8b2193fba8 100644
--- a/src/library/scala/xml/PrettyPrinter.scala
+++ b/src/library/scala/xml/PrettyPrinter.scala
@@ -85,6 +85,7 @@ class PrettyPrinter(width: Int, step: Int) {
* @return ...
*/
protected def makeBox(ind: Int, s: String) = {
+ // XXX um...
if (cur < ind)
cur == ind
if (cur + s.length > width) { // fits in this line
@@ -257,14 +258,6 @@ class PrettyPrinter(width: Int, step: Int) {
// public convenience methods
- /** returns a formatted string containing well-formed XML with
- * default namespace prefix mapping
- *
- * @param n the node to be serialized
- * @return ...
- */
- def format(n: Node): String = format(n, null) //Utility.defaultPrefixes(n))
-
/** Returns a formatted string containing well-formed XML with
* given namespace to prefix mapping.
*
@@ -272,32 +265,23 @@ class PrettyPrinter(width: Int, step: Int) {
* @param pmap the namespace to prefix mapping
* @return ...
*/
- def format(n: Node, pscope: NamespaceBinding): String =
+ def format(n: Node, pscope: NamespaceBinding = null): String =
sbToString(format(n, pscope, _))
- /** Returns a formatted string containing well-formed XML nodes with
- * default namespace prefix mapping.
- *
- * @param nodes ...
- * @return ...
- */
- def formatNodes(nodes: Seq[Node]): String =
- formatNodes(nodes, null)
-
/** Returns a formatted string containing well-formed XML.
*
- * @param nodes the sequence of nodes to be serialized
- * @param pmap the namespace to prefix mapping
+ * @param nodes the sequence of nodes to be serialized
+ * @param pscope the namespace to prefix mapping
*/
- def formatNodes(nodes: Seq[Node], pscope: NamespaceBinding): String =
+ def formatNodes(nodes: Seq[Node], pscope: NamespaceBinding = null): String =
sbToString(formatNodes(nodes, pscope, _))
/** Appends a formatted string containing well-formed XML with
* the given namespace to prefix mapping to the given stringbuffer.
*
- * @param n the node to be serialized
- * @param pmap the namespace to prefix mapping
- * @param sb the string buffer to which to append to
+ * @param nodes the nodes to be serialized
+ * @param pscope the namespace to prefix mapping
+ * @param sb the string buffer to which to append to
*/
def formatNodes(nodes: Seq[Node], pscope: NamespaceBinding, sb: StringBuilder): Unit =
nodes foreach (n => sb append format(n, pscope))
diff --git a/src/library/scala/xml/include/sax/Main.scala b/src/library/scala/xml/include/sax/Main.scala
index 23b379af2b..4df95d1046 100644
--- a/src/library/scala/xml/include/sax/Main.scala
+++ b/src/library/scala/xml/include/sax/Main.scala
@@ -10,99 +10,73 @@
package scala.xml
package include.sax
-import scala.xml.include._
-import org.xml.sax.SAXException
-import org.xml.sax.SAXParseException
-import org.xml.sax.EntityResolver
+import scala.xml.include._
+import scala.util.control.Exception.{ catching, ignoring }
+import org.xml.sax.{ SAXException, SAXParseException, EntityResolver, XMLReader }
import org.xml.sax.helpers.XMLReaderFactory
-import org.xml.sax.XMLReader
object Main {
+ private val xercesClass = "org.apache.xerces.parsers.SAXParser"
+ private val namespacePrefixes = "http://xml.org/sax/features/namespace-prefixes"
+ private val lexicalHandler = "http://xml.org/sax/properties/lexical-handler"
- /**
- * The driver method for xinc
- * Output is written to System.out via Conolse
- * </p>
- *
- * @param args contains the URLs and/or filenames
- * of the documents to be procesed.
- */
- def main(args: Array[String]) {
- var parser: XMLReader = null
- var err = false
- try {
- parser = XMLReaderFactory.createXMLReader()
- }
- catch {
- case e:SAXException =>
- try {
- parser = XMLReaderFactory.createXMLReader(
- "org.apache.xerces.parsers.SAXParser")
- } catch {
- case e2:SAXException =>
- System.err.println("Could not find an XML parser")
- err = true
- }
- }
+ /**
+ * The driver method for xinc
+ * Output is written to System.out via Conolse
+ * </p>
+ *
+ * @param args contains the URLs and/or filenames
+ * of the documents to be procesed.
+ */
+ def main(args: Array[String]) {
+ def saxe[T](body: => T) = catching[T](classOf[SAXException]) opt body
+ def error(msg: String) = System.err.println(msg)
+
+ val parser: XMLReader =
+ saxe[XMLReader](XMLReaderFactory.createXMLReader()) getOrElse (
+ saxe[XMLReader](XMLReaderFactory.createXMLReader(xercesClass)) getOrElse (
+ return error("Could not find an XML parser")
+ )
+ )
+
+ // Need better namespace handling
+ try parser.setFeature(namespacePrefixes, true)
+ catch { case e: SAXException => return System.err.println(e) }
+
+ if (args.isEmpty)
+ return
- if(err) return;
- // Need better namespace handling
+ val (resolver, args2): (Option[EntityResolver], Array[String]) =
+ if (args.size < 2 || args(0) != "-r") (None, args)
+ else catching(classOf[Exception]) opt {
+ val r = Class.forName(args(1)).newInstance().asInstanceOf[EntityResolver]
+ parser setEntityResolver r
+ (r, args drop 2)
+ } orElse (return error("Could not load requested EntityResolver"))
+
+ for (arg <- args2) {
try {
- parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
- }
- catch {
- case e:SAXException =>
- System.err.println(e)
- err = true
- }
- if (err) return
+ val includer = new XIncludeFilter()
+ includer setParent parser
+ val s = new XIncluder(System.out, "UTF-8")
+ includer setContentHandler s
- if (args.length == 0) return
- var resolver: EntityResolver = null
- var arg: Int = 0
- if (args(0).equals("-r")) {
- try {
- resolver = Class.forName(args(1)).newInstance().asInstanceOf[EntityResolver];
- parser.setEntityResolver(resolver);
- }
- catch {
- case ex:Exception =>
- System.err.println("Could not load requested EntityResolver")
- err = true
+ resolver map (includer setEntityResolver _)
+ // SAXException here means will not support comments
+ ignoring(classOf[SAXException]) {
+ includer.setProperty(lexicalHandler, s)
+ s setFilter includer
}
- arg = 2
+ includer parse arg
}
- if (err) return
-
- while (arg < args.length) {
- try {
- val includer = new XIncludeFilter();
- includer.setParent(parser)
- val s = new XIncluder(System.out, "UTF-8")
- includer.setContentHandler(s)
- if (resolver != null) includer.setEntityResolver(resolver)
- try {
- includer.setProperty(
- "http://xml.org/sax/properties/lexical-handler",
- s)
- s.setFilter(includer)
- }
- catch {
- case e:SAXException => // Will not support comments
- }
- includer.parse(args(arg))
- }
- catch {
- case e:SAXParseException =>
- System.err.println(e)
- System.err.println("Problem in " + e.getSystemId()
- + " at line " + e.getLineNumber())
- case e: Exception => // be specific about exceptions????
- System.err.println(e)
- e.printStackTrace()
- }
- arg += 1
+ catch {
+ case e: SAXParseException =>
+ error(e.toString)
+ error("Problem in %s at line %d".format(e.getSystemId, e.getLineNumber))
+ case e: SAXException =>
+ error(e.toString)
}
}
+ }
}
diff --git a/src/library/scala/xml/include/sax/XIncludeFilter.scala b/src/library/scala/xml/include/sax/XIncludeFilter.scala
index ed8953ea69..222c9f39f8 100644
--- a/src/library/scala/xml/include/sax/XIncludeFilter.scala
+++ b/src/library/scala/xml/include/sax/XIncludeFilter.scala
@@ -12,24 +12,11 @@ package scala.xml
package include.sax
import scala.xml.include._
-import org.xml.sax.Attributes
-import org.xml.sax.SAXException
-import org.xml.sax.XMLReader
-import org.xml.sax.EntityResolver
-import org.xml.sax.Locator
-import org.xml.sax.helpers.XMLReaderFactory
-import org.xml.sax.helpers.XMLFilterImpl
-import org.xml.sax.helpers.NamespaceSupport
-import org.xml.sax.helpers.AttributesImpl
-
-import java.net.URL
-import java.net.URLConnection
-import java.net.MalformedURLException
-import java.io.UnsupportedEncodingException
-import java.io.IOException
-import java.io.InputStream
-import java.io.BufferedInputStream
-import java.io.InputStreamReader
+import org.xml.sax.{ Attributes, SAXException, XMLReader, EntityResolver, Locator }
+import org.xml.sax.helpers.{ XMLReaderFactory, XMLFilterImpl, NamespaceSupport, AttributesImpl }
+
+import java.net.{ URL, URLConnection, MalformedURLException }
+import java.io.{ UnsupportedEncodingException, IOException, InputStream, BufferedInputStream, InputStreamReader }
import java.util.Stack
/**
diff --git a/src/library/scala/xml/parsing/ConstructingParser.scala b/src/library/scala/xml/parsing/ConstructingParser.scala
index 623d2e3f37..962c629663 100644
--- a/src/library/scala/xml/parsing/ConstructingParser.scala
+++ b/src/library/scala/xml/parsing/ConstructingParser.scala
@@ -17,20 +17,13 @@ import java.io.File
import scala.io.{ Source, Codec }
object ConstructingParser {
-
- def fromFile(inp: File, preserveWS: Boolean) = {
+ def fromFile(inp: File, preserveWS: Boolean) =
// XXX why does the default implicit not work here when building locker,
// unless the empty parameter list is supplied?
- val p = new ConstructingParser(Source.fromFile(inp)(), preserveWS)
- p.nextch
- p
- }
+ new ConstructingParser(Source.fromFile(inp)(), preserveWS) initialize
- def fromSource(inp: Source, preserveWS: Boolean) = {
- val p = new ConstructingParser(inp, preserveWS)
- p.nextch
- p
- }
+ def fromSource(inp: Source, preserveWS: Boolean) =
+ new ConstructingParser(inp, preserveWS) initialize
}
/** An xml parser. parses XML and invokes callback methods of a MarkupHandler.
diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala
index a4af954e5a..15bd912c17 100644
--- a/src/library/scala/xml/parsing/MarkupParser.scala
+++ b/src/library/scala/xml/parsing/MarkupParser.scala
@@ -30,7 +30,9 @@ import Utility.Escapes.{ pairs => unescape }
* @author Burak Emir
* @version 1.0
*/
-trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with MarkupHandler =>
+trait MarkupParser extends AnyRef with TokenTests
+{
+ self: MarkupParser with MarkupHandler =>
val input: Source
@@ -239,6 +241,14 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
//var xEmbeddedBlock = false;
+ /** As the current code requires you to call nextch once manually
+ * after construction, this method formalizes that suboptimal reality.
+ */
+ def initialize: this.type = {
+ nextch
+ this
+ }
+
/** this method assign the next character to ch and advances in input */
def nextch {
if (curInput.hasNext) {
@@ -270,11 +280,7 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
}
}
- def xToken(that: Seq[Char]): Unit = {
- val it = that.iterator;
- while (it.hasNext)
- xToken(it.next);
- }
+ def xToken(that: Seq[Char]): Unit = that foreach xToken
/** parse attribute and create namespace scope, metadata
* [41] Attributes ::= { S Name Eq AttValue }
@@ -391,49 +397,26 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
val pos1 = pos
val sb: StringBuilder = new StringBuilder()
while (true) {
- if (ch==']' &&
- { sb.append(ch); nextch; ch == ']' } &&
- { sb.append(ch); nextch; ch == '>' } ) {
- sb.length = sb.length - 2
- nextch;
- return handle.text( pos1, sb.toString() );
- } else sb.append( ch );
+ if (ch==']' &&
+ { sb.append(ch); nextch; ch == ']' } &&
+ { sb.append(ch); nextch; ch == '>' } ) {
+ sb.setLength(sb.length - 2);
+ nextch;
+ return PCData(sb.toString)
+ } else sb.append( ch );
nextch;
}
+ // bq: (todo) increase grace when meeting CDATA section
throw FatalError("this cannot happen");
- };
+ }
/** CharRef ::= "&amp;#" '0'..'9' {'0'..'9'} ";"
* | "&amp;#x" '0'..'9'|'A'..'F'|'a'..'f' { hexdigit } ";"
*
* see [66]
*/
- def xCharRef(ch: () => Char, nextch: () => Unit): String = {
+ def xCharRef(ch: () => Char, nextch: () => Unit): String =
Utility.parseCharRef(ch, nextch, reportSyntaxError _)
- /*
- val hex = (ch() == 'x') && { nextch(); true };
- val base = if (hex) 16 else 10;
- var i = 0;
- while (ch() != ';') {
- ch() match {
- case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
- i = i * base + Character.digit( ch(), base );
- case 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
- | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' =>
- if (! hex)
- reportSyntaxError("hex char not allowed in decimal char ref\n"
- +"Did you mean to write &#x ?");
- else
- i = i * base + Character.digit(ch(), base);
- case _ =>
- reportSyntaxError("character '" + ch() + " not allowed in char ref\n");
- }
- nextch();
- }
- new String(Array(i.asInstanceOf[char]))
- */
- }
-
/** Comment ::= '&lt;!--' ((Char - '-') | ('-' (Char - '-')))* '--&gt;'
*
@@ -441,8 +424,7 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
*/
def xComment: NodeSeq = {
val sb: StringBuilder = new StringBuilder()
- xToken('-')
- xToken('-')
+ xToken("--")
while (true) {
if (ch == '-' && { sb.append(ch); nextch; ch == '-' }) {
sb.length = sb.length - 1
@@ -933,7 +915,7 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
case _ if isSpace(ch) =>
xSpace
case _ =>
- reportSyntaxError("markupdecl: unexpected character '"+ch+"' #" + ch.asInstanceOf[Int])
+ reportSyntaxError("markupdecl: unexpected character '"+ch+"' #" + ch.toInt)
nextch
}
@@ -1097,22 +1079,9 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
handle.notationDecl(notat, extID)
}
- /**
- * report a syntax error
- */
- def reportSyntaxError(pos: Int, str: String) {
- curInput.reportError(pos, str)
- //error("MarkupParser::synerr") // DEBUG
- }
-
+ def reportSyntaxError(pos: Int, str: String): Unit = curInput.reportError(pos, str)
def reportSyntaxError(str: String): Unit = reportSyntaxError(pos, str)
-
- /**
- * report a syntax error
- */
- def reportValidationError(pos: Int, str: String) {
- curInput.reportError(pos, str)
- }
+ def reportValidationError(pos: Int, str: String): Unit = reportSyntaxError(pos, str)
def push(entityName: String) {
//Console.println("BEFORE PUSHING "+ch)
@@ -1125,26 +1094,11 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
nextch
}
- /*
- def push(src:Source) = {
- curInput = src
- nextch
- }
- */
-
def pushExternal(systemId: String) {
- //Console.print("BEFORE PUSH, curInput = $"+curInput.descr)
- //Console.println(" stack = "+inpStack.map { x => "$"+x.descr })
-
- //Console.print("[PUSHING EXTERNAL "+systemId+"]")
if (!eof)
inpStack = curInput :: inpStack
curInput = externalSource(systemId)
-
- //Console.print("AFTER PUSH, curInput = $"+curInput.descr)
- //Console.println(" stack = "+inpStack.map { x => "$"+x.descr })
-
nextch
}
@@ -1154,8 +1108,6 @@ trait MarkupParser extends AnyRef with TokenTests { self: MarkupParser with Mar
ch = curInput.ch
pos = curInput.pos
eof = false // must be false, because of places where entity refs occur
- //Console.println("\n AFTER POP, curInput = $"+curInput.descr);
- //Console.println(inpStack.map { x => x.descr });
}
/** for the moment, replace only character references
diff --git a/src/library/scala/xml/parsing/XhtmlParser.scala b/src/library/scala/xml/parsing/XhtmlParser.scala
index 1b395a2739..8132c00cf4 100644
--- a/src/library/scala/xml/parsing/XhtmlParser.scala
+++ b/src/library/scala/xml/parsing/XhtmlParser.scala
@@ -8,52 +8,19 @@
// $Id$
-
package scala.xml
package parsing
import scala.io.Source
/** <p>
- * Extends the Markup Parser to do the right thing (tm) with PCData blocks.
- * </p>
- * <p>
- * (c) David Pollak, 2007 WorldWide Conferencing, LLC.
- * </p>
- */
-trait PCDataMarkupParser[PCM <: MarkupParser with MarkupHandler] extends MarkupParser { self: PCM =>
-
- /** '&lt;! CharData ::= [CDATA[ ( {char} - {char}"]]&gt;"{char} ) ']]&gt;'
- *
- * see [15]
- */
- override def xCharData: NodeSeq = {
- xToken("[CDATA[")
- val pos1 = pos
- val sb: StringBuilder = new StringBuilder()
- while (true) {
- if (ch==']' &&
- { sb.append(ch); nextch; ch == ']' } &&
- { sb.append(ch); nextch; ch == '>' } ) {
- sb.setLength(sb.length - 2);
- nextch;
- return PCData(sb.toString)
- } else sb.append( ch );
- nextch;
- }
- // bq: (todo) increase grace when meeting CDATA section
- throw FatalError("this cannot happen");
- }
-}
-
-/** <p>
* An XML Parser that preserves CDATA blocks and knows about HtmlEntities.
* </p>
* <p>
* (c) David Pollak, 2007 WorldWide Conferencing, LLC.
* </p>
*/
-class XhtmlParser(val input: Source) extends ConstructingHandler with PCDataMarkupParser[XhtmlParser] with ExternalSources {
+class XhtmlParser(val input: Source) extends ConstructingHandler with MarkupParser with ExternalSources {
val preserveWS = true
ent ++= XhtmlEntities()
}
@@ -66,9 +33,5 @@ class XhtmlParser(val input: Source) extends ConstructingHandler with PCDataMark
* </p>
*/
object XhtmlParser {
- def apply(source: Source): NodeSeq = {
- val p = new XhtmlParser(source)
- p.nextch
- p.document
- }
+ def apply(source: Source): NodeSeq = new XhtmlParser(source).initialize.document
}
diff --git a/src/library/scala/xml/pull/XMLEventReader.scala b/src/library/scala/xml/pull/XMLEventReader.scala
index c32bd81f4b..b09218a826 100644
--- a/src/library/scala/xml/pull/XMLEventReader.scala
+++ b/src/library/scala/xml/pull/XMLEventReader.scala
@@ -97,7 +97,7 @@ class XMLEventReader(src: Source) extends ProducerConsumerIterator[XMLEvent]
override def run() {
curInput = input
- interruptibly { this.nextch ; this.document() }
+ interruptibly { this.initialize.document() }
setEvent(POISON)
}
}
diff --git a/test/files/jvm/unittest_xml.scala b/test/files/jvm/unittest_xml.scala
index 63375cd15a..1569bb13af 100644
--- a/test/files/jvm/unittest_xml.scala
+++ b/test/files/jvm/unittest_xml.scala
@@ -2,14 +2,8 @@
object Test {
import scala.testing.SUnit._
- import scala.xml.{MetaData, Null, Parsing, PrefixedAttribute, UnprefixedAttribute }
+ import scala.xml.{MetaData, Null, Utility, PrefixedAttribute, UnprefixedAttribute }
- class ParsingTest extends TestCase("scala.xml.Parsing") with Assert {
- override def runTest = {
- assertTrue(Parsing.isNameStart('b'))
- assertFalse(Parsing.isNameStart(':'))
- }
- }
class MetaDataTest extends TestCase("scala.xml.MetaData") with Assert {
import scala.xml.{HasKeyValue, TopScope, NamespaceBinding, Node, Atom, Text }
@@ -65,6 +59,10 @@ object Test {
class UtilityTest extends TestCase("scala.xml.Utility") with Assert {
def runTest() = {
+ assertTrue(Utility.isNameStart('b'))
+ assertFalse(Utility.isNameStart(':'))
+
+
val x = <foo>
<toomuchws/>
</foo>
@@ -101,14 +99,11 @@ object Test {
def main(args:Array[String]) = {
val ts = new TestSuite(
- new ParsingTest,
new MetaDataTest,
new UtilityTest
)
val tr = new TestResult()
ts.run(tr)
- for(val failure <- tr.failures) {
- Console.println(failure)
- }
+ tr.failures foreach Console.println
}
}