/* NSC -- new Scala compiler * Copyright 2006-2009 LAMP/EPFL * @author Lex Spoon */ // $Id: MainGenericRunner.scala 17828 2009-05-26 18:12:53Z extempore $ package scala.tools.nsc import java.io.{File, IOException} import java.lang.{ClassNotFoundException, NoSuchMethodException} import java.lang.reflect.InvocationTargetException import java.net.{ URL, MalformedURLException } import scala.util.ScalaClassLoader import util.ClassPath import File.pathSeparator /** An object that runs Scala code. It has three possible * sources for the code to run: pre-compiled code, a script file, * or interactive entry. */ object MainGenericRunner { /** Append jars found in ${scala.home}/lib to * a specified classpath. Also append "." if the * input classpath is empty; otherwise do not. * * @param classpath * @return the new classpath */ private def addClasspathExtras(classpath: String): String = { val scalaHome = Properties.scalaHome def listDir(name: String): List[File] = { val libdir = new File(new File(scalaHome), name) if (!libdir.exists || libdir.isFile) Nil else libdir.listFiles.toList } lazy val jarsInLib = listDir("lib") filter (_.getName endsWith ".jar") lazy val dirsInClasses = listDir("classes") filter (_.isDirectory) val cpScala = if (scalaHome == null) Nil else (jarsInLib ::: dirsInClasses) map (_.toString) // either prepend existing classpath or append "." (if (classpath == "") cpScala ::: List(".") else classpath :: cpScala) mkString pathSeparator } def main(args: Array[String]) { def error(str: String) = Console.println(str) val command = new GenericRunnerCommand(args.toList, error) val settings = command.settings def sampleCompiler = new Global(settings) if (!command.ok) { println(command.usageMsg) println(sampleCompiler.pluginOptionsHelp) return } settings.classpath.value = addClasspathExtras(settings.classpath.value) settings.defines.applyToCurrentJVM if (settings.version.value) { Console.println( "Scala code runner " + Properties.versionString + " -- " + Properties.copyrightString) return } if (command.shouldStopWithInfo) { Console.println(command.getInfoMessage(sampleCompiler)) return } def exitSuccess : Nothing = exit(0) def exitFailure : Nothing = exit(1) def exitCond(b: Boolean) : Nothing = if(b) exitSuccess else exitFailure def fileToURL(f: File): Option[URL] = try { Some(f.toURL) } catch { case e => Console.println(e); None } def paths(str: String): List[URL] = for ( file <- ClassPath.expandPath(str) map (new File(_)) if file.exists; val url = fileToURL(file); if !url.isEmpty ) yield url.get def jars(dirs: String): List[URL] = for ( libdir <- ClassPath.expandPath(dirs) map (new File(_)) if libdir.isDirectory; jarfile <- libdir.listFiles if jarfile.isFile && jarfile.getName.endsWith(".jar"); val url = fileToURL(jarfile); if !url.isEmpty ) yield url.get def specToURL(spec: String): Option[URL] = try { Some(new URL(spec)) } catch { case e: MalformedURLException => Console.println(e); None } def urls(specs: String): List[URL] = if (specs == null || specs.length == 0) Nil else for ( spec <- specs.split(" ").toList; val url = specToURL(spec); if !url.isEmpty ) yield url.get val classpath: List[URL] = paths(settings.bootclasspath.value) ::: paths(settings.classpath.value) ::: jars(settings.extdirs.value) ::: urls(settings.Xcodebase.value) command.thingToRun match { case _ if settings.execute.value != "" => val fullArgs = command.thingToRun.toList ::: command.arguments exitCond(ScriptRunner.runCommand(settings, settings.execute.value, fullArgs)) case None => (new InterpreterLoop).main(settings) case Some(thingToRun) => val isObjectName = settings.howtorun.value match { case "object" => true case "script" => false case "guess" => ScalaClassLoader.classExists(classpath, thingToRun) } if (isObjectName) { try { ObjectRunner.run(classpath, thingToRun, command.arguments) } catch { case e: ClassNotFoundException => Console.println(e) exitFailure case e: NoSuchMethodException => Console.println(e) exitFailure case e: InvocationTargetException => e.getCause.printStackTrace exitFailure } } else { try { exitCond(ScriptRunner.runScript(settings, thingToRun, command.arguments)) } catch { case e: IOException => Console.println(e.getMessage()) exitFailure case e: SecurityException => Console.println(e) exitFailure } } } } }