001: /*
002: * JLisp.java
003: *
004: * Copyright (C) 2002-2004 Peter Graves
005: * $Id: JLisp.java,v 1.22 2004/09/12 01:48:24 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import java.io.IOException;
025: import java.io.OutputStreamWriter;
026: import java.net.ServerSocket;
027: import java.net.Socket;
028: import javax.swing.SwingUtilities;
029: import org.armedbear.lisp.ConditionThrowable;
030: import org.armedbear.lisp.Interpreter;
031: import org.armedbear.lisp.Lisp;
032: import org.armedbear.lisp.LispObject;
033:
034: public final class JLisp extends LispShell {
035: private Thread thread;
036: private final File initialDir;
037:
038: private int port;
039: private Socket socket;
040: private Interpreter interpreter;
041:
042: private JLisp(File initialDir) {
043: super ();
044: this .initialDir = initialDir;
045: title = "jlisp";
046: mode = LispShellMode.getMode();
047: formatter = mode.getFormatter(this );
048: setInitialized(true);
049: }
050:
051: protected void initializeHistory() {
052: history = new History("jlisp.history", 30);
053: }
054:
055: public String toString() {
056: return "jlisp";
057: }
058:
059: // Returns true if underlying process is alive and well.
060: protected boolean checkProcess() {
061: return true;
062: }
063:
064: protected void startProcess() {
065: thread = new Thread("JLisp interpreter") {
066: public void run() {
067: try {
068: startServer();
069: if (interpreter != null) {
070: Editor.setLispInitialized(true);
071: interpreter.run(null);
072: }
073: } catch (Exception e) {
074: Log.error(e);
075: }
076: Log.debug("interpreter thread exiting");
077: Lisp.resetIO();
078: Runnable processExitedRunnable = new Runnable() {
079: public void run() {
080: appendString("\nProcess exited\n");
081: updateDisplayInAllFrames();
082: }
083: };
084: SwingUtilities.invokeLater(processExitedRunnable);
085: }
086: };
087: thread.setDaemon(true);
088: thread.start();
089:
090: synchronized (this ) {
091: if (port == 0) {
092: try {
093: wait(3000);
094: } catch (InterruptedException e) {
095: Log.error(e);
096: }
097: if (port == 0)
098: return;
099: }
100: }
101:
102: try {
103: socket = new Socket("localhost", port);
104: stdin = new OutputStreamWriter(socket.getOutputStream());
105: stdoutThread = new StdoutThread(socket.getInputStream());
106: stdoutThread.setName("JLisp reader");
107: stdoutThread.setDaemon(true);
108: stdoutThread.start();
109: } catch (IOException e) {
110: Log.error(e);
111: }
112: }
113:
114: private void startServer() {
115: try {
116: ServerSocket serverSocket = new ServerSocket(0);
117: port = serverSocket.getLocalPort();
118: synchronized (this ) {
119: notify();
120: }
121: Socket socket = serverSocket.accept(); // Blocks.
122: interpreter = Interpreter.createInstance(socket
123: .getInputStream(), socket.getOutputStream(),
124: initialDir.canonicalPath());
125: if (interpreter != null) {
126: // Print j version banner.
127: interpreter.getStandardOutput()._writeLine(
128: Version.getLongVersionString());
129: }
130: } catch (Throwable t) {
131: Log.error(t);
132: }
133: }
134:
135: public synchronized void dispose() {
136: Thread disposeThread = new Thread("JLisp dispose") {
137: public void run() {
138: Log.debug("JLisp.dispose");
139: if (interpreter != null)
140: interpreter.kill();
141: if (socket != null) {
142: try {
143: Log.debug("closing socket");
144: socket.close();
145: Log.debug("back from closing socket");
146: } catch (IOException e) {
147: Log.debug(e);
148: }
149: socket = null;
150: }
151: if (interpreter != null) {
152: interpreter.dispose();
153: interpreter = null;
154: }
155: }
156: };
157: disposeThread.setDaemon(true);
158: disposeThread.start();
159: }
160:
161: public static void jlisp() {
162: final Editor editor = Editor.currentEditor();
163: // Look for existing jlisp buffer.
164: for (BufferIterator it = new BufferIterator(); it.hasNext();) {
165: Buffer buf = it.nextBuffer();
166: if (buf instanceof JLisp) {
167: editor.makeNext(buf);
168: editor.activateInOtherWindow(buf);
169: return;
170: }
171: }
172: // Not found.
173: editor.setWaitCursor();
174: File initialDir = editor.getCurrentDirectory();
175: if (initialDir == null || initialDir.isRemote())
176: initialDir = Directories.getUserHomeDirectory();
177: JLisp jlisp = new JLisp(initialDir);
178: jlisp.startProcess();
179: editor.makeNext(jlisp);
180: Editor ed;
181: Buffer b = editor.getBuffer();
182: if (b != null && b.isPaired()) {
183: Frame frame = editor.getFrame();
184: editor.switchToBuffer(jlisp);
185: ed = frame.getCurrentEditor();
186: } else
187: ed = editor.activateInOtherWindow(jlisp);
188: ed.eob();
189: editor.setDefaultCursor();
190: }
191:
192: public static void runStartupScript(File file)
193: throws ConditionThrowable {
194: if (!Editor.isLispInitialized()) {
195: Interpreter.initializeLisp(true);
196: Editor.setLispInitialized(true);
197: }
198: FastStringBuffer sb = new FastStringBuffer("(load \"");
199: if (Platform.isPlatformWindows()) {
200: String cp = file.canonicalPath();
201: final int limit = cp.length();
202: for (int i = 0; i < limit; i++) {
203: char c = cp.charAt(i);
204: if (c == '\\')
205: sb.append('\\'); // Double backslash.
206: sb.append(c);
207: }
208: } else
209: sb.append(file.canonicalPath());
210: sb.append("\")");
211: Interpreter.evaluate(sb.toString());
212: }
213:
214: public static LispObject runLispCommand(String command)
215: throws ConditionThrowable {
216: if (!Editor.isLispInitialized()) {
217: Interpreter.initializeLisp(true);
218: Editor.setLispInitialized(true);
219: }
220: return Interpreter.evaluate(command);
221: }
222: }
|