src/Pure/System/program_progress.scala
author wenzelm
Thu, 07 Nov 2024 16:13:58 +0100
changeset 81392 92aa6f7b470c
parent 79873 6c19c29ddcbe
permissions -rw-r--r--
clarified output representation: postpone Pretty.separate;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
79873
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/System/program_progress.scala
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     3
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     4
Structured program progress.
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     5
*/
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     6
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     7
package isabelle
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     8
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
     9
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    10
object Program_Progress {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    11
  class Program private[Program_Progress](heading: String, title: String) {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    12
    private val output_buffer = new StringBuffer(256)  // synchronized
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    13
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    14
    def output(message: Progress.Message): Unit = synchronized {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    15
      if (output_buffer.length() > 0) output_buffer.append('\n')
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    16
      output_buffer.append(message.output_text)
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    17
    }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    18
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    19
    val start_time: Time = Time.now()
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    20
    private var stop_time: Option[Time] = None
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    21
    def stop_now(): Unit = synchronized { stop_time = Some(Time.now()) }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    22
81392
92aa6f7b470c clarified output representation: postpone Pretty.separate;
wenzelm
parents: 79873
diff changeset
    23
    def output(): (Command.Results, XML.Elem) = synchronized {
79873
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    24
      val output_text = output_buffer.toString
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    25
      val elapsed_time = stop_time.map(t => t - start_time)
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    26
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    27
      val message_prefix = heading + " "
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    28
      val message_suffix =
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    29
        elapsed_time match {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    30
          case None => " ..."
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    31
          case Some(t) => " ... (" + t.message + " elapsed time)"
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    32
        }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    33
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    34
      val (results, message) =
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    35
        if (output_text.isEmpty) {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    36
          (Command.Results.empty, XML.string(message_prefix + title + message_suffix))
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    37
        }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    38
        else {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    39
          val i = Document_ID.make()
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    40
          val results = Command.Results.make(List(i -> Protocol.writeln_message(output_text)))
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    41
          val message =
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    42
            XML.string(message_prefix) :::
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    43
            List(XML.Elem(Markup(Markup.WRITELN, Markup.Serial(i)), XML.string(title))) :::
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    44
            XML.string(message_suffix)
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    45
          (results, message)
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    46
        }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    47
81392
92aa6f7b470c clarified output representation: postpone Pretty.separate;
wenzelm
parents: 79873
diff changeset
    48
      (results, XML.elem(Markup.TRACING_MESSAGE, message))
79873
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    49
    }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    50
  }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    51
}
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    52
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    53
abstract class Program_Progress(
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    54
  default_heading: String = "Running",
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    55
  default_title: String = "program",
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    56
  override val verbose: Boolean = false
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    57
) extends Progress {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    58
  private var _finished_programs: List[Program_Progress.Program] = Nil
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    59
  private var _running_program: Option[Program_Progress.Program] = None
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    60
81392
92aa6f7b470c clarified output representation: postpone Pretty.separate;
wenzelm
parents: 79873
diff changeset
    61
  def output(): (Command.Results, List[XML.Elem]) = synchronized {
79873
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    62
    val programs = (_running_program.toList ::: _finished_programs).reverse
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    63
    val programs_output = programs.map(_.output())
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    64
    val results = Command.Results.merge(programs_output.map(_._1))
81392
92aa6f7b470c clarified output representation: postpone Pretty.separate;
wenzelm
parents: 79873
diff changeset
    65
    (results, programs_output.map(_._2))
79873
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    66
  }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    67
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    68
  private def start_program(heading: String, title: String): Unit = synchronized {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    69
    _running_program = Some(new Program_Progress.Program(heading, title))
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    70
  }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    71
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    72
  def stop_program(): Unit = synchronized {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    73
    _running_program match {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    74
      case Some(program) =>
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    75
        program.stop_now()
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    76
        _finished_programs ::= program
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    77
        _running_program = None
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    78
      case None =>
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    79
    }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    80
  }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    81
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    82
  def detect_program(s: String): Option[String]
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    83
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    84
  override def output(message: Progress.Message): Unit = synchronized {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    85
    val writeln_msg = if (message.kind == Progress.Kind.writeln) message.text else ""
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    86
    detect_program(writeln_msg).map(Word.explode) match {
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    87
      case Some(a :: bs) =>
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    88
        stop_program()
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    89
        start_program(a, Word.implode(bs))
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    90
      case _ =>
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    91
        if (_running_program.isEmpty) start_program(default_heading, default_title)
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    92
        if (do_output(message)) _running_program.get.output(message)
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    93
    }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    94
  }
6c19c29ddcbe clarified modules;
wenzelm
parents:
diff changeset
    95
}