74 STDIN, STDOUT, STDERR, SIGNAL, EXIT, // Posix channels/events |
74 STDIN, STDOUT, STDERR, SIGNAL, EXIT, // Posix channels/events |
75 WRITELN, PRIORITY, TRACING, WARNING, ERROR, DEBUG, PROMPT, // Isabelle messages |
75 WRITELN, PRIORITY, TRACING, WARNING, ERROR, DEBUG, PROMPT, // Isabelle messages |
76 SYSTEM // internal system notification |
76 SYSTEM // internal system notification |
77 }; |
77 }; |
78 public Kind kind; |
78 public Kind kind; |
|
79 public Properties props; |
79 public String result; |
80 public String result; |
80 |
81 |
81 public Result(Kind kind, String result) { |
82 public Result(Kind kind, Properties props, String result) { |
82 this.kind = kind; |
83 this.kind = kind; |
|
84 this.props = props; |
83 this.result = result; |
85 this.result = result; |
84 } |
86 } |
85 |
87 |
86 public boolean isRaw() { |
88 public boolean isRaw() { |
87 return |
89 return |
97 this.kind == Kind.PROMPT || |
99 this.kind == Kind.PROMPT || |
98 this.kind == Kind.SYSTEM; |
100 this.kind == Kind.SYSTEM; |
99 } |
101 } |
100 |
102 |
101 public String toString() { |
103 public String toString() { |
102 return this.kind.toString() + " [[" + this.result + "]]"; |
104 if (this.props == null) { |
|
105 return this.kind.toString() + " [[" + this.result + "]]"; |
|
106 } else { |
|
107 return this.kind.toString() + " " + props.toString() + " [[" + this.result + "]]"; |
|
108 } |
103 } |
109 } |
104 } |
110 } |
105 |
111 |
106 |
112 |
107 /** |
113 /** |
108 * Main result queue -- accumulates cooked messages asynchronously. |
114 * Main result queue -- accumulates cooked messages asynchronously. |
109 */ |
115 */ |
110 public LinkedBlockingQueue<Result> results; |
116 public LinkedBlockingQueue<Result> results; |
111 |
117 |
|
118 private synchronized void putResult(Result.Kind kind, Properties props, String result) { |
|
119 try { |
|
120 results.put(new Result(kind, props, result)); |
|
121 } catch (InterruptedException exn) { } |
|
122 } |
112 private synchronized void putResult(Result.Kind kind, String result) { |
123 private synchronized void putResult(Result.Kind kind, String result) { |
113 try { |
124 putResult(kind, null, result); |
114 results.put(new Result(kind, result)); |
|
115 } catch (InterruptedException exn) { } |
|
116 } |
125 } |
117 |
126 |
118 |
127 |
119 /** |
128 /** |
120 * Interrupts Isabelle process via Posix signal. |
129 * Interrupts Isabelle process via Posix signal. |
310 public synchronized void ML(Properties props, String text) throws IsabelleProcessException |
319 public synchronized void ML(Properties props, String text) throws IsabelleProcessException |
311 { |
320 { |
312 command(props, "ML " + encodeString(text)); |
321 command(props, "ML " + encodeString(text)); |
313 } |
322 } |
314 |
323 |
315 |
324 |
316 /* input from the process (stdout/stderr) */ |
325 /* input from the process (stdout/stderr) */ |
317 |
326 |
318 private volatile BufferedReader inputReader; |
327 private volatile BufferedReader inputReader; |
319 private class InputThread extends Thread |
328 private class InputThread extends Thread |
320 { |
329 { |
321 public void run() |
330 public void run() |
322 { |
331 { |
323 Result.Kind kind = Result.Kind.STDOUT; |
332 Result.Kind kind = Result.Kind.STDOUT; |
|
333 Properties props = null; |
324 StringBuffer buf = new StringBuffer(100); |
334 StringBuffer buf = new StringBuffer(100); |
325 |
335 |
326 try { |
336 try { |
327 while (inputReader != null) { |
337 while (inputReader != null) { |
328 if (kind == Result.Kind.STDOUT && pid != null) { |
338 if (kind == Result.Kind.STDOUT && pid != null) { |
334 } |
344 } |
335 if (buf.length() > 0) { |
345 if (buf.length() > 0) { |
336 putResult(kind, buf.toString()); |
346 putResult(kind, buf.toString()); |
337 buf = new StringBuffer(100); |
347 buf = new StringBuffer(100); |
338 } |
348 } |
339 if (c == 2) { |
349 if (c == -1) { |
|
350 inputReader.close(); |
|
351 inputReader = null; |
|
352 tryClose(); |
|
353 } |
|
354 else if (c == 2) { |
340 c = inputReader.read(); |
355 c = inputReader.read(); |
341 switch (c) { |
356 switch (c) { |
342 case 'A': kind = Result.Kind.WRITELN; break; |
357 case 'A': kind = Result.Kind.WRITELN; break; |
343 case 'B': kind = Result.Kind.PRIORITY; break; |
358 case 'B': kind = Result.Kind.PRIORITY; break; |
344 case 'C': kind = Result.Kind.TRACING; break; |
359 case 'C': kind = Result.Kind.TRACING; break; |
346 case 'E': kind = Result.Kind.ERROR; break; |
361 case 'E': kind = Result.Kind.ERROR; break; |
347 case 'F': kind = Result.Kind.DEBUG; break; |
362 case 'F': kind = Result.Kind.DEBUG; break; |
348 case 'G': kind = Result.Kind.PROMPT; break; |
363 case 'G': kind = Result.Kind.PROMPT; break; |
349 default: kind = Result.Kind.STDOUT; break; |
364 default: kind = Result.Kind.STDOUT; break; |
350 } |
365 } |
351 } |
366 props = null; |
352 if (c == -1) { |
|
353 inputReader.close(); |
|
354 inputReader = null; |
|
355 tryClose(); |
|
356 } |
367 } |
357 } else { |
368 } else { |
358 // line mode |
369 // line mode |
359 String line = null; |
370 String line = null; |
360 if ((line = inputReader.readLine()) != null) { |
371 if ((line = inputReader.readLine()) != null) { |
365 buf.append("\n"); |
376 buf.append("\n"); |
366 putResult(kind, buf.toString()); |
377 putResult(kind, buf.toString()); |
367 buf = new StringBuffer(100); |
378 buf = new StringBuffer(100); |
368 } else { |
379 } else { |
369 int len = line.length(); |
380 int len = line.length(); |
370 if (len >= 2 && line.charAt(len - 2) == 2 && line.charAt(len - 1) == '.') { |
381 // property |
|
382 if (line.endsWith("\u0002,")) { |
|
383 int i = line.indexOf("="); |
|
384 if (i > 0) { |
|
385 String name = line.substring(0, i); |
|
386 String value = line.substring(i + 1, len - 2); |
|
387 if (props == null) |
|
388 props = new Properties(); |
|
389 if (!props.containsKey(name)) { |
|
390 props.setProperty(name, value); |
|
391 } |
|
392 } |
|
393 } |
|
394 // last text line |
|
395 else if (line.endsWith("\u0002.")) { |
371 buf.append(line.substring(0, len - 2)); |
396 buf.append(line.substring(0, len - 2)); |
372 putResult(kind, buf.toString()); |
397 putResult(kind, props, buf.toString()); |
373 buf = new StringBuffer(100); |
398 buf = new StringBuffer(100); |
374 kind = Result.Kind.STDOUT; |
399 kind = Result.Kind.STDOUT; |
375 } else { |
400 } |
|
401 // text line |
|
402 else { |
376 buf.append(line); |
403 buf.append(line); |
377 buf.append("\n"); |
404 buf.append("\n"); |
378 } |
405 } |
379 } |
406 } |
380 } else { |
407 } else { |