src/Pure/System/tty_loop.scala
author wenzelm
Sat, 10 Mar 2018 13:03:01 +0100
changeset 67808 9cb7f5f0bf41
parent 67802 32d76f08023f
child 67833 e135d03f656f
permissions -rw-r--r--
clarified interrupt handling;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
67802
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/System/tty_loop.scala
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     3
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     4
Line-oriented TTY loop.
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     5
*/
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     6
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     7
package isabelle
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     8
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
     9
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    10
import java.io.{IOException, BufferedReader, BufferedWriter, InputStreamReader}
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    11
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    12
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    13
class TTY_Loop(
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    14
  process_writer: BufferedWriter,
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    15
  process_reader: BufferedReader,
67808
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    16
  process_interrupt: Option[() => Unit] = None)
67802
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    17
{
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    18
  private val console_output = Future.thread[Unit]("console_output") {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    19
    try {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    20
      var result = new StringBuilder(100)
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    21
      var finished = false
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    22
      while (!finished) {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    23
        var c = -1
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    24
        var done = false
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    25
        while (!done && (result.length == 0 || process_reader.ready)) {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    26
          c = process_reader.read
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    27
          if (c >= 0) result.append(c.asInstanceOf[Char])
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    28
          else done = true
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    29
        }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    30
        if (result.length > 0) {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    31
          System.out.print(result.toString)
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    32
          System.out.flush()
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    33
          result.length = 0
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    34
        }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    35
        else {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    36
          process_reader.close()
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    37
          finished = true
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    38
        }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    39
      }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    40
    }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    41
    catch { case e: IOException => case Exn.Interrupt() => }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    42
  }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    43
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    44
  private val console_input = Future.thread[Unit]("console_input") {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    45
    val console_reader = new BufferedReader(new InputStreamReader(System.in))
67808
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    46
    def body
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    47
    {
67802
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    48
      try {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    49
        var finished = false
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    50
        while (!finished) {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    51
          console_reader.readLine() match {
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    52
            case null =>
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    53
              process_writer.close()
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    54
              finished = true
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    55
            case line =>
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    56
              process_writer.write(line)
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    57
              process_writer.write("\n")
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    58
              process_writer.flush()
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    59
          }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    60
        }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    61
      }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    62
      catch { case e: IOException => case Exn.Interrupt() => }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    63
    }
67808
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    64
    process_interrupt match {
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    65
      case None => body
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    66
      case Some(interrupt) =>
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    67
        POSIX_Interrupt.handler { interrupt() } { body }
9cb7f5f0bf41 clarified interrupt handling;
wenzelm
parents: 67802
diff changeset
    68
    }
67802
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    69
  }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    70
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    71
  def join { console_output.join; console_input.join }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    72
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    73
  def cancel { console_input.cancel }
32d76f08023f more general TTY loop;
wenzelm
parents:
diff changeset
    74
}