From 1b14f49ff297a29c489dd184ee8f1f3c885a1b33 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 13 Mar 2010 19:24:43 +0000 Subject: More support code for the big partest patch I'm... More support code for the big partest patch I'm working on to finally finish classpaths for good. No review. --- src/compiler/scala/tools/nsc/io/Directory.scala | 5 +- src/compiler/scala/tools/nsc/io/File.scala | 2 - src/compiler/scala/tools/nsc/io/Path.scala | 6 ++- src/compiler/scala/tools/nsc/io/Process.scala | 18 ++++--- .../scala/tools/nsc/settings/AbsSettings.scala | 3 ++ .../scala/tools/nsc/util/CommandLineParser.scala | 59 ++++++++++++++-------- .../scala/tools/nsc/util/ShowPickled.scala | 2 +- src/library/scala/util/Properties.scala | 1 + 8 files changed, 59 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/io/Directory.scala b/src/compiler/scala/tools/nsc/io/Directory.scala index 965ac51203..822dfbdffe 100644 --- a/src/compiler/scala/tools/nsc/io/Directory.scala +++ b/src/compiler/scala/tools/nsc/io/Directory.scala @@ -36,8 +36,7 @@ import Path._ * @author Paul Phillips * @since 2.8 */ -class Directory(jfile: JFile) extends Path(jfile) -{ +class Directory(jfile: JFile) extends Path(jfile) { override def toDirectory: Directory = this override def toFile: File = new File(jfile) override def isValid = jfile.isDirectory() || !jfile.exists() @@ -82,6 +81,4 @@ class Directory(jfile: JFile) extends Path(jfile) } f.delete() } - - override def toString() = "Directory(%s)".format(path) } diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala index d19b2cc269..aecbfbd048 100644 --- a/src/compiler/scala/tools/nsc/io/File.scala +++ b/src/compiler/scala/tools/nsc/io/File.scala @@ -117,6 +117,4 @@ with Streamable.Chars () } - - override def toString() = "File(%s)".format(path) } diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala index 823e11b304..98d981f65e 100644 --- a/src/compiler/scala/tools/nsc/io/Path.scala +++ b/src/compiler/scala/tools/nsc/io/Path.scala @@ -97,6 +97,10 @@ class Path private[io] (val jfile: JFile) { def toAbsolute: Path = if (isAbsolute) this else Path(jfile.getAbsolutePath()) def toURI: URI = jfile.toURI() def toURL: URL = toURI.toURL() + /** If this path is absolute, returns it: otherwise, returns an absolute + * path made up of root / this. + */ + def toAbsoluteWithRoot(root: Path) = if (isAbsolute) this else root.toAbsolute / this /** Creates a new Path with the specified path appended. Assumes * the type of the new component implies the type of the result. @@ -225,7 +229,7 @@ class Path private[io] (val jfile: JFile) { // def copyTo(target: Path, options ...): Boolean // def moveTo(target: Path, options ...): Boolean - override def toString() = "Path(%s)".format(path) + override def toString() = path override def equals(other: Any) = other match { case x: Path => path == x.path case _ => false diff --git a/src/compiler/scala/tools/nsc/io/Process.scala b/src/compiler/scala/tools/nsc/io/Process.scala index 306c88a854..7580cf22ab 100644 --- a/src/compiler/scala/tools/nsc/io/Process.scala +++ b/src/compiler/scala/tools/nsc/io/Process.scala @@ -6,7 +6,7 @@ package scala.tools.nsc package io import concurrent.ThreadRunner -import scala.util.Properties.{ isWin, isMac } +import scala.util.Properties.{ isWin, isMac, lineSeparator } import scala.util.control.Exception.catching import java.lang.{ Process => JProcess, ProcessBuilder => JProcessBuilder } import java.io.{ IOException, InputStream, OutputStream, BufferedReader, InputStreamReader, PrintWriter, File => JFile } @@ -68,8 +68,7 @@ object Process } } - private[Process] class ProcessBuilder(val pb: JProcessBuilder) - { + private[Process] class ProcessBuilder(val pb: JProcessBuilder) { def this(cmd: String*) = this(new JProcessBuilder(cmd: _*)) def start() = new Process(() => pb.start()) @@ -116,7 +115,7 @@ object Process cwd: Path = null, redirect: Boolean = false ): Process = - exec(shell(command), env, cwd) + exec(shell(command), env, cwd, redirect) /** Executes the given command line. * @@ -129,12 +128,11 @@ object Process cwd: Path = null, redirect: Boolean = false ): Process = - new ProcessBuilder(command: _*) withEnv env withCwd cwd start + new ProcessBuilder(command: _*) withEnv env withCwd cwd withRedirectedErrorStream redirect start } import Process._ -class Process(processCreator: () => JProcess) extends Iterable[String] -{ +class Process(processCreator: () => JProcess) extends Iterable[String] { lazy val process = processCreator() def exitValue(): Option[Int] = @@ -144,6 +142,7 @@ class Process(processCreator: () => JProcess) extends Iterable[String] def destroy() = process.destroy() def rerun() = new Process(processCreator) + def slurp() = _out.slurp() def stdout = iterator def iterator = _out.iterator def stderr = _err.iterator @@ -153,6 +152,11 @@ class Process(processCreator: () => JProcess) extends Iterable[String] private val queue = new LinkedBlockingQueue[String] private val reader = new BufferedReader(new InputStreamReader(in)) + def slurp(): String = { + join() + queue.toArray map (_ + lineSeparator) mkString + } + def iterator = { join() // make sure this thread is complete new Iterator[String] { diff --git a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala index 5750224e3d..a10f422212 100644 --- a/src/compiler/scala/tools/nsc/settings/AbsSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/AbsSettings.scala @@ -25,6 +25,9 @@ trait AbsSettings { // only settings which differ from default def userSetSettings = visibleSettings filterNot (_.isDefault) + // an argument list which (should) be usable to recreate the Settings + def recreateArgs = userSetSettings.toList flatMap (_.unparse) + // checks both name and any available abbreviations def lookupSetting(cmd: String): Option[Setting] = allSettings find (_ respondsTo cmd) diff --git a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala index 9f9eda0ef3..09398ca2c4 100644 --- a/src/compiler/scala/tools/nsc/util/CommandLineParser.scala +++ b/src/compiler/scala/tools/nsc/util/CommandLineParser.scala @@ -30,16 +30,19 @@ case class CommandLine( ) { def this(args: List[String]) = this(args, Nil, Nil) def this(args: Array[String]) = this(args.toList, Nil, Nil) - def this(args: Array[String], unaryArguments: List[String]) = this(args.toList, unaryArguments, Nil) - def this(line: String) = this(CommandLineParser tokenize line) + def this(line: String) = this(CommandLineParser tokenize line, Nil, Nil) def withUnaryArgs(xs: List[String]) = copy(unaryArguments = xs) def withBinaryArgs(xs: List[String]) = copy(binaryArguments = xs) - def enforceArity = true + def originalArgs = args def assumeBinary = true + def enforceArity = true + def onlyKnownOptions = false val Terminator = "--" + val ValueForUnaryOption = "true" // so if --opt is given, x(--opt) = true + def mapForUnary(opt: String) = Map(opt -> ValueForUnaryOption) def errorFn(msg: String) = println(msg) @@ -47,32 +50,44 @@ case class CommandLine( * residualArgs are what is left after removing the options and their args. */ lazy val (argMap, residualArgs) = { - val residual = new ListBuffer[String] - def isOption(s: String) = s startsWith "-" + val residualBuffer = new ListBuffer[String] + def isValidOption(s: String) = !onlyKnownOptions || (unaryArguments contains s) || (binaryArguments contains s) + def isOption(s: String) = (s startsWith "-") && (isValidOption(s) || { unknownOption(s) ; false }) def isUnary(s: String) = isOption(s) && (unaryArguments contains s) def isBinary(s: String) = isOption(s) && !isUnary(s) && (assumeBinary || (binaryArguments contains s)) + def unknownOption(opt: String) = + errorFn("Option '%s' not recognized.".format(opt)) def missingArg(opt: String, what: String) = errorFn("Option '%s' requires argument, found %s instead.".format(opt, what)) - def loop(args: List[String]): Map[String, String] = args match { - case Nil => Map() - case x :: xs if !isOption(x) => residual += x ; loop(xs) - case x :: xs if isUnary(x) => Map(x -> "") ++ loop(xs) - case x :: Nil => if (enforceArity) missingArg(x, "EOF") ; Map(x -> "") - case Terminator :: xs => residual ++= xs ; Map() - case x :: Terminator :: xs => residual ++= xs ; Map(x -> "") - case x1 :: x2 :: xs => - if (enforceArity && isOption(x2)) - missingArg(x1, x2) - - if (isOption(x2)) Map(x1 -> "") ++ loop(x2 :: xs) - else Map(x1 -> x2) ++ loop(xs) + def loop(args: List[String]): Map[String, String] = { + def residual(xs: List[String]) = { residualBuffer ++= xs ; Map[String, String]() } + if (args.isEmpty) return Map() + val hd :: rest = args + if (rest.isEmpty) { + if (isBinary(hd) && enforceArity) + missingArg(hd, "EOF") + + if (isOption(hd)) mapForUnary(hd) else residual(args) + } + else + if (hd == Terminator) residual(rest) + else { + val hd1 :: hd2 :: rest = args + + if (hd2 == Terminator) mapForUnary(hd1) ++ residual(rest) + else if (isUnary(hd1)) mapForUnary(hd1) ++ loop(hd2 :: rest) + else if (isBinary(hd1)) { + if (isOption(hd2) && enforceArity) + missingArg(hd1, hd2) + + Map(hd1 -> hd2) ++ loop(rest) + } + else { residual(List(hd1)) ++ loop(hd2 :: rest) } + } } - val (unaries, rest) = args partition (unaryArguments contains _) - val map = loop(rest) - - (map ++ Map(unaries map (x => x -> ""): _*), residual.toList) + (loop(args), residualBuffer.toList) } def isSet(arg: String) = args contains arg diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index 260c048b8a..197eb28661 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -290,7 +290,7 @@ object ShowPickled extends Names { /** Option --bare suppresses numbers so the output can be diffed. */ def main(args: Array[String]) { - val parsed = new CommandLine(args, List("--bare")) + val parsed = CommandLine(args.toList, List("--bare"), Nil) def isBare = parsed isSet "--bare" parsed.residualArgs foreach { arg => diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index afd83eb187..b781e46be5 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -49,6 +49,7 @@ private[scala] trait PropertiesTrait def propOrEmpty(name: String) = propOrElse(name, "") def propOrNull(name: String) = propOrElse(name, null) def propOrNone(name: String) = Option(propOrNull(name)) + def propOrFalse(name: String) = propOrNone(name) exists (x => List("yes", "on", "true") contains x.toLowerCase) def setProp(name: String, value: String) = System.setProperty(name, value) def clearProp(name: String) = System.clearProperty(name) -- cgit v1.2.3