src/Pure/System/process_result.scala
author wenzelm
Wed, 17 Apr 2024 21:20:31 +0200
changeset 80128 2fe244c4bb01
parent 78442 c38aebdf1a3d
permissions -rw-r--r--
clarified signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/System/process_result.scala
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     3
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     4
Result of system process.
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     5
*/
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     6
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     7
package isabelle
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
     8
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
     9
object Process_Result {
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    10
  /* return code */
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    11
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
    12
  object RC {
77253
792dad9cb04f clarified data structure: absorb Option[Process_Result] into Process_Result, e.g. to simplify database storage;
wenzelm
parents: 77243
diff changeset
    13
    val undefined = -1
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    14
    val ok = 0
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    15
    val error = 1
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    16
    val failure = 2
77243
629dce95bb5c clarified signature: avoid adhoc constants;
wenzelm
parents: 75393
diff changeset
    17
    val startup_failure = 127
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    18
    val interrupt = 130
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    19
    val timeout = 142
71749
77232ff6b8f6 tuned message;
wenzelm
parents: 71748
diff changeset
    20
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
    21
    private def text(rc: Int): String = {
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    22
      val txt =
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    23
        rc match {
77253
792dad9cb04f clarified data structure: absorb Option[Process_Result] into Process_Result, e.g. to simplify database storage;
wenzelm
parents: 77243
diff changeset
    24
          case `undefined` => "UNDEFINED"
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    25
          case `ok` => "OK"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    26
          case `error` => "ERROR"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    27
          case `failure` => "FAILURE"
78438
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    28
          case `startup_failure` => "COMMAND NOT FOUND"
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    29
          case `interrupt` => "INTERRUPT"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    30
          case 131 => "QUIT SIGNAL"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    31
          case 137 => "KILL SIGNAL"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    32
          case 138 => "BUS ERROR"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    33
          case 139 => "SEGMENTATION VIOLATION"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    34
          case `timeout` => "TIMEOUT"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    35
          case 143 => "TERMINATION SIGNAL"
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    36
          case _ => ""
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    37
        }
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    38
      if (txt.isEmpty) txt else " (" + txt + ")"
71749
77232ff6b8f6 tuned message;
wenzelm
parents: 71748
diff changeset
    39
    }
74067
0b1462ce5fda clarified signature;
wenzelm
parents: 73277
diff changeset
    40
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    41
    def print_long(rc: Int): String = "Return code: " + rc + text(rc)
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    42
    def print(rc: Int): String = "return code " + rc + text(rc)
78438
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    43
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    44
    def merge(rc1: Int, rc2: Int): Int =
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    45
      if (rc1 == interrupt || rc2 == interrupt) interrupt
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    46
      else rc1 max rc2
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    47
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    48
    def merge(rcs: IterableOnce[Int]): Int = rcs.iterator.foldLeft(ok)(merge)
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    49
78442
c38aebdf1a3d tuned signature: more operations;
wenzelm
parents: 78438
diff changeset
    50
    def apply(ok: Boolean): Int = if (ok) RC.ok else RC.error
c38aebdf1a3d tuned signature: more operations;
wenzelm
parents: 78438
diff changeset
    51
    def apply(exn: Throwable): Int = if (Exn.is_interrupt(exn)) interrupt else error
78438
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    52
    def apply(result: Exn.Result[Process_Result]): Int =
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    53
      result match {
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    54
        case Exn.Res(res) => res.rc
78442
c38aebdf1a3d tuned signature: more operations;
wenzelm
parents: 78438
diff changeset
    55
        case Exn.Exn(exn) => apply(exn)
78438
d79eb2a6de0f clarified signature: more operations;
wenzelm
parents: 77253
diff changeset
    56
      }
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    57
  }
77243
629dce95bb5c clarified signature: avoid adhoc constants;
wenzelm
parents: 75393
diff changeset
    58
77253
792dad9cb04f clarified data structure: absorb Option[Process_Result] into Process_Result, e.g. to simplify database storage;
wenzelm
parents: 77243
diff changeset
    59
  val undefined: Process_Result = Process_Result(RC.undefined)
77243
629dce95bb5c clarified signature: avoid adhoc constants;
wenzelm
parents: 75393
diff changeset
    60
  val ok: Process_Result = Process_Result(RC.ok)
629dce95bb5c clarified signature: avoid adhoc constants;
wenzelm
parents: 75393
diff changeset
    61
  val error: Process_Result = Process_Result(RC.error)
629dce95bb5c clarified signature: avoid adhoc constants;
wenzelm
parents: 75393
diff changeset
    62
  val startup_failure: Process_Result = Process_Result(RC.startup_failure)
71747
1dd514c8c1df clarified signature;
wenzelm
parents: 71646
diff changeset
    63
}
1dd514c8c1df clarified signature;
wenzelm
parents: 71646
diff changeset
    64
62401
15a2533f1f0a more informative Process_Result;
wenzelm
parents: 62400
diff changeset
    65
final case class Process_Result(
62402
bff56eae3ec5 more informative Build.build_results;
wenzelm
parents: 62401
diff changeset
    66
  rc: Int,
bff56eae3ec5 more informative Build.build_results;
wenzelm
parents: 62401
diff changeset
    67
  out_lines: List[String] = Nil,
bff56eae3ec5 more informative Build.build_results;
wenzelm
parents: 62401
diff changeset
    68
  err_lines: List[String] = Nil,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
    69
  timing: Timing = Timing.zero
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
    70
) {
73277
0110e2e2964c clarified signature: always trim_line of Process_Result.out/err, uniformly in ML and Scala;
wenzelm
parents: 73134
diff changeset
    71
  def out: String = Library.trim_line(cat_lines(out_lines))
0110e2e2964c clarified signature: always trim_line of Process_Result.out/err, uniformly in ML and Scala;
wenzelm
parents: 73134
diff changeset
    72
  def err: String = Library.trim_line(cat_lines(err_lines))
71631
3f02bc5a5a03 more accurate treatment of errors;
wenzelm
parents: 68927
diff changeset
    73
71646
86f064893dac clarified signature: more robust;
wenzelm
parents: 71631
diff changeset
    74
  def output(outs: List[String]): Process_Result =
86f064893dac clarified signature: more robust;
wenzelm
parents: 71631
diff changeset
    75
    copy(out_lines = out_lines ::: outs.flatMap(split_lines))
86f064893dac clarified signature: more robust;
wenzelm
parents: 71631
diff changeset
    76
  def errors(errs: List[String]): Process_Result =
86f064893dac clarified signature: more robust;
wenzelm
parents: 71631
diff changeset
    77
    copy(err_lines = err_lines ::: errs.flatMap(split_lines))
72002
5c4800f6b25a more robust protocol for "Timing ..." messages, notably for pide_session=true;
wenzelm
parents: 71749
diff changeset
    78
  def error(err: String): Process_Result =
5c4800f6b25a more robust protocol for "Timing ..." messages, notably for pide_session=true;
wenzelm
parents: 71749
diff changeset
    79
    if (err.isEmpty) this else errors(List(err))
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
    80
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    81
  def ok: Boolean = rc == Process_Result.RC.ok
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    82
  def interrupted: Boolean = rc == Process_Result.RC.interrupt
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
    83
77253
792dad9cb04f clarified data structure: absorb Option[Process_Result] into Process_Result, e.g. to simplify database storage;
wenzelm
parents: 77243
diff changeset
    84
  def defined: Boolean = rc > Process_Result.RC.undefined
792dad9cb04f clarified data structure: absorb Option[Process_Result] into Process_Result, e.g. to simplify database storage;
wenzelm
parents: 77243
diff changeset
    85
  def strict: Process_Result = if (defined) this else copy(rc = Process_Result.RC.error)
792dad9cb04f clarified data structure: absorb Option[Process_Result] into Process_Result, e.g. to simplify database storage;
wenzelm
parents: 77243
diff changeset
    86
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    87
  def timeout_rc: Process_Result = copy(rc = Process_Result.RC.timeout)
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    88
  def timeout: Boolean = rc == Process_Result.RC.timeout
73134
8a8ffe78eee7 clarified return code: re-use SIGALRM for soft timeout;
wenzelm
parents: 72726
diff changeset
    89
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    90
  def error_rc: Process_Result =
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
    91
    if (interrupted) this else copy(rc = rc max Process_Result.RC.error)
68927
01f46a4b22b4 tuned signature;
wenzelm
parents: 68091
diff changeset
    92
72726
ec6a27bbdab8 proper return code for more errors (amending d892f6d66402);
wenzelm
parents: 72556
diff changeset
    93
  def errors_rc(errs: List[String]): Process_Result =
ec6a27bbdab8 proper return code for more errors (amending d892f6d66402);
wenzelm
parents: 72556
diff changeset
    94
    if (errs.isEmpty) this else errors(errs).error_rc
ec6a27bbdab8 proper return code for more errors (amending d892f6d66402);
wenzelm
parents: 72556
diff changeset
    95
64408
50bcf976f276 clarified hg push return code: 1 means "nothing to push";
wenzelm
parents: 64138
diff changeset
    96
  def check_rc(pred: Int => Boolean): Process_Result =
50bcf976f276 clarified hg push return code: 1 means "nothing to push";
wenzelm
parents: 64138
diff changeset
    97
    if (pred(rc)) this
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
    98
    else if (interrupted) throw Exn.Interrupt()
62492
0e53fade87fe clarified modules;
wenzelm
parents: 62405
diff changeset
    99
    else Exn.error(err)
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
   100
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
   101
  def check: Process_Result = check_rc(_ == Process_Result.RC.ok)
64408
50bcf976f276 clarified hg push return code: 1 means "nothing to push";
wenzelm
parents: 64138
diff changeset
   102
74306
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
   103
  def print_return_code: String = Process_Result.RC.print_long(rc)
a117c076aa22 clarified signature;
wenzelm
parents: 74067
diff changeset
   104
  def print_rc: String = Process_Result.RC.print(rc)
71747
1dd514c8c1df clarified signature;
wenzelm
parents: 71646
diff changeset
   105
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
   106
  def print: Process_Result = {
64138
cf0c8c5782af eliminated extra trim_line: Process_Result.out/err are based on cat_lines, without trailing newline;
wenzelm
parents: 64024
diff changeset
   107
    Output.warning(err)
cf0c8c5782af eliminated extra trim_line: Process_Result.out/err are based on cat_lines, without trailing newline;
wenzelm
parents: 64024
diff changeset
   108
    Output.writeln(out)
62404
13a0f537e232 retain tail out_lines as printed, but not the whole log content;
wenzelm
parents: 62402
diff changeset
   109
    copy(out_lines = Nil, err_lines = Nil)
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
   110
  }
62553
d2e0d626fb96 tuned signature;
wenzelm
parents: 62492
diff changeset
   111
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 74306
diff changeset
   112
  def print_stdout: Process_Result = {
64138
cf0c8c5782af eliminated extra trim_line: Process_Result.out/err are based on cat_lines, without trailing newline;
wenzelm
parents: 64024
diff changeset
   113
    Output.warning(err, stdout = true)
cf0c8c5782af eliminated extra trim_line: Process_Result.out/err are based on cat_lines, without trailing newline;
wenzelm
parents: 64024
diff changeset
   114
    Output.writeln(out, stdout = true)
62553
d2e0d626fb96 tuned signature;
wenzelm
parents: 62492
diff changeset
   115
    copy(out_lines = Nil, err_lines = Nil)
d2e0d626fb96 tuned signature;
wenzelm
parents: 62492
diff changeset
   116
  }
62400
833af0d6d469 clarified modules;
wenzelm
parents:
diff changeset
   117
}