1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Fix for 75327 ScannerInfo incorrecly parses ScannerInfoProvider command data streams.

Original patch from Brad Jarvinen (Brad.Jarvinen@palmsource.com) with slight modifications.
This commit is contained in:
Vladimir Hirsl 2004-10-22 20:34:08 +00:00
parent f7fa7bf98f
commit 41c98b2b5b
5 changed files with 215 additions and 140 deletions

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.make.internal.core.MakeMessages;
import org.eclipse.cdt.make.internal.core.StreamMonitor;
import org.eclipse.cdt.make.internal.core.scannerconfig.ConsoleOutputSniffer;
import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IMarker;
@ -187,19 +188,21 @@ public class MakeBuilder extends ACBuilder {
OutputStream stdout = epm.getOutputStream();
OutputStream stderr = epm.getOutputStream();
// Sniff console output for scanner info
OutputStream sniffer = ScannerInfoConsoleParserFactory.getMakeBuilderOutputSniffer(
epm.getOutputStream(), getProject(), workingDirectory, this);
ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getMakeBuilderOutputSniffer(
stdout, stderr, getProject(), workingDirectory, this);
OutputStream consoleOut = (sniffer == null ? stdout : sniffer.getOutputStream());
OutputStream consoleErr = (sniffer == null ? stderr : sniffer.getErrorStream());
Process p = launcher.execute(buildCommand, buildArguments, env, workingDirectory);
if (p != null) {
try {
// Close the input of the Process explicitely.
// Close the input of the Process explicitly.
// We will never write to it.
p.getOutputStream().close();
} catch (IOException e) {
}
// Before launching give visual cues via the monitor
monitor.subTask(MakeMessages.getString("MakeBuilder.Invoking_Command") + launcher.getCommandLine()); //$NON-NLS-1$
if (launcher.waitAndRead(sniffer, sniffer, new SubProgressMonitor(monitor, 0))
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0))
!= CommandLauncher.OK)
errMsg = launcher.getErrorMessage();
monitor.subTask(MakeMessages.getString("MakeBuilder.Updating_project")); //$NON-NLS-1$
@ -235,7 +238,8 @@ public class MakeBuilder extends ACBuilder {
stderr.close();
monitor.subTask(MakeMessages.getString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$
sniffer.close();
consoleOut.close();
consoleErr.close();
epm.reportProblems();
cos.close();
}

View file

@ -0,0 +1,181 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.make.internal.core.scannerconfig;
import java.io.IOException;
import java.io.OutputStream;
import org.eclipse.cdt.make.core.scannerconfig.*;
/**
* Intercepts an output to console and forwards it to line parsers for processing
*
* @author vhirsl
*/
public class ConsoleOutputSniffer {
/*
* Private class to sniffer the output stream for this snifffer.
*/
private class ConsoleOutputStream extends OutputStream {
// Stream's private buffer for the stream's read contents.
private StringBuffer currentLine = new StringBuffer();
private OutputStream outputStream = null;
/**
* @param consoleErrorStream
*/
public ConsoleOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException {
currentLine.append((char) b);
checkLine(false);
// Continue writing the bytes to the console's output.
if (outputStream != null) {
outputStream.write(b);
}
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off != 0 || (len < 0) || (len > b.length)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
currentLine.append(new String(b, 0, len));
checkLine(false);
// Continue writing the bytes to the console's output.
if (outputStream != null)
outputStream.write(b, off, len);
}
/* (non-Javadoc)
* @see java.io.OutputStream#close()
*/
public void close() throws IOException {
checkLine(true);
closeConsoleOutputStream();
}
/* (non-Javadoc)
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException {
if (outputStream != null) {
outputStream.flush();
}
}
/*
* Checks to see if the already read input constitutes
* a complete line (e.g. does the sniffing). If so, then
* send it to processLine.
*
* @param flush
*/
private void checkLine(boolean flush) {
String buffer = currentLine.toString();
int i = 0;
while ((i = buffer.indexOf('\n')) != -1) {
String line = buffer.substring(0, i).trim(); // get rid of any trailing \r
if (line.length() > 0)
processLine(line);
buffer = buffer.substring(i + 1); // skip the \n and advance
}
currentLine.setLength(0);
if (flush) {
if (buffer.length() > 0) {
processLine(buffer);
}
} else {
currentLine.append(buffer);
}
}
} // end ConsoleOutputStream class
private int nOpens = 0;
private OutputStream consoleOutputStream;
private OutputStream consoleErrorStream;
private IScannerInfoConsoleParser[] parsers;
public ConsoleOutputSniffer(IScannerInfoConsoleParser[] parsers) {
this.parsers = parsers;
}
public ConsoleOutputSniffer(OutputStream outputStream, OutputStream errorStream, IScannerInfoConsoleParser[] parsers) {
this(parsers);
this.consoleOutputStream = outputStream;
this.consoleErrorStream = errorStream;
}
/**
* Returns an output stream that will be sniffed.
* This stream should be hooked up so the command
* output stream goes into here.
*
* @return
*/
public OutputStream getOutputStream() {
incNOpens();
return new ConsoleOutputStream(consoleOutputStream);
}
/**
* Returns an error stream that will be sniffed.
* This stream should be hooked up so the command
* error stream goes into here.
*
* @return
*/
public OutputStream getErrorStream() {
incNOpens();
return new ConsoleOutputStream(consoleErrorStream);
}
private synchronized void incNOpens() {
nOpens++;
}
/*
*/
public synchronized void closeConsoleOutputStream() throws IOException {
if (nOpens > 0 && --nOpens == 0) {
for (int i = 0; i < parsers.length; ++i) {
parsers[i].shutdown();
}
}
}
/*
* Processes the line by passing the line to the parsers.
*
* @param line
*/
private synchronized void processLine(String line) {
for (int i = 0; i < parsers.length; ++i) {
parsers[i].processLine(line);
}
}
}

View file

@ -1,117 +0,0 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.make.internal.core.scannerconfig;
import java.io.IOException;
import java.io.OutputStream;
import org.eclipse.cdt.make.core.scannerconfig.*;
/**
* Intercepts an output to console and forwards it to line parsers for processing
*
* @author vhirsl
*/
public class ConsoleOutputStreamSniffer extends OutputStream {
private StringBuffer currentLine = new StringBuffer();
private OutputStream outputStream;
private int nOpens = 0;
private IScannerInfoConsoleParser[] parsers;
public ConsoleOutputStreamSniffer(IScannerInfoConsoleParser[] parsers) {
this.parsers = parsers;
}
public ConsoleOutputStreamSniffer(OutputStream outputStream, IScannerInfoConsoleParser[] parsers) {
this(parsers);
nOpens = 1;
this.outputStream = outputStream;
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(int)
*/
public void write(int b) throws IOException {
currentLine.append((char) b);
checkLine(false);
if (outputStream != null) {
outputStream.write(b);
}
}
/**
* @param flush
*/
private void checkLine(boolean flush) {
String buffer = currentLine.toString();
int i = 0;
while ((i = buffer.indexOf('\n')) != -1) {
String line = buffer.substring(0, i).trim(); // get rid of any trailing \r
processLine(line);
buffer = buffer.substring(i + 1); // skip the \n and advance
}
currentLine.setLength(0);
if (flush) {
if (buffer.length() > 0) {
processLine(buffer);
}
} else {
currentLine.append(buffer);
}
}
/**
* @param line
*/
private void processLine(String line) {
for (int i = 0; i < parsers.length; ++i) {
parsers[i].processLine(line);
}
}
/* (non-Javadoc)
* @see java.io.OutputStream#close()
*/
public void close() throws IOException {
if (nOpens > 0 && --nOpens == 0) {
checkLine(true);
if (outputStream != null)
outputStream.close();
}
for (int i = 0; i < parsers.length; ++i) {
parsers[i].shutdown();
}
}
/* (non-Javadoc)
* @see java.io.OutputStream#flush()
*/
public void flush() throws IOException {
if (outputStream != null) {
outputStream.flush();
}
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off != 0 || (len < 0) || (len > b.length)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
currentLine.append(new String(b, 0, len));
checkLine(false);
if (outputStream != null)
outputStream.write(b, off, len);
}
}

View file

@ -103,8 +103,10 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP
+ fCompileCommand.toString() + ca);
cos = new StreamMonitor(new SubProgressMonitor(monitor, 70), cos, 100);
OutputStream sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer(
cos, currentProject, buildInfo, collector);
ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer(
cos, cos, currentProject, buildInfo, collector);
OutputStream consoleOut = (sniffer == null ? cos : sniffer.getOutputStream());
OutputStream consoleErr = (sniffer == null ? cos : sniffer.getErrorStream());
TraceUtil.outputTrace("Default provider is executing command:", fCompileCommand.toString() + ca, ""); //$NON-NLS-1$ //$NON-NLS-2$
Process p = launcher.execute(fCompileCommand, compileArguments, setEnvironment(launcher), fWorkingDirectory);
if (p != null) {
@ -114,7 +116,7 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP
p.getOutputStream().close();
} catch (IOException e) {
}
if (launcher.waitAndRead(sniffer, sniffer, new SubProgressMonitor(monitor, 0)) != CommandLauncher.OK) {
if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != CommandLauncher.OK) {
errMsg = launcher.getErrorMessage();
}
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Parsing_Output")); //$NON-NLS-1$
@ -130,7 +132,8 @@ public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoP
}
monitor.subTask(MakeMessages.getString("ExternalScannerInfoProvider.Creating_Markers")); //$NON-NLS-1$
sniffer.close();
consoleOut.close();
consoleErr.close();
cos.close();
}
catch (Exception e) {

View file

@ -41,12 +41,14 @@ public class ScannerInfoConsoleParserFactory {
* @param markerGenerator
* @param scBuildInfo
* @param collector - scanner info collector
* @return OutputStream
* @return ConsoleOutputSniffer
*/
public static OutputStream getESIProviderOutputSniffer(OutputStream outputStream,
IProject currentProject,
IScannerConfigBuilderInfo scBuildInfo,
IScannerInfoCollector collector) {
public static ConsoleOutputSniffer getESIProviderOutputSniffer(
OutputStream outputStream,
OutputStream errorStream,
IProject currentProject,
IScannerConfigBuilderInfo scBuildInfo,
IScannerInfoCollector collector) {
if (scBuildInfo.isESIProviderCommandEnabled()) {
// get the ESIProvider console parser
IScannerInfoConsoleParser clParser = MakeCorePlugin.getDefault().
@ -55,10 +57,10 @@ public class ScannerInfoConsoleParserFactory {
clParser.startup(currentProject, null /*new ScannerInfoConsoleParserUtility(
currentProject, null, markerGenerator)*/, collector);
// create an output stream sniffer
return new ConsoleOutputStreamSniffer(outputStream, new
return new ConsoleOutputSniffer(outputStream, errorStream, new
IScannerInfoConsoleParser[] {clParser});
}
return outputStream;
return null;
}
/**
@ -69,12 +71,14 @@ public class ScannerInfoConsoleParserFactory {
* @param currentProject
* @param workingDirectory
* @param markerGenerator
* @return OutputStream
* @return ConsoleOutputSniffer
*/
public static OutputStream getMakeBuilderOutputSniffer(OutputStream outputStream,
IProject currentProject,
IPath workingDirectory,
IMarkerGenerator markerGenerator) {
public static ConsoleOutputSniffer getMakeBuilderOutputSniffer(
OutputStream outputStream,
OutputStream errorStream,
IProject currentProject,
IPath workingDirectory,
IMarkerGenerator markerGenerator) {
try {
// get the SC builder settings
if (currentProject.hasNature(ScannerConfigNature.NATURE_ID)) {
@ -99,7 +103,7 @@ public class ScannerInfoConsoleParserFactory {
scBuildInfo.isSIProblemGenerationEnabled() ? markerGenerator : null),
ScannerInfoCollector.getInstance());
// create an output stream sniffer
return new ConsoleOutputStreamSniffer(outputStream, new
return new ConsoleOutputSniffer(outputStream, errorStream, new
IScannerInfoConsoleParser[] {clParser});
}
}
@ -107,6 +111,6 @@ public class ScannerInfoConsoleParserFactory {
catch (CoreException e) {
MakeCorePlugin.log(e.getStatus());
}
return outputStream;
return null;
}
}