# HG changeset patch # User wenzelm # Date 1309810292 -7200 # Node ID 39fdbd814c7ff2077b4c51998bdeca5ef0684bac # Parent bfc0bb115fa189334a3b483e5a57b80c614ea9ce quasi-static Isabelle_System -- reduced tendency towards "functorial style"; diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/System/gui_setup.scala --- a/src/Pure/System/gui_setup.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/System/gui_setup.scala Mon Jul 04 22:11:32 2011 +0200 @@ -44,14 +44,15 @@ text.append("JVM name: " + Platform.jvm_name + "\n") text.append("JVM platform: " + Platform.jvm_platform + "\n") try { - val isabelle_system = Isabelle_System.default - text.append("ML platform: " + isabelle_system.getenv("ML_PLATFORM") + "\n") - text.append("Isabelle platform: " + isabelle_system.getenv("ISABELLE_PLATFORM") + "\n") - val platform64 = isabelle_system.getenv("ISABELLE_PLATFORM64") + Isabelle_System.init() + text.append("ML platform: " + Isabelle_System.getenv("ML_PLATFORM") + "\n") + text.append("Isabelle platform: " + Isabelle_System.getenv("ISABELLE_PLATFORM") + "\n") + val platform64 = Isabelle_System.getenv("ISABELLE_PLATFORM64") if (platform64 != "") text.append("Isabelle platform (64 bit): " + platform64 + "\n") - text.append("Isabelle home: " + isabelle_system.getenv("ISABELLE_HOME") + "\n") - text.append("Isabelle java: " + isabelle_system.this_java() + "\n") - } catch { case ERROR(msg) => text.append(msg + "\n") } + text.append("Isabelle home: " + Isabelle_System.getenv("ISABELLE_HOME") + "\n") + text.append("Isabelle java: " + Isabelle_System.getenv("THIS_JAVA") + "\n") + } + catch { case ERROR(msg) => text.append(msg + "\n") } // reactions listenTo(ok) diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/System/isabelle_process.scala --- a/src/Pure/System/isabelle_process.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/System/isabelle_process.scala Mon Jul 04 22:11:32 2011 +0200 @@ -62,7 +62,7 @@ } -class Isabelle_Process(system: Isabelle_System, timeout: Time, receiver: Actor, args: String*) +class Isabelle_Process(timeout: Time, receiver: Actor, args: String*) { import Isabelle_Process._ @@ -70,8 +70,7 @@ /* demo constructor */ def this(args: String*) = - this(Isabelle_System.default, Time.seconds(10), - actor { loop { react { case res => Console.println(res) } } }, args: _*) + this(Time.seconds(10), actor { loop { react { case res => Console.println(res) } } }, args: _*) /* results */ @@ -93,7 +92,7 @@ private def put_result(kind: String, text: String) { - put_result(kind, Nil, List(XML.Text(system.symbols.decode(text)))) + put_result(kind, Nil, List(XML.Text(Isabelle_System.symbols.decode(text)))) } @@ -117,15 +116,16 @@ /** process manager **/ - private val in_fifo = system.mk_fifo() - private val out_fifo = system.mk_fifo() - private def rm_fifos() { system.rm_fifo(in_fifo); system.rm_fifo(out_fifo) } + private val in_fifo = Isabelle_System.mk_fifo() + private val out_fifo = Isabelle_System.mk_fifo() + private def rm_fifos() { Isabelle_System.rm_fifo(in_fifo); Isabelle_System.rm_fifo(out_fifo) } private val process = try { val cmdline = - List(system.getenv_strict("ISABELLE_PROCESS"), "-W", in_fifo + ":" + out_fifo) ++ args - new system.Managed_Process(true, cmdline: _*) + List(Isabelle_System.getenv_strict("ISABELLE_PROCESS"), "-W", + in_fifo + ":" + out_fifo) ++ args + new Isabelle_System.Managed_Process(true, cmdline: _*) } catch { case e: IOException => rm_fifos(); throw(e) } @@ -168,8 +168,8 @@ } else { // rendezvous - val command_stream = system.fifo_output_stream(in_fifo) - val message_stream = system.fifo_input_stream(out_fifo) + val command_stream = Isabelle_System.fifo_output_stream(in_fifo) + val message_stream = Isabelle_System.fifo_input_stream(out_fifo) standard_input = stdin_actor() val stdout = stdout_actor() @@ -341,7 +341,7 @@ if (i != n) throw new Protocol_Error("bad message chunk content") - YXML.parse_body_failsafe(YXML.decode_chars(system.symbols.decode, buf, 0, n)) + YXML.parse_body_failsafe(YXML.decode_chars(Isabelle_System.symbols.decode, buf, 0, n)) //}}} } diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/System/isabelle_system.scala --- a/src/Pure/System/isabelle_system.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/System/isabelle_system.scala Mon Jul 04 22:11:32 2011 +0200 @@ -1,7 +1,8 @@ /* Title: Pure/System/isabelle_system.scala Author: Makarius -Isabelle system support (settings environment etc.). +Fundamental Isabelle system environment: settings, symbols etc. +Quasi-static module with optional init operation. */ package isabelle @@ -21,15 +22,24 @@ object Isabelle_System { - lazy val default: Isabelle_System = new Isabelle_System -} + /** implicit state **/ -class Isabelle_System(this_isabelle_home: String) extends Standard_System -{ - def this() = this(null) + private case class State( + standard_system: Standard_System, + settings: Map[String, String], + symbols: Symbol.Interpretation) + @volatile private var _state: Option[State] = None - /** Isabelle environment **/ + private def check_state(): State = + { + if (_state.isEmpty) init() // unsynchronized check + _state.get + } + + def standard_system: Standard_System = check_state().standard_system + def settings: Map[String, String] = check_state().settings + def symbols: Symbol.Interpretation = check_state().symbols /* isabelle_home precedence: @@ -37,50 +47,67 @@ (2) ISABELLE_HOME process environment variable (e.g. inherited from running isabelle tool) (3) isabelle.home system property (e.g. via JVM application boot process) */ + def init(this_isabelle_home: String = null) = synchronized { + if (_state.isEmpty) { + import scala.collection.JavaConversions._ - private val environment: Map[String, String] = - { - import scala.collection.JavaConversions._ + val standard_system = new Standard_System - val env0 = Map(System.getenv.toList: _*) + - ("THIS_JAVA" -> this_java()) + val settings = + { + val env = Map(System.getenv.toList: _*) + + ("THIS_JAVA" -> standard_system.this_java()) - val isabelle_home = - if (this_isabelle_home != null) this_isabelle_home - else - env0.get("ISABELLE_HOME") match { - case None | Some("") => - val path = System.getProperty("isabelle.home") - if (path == null || path == "") error("Unknown Isabelle home directory") - else path - case Some(path) => path - } + val isabelle_home = + if (this_isabelle_home != null) this_isabelle_home + else + env.get("ISABELLE_HOME") match { + case None | Some("") => + val path = System.getProperty("isabelle.home") + if (path == null || path == "") error("Unknown Isabelle home directory") + else path + case Some(path) => path + } - Standard_System.with_tmp_file("settings") { dump => - val shell_prefix = - if (Platform.is_windows) List(platform_root + "\\bin\\bash", "-l") else Nil - val cmdline = - shell_prefix ::: List(isabelle_home + "/bin/isabelle", "getenv", "-d", dump.toString) - val (output, rc) = Standard_System.raw_exec(null, env0, true, cmdline: _*) - if (rc != 0) error(output) + Standard_System.with_tmp_file("settings") { dump => + val shell_prefix = + if (Platform.is_windows) List(standard_system.platform_root + "\\bin\\bash", "-l") + else Nil + val cmdline = + shell_prefix ::: List(isabelle_home + "/bin/isabelle", "getenv", "-d", dump.toString) + val (output, rc) = Standard_System.raw_exec(null, env, true, cmdline: _*) + if (rc != 0) error(output) - val entries = - for (entry <- Source.fromFile(dump).mkString split "\0" if entry != "") yield { - val i = entry.indexOf('=') - if (i <= 0) (entry -> "") - else (entry.substring(0, i) -> entry.substring(i + 1)) + val entries = + for (entry <- Source.fromFile(dump).mkString split "\0" if entry != "") yield { + val i = entry.indexOf('=') + if (i <= 0) (entry -> "") + else (entry.substring(0, i) -> entry.substring(i + 1)) + } + Map(entries: _*) + + ("HOME" -> System.getenv("HOME")) + + ("PATH" -> System.getenv("PATH")) + } } - Map(entries: _*) + - ("HOME" -> System.getenv("HOME")) + - ("PATH" -> System.getenv("PATH")) + + val symbols = + { + val isabelle_symbols = settings.getOrElse("ISABELLE_SYMBOLS", "") + if (isabelle_symbols == "") error("Undefined environment variable: ISABELLE_SYMBOLS") + val files = + isabelle_symbols.split(":").toList.map(s => new File(standard_system.jvm_path(s))) + new Symbol.Interpretation(Standard_System.try_read(files).split("\n").toList) } + + _state = Some(State(standard_system, settings, symbols)) + } } /* getenv */ def getenv(name: String): String = - environment.getOrElse(if (name == "HOME") "HOME_JVM" else name, "") + settings.getOrElse(if (name == "HOME") "HOME_JVM" else name, "") def getenv_strict(name: String): String = { @@ -88,9 +115,6 @@ if (value != "") value else error("Undefined environment variable: " + name) } - override def toString = getenv_strict("ISABELLE_HOME") - - /** file-system operations **/ @@ -98,9 +122,11 @@ def standard_path(path: Path): String = path.expand(getenv_strict).implode - def platform_path(path: Path): String = jvm_path(standard_path(path)) + def platform_path(path: Path): String = standard_system.jvm_path(standard_path(path)) def platform_file(path: Path) = new File(platform_path(path)) + def posix_path(jvm_path: String): String = standard_system.posix_path(jvm_path) + /* try_read */ @@ -142,9 +168,9 @@ def execute(redirect: Boolean, args: String*): Process = { val cmdline = - if (Platform.is_windows) List(platform_root + "\\bin\\env.exe") ++ args + if (Platform.is_windows) List(standard_system.platform_root + "\\bin\\env.exe") ++ args else args - Standard_System.raw_execute(null, environment, redirect, cmdline: _*) + Standard_System.raw_execute(null, settings, redirect, cmdline: _*) } @@ -271,7 +297,7 @@ } def rm_fifo(fifo: String): Boolean = - (new File(jvm_path(if (Platform.is_windows) fifo + ".lnk" else fifo))).delete + (new File(standard_system.jvm_path(if (Platform.is_windows) fifo + ".lnk" else fifo))).delete def fifo_input_stream(fifo: String): InputStream = { @@ -328,13 +354,6 @@ } - /* symbols */ - - val symbols = new Symbol.Interpretation( - try_read(getenv_strict("ISABELLE_SYMBOLS").split(":").toList.map(Path.explode)) - .split("\n").toList) - - /* fonts */ def get_font(family: String = "IsabelleText", size: Int = 1, bold: Boolean = false): Font = diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/System/session.scala --- a/src/Pure/System/session.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/System/session.scala Mon Jul 04 22:11:32 2011 +0200 @@ -40,7 +40,7 @@ } -class Session(val system: Isabelle_System, val file_store: Session.File_Store) +class Session(val file_store: Session.File_Store) { /* real time parameters */ // FIXME properties or settings (!?) @@ -117,7 +117,7 @@ val new_id = new Counter - @volatile private var syntax = new Outer_Syntax(system.symbols) + @volatile private var syntax = new Outer_Syntax(Isabelle_System.symbols) def current_syntax(): Outer_Syntax = syntax @volatile private var reverse_syslog = List[XML.Elem]() @@ -138,16 +138,14 @@ /* theory files */ - val thy_header = new Thy_Header(system.symbols) - val thy_load = new Thy_Load { override def check_thy(dir: Path, name: String): (String, Thy_Header.Header) = { - val file = system.platform_file(dir + Thy_Header.thy_path(name)) + val file = Isabelle_System.platform_file(dir + Thy_Header.thy_path(name)) if (!file.exists || !file.isFile) error("No such file: " + quote(file.toString)) val text = Standard_System.read_file(file) - val header = thy_header.read(text) + val header = Thy_Header.read(text) (text, header) } } @@ -202,7 +200,8 @@ if (global_state.peek().lookup_command(command.id).isEmpty) { global_state.change(_.define_command(command)) prover.get. - define_command(command.id, system.symbols.encode(command.source)) + define_command(command.id, + Isabelle_System.symbols.encode(command.source)) } Some(command.id) } @@ -311,8 +310,7 @@ case Start(timeout, args) if prover.isEmpty => if (phase == Session.Inactive || phase == Session.Failed) { phase = Session.Startup - prover = - Some(new Isabelle_Process(system, timeout, this_actor, args:_*) with Isar_Document) + prover = Some(new Isabelle_Process(timeout, this_actor, args:_*) with Isar_Document) } case Stop => diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/System/session_manager.scala --- a/src/Pure/System/session_manager.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/System/session_manager.scala Mon Jul 04 22:11:32 2011 +0200 @@ -10,7 +10,7 @@ import java.io.{File, FileFilter} -class Session_Manager(system: Isabelle_System) +class Session_Manager { val ROOT_NAME = "session.root" @@ -42,7 +42,8 @@ def component_sessions(): List[List[String]] = { val toplevel_sessions = - system.components().map(s => system.platform_file(Path.explode(s))).filter(is_session_dir) + Isabelle_System.components().map(s => + Isabelle_System.platform_file(Path.explode(s))).filter(is_session_dir) ((Nil: List[List[String]]) /: toplevel_sessions)(find_sessions(Nil, _, _)).reverse } } diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/System/standard_system.scala --- a/src/Pure/System/standard_system.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/System/standard_system.scala Mon Jul 04 22:11:32 2011 +0200 @@ -96,6 +96,16 @@ def read_file(file: File): String = slurp(new FileInputStream(file)) + def try_read(files: Seq[File]): String = + { + val buf = new StringBuilder + for { + file <- files if file.isFile + c <- (Source.fromFile(file) ++ Iterator.single('\n')) + } buf.append(c) + buf.toString + } + def write_file(file: File, text: CharSequence) { val writer = diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/Thy/html.scala --- a/src/Pure/Thy/html.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/Thy/html.scala Mon Jul 04 22:11:32 2011 +0200 @@ -55,9 +55,10 @@ def sup(txt: String): XML.Elem = XML.elem("sup", List(XML.Text(txt))) def bold(txt: String): XML.Elem = span("bold", List(XML.Text(txt))) - def spans(symbols: Symbol.Interpretation, - input: XML.Tree, original_data: Boolean = false): XML.Body = + def spans(input: XML.Tree, original_data: Boolean = false): XML.Body = { + val symbols = Isabelle_System.symbols + def html_spans(tree: XML.Tree): XML.Body = tree match { case XML.Elem(m @ Markup(name, props), ts) => diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Pure/Thy/thy_header.scala --- a/src/Pure/Thy/thy_header.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Pure/Thy/thy_header.scala Mon Jul 04 22:11:32 2011 +0200 @@ -15,7 +15,7 @@ import java.io.File -object Thy_Header +object Thy_Header extends Parse.Parser { val HEADER = "header" val THEORY = "theory" @@ -47,12 +47,6 @@ case Thy_Path2(dir, name) => Some((dir, name)) case _ => None } -} - - -class Thy_Header(symbols: Symbol.Interpretation) extends Parse.Parser -{ - import Thy_Header._ /* header */ @@ -81,7 +75,7 @@ def read(reader: Reader[Char]): Header = { - val token = lexicon.token(symbols, _ => false) + val token = lexicon.token(Isabelle_System.symbols, _ => false) val toks = new mutable.ListBuffer[Token] @tailrec def scan_to_begin(in: Reader[Char]) @@ -119,6 +113,6 @@ val header = read(source) val name1 = header.name if (name == name1) header - else error("Bad file name " + Thy_Header.thy_path(name) + " for theory " + quote(name1)) + else error("Bad file name " + thy_path(name) + " for theory " + quote(name1)) } } diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Tools/jEdit/src/document_model.scala --- a/src/Tools/jEdit/src/document_model.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Tools/jEdit/src/document_model.scala Mon Jul 04 22:11:32 2011 +0200 @@ -63,7 +63,7 @@ private def capture_header(): Exn.Result[Thy_Header.Header] = Exn.capture { - session.thy_header.check(thy_name, buffer.getSegment(0, buffer.getLength)) + Thy_Header.check(thy_name, buffer.getSegment(0, buffer.getLength)) } private object pending_edits // owned by Swing thread diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Tools/jEdit/src/document_view.scala --- a/src/Tools/jEdit/src/document_view.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Tools/jEdit/src/document_view.scala Mon Jul 04 22:11:32 2011 +0200 @@ -143,7 +143,7 @@ private def exit_popup() { html_popup.map(_.hide) } private val html_panel = - new HTML_Panel(Isabelle.system, Isabelle.font_family(), scala.math.round(Isabelle.font_size())) + new HTML_Panel(Isabelle.font_family(), scala.math.round(Isabelle.font_size())) html_panel.setBorder(BorderFactory.createLineBorder(Color.black)) private def html_panel_resize() diff -r bfc0bb115fa1 -r 39fdbd814c7f src/Tools/jEdit/src/html_panel.scala --- a/src/Tools/jEdit/src/html_panel.scala Mon Jul 04 20:18:19 2011 +0200 +++ b/src/Tools/jEdit/src/html_panel.scala Mon Jul 04 22:11:32 2011 +0200 @@ -37,11 +37,7 @@ } -class HTML_Panel( - system: Isabelle_System, - initial_font_family: String, - initial_font_size: Int) - extends HtmlPanel +class HTML_Panel(initial_font_family: String, initial_font_size: Int) extends HtmlPanel { /** Lobo setup **/ @@ -96,7 +92,8 @@