Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

85 lines (77 sloc) 2.935 kB
/* sbt -- Simple Build Tool
* Copyright 2009 Mark Harrah
*/
package xsbt.test
import java.io.{BufferedReader, File, InputStreamReader}
import scala.util.parsing.combinator._
import scala.util.parsing.input.Positional
import Character.isWhitespace
import sbt.IO
/*
statement*
statement ::= startChar successChar word+ nl
startChar ::= <single character>
successChar ::= '+' | '-'
word ::= [^ \[\]]+
comment ::= '#' \S* nl
nl ::= '\r' \'n' | '\n' | '\r' | eof
*/
final case class Statement(command: String, arguments: List[String], successExpected: Boolean, line: Int) extends NotNull
{
def linePrefix = "{line " + line + "} "
}
private object TestScriptParser
{
val SuccessLiteral = "success"
val FailureLiteral = "failure"
val WordRegex = """[^ \[\]\s'\"][^ \[\]\s]*""".r
}
import TestScriptParser._
class TestScriptParser(handlers: Map[Char, StatementHandler]) extends RegexParsers with NotNull
{
require(!handlers.isEmpty)
override def skipWhitespace = false
import IO.read
if(handlers.keys.exists(isWhitespace))
error("Start characters cannot be whitespace")
if(handlers.keys.exists(key => key == '+' || key == '-'))
error("Start characters cannot be '+' or '-'")
def parse(scriptFile: File): List[(StatementHandler, Statement)] = parse(read(scriptFile), Some(scriptFile.getCanonicalPath))
def parse(script: String): List[(StatementHandler, Statement)] = parse(script, None)
private def parse(script: String, label: Option[String]): List[(StatementHandler, Statement)] =
{
parseAll(statements, script) match
{
case Success(result, next) => result
case err: NoSuccess =>
{
val labelString = label.map("'" + _ + "' ").getOrElse("")
error("Could not parse test script, " + labelString + err.toString)
}
}
}
lazy val statements = rep1(space ~> statement <~ newline )
def statement: Parser[ ( StatementHandler, Statement ) ] =
{
trait PositionalStatement extends Positional {
def tuple: (StatementHandler, Statement )
}
positioned {
val command = (word | err("expected command"))
val arguments = rep(space ~> (word | failure("expected argument") ))
(successParser ~ (space ~> startCharacterParser <~ space) ~! command ~! arguments) ^^
{
case successExpected ~ start ~ command ~ arguments =>
new PositionalStatement {
def tuple = ( handlers(start), new Statement(command, arguments, successExpected, pos.line) )
}
}
} ^^ (_.tuple)
}
def successParser: Parser[Boolean] = ( '+' ^^^ true) | ('-' ^^^ false) | success(true)
def space: Parser[String] = """[ \t]*""".r
lazy val word: Parser[String] = ("\'" ~> "[^'\n\r]*".r <~ "\'") | ("\"" ~> "[^\"\n\r]*".r <~ "\"") | WordRegex
def startCharacterParser: Parser[Char] = elem("start character", handlers.contains _) |
( ( newline | err("expected start character " +handlers.keys.mkString("(", "", ")") ) ) ~> failure("end of input") )
def newline = """\s*([\n\r]|$)""".r
}
Jump to Line
Something went wrong with that request. Please try again.