| author | blanchet | 
| Tue, 27 Jul 2010 19:17:15 +0200 | |
| changeset 38027 | 505657ddb047 | 
| parent 37784 | 1d639d28832c | 
| child 38236 | d8c7be27e01d | 
| permissions | -rw-r--r-- | 
| 14815 | 1  | 
(* Title: Pure/General/output.ML  | 
2  | 
Author: Makarius, Hagia Maria Sion Abbey (Jerusalem)  | 
|
3  | 
||
| 22585 | 4  | 
Output channels and timing messages.  | 
| 14815 | 5  | 
*)  | 
6  | 
||
7  | 
signature BASIC_OUTPUT =  | 
|
8  | 
sig  | 
|
| 
23660
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
9  | 
type output = string  | 
| 
18682
 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 
wenzelm 
parents: 
17539 
diff
changeset
 | 
10  | 
val writeln: string -> unit  | 
| 
 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 
wenzelm 
parents: 
17539 
diff
changeset
 | 
11  | 
val priority: string -> unit  | 
| 
 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 
wenzelm 
parents: 
17539 
diff
changeset
 | 
12  | 
val tracing: string -> unit  | 
| 
 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 
wenzelm 
parents: 
17539 
diff
changeset
 | 
13  | 
val warning: string -> unit  | 
| 22826 | 14  | 
val legacy_feature: string -> unit  | 
| 
25686
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
15  | 
val cond_timeit: bool -> string -> (unit -> 'a) -> 'a  | 
| 14815 | 16  | 
val timeit: (unit -> 'a) -> 'a  | 
17  | 
  val timeap: ('a -> 'b) -> 'a -> 'b
 | 
|
18  | 
  val timeap_msg: string -> ('a -> 'b) -> 'a -> 'b
 | 
|
| 32738 | 19  | 
val timing: bool Unsynchronized.ref  | 
| 14815 | 20  | 
end;  | 
21  | 
||
22  | 
signature OUTPUT =  | 
|
23  | 
sig  | 
|
24  | 
include BASIC_OUTPUT  | 
|
| 
23660
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
25  | 
val default_output: string -> output * int  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
26  | 
val default_escape: output -> string  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
27  | 
val add_mode: string -> (string -> output * int) -> (output -> string) -> unit  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
28  | 
val output_width: string -> output * int  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
29  | 
val output: string -> output  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
30  | 
val escape: output -> string  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
31  | 
val std_output: output -> unit  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
32  | 
val std_error: output -> unit  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
33  | 
val writeln_default: output -> unit  | 
| 32738 | 34  | 
val writeln_fn: (output -> unit) Unsynchronized.ref  | 
35  | 
val priority_fn: (output -> unit) Unsynchronized.ref  | 
|
36  | 
val tracing_fn: (output -> unit) Unsynchronized.ref  | 
|
37  | 
val warning_fn: (output -> unit) Unsynchronized.ref  | 
|
38  | 
val error_fn: (output -> unit) Unsynchronized.ref  | 
|
39  | 
val debug_fn: (output -> unit) Unsynchronized.ref  | 
|
40  | 
val prompt_fn: (output -> unit) Unsynchronized.ref  | 
|
41  | 
val status_fn: (output -> unit) Unsynchronized.ref  | 
|
| 
25845
 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 
wenzelm 
parents: 
25686 
diff
changeset
 | 
42  | 
val error_msg: string -> unit  | 
| 
 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 
wenzelm 
parents: 
25686 
diff
changeset
 | 
43  | 
val prompt: string -> unit  | 
| 27605 | 44  | 
val status: string -> unit  | 
| 32738 | 45  | 
val debugging: bool Unsynchronized.ref  | 
| 
32966
 
5b21661fe618
indicate CRITICAL nature of various setmp combinators;
 
wenzelm 
parents: 
32738 
diff
changeset
 | 
46  | 
  val no_warnings_CRITICAL: ('a -> 'b) -> 'a -> 'b
 | 
| 22130 | 47  | 
val debug: (unit -> string) -> unit  | 
| 14815 | 48  | 
end;  | 
49  | 
||
50  | 
structure Output: OUTPUT =  | 
|
51  | 
struct  | 
|
52  | 
||
| 23616 | 53  | 
(** print modes **)  | 
| 14881 | 54  | 
|
| 
23660
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
55  | 
type output = string; (*raw system output*)  | 
| 
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
56  | 
|
| 23616 | 57  | 
fun default_output s = (s, size s);  | 
| 
23660
 
18765718cf62
type output = string indicates raw system output;
 
wenzelm 
parents: 
23616 
diff
changeset
 | 
58  | 
fun default_escape (s: output) = s;  | 
| 14815 | 59  | 
|
| 23616 | 60  | 
local  | 
61  | 
  val default = {output = default_output, escape = default_escape};
 | 
|
| 32738 | 62  | 
  val modes = Unsynchronized.ref (Symtab.make [("", default)]);
 | 
| 23616 | 63  | 
in  | 
| 
23922
 
707639e9497d
marked some CRITICAL sections (for multithreading);
 
wenzelm 
parents: 
23862 
diff
changeset
 | 
64  | 
fun add_mode name output escape = CRITICAL (fn () =>  | 
| 32738 | 65  | 
    Unsynchronized.change modes (Symtab.update_new (name, {output = output, escape = escape})));
 | 
| 23616 | 66  | 
fun get_mode () =  | 
| 24612 | 67  | 
the_default default (Library.get_first (Symtab.lookup (! modes)) (print_mode_value ()));  | 
| 23616 | 68  | 
end;  | 
| 14815 | 69  | 
|
| 19265 | 70  | 
fun output_width x = #output (get_mode ()) x;  | 
| 14815 | 71  | 
val output = #1 o output_width;  | 
| 23727 | 72  | 
|
| 23616 | 73  | 
fun escape x = #escape (get_mode ()) x;  | 
| 14815 | 74  | 
|
75  | 
||
76  | 
||
77  | 
(** output channels **)  | 
|
78  | 
||
| 14984 | 79  | 
(* output primitives -- normally NOT used directly!*)  | 
80  | 
||
| 24058 | 81  | 
fun std_output s = NAMED_CRITICAL "IO" (fn () =>  | 
| 
23922
 
707639e9497d
marked some CRITICAL sections (for multithreading);
 
wenzelm 
parents: 
23862 
diff
changeset
 | 
82  | 
(TextIO.output (TextIO.stdOut, s); TextIO.flushOut TextIO.stdOut));  | 
| 
 
707639e9497d
marked some CRITICAL sections (for multithreading);
 
wenzelm 
parents: 
23862 
diff
changeset
 | 
83  | 
|
| 24058 | 84  | 
fun std_error s = NAMED_CRITICAL "IO" (fn () =>  | 
| 
23922
 
707639e9497d
marked some CRITICAL sections (for multithreading);
 
wenzelm 
parents: 
23862 
diff
changeset
 | 
85  | 
(TextIO.output (TextIO.stdErr, s); TextIO.flushOut TextIO.stdErr));  | 
| 14815 | 86  | 
|
| 27605 | 87  | 
fun writeln_default "" = ()  | 
88  | 
| writeln_default s = std_output (suffix "\n" s);  | 
|
| 14815 | 89  | 
|
| 14984 | 90  | 
|
91  | 
(* Isabelle output channels *)  | 
|
92  | 
||
| 32738 | 93  | 
val writeln_fn = Unsynchronized.ref writeln_default;  | 
94  | 
val priority_fn = Unsynchronized.ref (fn s => ! writeln_fn s);  | 
|
95  | 
val tracing_fn = Unsynchronized.ref (fn s => ! writeln_fn s);  | 
|
96  | 
val warning_fn = Unsynchronized.ref (std_output o suffix "\n" o prefix_lines "### ");  | 
|
97  | 
val error_fn = Unsynchronized.ref (std_output o suffix "\n" o prefix_lines "*** ");  | 
|
98  | 
val debug_fn = Unsynchronized.ref (std_output o suffix "\n" o prefix_lines "::: ");  | 
|
99  | 
val prompt_fn = Unsynchronized.ref std_output;  | 
|
100  | 
val status_fn = Unsynchronized.ref (fn _: string => ());  | 
|
| 14815 | 101  | 
|
102  | 
fun writeln s = ! writeln_fn (output s);  | 
|
103  | 
fun priority s = ! priority_fn (output s);  | 
|
104  | 
fun tracing s = ! tracing_fn (output s);  | 
|
105  | 
fun warning s = ! warning_fn (output s);  | 
|
| 
25845
 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 
wenzelm 
parents: 
25686 
diff
changeset
 | 
106  | 
fun error_msg s = ! error_fn (output s);  | 
| 
 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 
wenzelm 
parents: 
25686 
diff
changeset
 | 
107  | 
fun prompt s = ! prompt_fn (output s);  | 
| 27605 | 108  | 
fun status s = ! status_fn (output s);  | 
| 15190 | 109  | 
|
| 
37784
 
1d639d28832c
removed impractical tolerate_legacy_features flag;
 
wenzelm 
parents: 
32966 
diff
changeset
 | 
110  | 
fun legacy_feature s = warning ("Legacy feature! " ^ s);
 | 
| 22826 | 111  | 
|
| 
32966
 
5b21661fe618
indicate CRITICAL nature of various setmp combinators;
 
wenzelm 
parents: 
32738 
diff
changeset
 | 
112  | 
fun no_warnings_CRITICAL f = setmp_CRITICAL warning_fn (K ()) f;  | 
| 16191 | 113  | 
|
| 32738 | 114  | 
val debugging = Unsynchronized.ref false;  | 
| 22130 | 115  | 
fun debug s = if ! debugging then ! debug_fn (output (s ())) else ()  | 
| 15190 | 116  | 
|
| 14815 | 117  | 
|
118  | 
||
119  | 
(** timing **)  | 
|
120  | 
||
| 
25686
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
121  | 
(*conditional timing with message*)  | 
| 
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
122  | 
fun cond_timeit flag msg e =  | 
| 14815 | 123  | 
if flag then  | 
| 23862 | 124  | 
let  | 
125  | 
val start = start_timing ();  | 
|
| 
25686
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
126  | 
val result = Exn.capture e ();  | 
| 
30187
 
b92b3375e919
end_timing: generalized result -- message plus with explicit time values;
 
wenzelm 
parents: 
29606 
diff
changeset
 | 
127  | 
val end_msg = #message (end_timing start);  | 
| 
25686
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
128  | 
val _ = warning (if msg = "" then end_msg else msg ^ "\n" ^ end_msg);  | 
| 
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
129  | 
in Exn.release result end  | 
| 
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
130  | 
else e ();  | 
| 25667 | 131  | 
|
| 23862 | 132  | 
(*unconditional timing*)  | 
| 
25686
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
133  | 
fun timeit e = cond_timeit true "" e;  | 
| 14815 | 134  | 
|
135  | 
(*timed application function*)  | 
|
136  | 
fun timeap f x = timeit (fn () => f x);  | 
|
| 
25686
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
137  | 
fun timeap_msg msg f x = cond_timeit true msg (fn () => f x);  | 
| 
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
138  | 
|
| 
 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 
wenzelm 
parents: 
25682 
diff
changeset
 | 
139  | 
(*global timing mode*)  | 
| 32738 | 140  | 
val timing = Unsynchronized.ref false;  | 
| 14815 | 141  | 
|
142  | 
end;  | 
|
143  | 
||
| 32738 | 144  | 
structure Basic_Output: BASIC_OUTPUT = Output;  | 
145  | 
open Basic_Output;  |