author | wenzelm |
Fri, 15 Aug 2008 15:50:52 +0200 | |
changeset 27885 | 76b51cd0a37c |
parent 27844 | 86f0f91471d0 |
child 27961 | 2cd133df7587 |
permissions | -rw-r--r-- |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/Tools/isabelle_process.ML |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
2 |
ID: $Id$ |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
3 |
Author: Makarius |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
4 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
5 |
Isabelle process wrapper -- interaction via external program. |
25631 | 6 |
|
7 |
General format of process output: |
|
8 |
||
9 |
(a) unmarked stdout/stderr, no line structure (output should be |
|
25842 | 10 |
processed immediately as it arrives); |
25631 | 11 |
|
25841 | 12 |
(b) properly marked-up messages, e.g. for writeln channel |
25810 | 13 |
|
14 |
"\002A" ^ props ^ "\002,\n" ^ text ^ "\002.\n" |
|
15 |
||
25841 | 16 |
where the props consist of name=value lines terminated by "\002,\n" |
25810 | 17 |
each, and the remaining text is any number of lines (output is |
25842 | 18 |
supposed to be processed in one piece); |
25841 | 19 |
|
25842 | 20 |
(c) special init message holds "pid" and "session" property. |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
21 |
*) |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
22 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
23 |
signature ISABELLE_PROCESS = |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
24 |
sig |
26574
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
25 |
val isabelle_processN: string |
26208 | 26 |
val full_markupN: string |
26574
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
27 |
val yxmlN: string |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
28 |
val init: unit -> unit |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
29 |
end; |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
30 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
31 |
structure IsabelleProcess: ISABELLE_PROCESS = |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
32 |
struct |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
33 |
|
26550 | 34 |
(* print modes *) |
25554 | 35 |
|
25748 | 36 |
val isabelle_processN = "isabelle_process"; |
26550 | 37 |
val full_markupN = "full_markup"; |
26574
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
38 |
val yxmlN = "YXML"; |
25748 | 39 |
|
26550 | 40 |
val _ = Output.add_mode isabelle_processN Output.default_output Output.default_escape; |
25554 | 41 |
|
26550 | 42 |
val _ = Markup.add_mode isabelle_processN (fn (name, props) => |
43 |
if print_mode_active full_markupN orelse name = Markup.positionN |
|
44 |
then YXML.output_markup (name, props) else ("", "")); |
|
25841 | 45 |
|
46 |
||
47 |
(* message markup *) |
|
48 |
||
26527 | 49 |
fun special ch = Symbol.STX ^ ch; |
25810 | 50 |
val special_sep = special ","; |
25576 | 51 |
val special_end = special "."; |
25554 | 52 |
|
25841 | 53 |
local |
25810 | 54 |
|
26574
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
55 |
fun clean_string bad str = |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
56 |
if exists_string (member (op =) bad) str then |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
57 |
translate_string (fn c => if member (op =) bad c then Symbol.DEL else c) str |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
58 |
else str; |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
59 |
|
26550 | 60 |
fun message_props props = |
26574
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
61 |
let val clean = clean_string [Symbol.STX, "\n", "\r"] |
25841 | 62 |
in implode (map (fn (x, y) => clean x ^ "=" ^ clean y ^ special_sep ^ "\n") props) end; |
63 |
||
26550 | 64 |
fun message_text ts = |
26574
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
65 |
let |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
66 |
val doc = XML.Elem ("message", [], ts); |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
67 |
val msg = |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
68 |
if not (print_mode_active full_markupN) then |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
69 |
Buffer.content (fold XML.add_content ts Buffer.empty) |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
70 |
else if print_mode_active yxmlN then YXML.string_of doc |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
71 |
else XML.header ^ XML.string_of doc; |
560d07845442
support "YXML" mode for output transfer notation;
wenzelm
parents:
26550
diff
changeset
|
72 |
in clean_string [Symbol.STX] msg end; |
26550 | 73 |
|
74 |
fun message_pos ts = get_first get_pos ts |
|
75 |
and get_pos (elem as XML.Elem (name, atts, ts)) = |
|
25841 | 76 |
if name = Markup.positionN then SOME (Position.of_properties atts) |
26550 | 77 |
else message_pos ts |
27434 | 78 |
| get_pos _ = NONE; |
25554 | 79 |
|
80 |
in |
|
81 |
||
27844 | 82 |
fun message _ "" = () |
83 |
| message ch body = |
|
84 |
let |
|
85 |
val (txt, pos) = |
|
86 |
let val ts = YXML.parse_body body |
|
87 |
in (message_text ts, the_default Position.none (message_pos ts)) end |
|
88 |
handle Fail msg => ("*** MALFORMED MESSAGE ***\n" ^ msg, Position.none); |
|
89 |
val props = |
|
90 |
Position.properties_of (Position.thread_data ()) |
|
91 |
|> Position.default_properties pos; |
|
92 |
in Output.writeln_default (special ch ^ message_props props ^ txt ^ special_end) end; |
|
25554 | 93 |
|
25841 | 94 |
fun init_message () = |
95 |
let |
|
25849 | 96 |
val pid = ("pid", string_of_pid (Posix.ProcEnv.getpid ())); |
97 |
val session = ("session", List.last (Session.id ()) handle List.Empty => "unknown"); |
|
25841 | 98 |
val welcome = Session.welcome (); |
26550 | 99 |
in Output.writeln_default (special "H" ^ message_props [pid, session] ^ welcome ^ special_end) end; |
25748 | 100 |
|
25554 | 101 |
end; |
102 |
||
103 |
||
25841 | 104 |
(* channels *) |
105 |
||
106 |
fun setup_channels () = |
|
25849 | 107 |
(Output.writeln_fn := message "A"; |
108 |
Output.priority_fn := message "B"; |
|
109 |
Output.tracing_fn := message "C"; |
|
110 |
Output.warning_fn := message "D"; |
|
111 |
Output.error_fn := message "E"; |
|
112 |
Output.debug_fn := message "F"; |
|
27604 | 113 |
Output.prompt_fn := message "G"; |
114 |
Output.status_fn := message "I"); |
|
25841 | 115 |
|
116 |
||
25554 | 117 |
(* init *) |
118 |
||
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
119 |
fun init () = |
25841 | 120 |
(change print_mode (update (op =) isabelle_processN); |
25554 | 121 |
setup_channels (); |
25841 | 122 |
init_message (); |
26643 | 123 |
Isar.toplevel_loop {init = true, welcome = false, sync = true, secure = true}); |
25528
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
124 |
|
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
125 |
end; |
e67230c2b952
Isabelle process wrapper -- interaction via external program.
wenzelm
parents:
diff
changeset
|
126 |