From 210b36f4aaff2c8d574cd202703339ee734e797d Mon Sep 17 00:00:00 2001 From: michelou Date: Wed, 12 Apr 2006 16:55:00 +0000 Subject: [PATCH] added options '-windowtitle' and '-documenttitle' to command scaladoc added attributes 'windowtitle' and 'documenttitle' to Ant task 'Scaladoc' added option '-encoding iso-8859-1' in script test/scalatest removed leading tabs in scala/xml/*.scala git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@7124 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- build.xml | 6 +- src/compiler/scala/tools/ant/Scaladoc.scala | 115 +++++++++------ src/compiler/scala/tools/nsc/Main.scala | 10 +- src/compiler/scala/tools/nsc/Settings.scala | 12 +- .../scala/tools/nsc/doc/DocGenerator.scala | 110 +++++++------- .../scala/tools/nsc/doc/DocUtil.scala | 12 +- src/library/scala/xml/Text.scala | 20 +-- src/library/scala/xml/Utility.scala | 134 +++++++++--------- test/scalatest | 14 +- 9 files changed, 240 insertions(+), 193 deletions(-) diff --git a/build.xml b/build.xml index 72df20510..da4c6e534 100644 --- a/build.xml +++ b/build.xml @@ -925,6 +925,8 @@ DOCUMENTATION srcdir="${src.dir}" destdir="${api.lib.dir}" sourcepath="" + windowtitle="Scala Library Documentation" + documenttitle="<div>Scala 2<div>${version.number}</div></div>" > @@ -934,7 +936,7 @@ DOCUMENTATION - + diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala index a9866b715..d2270dd83 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/compiler/scala/tools/ant/Scaladoc.scala @@ -2,17 +2,18 @@ ** / |/ / ____/ ____/ ** ** / | | /___ / /___ ** ** /_/|__/_____/_____/ Copyright 2005-2006 LAMP/EPFL ** -** -** $Id$ +** ** \* */ +// $Id$ + package scala.tools.ant { - - + + import java.io.{File, InputStream, FileWriter} import java.net.{URL, URLClassLoader} import java.util.{ArrayList, Vector} - + import org.apache.tools.ant.{AntClassLoader, BuildException, DirectoryScanner, Project} import org.apache.tools.ant.taskdefs.MatchingTask @@ -38,7 +39,9 @@ package scala.tools.ant { *
  • bootclasspathref,
  • *
  • extdirs,
  • *
  • extdirsref,
  • - *
  • encoding.
  • + *
  • encoding,
  • + *
  • windowtitle,
  • + *
  • documenttitle.
  • * * It also takes the following parameters as nested elements:
      *
    • src (for srcdir),
    • @@ -47,22 +50,23 @@ package scala.tools.ant { *
    • bootclasspath,
    • *
    • extdirs.
    • *
    - * - * @author Gilles Dubochet */ + * + * @author Gilles Dubochet, Stephane Micheloud + */ class Scaladoc extends MatchingTask { - + /** The unique Ant file utilities instance to use in this task. */ private val fileUtils = FileUtils.newFileUtils() - + /******************************************************************************\ ** Ant user-properties ** \******************************************************************************/ - + /** The directories that contain source files to compile. */ private var origin: Option[Path] = None /** The directory to put the compiled files in. */ private var destination: Option[File] = None - + /** The class path to use for this compilation. */ private var classpath: Option[Path] = None /** The source path to use for this compilation. */ @@ -71,50 +75,55 @@ package scala.tools.ant { private var bootclasspath: Option[Path] = None /** The external extensions path to use for this compilation. */ private var extdirs: Option[Path] = None - + /** The character encoding of the files to compile. */ private var encoding: Option[String] = None - + + /** The window title of the generated HTML documentation. */ + private var windowtitle: Option[String] = None + /** The document title of the generated HTML documentation. */ + private var documenttitle: Option[String] = None + /******************************************************************************\ ** Properties setters ** \******************************************************************************/ - + /** Sets the srcdir attribute. Used by Ant. * @param input The value of origin. */ def setSrcdir(input: Path) = if (origin.isEmpty) origin = Some(input) else origin.get.append(input) - + /** Sets the origin as a nested src Ant parameter. * @return An origin path to be configured. */ def createSrc(): Path = { if (origin.isEmpty) origin = Some(new Path(getProject())) origin.get.createPath() } - + /** Sets the origin as an external reference Ant parameter. * @param input A reference to an origin path. */ def setSrcref(input: Reference) = createSrc().setRefid(input) - + /** Sets the destdir attribute. Used by Ant. * @param input The value of destination. */ def setDestdir(input: File) = destination = Some(input) - + /** Sets the classpath attribute. Used by Ant. * @param input The value of classpath. */ def setClasspath(input: Path) = if (classpath.isEmpty) classpath = Some(input) else classpath.get.append(input) - + /** Sets the classpath as a nested classpath Ant parameter. * @return A class path to be configured. */ def createClasspath(): Path = { if (classpath.isEmpty) classpath = Some(new Path(getProject())) classpath.get.createPath() } - + /** Sets the classpath as an external reference Ant parameter. * @param input A reference to a class path. */ def setClasspathref(input: Reference) = @@ -151,7 +160,7 @@ package scala.tools.ant { if (bootclasspath.isEmpty) bootclasspath = Some(new Path(getProject())) bootclasspath.get.createPath() } - + /** Sets the bootclasspath as an external reference Ant * parameter. * @param input A reference to a source path. */ @@ -175,12 +184,22 @@ package scala.tools.ant { * @param input A reference to an extensions path. */ def setExtdirsref(input: Reference) = createExtdirs().setRefid(input) - - /** Sets the encoding attribute. Used by Ant. + + /** Sets the encoding attribute. Used by Ant. * @param input The value of encoding. */ def setEncoding(input: String): Unit = encoding = Some(input) + /** Sets the windowtitle attribute. + * @param input The value of windowtitle. */ + def setWindowtitle(input: String): Unit = + windowtitle = Some(input) + + /** Sets the documenttitle attribute. + * @param input The value of documenttitle. */ + def setDocumenttitle(input: String): Unit = + documenttitle = Some(input) + /******************************************************************************\ ** Properties getters ** \******************************************************************************/ @@ -189,15 +208,14 @@ package scala.tools.ant { * @returns The class path as a list of files. */ private def getClasspath: List[File] = if (classpath.isEmpty) error("Member 'classpath' is empty.") - else - List.fromArray(classpath.get.list()).map(nameToFile) - + else List.fromArray(classpath.get.list()).map(nameToFile) + /** Gets the value of the origin attribute in a Scala-friendly form. * @returns The origin path as a list of files. */ private def getOrigin: List[File] = if (origin.isEmpty) error("Member 'origin' is empty.") else List.fromArray(origin.get.list()).map(nameToFile) - + /** Gets the value of the destination attribute in a Scala-friendly form. * @returns The destination as a file. */ private def getDestination: File = @@ -221,16 +239,16 @@ package scala.tools.ant { private def getExtdirs: List[File] = if (extdirs.isEmpty) error("Member 'extdirs' is empty.") else List.fromArray(extdirs.get.list()).map(nameToFile) - + /******************************************************************************\ ** Compilation and support methods ** \******************************************************************************/ - + /** This is forwarding method to circumvent bug #281 in Scala 2. Remove when * bug has been corrected. */ override protected def getDirectoryScanner(baseDir: java.io.File) = super.getDirectoryScanner(baseDir) - + /** Transforms a string name into a file relative to the provided base * directory. * @param base A file pointing to the location relative to which the name @@ -239,14 +257,14 @@ package scala.tools.ant { * @return A file created from the name and the base file. */ private def nameToFile(base: File)(name: String): File = existing(fileUtils.resolveFile(base, name)) - + /** Transforms a string name into a file relative to the build root * directory. * @param name A relative or absolute path to the file as a string. * @return A file created from the name. */ private def nameToFile(name: String): File = existing(getProject().resolveFile(name)) - + /** Tests if a file exists and prints a warning in case it doesn't. Always * returns the file, even if it doesn't exist. * @param file A file to test for existance. @@ -257,26 +275,26 @@ package scala.tools.ant { Project.MSG_WARN) file } - + /** Transforms a path into a Scalac-readable string. * @param path A path to convert. * @return A string-representation of the path like 'a.jar:b.jar'. */ private def asString(path: List[File]): String = path.map(asString).mkString("", File.pathSeparator, "") - + /** Transforms a file into a Scalac-readable string. * @param path A file to convert. * @return A string-representation of the file like '/x/k/a.scala'. */ private def asString(file: File): String = file.getAbsolutePath() - + /** Generates a build error. Error location will be the current task in the * ant file. * @param message A message describing the error. * @throws BuildException A build error exception thrown in every case. */ private def error(message: String): Nothing = throw new BuildException(message, getLocation()) - + private def readResource(resource: String): String = { val chars = new Iterator[Char] { private val stream = @@ -296,7 +314,7 @@ package scala.tools.ant { } builder.toString() } - + private def writeFile(file: File, content: String) = if (file.exists() && !file.canWrite()) error("File " + file + " is not writable") @@ -312,18 +330,17 @@ package scala.tools.ant { /** Performs the compilation. */ override def execute() = { - // Tests if all mandatory attributes are set and valid. if (origin.isEmpty) error("Attribute 'srcdir' is not set.") if (getOrigin.isEmpty) error("Attribute 'srcdir' is not set.") if (!destination.isEmpty && !destination.get.isDirectory()) error("Attribute 'destdir' does not refer to an existing directory.") if (destination.isEmpty) destination = Some(getOrigin.head) - + val mapper = new GlobPatternMapper() mapper.setTo("*.html") mapper.setFrom("*.scala") - + // Scans source directories to build up a compile lists. // If force is false, only files were the .class file in destination is // older than the .scala file will be used. @@ -342,14 +359,14 @@ package scala.tools.ant { ) else log("No files selected for documentation", Project.MSG_VERBOSE) - + list } } yield { log(originFile.toString(), Project.MSG_DEBUG) nameToFile(originDir)(originFile) } - + // Builds-up the compilation settings for Scalac with the existing Ant // parameters. val reporter = new ConsoleReporter() @@ -366,15 +383,19 @@ package scala.tools.ant { settings.bootclasspath.value = asString(getBootclasspath) if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs) if (!encoding.isEmpty) settings.encoding.value = encoding.get - + if (!windowtitle.isEmpty) settings.windowtitle.value = windowtitle.get + if (!documenttitle.isEmpty) settings.documenttitle.value = documenttitle.get + // Compiles the actual code object compiler extends Global(settings, reporter) try { val run = new compiler.Run - run.compile(sourceFiles.map(f:File=>f.toString())) + run.compile(sourceFiles.map(f: File => f.toString())) object generator extends DocGenerator { val global = compiler val outdir = settings.outdir.value + val windowTitle = settings.windowtitle.value + val documentTitle = settings.documenttitle.value } generator.process(run.units) if (reporter.errors > 0) @@ -411,7 +432,7 @@ package scala.tools.ant { readResource("scala/tools/ant/resources/style.css") ) } - + } - + } diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index b69ef5cbe..bd6498fca 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -16,9 +16,9 @@ import scala.tools.nsc.doc.DocGenerator object Main extends Object with EvalLoop { val PRODUCT: String = - System.getProperty("scala.product", "scalac") + System.getProperty("scala.tool.name", "scalac") val VERSION: String = - System.getProperty("scala.version", "unknown version") + System.getProperty("scala.tool.version", "unknown version") val COPYRIGHT: String = System.getProperty("scala.copyright", "(c) 2002-2006 LAMP/EPFL") val versionMsg = PRODUCT + " " + VERSION + " -- " + COPYRIGHT @@ -60,8 +60,10 @@ object Main extends Object with EvalLoop { run compile command.files if (command.settings.doc.value) { object generator extends DocGenerator { - val global : compiler.type = compiler; - val outdir = command.settings.outdir.value; + val global : compiler.type = compiler + val outdir = command.settings.outdir.value + val windowTitle = command.settings.windowtitle.value + val documentTitle = command.settings.documenttitle.value }; generator.process(run.units) } diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index df5a402cc..5a43e4e5e 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -11,7 +11,7 @@ import java.io.File class Settings(error: String => unit) { private var allsettings: List[Setting] = List() - + private def getProperty(name: String): String = if (System.getProperty(name) != "") System.getProperty(name) @@ -23,7 +23,6 @@ class Settings(error: String => unit) { getProperty("env.classpath"), ".") else getProperty("java.class.path") - private val bootclasspathDefault = alternatePath( @@ -56,11 +55,14 @@ class Settings(error: String => unit) { if (guess.exists()) guess.getPath() else null } else null } - + private val encodingDefault = new java.io.OutputStreamWriter( new java.io.ByteArrayOutputStream()).getEncoding - + + private val windowtitleDefault = "Scala Library Documentation" + private val documenttitleDefault = "Scala 2" + val doc = BooleanSetting("-doc", "Generate documentation"); val debuginfo = BooleanSetting("-g", "Generate debugging info") val nowarnings = BooleanSetting("-nowarn", "Generate no warnings") @@ -74,6 +76,8 @@ class Settings(error: String => unit) { val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", extdirsDefault) val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", ".") val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault) + val windowtitle = StringSetting ("-windowtitle", "windowtitle", "Specify window title of generated HTML documentation", windowtitleDefault) + val documenttitle = StringSetting ("-documenttitle", "documenttitle", "Specify document title of generated HTML documentation", documenttitleDefault) val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm", "msil"), "jvm") val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0") val debug = BooleanSetting("-debug", "Output debugging messages") diff --git a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala index e3cce32ee..8dd6806f6 100644 --- a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala +++ b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala @@ -17,24 +17,26 @@ abstract class DocGenerator extends Models { import global._ import DocUtil._ def outdir: String + def windowTitle: String + def documentTitle: String def contentFrame = "contentFrame" def classesFrame = "classesFrame" def modulesFrame = "modulesFrame" - def emptyMap = ListMap.Empty[Kind,TreeSet[HasTree]]; + def emptyMap = ListMap.Empty[Kind,TreeSet[HasTree]] override def acceptPrivate = false; abstract class Frame extends UrlContext { def path: String; // relative to outdir def relative: String = { - assert(path != null); - var idx = 0; - var ct = ""; + assert(path != null) + var idx = 0 + var ct = "" while (idx != -1) { idx = path.indexOf('/', idx); //System.err.println(path + " idx=" + idx); ct = ct + (if (idx != -1) "../" else ""); - idx = idx + (if (idx == -1) 0 else 1); + idx = idx + (if (idx == -1) 0 else 1) } ct } @@ -54,7 +56,7 @@ abstract class DocGenerator extends Models { writer.close() } - def urlFor(sym : Symbol, target : String) : NodeSeq = try { + def urlFor(sym: Symbol, target: String): NodeSeq = try { if (sym.sourceFile == null) Text(sym.fullNameString('.')); else aref(urlFor(sym), target, sym.nameString); } catch { @@ -72,7 +74,7 @@ abstract class DocGenerator extends Models { Text(tpe.symbol.toString()) } - def urlFor0(sym : Symbol, orig : Symbol) : String = { + def urlFor0(sym: Symbol, orig: Symbol): String = { (if (sym == NoSymbol) { "XXX"; } else if (sym.owner.isPackageClass) sym.fullNameString('/'); @@ -104,12 +106,17 @@ abstract class DocGenerator extends Models { save(page(title, body, hasBody)) } + val doctitle: NodeSeq = +
    + {load(documentTitle)} +
    ; + abstract class ListModuleFrame extends Frame { val path = "modules"; val title = "List of all packages"; def modules : TreeMap[String,ModuleClassSymbol]; def body : NodeSeq = { - val x = div0("Scala 2") concat + val x = doctitle concat aref("all-classes.html", classesFrame, "All objects and classes"); val y =

    Packages ; } - def fullComment(mmbr : HasTree) : NodeSeq = { + def fullComment(mmbr: HasTree): NodeSeq = { if (comments.contains(mmbr.tree.symbol)) comment(comments(mmbr.tree.symbol), false) else NodeSeq.Empty; }; - def shortComment(mmbr : HasTree) : NodeSeq = { + def shortComment(mmbr: HasTree): NodeSeq = { if (comments.contains(mmbr.tree.symbol)) comment(comments(mmbr.tree.symbol), true) else NodeSeq.Empty; }; - def ifT (cond : Boolean, nodes : NodeSeq) = if (cond) nodes else NodeSeq.Empty; + def ifT (cond: Boolean, nodes: NodeSeq) = if (cond) nodes else NodeSeq.Empty; def ifT (tree : Tree, nodes : NodeSeq, before : Boolean) = { if (tree != EmptyTree && tree.tpe.symbol != definitions.AnyClass && @@ -295,8 +302,8 @@ abstract class DocGenerator extends Models { def forType(tpe: Type): NodeSeq = urlFor(tpe, contentFrame); - def forTree(tree : Tree) : NodeSeq = tree match { - case vdef : ValDef => + def forTree(tree: Tree): NodeSeq = tree match { + case vdef : ValDef => Text(vdef.symbol.name.toString()).concat(Text(" : ")).concat(forTree(vdef.tpt)); case sel : Select => forTree(sel.qualifier).concat(Text(sel.symbol.nameString)); case tree : AbsTypeDef => @@ -319,17 +326,17 @@ abstract class DocGenerator extends Models { def surround(open: String, close: String, node: NodeSeq): NodeSeq = Text(open).concat(node).concat(Text(close)); - def typesFor(ht : HasTree) : NodeSeq = { + def typesFor(ht: HasTree): NodeSeq = { val tparams = ht.tree match { - case cdef : ClassDef => cdef.tparams; - case ddef : DefDef => ddef.tparams; - case adef : AliasTypeDef => adef.tparams; - case _ => Nil; + case cdef: ClassDef => cdef.tparams + case ddef: DefDef => ddef.tparams + case adef: AliasTypeDef => adef.tparams + case _ => Nil } if (tparams.isEmpty) Text(""); else surround("[", "]", forTrees(tparams)); } - def argsFor(ht : HasTree) : NodeSeq = ht.tree match { + def argsFor(ht: HasTree): NodeSeq = ht.tree match { case ddef : DefDef => if (!ddef.vparamss.isEmpty && (!ddef.vparamss.tail.isEmpty || !ddef.vparamss.head.isEmpty)) { @@ -339,15 +346,16 @@ abstract class DocGenerator extends Models { } else NodeSeq.Empty; case _ => NodeSeq.Empty; } - def resultFor(ht : HasTree) : NodeSeq = ht.tree match { + def resultFor(ht: HasTree): NodeSeq = ht.tree match { case vdef : ValOrDefDef => if (!vdef.symbol.nameString.equals("this")) Text(" : ").concat(forTree(vdef.tpt)); else NodeSeq.Empty; - case _ => NodeSeq.Empty; - } + case _ => + NodeSeq.Empty + } } - + abstract class ListClassContentFrame extends ContentFrame0 { def classes: ListMap[Kind,TreeSet[HasTree]] def module: ModuleClassSymbol @@ -355,7 +363,7 @@ abstract class DocGenerator extends Models { def path = module.fullNameString('/') + "$content"; def title = "All Classes and Objects in " + module.fullNameString('.'); - def body : NodeSeq = { + def body: NodeSeq = {
    Scala 2
    API Specification @@ -378,8 +386,8 @@ abstract class DocGenerator extends Models { } abstract class ContentFrame extends ContentFrame0 { - def clazz: ImplMod; - def kind: Kind; + def clazz: ImplMod + def kind: Kind def body: NodeSeq = {navigation}{header0}{fullHeader(clazz)}; final def path = urlFor0(clazz.tree.symbol,clazz.tree.symbol); @@ -387,7 +395,7 @@ abstract class DocGenerator extends Models { //
    // // - def navigation : NodeSeq = + def navigation: NodeSeq =
    @@ -150,15 +157,15 @@ abstract class DocGenerator extends Models { } abstract class ListClassFrame extends Frame { - def classes: ListMap[Kind,TreeSet[HasTree]]; + def classes: ListMap[Kind,TreeSet[HasTree]] + + def navLabel: String - def navLabel: String; - private def path0 = { - val p = path; + val p = path if (p.endsWith("$package")) - p.substring(0, p.length() - ("$package").length()); - else p; + p.substring(0, p.length() - ("$package").length()) + else p } def body : NodeSeq = { @@ -254,7 +261,7 @@ abstract class DocGenerator extends Models { } } ; } else NodeSeq.Empty; - def shortHeader(mmbr : HasTree) : NodeSeq = { + def shortHeader(mmbr: HasTree): NodeSeq = {
    { { for (val str <- stringsFor(mmbr.mods)) yield {(Text(str + " "))}; } } @@ -270,15 +277,15 @@ abstract class DocGenerator extends Models {
    - {div0("Scala 2")} + {doctitle} ; - - def header0 : NodeSeq = + + def header0: NodeSeq =


    in {aref(urlFor(clazz.tree.symbol.owner), "_self", clazz.tree.symbol.owner.fullNameString('.'))}
    {Text(codeFor(kind))} @@ -451,12 +459,12 @@ abstract class DocGenerator extends Models { def path = "all-classes" def navLabel = "root-page" }; - + // class from for each module. for (val top <- topLevel.elements) { - val module = top._1; - val members = top._2; - + val module = top._1 + val members = top._2 + new ListClassFrame { def title = "List of classes and objects in package " + module.fullNameString('.') def classes = top._2 @@ -468,7 +476,7 @@ abstract class DocGenerator extends Models { def classes = top._2; def module = module0; }; - + // do root frame for each class and object for (val kind <- members.elements) for (val mmbr <- kind._2.toList) { val kind0 = kind._1; @@ -482,10 +490,10 @@ abstract class DocGenerator extends Models { } new Frame { - def title = "Scala Library Documentation"; - def body = index; - def path = "index"; - override def hasBody = false; + def title = windowTitle + def body = index + def path = "index" + override def hasBody = false }; for (val base <- "style.css" :: "script.js" :: Nil) { val input = getClass().getClassLoader().getResourceAsStream("scala/tools/nsc/doc/" + base); @@ -503,7 +511,7 @@ abstract class DocGenerator extends Models { } } input.close(); - output.close(); + output.close() } } } @@ -528,10 +536,10 @@ abstract class DocGenerator extends Models { def parse(str : String) : NodeSeq = { new SpecialNode { - def label = "#PCDATA"; - def toString(sb:StringBuffer): StringBuffer = { + def label = "#PCDATA" + def toString(sb: StringBuffer): StringBuffer = { sb.append(str.trim()); - sb; + sb } } @@ -544,7 +552,7 @@ abstract class DocGenerator extends Models { else parsedxml1; */ }; - + def comment(comment : String, isShort : Boolean) : NodeSeq = { var ret : List[Node] = Nil; assert(comment != null); diff --git a/src/compiler/scala/tools/nsc/doc/DocUtil.scala b/src/compiler/scala/tools/nsc/doc/DocUtil.scala index a7ffa9ac8..8fe34b46f 100644 --- a/src/compiler/scala/tools/nsc/doc/DocUtil.scala +++ b/src/compiler/scala/tools/nsc/doc/DocUtil.scala @@ -2,10 +2,13 @@ * Copyright 2005-2006 LAMP/EPFL * @author Sean McDirmid */ -// $Id: $ +// $Id$ package scala.tools.nsc.doc +import java.io.StringReader +import org.xml.sax.InputSource + import scala.collection.immutable._ import scala.xml._ @@ -14,6 +17,13 @@ object DocUtil { def dquote(str: String): NodeSeq = DQUOTE :: Text(str) :: DQUOTE :: Nil + def load(str: String): NodeSeq = { + val xmlStr = str.replaceAll("<", "<").replaceAll(">",">") + .replaceAll("&", "&").replaceAll(""", "\"") + val xmlSrc = new InputSource(new StringReader(xmlStr)) + XML.load(xmlSrc) + } + object DQUOTE extends SpecialNode { def toString(sb: StringBuffer) = { sb.append("\""); sb diff --git a/src/library/scala/xml/Text.scala b/src/library/scala/xml/Text.scala index 9217d9631..71d161624 100644 --- a/src/library/scala/xml/Text.scala +++ b/src/library/scala/xml/Text.scala @@ -9,7 +9,7 @@ // $Id$ -package scala.xml; +package scala.xml /** an XML node for text (PCDATA). Used in both non-bound and bound XML @@ -17,19 +17,19 @@ package scala.xml; * @author Burak Emir * @param text the text contained in this node, may not be null. */ -case class Text( _data: String ) extends Atom[String](_data) { +case class Text(_data: String) extends Atom[String](_data) { - if(null == data) - throw new java.lang.NullPointerException("tried to construct Text with null"); + if (null == data) + throw new java.lang.NullPointerException("tried to construct Text with null") - final override def equals(x:Any) = x match { - case s:String => s.equals( data.toString() ); - case s:Text => data == s.data ; - case _ => false; + final override def equals(x: Any) = x match { + case s:String => s.equals(data.toString()) + case s:Text => data == s.data + case _ => false } /** returns text, with some characters escaped according to XML spec */ - override def toString(sb:StringBuffer) = - Utility.escape( data.toString(), sb ); + override def toString(sb: StringBuffer) = + Utility.escape(data.toString(), sb) } diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 25f79b5ab..d88bc49ca 100644 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -9,37 +9,36 @@ // $Id$ -package scala.xml; +package scala.xml -import java.lang.StringBuffer; -import scala.collection.mutable; +import java.lang.StringBuffer +import scala.collection.mutable /** - * Utility functions for processing instances of bound and not bound XML - * classes, as well as escaping text nodes + * Utility functions for processing instances of bound and + * not bound XML classes, as well as escaping text nodes. */ object Utility extends AnyRef with parsing.TokenTests { - def view(s: String): Text = Text(s); + def view(s: String): Text = Text(s) /* escapes the characters < > & and " from string */ - final def escape(text: String): String = - escape(text, new StringBuffer()).toString(); - + final def escape(text: String): String = + escape(text, new StringBuffer()).toString() /* appends escaped string to s */ final def escape(text: String, s: StringBuffer): StringBuffer = { for (val c <- Iterator.fromString(text)) c match { - case '<' => s.append("<"); - case '>' => s.append(">"); - case '&' => s.append("&"); - case '"' => s.append("""); - case _ => s.append(c); + case '<' => s.append("<") + case '>' => s.append(">") + case '&' => s.append("&") + case '"' => s.append(""") + case _ => s.append(c) } s } - + /** * Returns a set of all namespaces used in a sequence of nodes * and all their descendants, including the empty namespaces. @@ -48,13 +47,13 @@ object Utility extends AnyRef with parsing.TokenTests { */ def collectNamespaces(nodes: Seq[Node]): mutable.Set[String] = { - var m = new mutable.HashSet[String](); - val it = nodes.elements; + var m = new mutable.HashSet[String]() + val it = nodes.elements while (it.hasNext) collectNamespaces(it.next, m); m } - + /** adds all namespaces in node to set */ def collectNamespaces(n: Node, set: mutable.Set[String]): Unit = { if( n.typeTag$ >= 0 ) { @@ -84,9 +83,9 @@ object Utility extends AnyRef with parsing.TokenTests { * @todo define a way to escape literal characters to &xx; references */ def toXML(n: Node, stripComment: Boolean): String = { - val sb = new StringBuffer(); - toXML(n, TopScope, sb, stripComment); - sb.toString(); + val sb = new StringBuffer() + toXML(n, TopScope, sb, stripComment) + sb.toString() } @@ -100,35 +99,34 @@ object Utility extends AnyRef with parsing.TokenTests { def toXML(x: Node, pscope: NamespaceBinding, sb: StringBuffer, stripComment: Boolean): Unit = { x match { - case c: Comment if !stripComment => - c.toString(sb) + case c: Comment if !stripComment => + c.toString(sb) - case x: SpecialNode => - x.toString(sb) - - case _ => + case x: SpecialNode => + x.toString(sb) + + case _ => // print tag with namespace declarations - sb.append('<'); - x.nameToString(sb); + sb.append('<') + x.nameToString(sb) if (x.attributes != null) { x.attributes.toString(sb) } - x.scope.toString(sb, pscope); - sb.append('>'); - for (val c <- x.child.elements) { - toXML(c, x.scope, sb, stripComment); - } - sb.append("') + for (val c <- x.child.elements) { + toXML(c, x.scope, sb, stripComment) + } + sb.append("') - } } /** returns prefix of qualified name if any */ final def prefix(name: String): Option[String] = { - val i = name.indexOf(':'.asInstanceOf[Int]); + val i = name.indexOf(':'.asInstanceOf[Int]) if( i != -1 ) Some( name.substring(0, i) ) else None } @@ -141,10 +139,10 @@ object Utility extends AnyRef with parsing.TokenTests { * @param children */ def hashCode(pre: String, label: String, attribHashCode: Int, scpeHash: Int, children: Seq[Node]) = { - ( if(pre!=null) {41 * pre.hashCode() % 7} else {0}) - + label.hashCode() * 53 - + attribHashCode * 7 - + scpeHash * 31 + ( if(pre!=null) {41 * pre.hashCode() % 7} else {0}) + + label.hashCode() * 53 + + attribHashCode * 7 + + scpeHash * 31 + children.hashCode() } @@ -161,21 +159,21 @@ object Utility extends AnyRef with parsing.TokenTests { */ def systemLiteralToString(s: String): String = { - val sb = new StringBuffer(); - systemLiteralToString(sb, s); - sb.toString(); - } + val sb = new StringBuffer() + systemLiteralToString(sb, s) + sb.toString() + } def systemLiteralToString(sb: StringBuffer, s: String): StringBuffer = { - sb.append("SYSTEM "); - appendQuoted(s, sb); + sb.append("SYSTEM ") + appendQuoted(s, sb) } def publicLiteralToString(s: String): String = { - val sb = new StringBuffer(); - systemLiteralToString(sb, s); - sb.toString(); - } + val sb = new StringBuffer() + systemLiteralToString(sb, s) + sb.toString() + } def publicLiteralToString(sb: StringBuffer, s: String): StringBuffer = { sb.append("PUBLIC \"").append(s).append('"') @@ -200,11 +198,11 @@ object Utility extends AnyRef with parsing.TokenTests { * @param sb */ def appendEscapedQuoted(s: String, sb: StringBuffer) = { - sb.append('"'); - val z:Seq[Char] = Predef.string2seq(s); + sb.append('"') + val z:Seq[Char] = Predef.string2seq(s) for( val c <- z ) c match { - case '"' => sb.append('\\'); sb.append('"'); - case _ => sb.append( c ); + case '"' => sb.append('\\'); sb.append('"') + case _ => sb.append(c) } sb.append('"') } @@ -212,36 +210,36 @@ object Utility extends AnyRef with parsing.TokenTests { def getName(s: String, index: Int): String = { var i = index; val sb = new StringBuffer(); - if(i < s.length()) { + if (i < s.length()) { var c = s.charAt(i); - if(isNameStart(s.charAt(i))) - while(i < s.length() && { c = s.charAt(i); isNameChar(c)}) { + if (isNameStart(s.charAt(i))) + while (i < s.length() && { c = s.charAt(i); isNameChar(c)}) { sb.append(c); - i = i + 1; - } - sb.toString(); + i = i + 1 + } + sb.toString() } else null } /** returns null if the value is a correct attribute value, error message if it isn't */ def checkAttributeValue(value: String): String = { - var i = 0; - while(i < value.length()) { + var i = 0 + while (i < value.length()) { value.charAt(i) match { case '<' => return "< not allowed in attribute value"; case '&' => val n = getName(value, i+1); - if(n== null) + if (n== null) return "malformed entity reference in attribute value ["+value+"]"; i = i + n.length() + 1; - if(i >= value.length() || value.charAt(i) != ';') + if (i >= value.length() || value.charAt(i) != ';') return "malformed entity reference in attribute value ["+value+"]"; case _ => } - i = i + 1; + i = i + 1 } - return null; + null } } diff --git a/test/scalatest b/test/scalatest index a5bd6a354..faa9a97c8 100755 --- a/test/scalatest +++ b/test/scalatest @@ -203,7 +203,7 @@ test_print_failure() { test_run_pos() { rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && - $SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && + $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala && rm -rf "$dstbase".obj; } @@ -211,7 +211,7 @@ test_run_pos() { test_run_neg() { rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && - ( cd "$srcdir" && $SOCOS -d "$os_dstbase".obj "$@" "$testname".scala; ); + ( cd "$srcdir" && $SCALAC -d "$os_dstbase".obj "$@" "$testname".scala; ); if [ "$?" = 0 ]; then status=1; else status=0; fi; rm -rf "$dstbase".obj; return $status; @@ -221,7 +221,7 @@ test_run_neg() { test_run_jvm() { rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && - $SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && + $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala && classpath=`get_os_pathlist "$os_dstbase".obj:$CLASSPATH` && $SCALA -classpath $classpath Test "jvm" && rm -rf "$dstbase".obj; @@ -235,7 +235,7 @@ test_run_dis() { fi; rm -rf "$dstbase".obj && mkdir -p "$dstbase".obj && - $SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && + $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala && $SCALAP -classpath "$os_dstbase".obj `cat "$argsfile"` && rm -rf "$dstbase".obj; } @@ -245,7 +245,7 @@ test_run_msil() { assemblies=`get_os_pathlist "/home/linuxsoft/apps/msil"`; rm -f "$dstbase".il && rm -f "$dstbase".EXE && - $SOCOS -nowarn -target:msil -o "$os_dstbase" -r $assemblies "$@" \ + $SCALAC -nowarn -target:msil -o "$os_dstbase" -r $assemblies "$@" \ "$os_srcbase".scala && case "$UNAME" in CYGWIN* ) @@ -558,7 +558,7 @@ if [ "$TEST_ALL" = "true" ]; then fi; SCALA="${BIN_DIR}scala"; -SOCOS="${BIN_DIR}scalac"; +SCALAC="${BIN_DIR}scalac -encoding iso-8859-1"; SCALAP="${BIN_DIR}scalap"; SCALA_SCALA_ARGS="-Xmx512M $SCALA_SCALA_ARGS"; @@ -575,7 +575,7 @@ fi printf_outline "Source directory is : $SRCDIR\\n"; bin_dir=$BIN_DIR if [ -z "$bin_dir" ]; then - bin_dir=`which "$SOCOS"` && bin_dir=`dirname "$bin_dir"`/; + bin_dir=`which "$SCALAC"` && bin_dir=`dirname "$bin_dir"`/; bin_dir=`test_get_location ${bin_dir}scalac`; fi; printf_outline "Scala binaries in : $bin_dir\\n";