1 21 22 package org.armedbear.j; 23 24 import java.io.BufferedReader ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.InputStreamReader ; 28 import java.util.ArrayList ; 29 import javax.swing.SwingUtilities ; 30 31 public final class CompilationBuffer extends CompilationErrorBuffer 32 implements Runnable 33 { 34 private String command; 35 private String expandedCommand; 36 private Position posEndOfBuffer; 37 private File currentDir; 38 private Process process; 39 private int exitValue; 40 private File exitValueFile; 41 42 public CompilationBuffer(String command, File directory) 43 { 44 setCommand(command); 45 currentDir = directory; 46 mode = CompilationMode.getMode(); 47 try { 48 lockWrite(); 49 } 50 catch (InterruptedException e) { 51 Log.debug(e); 52 return; 53 } 54 try { 55 appendLine(""); 56 renumber(); 57 } 58 finally { 59 unlockWrite(); 60 } 61 setLoaded(true); 62 posEndOfBuffer = new Position(getFirstLine(), 0); 63 } 64 65 public synchronized final void initialize() 66 { 67 setTitle(expandedCommand = expandCommand(command)); 68 setInitialized(true); 69 } 70 71 public final void setCommand(String command) 72 { 73 this.command = command; 74 } 75 76 public final int exitValue() 77 { 78 return exitValue; 79 } 80 81 public void empty() 82 { 83 try { 84 lockWrite(); 85 } 86 catch (InterruptedException e) { 87 Log.debug(e); 88 return; 89 } 90 try { 91 super.empty(); 92 appendLine(""); 93 renumber(); 94 setLoaded(true); 95 posEndOfBuffer = new Position(getFirstLine(), 0); 96 setCurrentError(null); 97 } 98 finally { 99 unlockWrite(); 100 } 101 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 102 Editor ed = it.nextEditor(); 103 if (ed.getBuffer() == this) { 104 ed.setDot(getFirstLine(), 0); 105 ed.setTopLine(getFirstLine()); 106 ed.setMark(null); 107 } 108 } 109 } 110 111 public void run() 112 { 113 long start = System.currentTimeMillis(); 114 if (expandedCommand.startsWith("(")) { 115 FastStringBuffer sb = new FastStringBuffer(); 117 sb.append("(with-output-to-string (s) "); 118 sb.append("(let ((*standard-output* s)) "); 119 sb.append(expandedCommand); 120 sb.append(" ))"); 121 try { 122 org.armedbear.lisp.LispObject result = 123 JLisp.runLispCommand(sb.toString()); 124 appendLater(result.getStringValue()); 125 } 126 catch (Throwable t) { 127 Log.debug(t); 128 } 129 } else { 130 startProcess(); 131 if (process != null) { 132 CompilationBufferReaderThread stdoutThread = 133 new CompilationBufferReaderThread(process.getInputStream()); 134 stdoutThread.start(); 135 CompilationBufferReaderThread stderrThread = 136 new CompilationBufferReaderThread(process.getErrorStream()); 137 stderrThread.start(); 138 try { 139 exitValue = process.waitFor(); 140 if (exitValueFile != null && exitValueFile.isFile()) { 141 exitValue = getExitValueFromFile(exitValueFile); 142 exitValueFile.delete(); 143 exitValueFile = null; 144 } 145 stdoutThread.join(); 146 stderrThread.join(); 147 long elapsed = System.currentTimeMillis() - start; 148 FastStringBuffer sb = new FastStringBuffer(); 149 sb.append("\nCompilation "); 150 if (exitValue == 0) { 151 sb.append("finished ("); 152 sb.append(String.valueOf(elapsed)); 153 sb.append(" milliseconds)"); 154 } else 155 sb.append("exited abnormally"); 156 sb.append("\n"); 157 appendLater(sb.toString()); 158 } 159 catch (InterruptedException e) { 160 Log.error(e); 161 } 162 } else 163 appendLater("Unable to start compilation process\n"); 164 } 165 Editor.getTagFileManager().setEnabled(true); 166 } 167 168 private void startProcess() 169 { 170 process = null; 171 exitValue = -1; 172 try { 173 if (Platform.isPlatformWindows()) { 174 String cmd = "cd /d \"" + currentDir.canonicalPath() + 175 "\" && " + expandedCommand; 176 ArrayList list = new ArrayList (); 177 list.add("cmd.exe"); 178 list.add("/c"); 179 list.addAll(Utilities.tokenize(cmd)); 180 final int size = list.size(); 181 String [] cmdarray = new String [size]; 182 for (int i = 0; i < size; i++) 183 cmdarray[i] = (String ) list.get(i); 184 process = Runtime.getRuntime().exec(cmdarray); 185 } else { 186 if (Utilities.haveJpty()) { 188 exitValueFile = Utilities.getTempFile(); 189 FastStringBuffer sb = new FastStringBuffer(); 190 sb.append("(\\cd \""); 191 sb.append(currentDir.canonicalPath()); 192 sb.append("\" && "); 193 sb.append(expandedCommand); 194 sb.append("; echo $? > "); 195 sb.append(exitValueFile.canonicalPath()); 196 sb.append(')'); 197 final String cmd = sb.toString(); 198 String [] cmdarray = {"jpty", "/bin/sh", "-c", cmd}; 199 process = Runtime.getRuntime().exec(cmdarray); 200 } else { 201 String cmd = "(\\cd \"" + currentDir.canonicalPath() + 202 "\" && " + expandedCommand + ")"; 203 String [] cmdarray = {"/bin/sh", "-c", cmd}; 204 process = Runtime.getRuntime().exec(cmdarray); 205 } 206 } 207 } 208 catch (Throwable t) { 209 Log.error(t); 210 } 211 } 212 213 private String expandCommand(String s) 214 { 215 int length = s.length(); 216 FastStringBuffer sb = new FastStringBuffer(); 217 boolean inQuote = false; 218 for (int i = 0; i < length; i++) { 219 char c = s.charAt(i); 220 if (inQuote) { 221 sb.append(c); 222 if (c == '"') 223 inQuote = false; 224 } else { 225 if (c == '"') { 227 sb.append(c); 228 inQuote = true; 229 } else if (c == 'h') { 230 boolean replaced = false; 231 if (s.regionMatches(i, "here", 0, 4)) { 232 if (i == 0 || s.charAt(i-1) == ' ') { 234 if (i+4 == length || s.charAt(i+4) == ' ') { 235 File file = parentBuffer.getFile(); 236 if (file != null) { 237 String cp = file.canonicalPath(); 238 if (cp.indexOf(' ') >= 0) { 239 sb.append('"'); 242 sb.append(cp); 243 sb.append('"'); 244 } else 245 sb.append(cp); 246 replaced = true; 247 } 248 } 249 } 250 } 251 if (replaced) 252 i += 3; 253 else 254 sb.append(c); 255 } else 256 sb.append(c); 257 } 258 } 259 return sb.toString(); 260 } 261 262 private int getExitValueFromFile(File file) 263 { 264 int ret = -1; 265 if (file != null) { 266 try { 267 InputStream inputStream = file.getInputStream(); 268 BufferedReader reader = 269 new BufferedReader (new InputStreamReader (inputStream)); 270 String s = reader.readLine(); 271 reader.close(); 272 try { 273 ret = Integer.parseInt(s); 274 } 275 catch (NumberFormatException e) {} 276 } 277 catch (IOException e) {} 278 } 279 return ret; 280 } 281 282 public static void killCompilation() 283 { 284 for (BufferIterator it = new BufferIterator(); it.hasNext();) { 285 Buffer buf = it.nextBuffer(); 286 if (buf instanceof CompilationBuffer) { 287 ((CompilationBuffer)buf).killProcess(); 288 break; 289 } 290 } 291 } 292 293 private synchronized void killProcess() 294 { 295 if (process != null) { 296 process.destroy(); 297 try { 298 process.waitFor(); 299 process = null; 300 } 301 catch (InterruptedException e) { 302 Log.error(e); 303 } 304 } 305 } 306 307 public void dispose() 308 { 309 killProcess(); 310 } 311 312 private void appendLater(final String s) 313 { 314 Runnable runnable = new Runnable () { 315 public void run() 316 { 317 Position pos = posEndOfBuffer; 318 insertString(pos, s); 319 if (needsRenumbering()) 320 renumber(); 321 for (EditorIterator it = new EditorIterator(); it.hasNext();) { 322 Editor ed = it.nextEditor(); 323 if (ed.getBuffer() == CompilationBuffer.this) { 324 ed.eob(); 325 ed.getDisplay().setReframe(-2); 326 ed.setUpdateFlag(REPAINT); 327 ed.updateDisplay(); 328 } 329 } 330 resetUndo(); 331 } 332 }; 333 SwingUtilities.invokeLater(runnable); 334 } 335 336 public String getFileNameForDisplay() 337 { 338 return getTitle(); 339 } 340 341 public File getCurrentDirectory() 342 { 343 return currentDir; 344 } 345 346 public void setCurrentDirectory(File directory) 347 { 348 currentDir = directory; 349 } 350 351 public String toString() 353 { 354 return command; 355 } 356 357 private class CompilationBufferReaderThread extends ReaderThread 358 { 359 public CompilationBufferReaderThread(InputStream inputStream) 360 { 361 super(inputStream); 362 } 363 364 public void update(final String s) 365 { 366 appendLater(s); 367 } 368 } 369 } 370 | Popular Tags |