More support code for the big partest patch I'm working on to

finally finish classpaths for good.  No review.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@21159 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2010-03-13 19:24:43 +00:00
parent 7eb1d37efb
commit 9058add5a0
8 changed files with 59 additions and 37 deletions

View File

@ -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)
}

View File

@ -117,6 +117,4 @@ with Streamable.Chars
()
}
override def toString() = "File(%s)".format(path)
}

View File

@ -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

View File

@ -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] =
@ -143,7 +141,8 @@ class Process(processCreator: () => JProcess) extends Iterable[String]
def waitFor() = process.waitFor()
def destroy() = process.destroy()
def rerun() = new Process(processCreator)
def slurp() = _out.slurp()
def stdout = iterator
def iterator = _out.iterator
def stderr = _err.iterator
@ -152,6 +151,11 @@ class Process(processCreator: () => JProcess) extends Iterable[String]
class StreamedConsumer(in: InputStream) extends Thread with 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

View File

@ -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)

View File

@ -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)
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(x2)) Map(x1 -> "") ++ loop(x2 :: xs)
else Map(x1 -> x2) ++ loop(xs)
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

View File

@ -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 =>

View File

@ -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)