-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
4,383 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
/* ___ ____ ___ __ ___ ___ | ||
** / _// __// _ | / / / _ | / _ \ Scala classfile decoder | ||
** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003-2013, LAMP/EPFL | ||
** /____/\___/_/ |_/____/_/ |_/_/ http://scala-lang.org/ | ||
** | ||
*/ | ||
|
||
|
||
package scala.tools.scalap | ||
|
||
import scala.collection.mutable | ||
import mutable.ListBuffer | ||
|
||
object Arguments { | ||
case class Parser(optionPrefix: Char) { | ||
val options: mutable.Set[String] = new mutable.HashSet | ||
val prefixes: mutable.Set[String] = new mutable.HashSet | ||
val optionalArgs: mutable.Set[String] = new mutable.HashSet | ||
val prefixedBindings: mutable.Map[String, Char] = new mutable.HashMap | ||
val optionalBindings: mutable.Map[String, Char] = new mutable.HashMap | ||
|
||
def argumentError(message: String): Unit = Console.println(message) | ||
|
||
def withOption(option: String): Parser = { | ||
options += option | ||
this | ||
} | ||
|
||
def withOptionalArg(option: String): Parser = { | ||
optionalArgs += option | ||
this | ||
} | ||
|
||
def withOptionalBinding(option: String, separator: Char): Parser = { | ||
optionalBindings(option) = separator | ||
this | ||
} | ||
|
||
def withPrefixedArg(prefix: String): Parser = { | ||
prefixes += prefix | ||
this | ||
} | ||
|
||
def withPrefixedBinding(prefix: String, separator: Char): Parser = { | ||
prefixedBindings(prefix) = separator | ||
this | ||
} | ||
|
||
def parseBinding(str: String, separator: Char): (String, String) = (str indexOf separator) match { | ||
case -1 => argumentError(s"missing '$separator' in binding '$str'") ; ("", "") | ||
case idx => ((str take idx).trim, (str drop (idx + 1)).trim) | ||
} | ||
|
||
def parse(args: Array[String]): Arguments = { | ||
val res = new Arguments | ||
parse(args, res) | ||
res | ||
} | ||
|
||
def parse(args: Array[String], res: Arguments) { | ||
if (args != null) { | ||
var i = 0 | ||
while (i < args.length) | ||
if ((args(i) == null) || (args(i).length() == 0)) | ||
i += 1 | ||
else if (args(i).charAt(0) != optionPrefix) { | ||
res.addOther(args(i)) | ||
i += 1 | ||
} else if (options(args(i))) { | ||
res.addOption(args(i)) | ||
i += 1 | ||
} else if (optionalArgs contains args(i)) { | ||
if ((i + 1) == args.length) { | ||
argumentError(s"missing argument for '${args(i)}'") | ||
i += 1 | ||
} else { | ||
res.addArgument(args(i), args(i + 1)) | ||
i += 2 | ||
} | ||
} else if (optionalBindings contains args(i)) { | ||
if ((i + 1) == args.length) { | ||
argumentError(s"missing argument for '${args(i)}'") | ||
i += 1 | ||
} else { | ||
res.addBinding(args(i), | ||
parseBinding(args(i + 1), optionalBindings(args(i)))) | ||
i += 2 | ||
} | ||
} else { | ||
val iter = prefixes.iterator | ||
val j = i | ||
while ((i == j) && iter.hasNext) { | ||
val prefix = iter.next | ||
if (args(i) startsWith prefix) { | ||
res.addPrefixed(prefix, args(i).substring(prefix.length()).trim()) | ||
i += 1 | ||
} | ||
} | ||
if (i == j) { | ||
val iter = prefixedBindings.keysIterator | ||
while ((i == j) && iter.hasNext) { | ||
val prefix = iter.next | ||
if (args(i) startsWith prefix) { | ||
val arg = args(i).substring(prefix.length()).trim() | ||
i = i + 1 | ||
res.addBinding(prefix, | ||
parseBinding(arg, prefixedBindings(prefix))) | ||
} | ||
} | ||
if (i == j) { | ||
argumentError(s"unknown option '${args(i)}'") | ||
i = i + 1 | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
def parse(options: String*)(args: Array[String]): Arguments = { | ||
val parser = new Parser('-') | ||
options foreach parser.withOption | ||
parser parse args | ||
} | ||
} | ||
|
||
class Arguments { | ||
private val options = new mutable.HashSet[String] | ||
private val arguments = new mutable.HashMap[String, String] | ||
private val prefixes = new mutable.HashMap[String, mutable.HashSet[String]] | ||
private val bindings = new mutable.HashMap[String, mutable.HashMap[String, String]] | ||
private val others = new ListBuffer[String] | ||
|
||
def addOption(option: String): Unit = options += option | ||
|
||
def addArgument(option: String, arg: String): Unit = arguments(option) = arg | ||
|
||
def addPrefixed(prefix: String, arg: String): Unit = | ||
prefixes.getOrElseUpdate(prefix, new mutable.HashSet) += arg | ||
|
||
def addBinding(tag: String, key: String, value: String): Unit = | ||
if (key.length > 0) | ||
bindings.getOrElseUpdate(tag, new mutable.HashMap)(key) = value | ||
|
||
def addBinding(tag: String, binding: (String, String)): Unit = | ||
addBinding(tag, binding._1, binding._2) | ||
|
||
def addOther(arg: String): Unit = others += arg | ||
|
||
def contains(option: String): Boolean = options(option) | ||
|
||
def getArgument(option: String): Option[String] = arguments get option | ||
|
||
def getSuffixes(prefix: String): mutable.Set[String] = | ||
prefixes.getOrElse(prefix, new mutable.HashSet) | ||
|
||
def containsSuffix(prefix: String, suffix: String): Boolean = | ||
prefixes get prefix exists (set => set(suffix)) | ||
|
||
def getBindings(tag: String): mutable.Map[String, String] = | ||
bindings.getOrElse(tag, new mutable.HashMap) | ||
|
||
def getBinding(option: String, key: String): Option[String] = | ||
bindings get option flatMap (_ get key) | ||
|
||
def getOthers: List[String] = others.toList | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* ___ ____ ___ __ ___ ___ | ||
** / _// __// _ | / / / _ | / _ \ Scala classfile decoder | ||
** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003-2013, LAMP/EPFL | ||
** /____/\___/_/ |_/____/_/ |_/_/ http://scala-lang.org/ | ||
** | ||
*/ | ||
|
||
|
||
package scala | ||
package tools.scalap | ||
|
||
|
||
class ByteArrayReader(content: Array[Byte]) { | ||
|
||
/** the buffer containing the file | ||
*/ | ||
val buf: Array[Byte] = content | ||
|
||
/** the current input pointer | ||
*/ | ||
var bp: Int = 0 | ||
|
||
/** return byte at offset 'pos' | ||
*/ | ||
def byteAt(pos: Int): Byte = buf(pos) | ||
|
||
/** read a byte | ||
*/ | ||
def nextByte: Byte = { | ||
bp += 1 | ||
buf(bp - 1) | ||
} | ||
|
||
/** read some bytes | ||
*/ | ||
def nextBytes(len: Int): Array[Byte] = { | ||
val res = new Array[Byte](len) | ||
System.arraycopy(buf, bp, res, 0, len) | ||
bp += len | ||
res | ||
} | ||
|
||
/** read a character | ||
*/ | ||
def nextChar: Char = { | ||
bp += 2 | ||
getChar(bp - 2) | ||
} | ||
|
||
/** read an integer | ||
*/ | ||
def nextInt: Int = { | ||
bp += 4 | ||
getInt(bp - 4) | ||
} | ||
|
||
/** read a long | ||
*/ | ||
def nextLong: Long = { | ||
bp += 8 | ||
getLong(bp - 8) | ||
} | ||
|
||
/** read a float | ||
*/ | ||
def nextFloat: Float = java.lang.Float.intBitsToFloat(nextInt) | ||
|
||
/** read a double | ||
*/ | ||
def nextDouble: Double = java.lang.Double.longBitsToDouble(nextLong) | ||
|
||
/** read an UTF8 encoded string | ||
*/ | ||
def nextUTF8(len: Int): String = { | ||
val cs = scala.io.Codec.fromUTF8(buf, bp, len) | ||
bp += len | ||
new String(cs) | ||
} | ||
|
||
/** extract a character at position bp from buf | ||
*/ | ||
def getChar(bp: Int): Char = | ||
(((buf(bp) & 0xff) << 8) + (buf(bp + 1) & 0xff)).asInstanceOf[Char] | ||
|
||
/** extract an integer at position bp from buf | ||
*/ | ||
def getInt(bp: Int): Int = | ||
((buf(bp ) & 0xff) << 24) + | ||
((buf(bp + 1) & 0xff) << 16) + | ||
((buf(bp + 2) & 0xff) << 8) + | ||
(buf(bp + 3) & 0xff) | ||
|
||
/** extract a long integer at position bp from buf | ||
*/ | ||
def getLong(bp: Int): Long = | ||
(getInt(bp).toLong << 32) + (getInt(bp + 4).toLong & 0xffffffffL) | ||
|
||
/** extract a float at position bp from buf | ||
*/ | ||
def getFloat(bp: Int): Float = java.lang.Float.intBitsToFloat(getInt(bp)) | ||
|
||
/** extract a double at position bp from buf | ||
*/ | ||
def getDouble(bp: Int): Double = java.lang.Double.longBitsToDouble(getLong(bp)) | ||
|
||
/** skip next 'n' bytes | ||
*/ | ||
def skip(n: Int) { | ||
bp += n | ||
} | ||
|
||
} |
Oops, something went wrong.