1 /* |
1 /* |
2 * $Id$ |
2 * $Id$ |
3 * |
|
4 * Posix process wrapper for Isabelle (see also src/Pure/Tools/isabelle_process.ML). |
|
5 * |
|
6 * The process model: |
|
7 * |
|
8 * (1) input |
|
9 * - stdin stream |
|
10 * - signals (interrupt, kill) |
|
11 * |
|
12 * (2) output/results |
|
13 * - stdout stream, interspersed with marked Isabelle messages |
|
14 * - stderr stream |
|
15 * - process exit (return code) |
|
16 * |
|
17 * I/O is fully asynchronous, with unrestricted buffers. Text is encoded as UTF-8. |
|
18 * |
|
19 * System properties: |
|
20 * |
|
21 * isabelle.home ISABELLE_HOME of Isabelle installation |
|
22 * (default determined from isabelle-process via PATH) |
|
23 * isabelle.shell optional shell command for isabelle-process (also requires isabelle.home) |
|
24 * isabelle.kill optional kill command (default "kill") |
|
25 */ |
3 */ |
26 |
4 |
27 package isabelle; |
5 package isabelle; |
28 |
6 |
29 import java.io.*; |
7 import java.io.*; |
30 import java.util.ArrayList; |
8 import java.util.ArrayList; |
31 import java.util.Locale; |
9 import java.util.Locale; |
32 import java.util.concurrent.LinkedBlockingQueue; |
10 import java.util.concurrent.LinkedBlockingQueue; |
|
11 |
|
12 /** |
|
13 * Posix process wrapper for Isabelle (see also <code>src/Pure/Tools/isabelle_process.ML</code>). |
|
14 * <p> |
|
15 * |
|
16 * The process model: |
|
17 * <p> |
|
18 * |
|
19 * <ol> |
|
20 * <li> input |
|
21 * <ul> |
|
22 * <li> stdin stream |
|
23 * <li> signals (interrupt, kill) |
|
24 * </ul> |
|
25 * |
|
26 * <li> output/results |
|
27 * <ul> |
|
28 * <li> stdout stream, interspersed with marked Isabelle messages |
|
29 * <li> stderr stream |
|
30 * <li> process exit (return code) |
|
31 * </ul> |
|
32 * </ol> |
|
33 * |
|
34 * I/O is fully asynchronous, with unrestricted buffers. Text is encoded as UTF-8. |
|
35 * <p> |
|
36 * |
|
37 * System properties: |
|
38 * <p> |
|
39 * |
|
40 * <dl> |
|
41 * <dt> <code>isabelle.home</code> <di> <code>ISABELLE_HOME</code> of Isabelle installation |
|
42 * (default determined from isabelle-process via <code>PATH</code>) |
|
43 * <dt> <code>isabelle.shell</code> <di> optional shell command for <code>isabelle-process</code> (also requires isabelle.home) |
|
44 * <dt> <code>isabelle.kill</code> <di> optional kill command (default <code>kill</code>) |
|
45 */ |
33 |
46 |
34 public class IsabelleProcess { |
47 public class IsabelleProcess { |
35 private volatile Process proc = null; |
48 private volatile Process proc = null; |
36 private volatile String pid = null; |
49 private volatile String pid = null; |
37 private volatile boolean closing = false; |
50 private volatile boolean closing = false; |
38 private LinkedBlockingQueue<String> output = null; |
51 private LinkedBlockingQueue<String> output = null; |
39 |
52 |
40 |
53 |
41 /* exceptions */ |
54 /** |
42 |
55 * Models failures in process management. |
|
56 */ |
43 public static class IsabelleProcessException extends Exception { |
57 public static class IsabelleProcessException extends Exception { |
44 public IsabelleProcessException() { |
58 public IsabelleProcessException() { |
45 super(); |
59 super(); |
46 } |
60 } |
47 public IsabelleProcessException(String msg) { |
61 public IsabelleProcessException(String msg) { |
48 super(msg); |
62 super(msg); |
49 } |
63 } |
50 }; |
64 }; |
51 |
65 |
52 |
66 |
53 /* results from the process */ |
67 /** |
54 |
68 * Models cooked results from the process. |
|
69 */ |
55 public static class Result { |
70 public static class Result { |
56 public enum Kind { |
71 public enum Kind { |
57 STDIN, STDOUT, STDERR, SIGNAL, EXIT, // Posix channels/events |
72 STDIN, STDOUT, STDERR, SIGNAL, EXIT, // Posix channels/events |
58 WRITELN, PRIORITY, TRACING, WARNING, ERROR, DEBUG, // Isabelle messages |
73 WRITELN, PRIORITY, TRACING, WARNING, ERROR, DEBUG, // Isabelle messages |
59 SYSTEM // internal system notification |
74 SYSTEM // internal system notification |
69 public String toString() { |
84 public String toString() { |
70 return this.kind.toString() + " [[" + this.result + "]]"; |
85 return this.kind.toString() + " [[" + this.result + "]]"; |
71 } |
86 } |
72 } |
87 } |
73 |
88 |
|
89 |
|
90 /** |
|
91 * Main result queue -- accumulates cooked messages asynchronously. |
|
92 */ |
74 public LinkedBlockingQueue<Result> results; |
93 public LinkedBlockingQueue<Result> results; |
75 |
94 |
76 private synchronized void putResult(Result.Kind kind, String result) { |
95 private synchronized void putResult(Result.Kind kind, String result) { |
77 try { |
96 try { |
78 results.put(new Result(kind, result)); |
97 results.put(new Result(kind, result)); |
79 } catch (InterruptedException exn) { } |
98 } catch (InterruptedException exn) { } |
80 } |
99 } |
81 |
100 |
82 |
101 |
83 /* interrupt process */ |
102 /** |
84 |
103 * Interrupts Isabelle process via Posix signal. |
|
104 * @throws isabelle.IsabelleProcess.IsabelleProcessException |
|
105 */ |
85 public synchronized void interrupt() throws IsabelleProcessException |
106 public synchronized void interrupt() throws IsabelleProcessException |
86 { |
107 { |
87 if (proc != null && pid != null) { |
108 if (proc != null && pid != null) { |
88 String kill = System.getProperty("isabelle.kill", "kill"); |
109 String kill = System.getProperty("isabelle.kill", "kill"); |
89 String [] cmdline = {kill, "-INT", pid}; |
110 String [] cmdline = {kill, "-INT", pid}; |
210 private synchronized void outputSync(String text) throws IsabelleProcessException |
242 private synchronized void outputSync(String text) throws IsabelleProcessException |
211 { |
243 { |
212 output(" \\<^sync>\n; " + text + " \\<^sync>;\n"); |
244 output(" \\<^sync>\n; " + text + " \\<^sync>;\n"); |
213 } |
245 } |
214 |
246 |
|
247 /** |
|
248 * Feeds exactly one Isabelle command into the process. |
|
249 */ |
215 public synchronized void command(String text) throws IsabelleProcessException |
250 public synchronized void command(String text) throws IsabelleProcessException |
216 { |
251 { |
217 outputSync("Isabelle.command " + encodeString(text)); |
252 outputSync("Isabelle.command " + encodeString(text)); |
218 } |
253 } |
219 |
254 |
|
255 /** |
|
256 * Feeds ML toplevel declarations into the process. |
|
257 */ |
220 public synchronized void ML(String text) throws IsabelleProcessException |
258 public synchronized void ML(String text) throws IsabelleProcessException |
221 { |
259 { |
222 outputSync("ML " + encodeString(text)); |
260 outputSync("ML " + encodeString(text)); |
223 } |
261 } |
224 |
262 |