mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
improve build ouptut console streaming
This commit is contained in:
parent
425adf04b8
commit
6144b2233d
6 changed files with 304 additions and 277 deletions
|
@ -1,14 +1,11 @@
|
||||||
package org.eclipse.cdt.core;
|
package org.eclipse.cdt.core;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) Copyright IBM Corp. 2000, 2001.
|
* (c) Copyright IBM Corp. 2000, 2001. All Rights Reserved.
|
||||||
* All Rights Reserved.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PipedInputStream;
|
|
||||||
import java.io.PipedOutputStream;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.ProcessClosure;
|
import org.eclipse.cdt.internal.core.ProcessClosure;
|
||||||
|
@ -17,12 +14,11 @@ import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
|
|
||||||
public class CommandLauncher {
|
public class CommandLauncher {
|
||||||
|
|
||||||
public final static int COMMAND_CANCELED= 1;
|
public final static int COMMAND_CANCELED = 1;
|
||||||
public final static int ILLEGAL_COMMAND= -1;
|
public final static int ILLEGAL_COMMAND = -1;
|
||||||
public final static int OK= 0;
|
public final static int OK = 0;
|
||||||
|
|
||||||
protected Process fProcess;
|
protected Process fProcess;
|
||||||
protected boolean fShowCommand;
|
protected boolean fShowCommand;
|
||||||
|
@ -33,19 +29,18 @@ public class CommandLauncher {
|
||||||
private String lineSeparator;
|
private String lineSeparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of milliseconds to pause
|
* The number of milliseconds to pause between polling.
|
||||||
* between polling.
|
|
||||||
*/
|
*/
|
||||||
protected static final long DELAY = 50L;
|
protected static final long DELAY = 50L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new launcher
|
* Creates a new launcher Fills in stderr and stdout output to the given
|
||||||
* Fills in stderr and stdout output to the given streams.
|
* streams. Streams can be set to <code>null</code>, if output not
|
||||||
* Streams can be set to <code>null</code>, if output not required
|
* required
|
||||||
*/
|
*/
|
||||||
public CommandLauncher() {
|
public CommandLauncher() {
|
||||||
fProcess= null;
|
fProcess = null;
|
||||||
fShowCommand= false;
|
fShowCommand = false;
|
||||||
lineSeparator = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
lineSeparator = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +48,7 @@ public class CommandLauncher {
|
||||||
* Sets if the command should be printed out first before executing
|
* Sets if the command should be printed out first before executing
|
||||||
*/
|
*/
|
||||||
public void showCommand(boolean show) {
|
public void showCommand(boolean show) {
|
||||||
fShowCommand= show;
|
fShowCommand = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getErrorMessage() {
|
public String getErrorMessage() {
|
||||||
|
@ -97,12 +92,12 @@ public class CommandLauncher {
|
||||||
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory) {
|
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory) {
|
||||||
try {
|
try {
|
||||||
// add platform specific arguments (shell invocation)
|
// add platform specific arguments (shell invocation)
|
||||||
fCommandArgs= constructCommandArray(commandPath.toOSString(), args);
|
fCommandArgs = constructCommandArray(commandPath.toOSString(), args);
|
||||||
fProcess= ProcessFactory.getFactory().exec(fCommandArgs, env, changeToDirectory.toFile());
|
fProcess = ProcessFactory.getFactory().exec(fCommandArgs, env, changeToDirectory.toFile());
|
||||||
fErrorMessage= ""; //$NON-NLS-1$
|
fErrorMessage = ""; //$NON-NLS-1$
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
setErrorMessage(e.getMessage());
|
setErrorMessage(e.getMessage());
|
||||||
fProcess= null;
|
fProcess = null;
|
||||||
}
|
}
|
||||||
return fProcess;
|
return fProcess;
|
||||||
}
|
}
|
||||||
|
@ -119,16 +114,16 @@ public class CommandLauncher {
|
||||||
return ILLEGAL_COMMAND;
|
return ILLEGAL_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessClosure closure= new ProcessClosure(fProcess, out, err);
|
ProcessClosure closure = new ProcessClosure(fProcess, out, err);
|
||||||
closure.runBlocking(); // a blocking call
|
closure.runBlocking(); // a blocking call
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads output form the process to the streams. A progress monitor is polled to
|
* Reads output form the process to the streams. A progress monitor is
|
||||||
* test if the cancel button has been pressed.
|
* polled to test if the cancel button has been pressed. Destroys the
|
||||||
* Destroys the process if the monitor becomes canceled
|
* process if the monitor becomes canceled override to implement a different
|
||||||
* override to implement a different way to read the process inputs
|
* way to read the process inputs
|
||||||
*/
|
*/
|
||||||
public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) {
|
public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) {
|
||||||
if (fShowCommand) {
|
if (fShowCommand) {
|
||||||
|
@ -139,55 +134,13 @@ public class CommandLauncher {
|
||||||
return ILLEGAL_COMMAND;
|
return ILLEGAL_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
PipedOutputStream errOutPipe = new PipedOutputStream();
|
ProcessClosure closure = new ProcessClosure(fProcess, output, err);
|
||||||
PipedOutputStream outputPipe = new PipedOutputStream();
|
|
||||||
PipedInputStream errInPipe, inputPipe;
|
|
||||||
try {
|
|
||||||
errInPipe = new PipedInputStream(errOutPipe);
|
|
||||||
inputPipe = new PipedInputStream(outputPipe);
|
|
||||||
} catch( IOException e ) {
|
|
||||||
setErrorMessage(CCorePlugin.getResourceString("CommandLauncher.error.commandCanceled")); //$NON-NLS-1$
|
|
||||||
return COMMAND_CANCELED;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessClosure closure= new ProcessClosure(fProcess, outputPipe, errOutPipe);
|
|
||||||
closure.runNonBlocking();
|
closure.runNonBlocking();
|
||||||
byte buffer[] = new byte[1024];
|
|
||||||
int nbytes;
|
|
||||||
int waited = 0;
|
|
||||||
boolean flushed = false;
|
|
||||||
while (!monitor.isCanceled() && closure.isAlive()) {
|
while (!monitor.isCanceled() && closure.isAlive()) {
|
||||||
nbytes = 0;
|
|
||||||
try {
|
try {
|
||||||
if ( errInPipe.available() > 0 ) {
|
Thread.sleep(DELAY);
|
||||||
nbytes = errInPipe.read(buffer);
|
} catch (InterruptedException ie) {
|
||||||
err.write(buffer, 0, nbytes);
|
// ignore
|
||||||
}
|
|
||||||
if ( inputPipe.available() > 0 ) {
|
|
||||||
nbytes = inputPipe.read(buffer);
|
|
||||||
output.write(buffer, 0, nbytes);
|
|
||||||
}
|
|
||||||
} catch( IOException e) {
|
|
||||||
}
|
|
||||||
monitor.worked(0);
|
|
||||||
if (nbytes == 0) {
|
|
||||||
//DELAY * 10 is half a second with no new input, flush anything thats waiting
|
|
||||||
if( !flushed && waited > DELAY * 10 ){
|
|
||||||
try {
|
|
||||||
err.flush();
|
|
||||||
output.flush();
|
|
||||||
flushed = true;
|
|
||||||
} catch (IOException e1) {
|
|
||||||
}
|
|
||||||
waited = 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
waited += DELAY;
|
|
||||||
Thread.sleep(DELAY);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flushed = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,29 +156,8 @@ public class CommandLauncher {
|
||||||
try {
|
try {
|
||||||
fProcess.waitFor();
|
fProcess.waitFor();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
//System.err.println("Closure exception " +e);
|
// ignore
|
||||||
//e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain the pipes.
|
|
||||||
try {
|
|
||||||
while (errInPipe.available() > 0 || inputPipe.available() > 0) {
|
|
||||||
if ( errInPipe.available() > 0 ) {
|
|
||||||
nbytes = errInPipe.read(buffer);
|
|
||||||
err.write(buffer, 0, nbytes);
|
|
||||||
err.flush();
|
|
||||||
}
|
|
||||||
if ( inputPipe.available() > 0 ) {
|
|
||||||
nbytes = inputPipe.read(buffer);
|
|
||||||
output.write(buffer, 0, nbytes);
|
|
||||||
output.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errInPipe.close();
|
|
||||||
inputPipe.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +176,7 @@ public class CommandLauncher {
|
||||||
protected String getCommandLine(String[] commandArgs) {
|
protected String getCommandLine(String[] commandArgs) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
if (fCommandArgs != null) {
|
if (fCommandArgs != null) {
|
||||||
for (int i= 0; i < commandArgs.length; i++) {
|
for (int i = 0; i < commandArgs.length; i++) {
|
||||||
buf.append(commandArgs[i]);
|
buf.append(commandArgs[i]);
|
||||||
buf.append(' ');
|
buf.append(' ');
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,20 @@ package org.eclipse.cdt.internal.core;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundled state of a launched process including the threads linking the process in/output
|
* Bundled state of a launched process including the threads linking the process
|
||||||
* to console documents.
|
* in/output to console documents.
|
||||||
*/
|
*/
|
||||||
public class ProcessClosure {
|
public class ProcessClosure {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread which continuously reads from a input stream and pushes the read data
|
* Thread which continuously reads from a input stream and pushes the read
|
||||||
* to an output stream which is immediately flushed afterwards.
|
* data to an output stream which is immediately flushed afterwards.
|
||||||
*/
|
*/
|
||||||
protected static class ReaderThread extends Thread {
|
protected static class ReaderThread extends Thread {
|
||||||
|
|
||||||
|
@ -35,36 +32,39 @@ public class ProcessClosure {
|
||||||
*/
|
*/
|
||||||
public ReaderThread(ThreadGroup group, String name, InputStream in, OutputStream out) {
|
public ReaderThread(ThreadGroup group, String name, InputStream in, OutputStream out) {
|
||||||
super(group, name);
|
super(group, name);
|
||||||
fOutputStream= out;
|
fOutputStream = out;
|
||||||
fInputStream= in;
|
fInputStream = in;
|
||||||
setDaemon(true);
|
setDaemon(true);
|
||||||
lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
|
lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int len;
|
||||||
try {
|
try {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(fInputStream));
|
try {
|
||||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fOutputStream));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(fInputStream));
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
line += lineSeparator;
|
line += lineSeparator;
|
||||||
char[] array = line.toCharArray();
|
fOutputStream.write(line.getBytes());
|
||||||
writer.write(array, 0, array.length);
|
}
|
||||||
writer.flush();
|
} catch (IOException x) {
|
||||||
|
// ignore
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
// writer.flush();
|
||||||
|
fOutputStream.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fInputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException x) {
|
|
||||||
// ignore
|
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
|
||||||
fInputStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
fOutputStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,17 @@ public class ProcessClosure {
|
||||||
fFinished = true;
|
fFinished = true;
|
||||||
notify();
|
notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
fOutputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int fCounter= 0;
|
protected static int fCounter = 0;
|
||||||
|
|
||||||
protected Process fProcess;
|
protected Process fProcess;
|
||||||
|
|
||||||
|
@ -99,17 +107,20 @@ public class ProcessClosure {
|
||||||
protected ReaderThread fErrorReader;
|
protected ReaderThread fErrorReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a process closure and connects the launched process with
|
* Creates a process closure and connects the launched process with a
|
||||||
* a console document.
|
* console document.
|
||||||
* @param outputStream prcess stdout is written to this stream. Can be <code>null</code>, if
|
*
|
||||||
* not interested in reading the output
|
* @param outputStream
|
||||||
* @param errorStream prcess stderr is written to this stream. Can be <code>null</code>, if
|
* prcess stdout is written to this stream. Can be
|
||||||
* not interested in reading the output
|
* <code>null</code>, if not interested in reading the output
|
||||||
|
* @param errorStream
|
||||||
|
* prcess stderr is written to this stream. Can be
|
||||||
|
* <code>null</code>, if not interested in reading the output
|
||||||
*/
|
*/
|
||||||
public ProcessClosure(Process process, OutputStream outputStream, OutputStream errorStream) {
|
public ProcessClosure(Process process, OutputStream outputStream, OutputStream errorStream) {
|
||||||
fProcess= process;
|
fProcess = process;
|
||||||
fOutput= outputStream;
|
fOutput = outputStream;
|
||||||
fError= errorStream;
|
fError = errorStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,13 +128,13 @@ public class ProcessClosure {
|
||||||
* reader threads.
|
* reader threads.
|
||||||
*/
|
*/
|
||||||
public void runNonBlocking() {
|
public void runNonBlocking() {
|
||||||
ThreadGroup group= new ThreadGroup("CBuilder" + fCounter++); //$NON-NLS-1$
|
ThreadGroup group = new ThreadGroup("CBuilder" + fCounter++); //$NON-NLS-1$
|
||||||
|
|
||||||
InputStream stdin= fProcess.getInputStream();
|
InputStream stdin = fProcess.getInputStream();
|
||||||
InputStream stderr= fProcess.getErrorStream();
|
InputStream stderr = fProcess.getErrorStream();
|
||||||
|
|
||||||
fOutputReader= new ReaderThread(group, "OutputReader", stdin, fOutput); //$NON-NLS-1$
|
fOutputReader = new ReaderThread(group, "OutputReader", stdin, fOutput); //$NON-NLS-1$
|
||||||
fErrorReader= new ReaderThread(group, "ErrorReader", stderr, fError); //$NON-NLS-1$
|
fErrorReader = new ReaderThread(group, "ErrorReader", stderr, fError); //$NON-NLS-1$
|
||||||
|
|
||||||
fOutputReader.start();
|
fOutputReader.start();
|
||||||
fErrorReader.start();
|
fErrorReader.start();
|
||||||
|
@ -156,23 +167,26 @@ public class ProcessClosure {
|
||||||
fErrorReader.waitFor();
|
fErrorReader.waitFor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// it seems that thread termination and stream closing is working without
|
fOutputReader.close();
|
||||||
|
fErrorReader.close();
|
||||||
|
// it seems that thread termination and stream closing is working
|
||||||
|
// without
|
||||||
// any help
|
// any help
|
||||||
fProcess= null;
|
fProcess = null;
|
||||||
fOutputReader= null;
|
fOutputReader = null;
|
||||||
fErrorReader= null;
|
fErrorReader = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isAlive() {
|
public boolean isAlive() {
|
||||||
if (fProcess != null) {
|
if (fProcess != null) {
|
||||||
if (fOutputReader.isAlive() || fErrorReader.isAlive()) {
|
if (fOutputReader.isAlive() || fErrorReader.isAlive()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
fProcess= null;
|
|
||||||
fOutputReader= null;
|
|
||||||
fErrorReader= null;
|
|
||||||
}
|
}
|
||||||
|
fProcess = null;
|
||||||
|
fOutputReader.close();
|
||||||
|
fErrorReader.close();
|
||||||
|
fOutputReader = null;
|
||||||
|
fErrorReader = null;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +197,17 @@ public class ProcessClosure {
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
if (fProcess != null) {
|
if (fProcess != null) {
|
||||||
fProcess.destroy();
|
fProcess.destroy();
|
||||||
fProcess= null;
|
fProcess = null;
|
||||||
}
|
}
|
||||||
|
if (!fOutputReader.finished()) {
|
||||||
|
fOutputReader.waitFor();
|
||||||
|
}
|
||||||
|
if (!fErrorReader.finished()) {
|
||||||
|
fErrorReader.waitFor();
|
||||||
|
}
|
||||||
|
fOutputReader.close();
|
||||||
|
fErrorReader.close();
|
||||||
|
fOutputReader = null;
|
||||||
|
fErrorReader = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -79,37 +79,32 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
|
||||||
* front.
|
* front.
|
||||||
*/
|
*/
|
||||||
protected void showConsole() {
|
protected void showConsole() {
|
||||||
CUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
|
IWorkbenchWindow window = CUIPlugin.getActiveWorkbenchWindow();
|
||||||
|
if (window != null) {
|
||||||
public void run() {
|
IWorkbenchPage page = window.getActivePage();
|
||||||
IWorkbenchWindow window = CUIPlugin.getActiveWorkbenchWindow();
|
if (page != null) {
|
||||||
if (window != null) {
|
IViewPart consoleView = page.findView(IConsoleConstants.ID_CONSOLE_VIEW);
|
||||||
IWorkbenchPage page = window.getActivePage();
|
if (consoleView == null && BuildConsolePreferencePage.isAutoOpenConsole()) {
|
||||||
if (page != null) {
|
IWorkbenchPart activePart = page.getActivePart();
|
||||||
IViewPart consoleView = page.findView(IConsoleConstants.ID_CONSOLE_VIEW);
|
try {
|
||||||
if (consoleView == null && BuildConsolePreferencePage.isAutoOpenConsole()) {
|
consoleView = page.showView(IConsoleConstants.ID_CONSOLE_VIEW);
|
||||||
IWorkbenchPart activePart = page.getActivePart();
|
} catch (PartInitException pie) {
|
||||||
try {
|
CUIPlugin.getDefault().log(pie);
|
||||||
consoleView = page.showView(IConsoleConstants.ID_CONSOLE_VIEW);
|
}
|
||||||
} catch (PartInitException pie) {
|
//restore focus stolen by the creation of the
|
||||||
CUIPlugin.getDefault().log(pie);
|
// console
|
||||||
}
|
page.activate(activePart);
|
||||||
//restore focus stolen by the creation of the
|
} else {
|
||||||
// console
|
boolean bringToTop = shouldBringToTop(consoleView);
|
||||||
page.activate(activePart);
|
if (bringToTop) {
|
||||||
} else {
|
page.bringToTop(consoleView);
|
||||||
boolean bringToTop = shouldBringToTop(consoleView);
|
|
||||||
if (bringToTop) {
|
|
||||||
page.bringToTop(consoleView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (consoleView instanceof IConsoleView) {
|
|
||||||
((IConsoleView)consoleView).display(fConsole);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (consoleView instanceof IConsoleView) {
|
||||||
|
((IConsoleView)consoleView).display(fConsole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldBringToTop(IViewPart consoleView) {
|
boolean shouldBringToTop(IViewPart consoleView) {
|
||||||
|
@ -227,12 +222,12 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
|
||||||
}
|
}
|
||||||
|
|
||||||
public BuildConsoleStream getStream(int type) throws CoreException {
|
public BuildConsoleStream getStream(int type) throws CoreException {
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case BUILD_STREAM_TYPE_ERROR:
|
case BUILD_STREAM_TYPE_ERROR :
|
||||||
return errorStream;
|
return errorStream;
|
||||||
case BUILD_STREAM_TYPE_INFO:
|
case BUILD_STREAM_TYPE_INFO :
|
||||||
return infoStream;
|
return infoStream;
|
||||||
case BUILD_STREAM_TYPE_OUTPUT:
|
case BUILD_STREAM_TYPE_OUTPUT :
|
||||||
return outputStream;
|
return outputStream;
|
||||||
}
|
}
|
||||||
throw new CoreException(new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, -1, "No Such Console", null)); //$NON-NLS-1$
|
throw new CoreException(new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, -1, "No Such Console", null)); //$NON-NLS-1$
|
||||||
|
|
|
@ -117,20 +117,14 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
public void consoleChange(IBuildConsoleEvent event) {
|
public void consoleChange(IBuildConsoleEvent event) {
|
||||||
if (event.getType() == IBuildConsoleEvent.CONSOLE_START || event.getType() == IBuildConsoleEvent.CONSOLE_CLOSE) {
|
if (event.getType() == IBuildConsoleEvent.CONSOLE_START || event.getType() == IBuildConsoleEvent.CONSOLE_CLOSE) {
|
||||||
if (isAvailable()) {
|
if (isAvailable()) {
|
||||||
Display display = getControl().getDisplay();
|
|
||||||
if (event.getType() == IBuildConsoleEvent.CONSOLE_CLOSE && getProject() != event.getProject()) {
|
if (event.getType() == IBuildConsoleEvent.CONSOLE_CLOSE && getProject() != event.getProject()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setProject(event.getProject());
|
setProject(event.getProject());
|
||||||
display.asyncExec(new Runnable() {
|
if (isAvailable()) {
|
||||||
|
setDocument();
|
||||||
public void run() {
|
getConsole().setTitle(getProject());
|
||||||
if (isAvailable()) {
|
}
|
||||||
setDocument();
|
|
||||||
getConsole().setTitle(getProject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,14 +172,14 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
* Fill the context menu
|
* Fill the context menu
|
||||||
*
|
*
|
||||||
* @param menu
|
* @param menu
|
||||||
* menu
|
* menu
|
||||||
*/
|
*/
|
||||||
protected void contextMenuAboutToShow(IMenuManager menu) {
|
protected void contextMenuAboutToShow(IMenuManager menu) {
|
||||||
menu.add((IAction) fGlobalActions.get(ActionFactory.COPY.getId()));
|
menu.add((IAction)fGlobalActions.get(ActionFactory.COPY.getId()));
|
||||||
menu.add((IAction) fGlobalActions.get(ActionFactory.SELECT_ALL.getId()));
|
menu.add((IAction)fGlobalActions.get(ActionFactory.SELECT_ALL.getId()));
|
||||||
menu.add(new Separator("FIND")); //$NON-NLS-1$
|
menu.add(new Separator("FIND")); //$NON-NLS-1$
|
||||||
menu.add((IAction) fGlobalActions.get(ActionFactory.FIND.getId()));
|
menu.add((IAction)fGlobalActions.get(ActionFactory.FIND.getId()));
|
||||||
menu.add((IAction) fGlobalActions.get(ITextEditorActionConstants.GOTO_LINE));
|
menu.add((IAction)fGlobalActions.get(ITextEditorActionConstants.GOTO_LINE));
|
||||||
menu.add(fClearOutputAction);
|
menu.add(fClearOutputAction);
|
||||||
menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
|
menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
|
||||||
}
|
}
|
||||||
|
@ -200,7 +194,7 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
final String property = event.getProperty();
|
final String property = event.getProperty();
|
||||||
|
|
||||||
if (BuildConsole.P_STREAM_COLOR.equals(property) && source instanceof BuildConsoleStream) {
|
if (BuildConsole.P_STREAM_COLOR.equals(property) && source instanceof BuildConsoleStream) {
|
||||||
BuildConsoleStream stream = (BuildConsoleStream) source;
|
BuildConsoleStream stream = (BuildConsoleStream)source;
|
||||||
if (stream.getConsole().equals(getConsole()) && getControl() != null) {
|
if (stream.getConsole().equals(getConsole()) && getControl() != null) {
|
||||||
Display display = getControl().getDisplay();
|
Display display = getControl().getDisplay();
|
||||||
display.asyncExec(new Runnable() {
|
display.asyncExec(new Runnable() {
|
||||||
|
@ -233,8 +227,7 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
|
action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
|
||||||
action.setDisabledImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
|
action.setDisabledImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
|
||||||
ISharedImages.IMG_TOOL_COPY_DISABLED));
|
ISharedImages.IMG_TOOL_COPY_DISABLED));
|
||||||
action.setHoverImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
|
action.setHoverImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
|
||||||
ISharedImages.IMG_TOOL_COPY));
|
|
||||||
setGlobalAction(actionBars, ActionFactory.COPY.getId(), action);
|
setGlobalAction(actionBars, ActionFactory.COPY.getId(), action);
|
||||||
action = new TextViewerAction(getViewer(), ITextOperationTarget.SELECT_ALL);
|
action = new TextViewerAction(getViewer(), ITextOperationTarget.SELECT_ALL);
|
||||||
action.configureAction(ConsoleMessages.getString("BuildConsolePage.Select_&All@Ctrl+A_12"), //$NON-NLS-1$
|
action.configureAction(ConsoleMessages.getString("BuildConsolePage.Select_&All@Ctrl+A_12"), //$NON-NLS-1$
|
||||||
|
@ -255,14 +248,14 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
protected void updateSelectionDependentActions() {
|
protected void updateSelectionDependentActions() {
|
||||||
Iterator iterator = fSelectionActions.iterator();
|
Iterator iterator = fSelectionActions.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
updateAction((String) iterator.next());
|
updateAction((String)iterator.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateAction(String actionId) {
|
protected void updateAction(String actionId) {
|
||||||
IAction action = (IAction) fGlobalActions.get(actionId);
|
IAction action = (IAction)fGlobalActions.get(actionId);
|
||||||
if (action instanceof IUpdate) {
|
if (action instanceof IUpdate) {
|
||||||
((IUpdate) action).update();
|
((IUpdate)action).update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,19 +313,19 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
|
|
||||||
IProject convertSelectionToProject(ISelection selection) {
|
IProject convertSelectionToProject(ISelection selection) {
|
||||||
IProject project = null;
|
IProject project = null;
|
||||||
if (selection == null || !(selection instanceof IStructuredSelection)) {
|
if (selection == null || ! (selection instanceof IStructuredSelection)) {
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
IStructuredSelection ssel = (IStructuredSelection) selection;
|
IStructuredSelection ssel = (IStructuredSelection)selection;
|
||||||
Object element = ssel.getFirstElement();
|
Object element = ssel.getFirstElement();
|
||||||
if (element instanceof IAdaptable) {
|
if (element instanceof IAdaptable) {
|
||||||
IAdaptable input = (IAdaptable) element;
|
IAdaptable input = (IAdaptable)element;
|
||||||
if (input != null) {
|
if (input != null) {
|
||||||
IResource resource = null;
|
IResource resource = null;
|
||||||
if (input instanceof IResource) {
|
if (input instanceof IResource) {
|
||||||
resource = (IResource) input;
|
resource = (IResource)input;
|
||||||
} else {
|
} else {
|
||||||
resource = (IResource) input.getAdapter(IResource.class);
|
resource = (IResource)input.getAdapter(IResource.class);
|
||||||
}
|
}
|
||||||
if (resource != null) {
|
if (resource != null) {
|
||||||
project = resource.getProject();
|
project = resource.getProject();
|
||||||
|
@ -380,7 +373,7 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
* Sets the font for this page.
|
* Sets the font for this page.
|
||||||
*
|
*
|
||||||
* @param font
|
* @param font
|
||||||
* font
|
* font
|
||||||
*/
|
*/
|
||||||
protected void setFont(Font font) {
|
protected void setFont(Font font) {
|
||||||
getViewer().getTextWidget().setFont(font);
|
getViewer().getTextWidget().setFont(font);
|
||||||
|
@ -390,7 +383,7 @@ public class BuildConsolePage extends Page implements ISelectionListener, IPrope
|
||||||
* Sets the tab width for this page.
|
* Sets the tab width for this page.
|
||||||
*
|
*
|
||||||
* @param int
|
* @param int
|
||||||
* tab width
|
* tab width
|
||||||
*/
|
*/
|
||||||
protected void setTabs(int tabs) {
|
protected void setTabs(int tabs) {
|
||||||
getViewer().getTextWidget().setTabs(tabs);
|
getViewer().getTextWidget().setTabs(tabs);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.ConsoleOutputStream;
|
import org.eclipse.cdt.core.ConsoleOutputStream;
|
||||||
import org.eclipse.cdt.core.resources.IConsole;
|
import org.eclipse.cdt.core.resources.IConsole;
|
||||||
|
@ -30,6 +31,7 @@ import org.eclipse.jface.text.Region;
|
||||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
import org.eclipse.swt.widgets.Display;
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.ui.console.ConsolePlugin;
|
||||||
|
|
||||||
public class BuildConsolePartitioner
|
public class BuildConsolePartitioner
|
||||||
implements
|
implements
|
||||||
|
@ -54,6 +56,55 @@ public class BuildConsolePartitioner
|
||||||
boolean killed;
|
boolean killed;
|
||||||
BuildConsoleManager fManager;
|
BuildConsoleManager fManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A queue of stream entries written to standard out and standard err.
|
||||||
|
* Entries appended to the end of the queue and removed from the front.
|
||||||
|
* Intentionally a vector to obtain synchronization as entries are added and
|
||||||
|
* removed.
|
||||||
|
*/
|
||||||
|
private Vector fQueue = new Vector(5);
|
||||||
|
|
||||||
|
private boolean fAppending;
|
||||||
|
|
||||||
|
class StreamEntry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifier of the stream written to.
|
||||||
|
*/
|
||||||
|
private BuildConsoleStream fStream;
|
||||||
|
/**
|
||||||
|
* The text written
|
||||||
|
*/
|
||||||
|
private StringBuffer fText = null;
|
||||||
|
|
||||||
|
StreamEntry(String text, BuildConsoleStream stream) {
|
||||||
|
fText = new StringBuffer(text);
|
||||||
|
fStream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stream identifier
|
||||||
|
*/
|
||||||
|
public BuildConsoleStream getStream() {
|
||||||
|
return fStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendText(String text) {
|
||||||
|
fText.append(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return fText.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the text written
|
||||||
|
*/
|
||||||
|
public String getText() {
|
||||||
|
return fText.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BuildConsolePartitioner(BuildConsoleManager manager) {
|
public BuildConsolePartitioner(BuildConsoleManager manager) {
|
||||||
fManager = manager;
|
fManager = manager;
|
||||||
fMaxLines = BuildConsolePreferencePage.buildConsoleLines();
|
fMaxLines = BuildConsolePreferencePage.buildConsoleLines();
|
||||||
|
@ -71,19 +122,40 @@ public class BuildConsolePartitioner
|
||||||
* the stream to append to
|
* the stream to append to
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void appendToDocument(final String text, final BuildConsoleStream stream) {
|
public void appendToDocument(String text, BuildConsoleStream stream) {
|
||||||
if( text.length() == 0 )
|
boolean addToQueue = true;
|
||||||
return;
|
synchronized (fQueue) {
|
||||||
|
int i = fQueue.size();
|
||||||
|
if (i > 0) {
|
||||||
|
StreamEntry entry = (StreamEntry)fQueue.get(i - 1);
|
||||||
|
// if last stream is the same and we have not exceeded our
|
||||||
|
// display write limit, append.
|
||||||
|
if (entry.getStream() == stream && entry.size() < 10000) {
|
||||||
|
entry.appendText(text);
|
||||||
|
addToQueue = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addToQueue) {
|
||||||
|
fQueue.add(new StreamEntry(text, stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
Runnable r = new Runnable() {
|
Runnable r = new Runnable() {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
fLastStream = stream;
|
StreamEntry entry;
|
||||||
try {
|
try {
|
||||||
if (stream == null) {
|
entry = (StreamEntry)fQueue.remove(0);
|
||||||
fDocument.set(text);
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fLastStream = entry.getStream();
|
||||||
|
System.out.println(entry.getText().length());
|
||||||
|
try {
|
||||||
|
warnOfContentChange(fLastStream);
|
||||||
|
if (fLastStream == null) {
|
||||||
|
fDocument.set(entry.getText());
|
||||||
} else {
|
} else {
|
||||||
fDocument.replace(fDocument.getLength(), 0, text);
|
fDocument.replace(fDocument.getLength(), 0, entry.getText());
|
||||||
checkOverflow();
|
checkOverflow();
|
||||||
}
|
}
|
||||||
} catch (BadLocationException e) {
|
} catch (BadLocationException e) {
|
||||||
|
@ -91,11 +163,18 @@ public class BuildConsolePartitioner
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Display display = CUIPlugin.getStandardDisplay();
|
Display display = CUIPlugin.getStandardDisplay();
|
||||||
if (display != null) {
|
if (addToQueue && display != null) {
|
||||||
display.asyncExec(r);
|
display.asyncExec(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void warnOfContentChange(BuildConsoleStream stream) {
|
||||||
|
if (stream != null) {
|
||||||
|
ConsolePlugin.getDefault().getConsoleManager().warnOfContentChange(stream.getConsole());
|
||||||
|
}
|
||||||
|
fManager.showConsole();
|
||||||
|
}
|
||||||
|
|
||||||
public IDocument getDocument() {
|
public IDocument getDocument() {
|
||||||
return fDocument;
|
return fDocument;
|
||||||
}
|
}
|
||||||
|
@ -285,11 +364,20 @@ public class BuildConsolePartitioner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(IProject project) {
|
public void start(final IProject project) {
|
||||||
|
Display display = CUIPlugin.getStandardDisplay();
|
||||||
|
if (display != null) {
|
||||||
|
display.asyncExec(new Runnable() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
fManager.startConsoleActivity(project);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (BuildConsolePreferencePage.isClearBuildConsole()) {
|
if (BuildConsolePreferencePage.isClearBuildConsole()) {
|
||||||
appendToDocument("", null); //$NON-NLS-1$
|
appendToDocument("", null); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
fManager.startConsoleActivity(project);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BuildOutputStream extends ConsoleOutputStream {
|
public class BuildOutputStream extends ConsoleOutputStream {
|
||||||
|
@ -301,19 +389,14 @@ public class BuildConsolePartitioner
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
if( fBuffer.length() > 0 )
|
|
||||||
appendToDocument(readBuffer(), fStream);
|
|
||||||
fManager.showConsole();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void write(byte[] b, int off, int len) throws IOException {
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
super.write(b, off, len);
|
appendToDocument(new String(b, off, len), fStream);
|
||||||
if( fBuffer.length() > 4096 )
|
|
||||||
flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,8 +123,8 @@ public class BuildConsolePreferencePage extends FieldEditorPreferencePage implem
|
||||||
|
|
||||||
public static void initDefaults(IPreferenceStore prefs) {
|
public static void initDefaults(IPreferenceStore prefs) {
|
||||||
prefs.setDefault(PREF_CLEAR_CONSOLE, true);
|
prefs.setDefault(PREF_CLEAR_CONSOLE, true);
|
||||||
prefs.setDefault(PREF_AUTO_OPEN_CONSOLE, false);
|
prefs.setDefault(PREF_AUTO_OPEN_CONSOLE, true);
|
||||||
prefs.setDefault(PREF_CONSOLE_ON_TOP, true);
|
prefs.setDefault(PREF_CONSOLE_ON_TOP, false);
|
||||||
prefs.setDefault(PREF_BUILDCONSOLE_LINES, 500);
|
prefs.setDefault(PREF_BUILDCONSOLE_LINES, 500);
|
||||||
prefs.setDefault(PREF_BUILDCONSOLE_TAB_WIDTH, 4);
|
prefs.setDefault(PREF_BUILDCONSOLE_TAB_WIDTH, 4);
|
||||||
PreferenceConverter.setDefault(prefs, PREF_BUILDCONSOLE_OUTPUT_COLOR, new RGB(0, 0, 0));
|
PreferenceConverter.setDefault(prefs, PREF_BUILDCONSOLE_OUTPUT_COLOR, new RGB(0, 0, 0));
|
||||||
|
|
Loading…
Add table
Reference in a new issue