src/Pure/Tools/isabelle_process.scala
changeset 29174 d4058295affb
parent 29140 e7ac5bb20aed
child 29178 d41ccf3efbfc
equal deleted inserted replaced
29173:c14c9a41f1ac 29174:d4058295affb
     9 
     9 
    10 import java.util.Properties
    10 import java.util.Properties
    11 import java.util.concurrent.LinkedBlockingQueue
    11 import java.util.concurrent.LinkedBlockingQueue
    12 import java.io.{BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
    12 import java.io.{BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
    13   InputStream, OutputStream, IOException}
    13   InputStream, OutputStream, IOException}
    14 
       
    15 import isabelle.{Symbol, XML}
       
    16 
    14 
    17 
    15 
    18 object IsabelleProcess {
    16 object IsabelleProcess {
    19 
    17 
    20   /* results */
    18   /* results */
    67       kind == STATUS
    65       kind == STATUS
    68   }
    66   }
    69 
    67 
    70   class Result(val kind: Kind.Value, val props: Properties, val result: String) {
    68   class Result(val kind: Kind.Value, val props: Properties, val result: String) {
    71     override def toString = {
    69     override def toString = {
    72       val res = XML.content(YXML.parse_failsafe(result)).mkString("")
    70       val res = XML.content(YXML.parse_failsafe(result)).mkString
    73       if (props == null) kind.toString + " [[" + res + "]]"
    71       if (props == null) kind.toString + " [[" + res + "]]"
    74       else kind.toString + " " + props.toString + " [[" + res + "]]"
    72       else kind.toString + " " + props.toString + " [[" + res + "]]"
    75     }
    73     }
    76     def is_raw() = Kind.is_raw(kind)
    74     def is_raw() = Kind.is_raw(kind)
    77     def is_control() = Kind.is_control(kind)
    75     def is_control() = Kind.is_control(kind)
    79   }
    77   }
    80 
    78 
    81 }
    79 }
    82 
    80 
    83 
    81 
    84 class IsabelleProcess(args: String*) {
    82 class IsabelleProcess(isabelle_system: IsabelleSystem, args: String*) {
    85 
    83 
    86   import IsabelleProcess._
    84   import IsabelleProcess._
       
    85 
       
    86 
       
    87   /* alternative constructors */
       
    88 
       
    89   def this(args: String*) = this(new IsabelleSystem, args: _*)
    87 
    90 
    88 
    91 
    89   /* process information */
    92   /* process information */
    90 
    93 
    91   private var proc: Process = null
    94   private var proc: Process = null
   120   def interrupt() = synchronized {
   123   def interrupt() = synchronized {
   121     if (proc == null) error("Cannot interrupt Isabelle: no process")
   124     if (proc == null) error("Cannot interrupt Isabelle: no process")
   122     if (pid == null) put_result(Kind.SYSTEM, null, "Cannot interrupt: unknown pid")
   125     if (pid == null) put_result(Kind.SYSTEM, null, "Cannot interrupt: unknown pid")
   123     else {
   126     else {
   124       try {
   127       try {
   125         if (IsabelleSystem.exec("kill", "-INT", pid).waitFor == 0)
   128         if (isabelle_system.exec("kill", "-INT", pid).waitFor == 0)
   126           put_result(Kind.SIGNAL, null, "INT")
   129           put_result(Kind.SIGNAL, null, "INT")
   127         else
   130         else
   128           put_result(Kind.SYSTEM, null, "Cannot interrupt: kill command failed")
   131           put_result(Kind.SYSTEM, null, "Cannot interrupt: kill command failed")
   129       }
   132       }
   130       catch { case e: IOException => error("Cannot interrupt Isabelle: " + e.getMessage) }
   133       catch { case e: IOException => error("Cannot interrupt Isabelle: " + e.getMessage) }
   183 
   186 
   184   /* stdin */
   187   /* stdin */
   185 
   188 
   186   private class StdinThread(out_stream: OutputStream) extends Thread("isabelle: stdin") {
   189   private class StdinThread(out_stream: OutputStream) extends Thread("isabelle: stdin") {
   187     override def run() = {
   190     override def run() = {
   188       val writer = new BufferedWriter(new OutputStreamWriter(out_stream, IsabelleSystem.charset))
   191       val writer = new BufferedWriter(new OutputStreamWriter(out_stream, isabelle_system.charset))
   189       var finished = false
   192       var finished = false
   190       while (!finished) {
   193       while (!finished) {
   191         try {
   194         try {
   192           //{{{
   195           //{{{
   193           val s = output.take
   196           val s = output.take
   213 
   216 
   214   /* stdout */
   217   /* stdout */
   215 
   218 
   216   private class StdoutThread(in_stream: InputStream) extends Thread("isabelle: stdout") {
   219   private class StdoutThread(in_stream: InputStream) extends Thread("isabelle: stdout") {
   217     override def run() = {
   220     override def run() = {
   218       val reader = new BufferedReader(new InputStreamReader(in_stream, IsabelleSystem.charset))
   221       val reader = new BufferedReader(new InputStreamReader(in_stream, isabelle_system.charset))
   219       var result = new StringBuilder(100)
   222       var result = new StringBuilder(100)
   220 
   223 
   221       var finished = false
   224       var finished = false
   222       while (!finished) {
   225       while (!finished) {
   223         try {
   226         try {
   251 
   254 
   252   /* messages */
   255   /* messages */
   253 
   256 
   254   private class MessageThread(fifo: String) extends Thread("isabelle: messages") {
   257   private class MessageThread(fifo: String) extends Thread("isabelle: messages") {
   255     override def run() = {
   258     override def run() = {
   256       val reader = IsabelleSystem.fifo_reader(fifo)
   259       val reader = isabelle_system.fifo_reader(fifo)
   257       var kind: Kind.Value = null
   260       var kind: Kind.Value = null
   258       var props: Properties = null
   261       var props: Properties = null
   259       var result = new StringBuilder
   262       var result = new StringBuilder
   260 
   263 
   261       var finished = false
   264       var finished = false
   335 
   338 
   336   {
   339   {
   337     /* isabelle version */
   340     /* isabelle version */
   338 
   341 
   339     {
   342     {
   340       val (msg, rc) = IsabelleSystem.isabelle_tool("version")
   343       val (msg, rc) = isabelle_system.isabelle_tool("version")
   341       if (rc != 0) error("Version check failed -- bad Isabelle installation:\n" + msg)
   344       if (rc != 0) error("Version check failed -- bad Isabelle installation:\n" + msg)
   342       put_result(Kind.SYSTEM, null, msg)
   345       put_result(Kind.SYSTEM, null, msg)
   343     }
   346     }
   344 
   347 
   345 
   348 
   346     /* message fifo */
   349     /* message fifo */
   347 
   350 
   348     val message_fifo = IsabelleSystem.mk_fifo()
   351     val message_fifo = isabelle_system.mk_fifo()
   349     def rm_fifo() = IsabelleSystem.rm_fifo(message_fifo)
   352     def rm_fifo() = isabelle_system.rm_fifo(message_fifo)
   350 
   353 
   351     val message_thread = new MessageThread(message_fifo)
   354     val message_thread = new MessageThread(message_fifo)
   352     message_thread.start
   355     message_thread.start
   353 
   356 
   354 
   357 
   355     /* exec process */
   358     /* exec process */
   356 
   359 
   357     try {
   360     try {
   358       val cmdline =
   361       val cmdline =
   359         List(IsabelleSystem.getenv_strict("ISABELLE_PROCESS"), "-W", message_fifo) ++ args
   362         List(isabelle_system.getenv_strict("ISABELLE_PROCESS"), "-W", message_fifo) ++ args
   360       proc = IsabelleSystem.exec2(cmdline: _*)
   363       proc = isabelle_system.exec2(cmdline: _*)
   361     }
   364     }
   362     catch {
   365     catch {
   363       case e: IOException =>
   366       case e: IOException =>
   364         rm_fifo()
   367         rm_fifo()
   365         error("Failed to execute Isabelle process: " + e.getMessage)
   368         error("Failed to execute Isabelle process: " + e.getMessage)