1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-30 21:55:31 +02:00

[54812] - added API for untrimmed build output

This commit is contained in:
Alena Laskavaia 2008-10-23 15:37:20 +00:00
parent ee1e58259d
commit e91a1c6dc9
3 changed files with 355 additions and 6 deletions

View file

@ -0,0 +1,296 @@
/*******************************************************************************
* Copyright (c) 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.model.tests;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.IErrorParser;
import org.eclipse.cdt.core.IErrorParser2;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.ProblemMarkerInfo;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.core.internal.registry.ExtensionRegistry;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.ContributorFactoryOSGi;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
/**
* @author Alena Laskavaia
*
* Tests for ErrorParser manager and different parsers
*
*/
public class ErrorParserManagerTest extends TestCase {
IWorkspace workspace;
IWorkspaceRoot root;
NullProgressMonitor monitor;
private ICProject cProject;
private ErrorParserManager epManager;
private ArrayList<ProblemMarkerInfo> errorList;
private IMarkerGenerator markerGenerator;
/**
* Constructor for CModelTests.
* @param name
*/
public ErrorParserManagerTest(String name) {
super(name);
}
/**
* Sets up the test fixture.
*
* Called before every test case method.
*
* Example code test the packages in the project
* "com.qnx.tools.ide.cdt.core"
*/
protected void setUp() throws Exception {
/***
* The test of the tests assume that they have a working workspace
* and workspace root object to use to create projects/files in,
* so we need to get them setup first.
*/
IWorkspaceDescription desc;
workspace = ResourcesPlugin.getWorkspace();
root = workspace.getRoot();
monitor = new NullProgressMonitor();
if (workspace == null)
fail("Workspace was not setup");
if (root == null)
fail("Workspace root was not setup");
desc = workspace.getDescription();
desc.setAutoBuilding(false);
workspace.setDescription(desc);
errorList = new ArrayList<ProblemMarkerInfo>();
cProject = createProject("errorparsersanity");
markerGenerator = new IMarkerGenerator() {
public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) {
// Obsolete
}
public void addMarker(ProblemMarkerInfo problemMarkerInfo) {
errorList.add(problemMarkerInfo);
}
};
epManager = new ErrorParserManager(cProject.getProject(), markerGenerator, null);
}
/**
* Tears down the test fixture.
*
* Called after every test case method.
*/
protected void tearDown() {
// release resources here and clean-up
}
public static TestSuite suite() {
return new TestSuite(ErrorParserManagerTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
private ICProject createProject(String name) throws CoreException {
ICProject testProject;
testProject = CProjectHelper.createCProject(name, "none", IPDOMManager.ID_NO_INDEXER);
if (testProject == null) {
fail("Unable to create project");
}
return testProject;
}
private void output(String line) throws IOException {
epManager.write(line.getBytes(), 0, line.length());
}
private void end() throws IOException {
epManager.getOutputStream();
epManager.close();
epManager.reportProblems();
}
public void testParsersSanity() throws CoreException, IOException {
output("catchpoints.cpp:12: warning: no return statement in function returning non-void\n");
end();
assertEquals(1, errorList.size());
ProblemMarkerInfo problemMarkerInfo = errorList.get(0);
assertEquals("catchpoints.cpp no return statement in function returning non-void",problemMarkerInfo.description);
}
public void testParsersSanityTrimmed() throws CoreException, IOException {
output(" catchpoints.cpp:12: warning: no return statement in function returning non-void \n");
end();
assertEquals(1, errorList.size());
ProblemMarkerInfo problemMarkerInfo = errorList.get(0);
assertEquals("catchpoints.cpp no return statement in function returning non-void",problemMarkerInfo.description);
}
public void testOutput() throws IOException {
FileInputStream fileInputStream = new FileInputStream(CTestPlugin.getDefault().getFileInPlugin(
new Path("resources/errortests/output-1")));
byte b[] = new byte[1024];
while (true) {
int k = fileInputStream.read(b);
if (k < 0)
break;
epManager.write(b, 0, k);
}
end();
assertEquals(19, errorList.size());
}
private String addErrorParserExtension(String shortId, Class cl) {
String ext = "<plugin><extension id=\"" + shortId + "\" name=\"" + shortId
+ "\" point=\"org.eclipse.cdt.core.ErrorParser\">" + "<errorparser class=\"" + cl.getName() + "\"/>"
+ "</extension></plugin>";
IContributor contributor = ContributorFactoryOSGi.createContributor(CTestPlugin.getDefault().getBundle());
boolean added = Platform.getExtensionRegistry().addContribution(new ByteArrayInputStream(ext.getBytes()),
contributor, false, shortId, null,
((ExtensionRegistry) Platform.getExtensionRegistry()).getTemporaryUserToken());
assertTrue("failed to add extension", added);
String fullId = "org.eclipse.cdt.core.tests." + shortId;
IErrorParser[] errorParser = CCorePlugin.getDefault().getErrorParser(fullId);
assertTrue(errorParser.length > 0);
return fullId;
}
public static class TestParser1 implements IErrorParser2 {
String last = null;
public int getProcessLineBehaviour() {
return KEEP_UNTRIMMED;
}
public boolean processLine(String line, ErrorParserManager eoParser) {
if (line.startsWith(" ") && last!=null) {
eoParser.generateExternalMarker(null, 1, last+line, 1, "", null);
return true;
}
if (line.startsWith("bug:")) {
last = line;
return true;
} else {
last = null;
}
return false;
}
}
public void testNoTrimParser() throws IOException {
String id = addErrorParserExtension("test1", TestParser1.class);
epManager = new ErrorParserManager(cProject.getProject(), markerGenerator, new String[] { id });
output("bug: start\n");
output(" end");
end();
assertEquals(1, errorList.size());
ProblemMarkerInfo problemMarkerInfo = errorList.get(0);
assertEquals("bug: start end",problemMarkerInfo.description);
}
public static class TestParser2 implements IErrorParser2 {
public int getProcessLineBehaviour() {
return KEEP_LONGLINES;
}
public boolean processLine(String line, ErrorParserManager eoParser) {
if (line.startsWith("errorT: ")) {
eoParser.generateExternalMarker(null, 1, line, 1, "", null);
return true;
}
return false;
}
}
public void testLongLinesParser() throws IOException {
String id = addErrorParserExtension("test2", TestParser2.class);
epManager = new ErrorParserManager(cProject.getProject(), markerGenerator, new String[] { id });
StringBuffer buf = new StringBuffer("errorT: ");
for (int i = 0; i < 100; i++) {
buf.append("la la la la la "+i+" ");
}
output(buf.toString()+"\n");
end();
assertEquals(1, errorList.size());
ProblemMarkerInfo problemMarkerInfo = errorList.get(0);
int l = problemMarkerInfo.description.length();
assertTrue(l>1000);
String end = problemMarkerInfo.description.substring(l-10,l);
// check - line trimmed but long
assertEquals("a la la 99",end);
}
public static class TestParser3 implements IErrorParser2 {
public int getProcessLineBehaviour() {
return KEEP_LONGLINES | KEEP_UNTRIMMED;
}
public boolean processLine(String line, ErrorParserManager eoParser) {
if (line.startsWith("errorT: ")) {
eoParser.generateExternalMarker(null, 1, line, 1, "", null);
return true;
}
return false;
}
}
public void testLongLinesUntrimmedParser() throws IOException {
String id = addErrorParserExtension("test3", TestParser3.class);
epManager = new ErrorParserManager(cProject.getProject(), markerGenerator, new String[] { id });
StringBuffer buf = new StringBuffer("errorT: ");
for (int i = 0; i < 100; i++) {
buf.append("la la la la la "+i+" ");
}
output(buf.toString()+"\n");
end();
assertEquals(1, errorList.size());
ProblemMarkerInfo problemMarkerInfo = errorList.get(0);
int l = problemMarkerInfo.description.length();
assertTrue(l>1000);
String end = problemMarkerInfo.description.substring(l-10,l);
// check - line trimmed but long
assertEquals(" la la 99 ",end);
}
}

View file

@ -201,14 +201,29 @@ public class ErrorParserManager extends OutputStream {
if (fErrorParsers.size() == 0)
return;
// If the line is too long, it is most likely a command line and not an error message
// Don't process it since it'll probably be really slow and won't find an error anyway
if (line.length() > 1000)
return;
String lineTrimmed = line.trim();
for (IErrorParser[] parsers : fErrorParsers.values()) {
for (IErrorParser curr : parsers) {
if (curr.processLine(line, this)) {
int types = IErrorParser2.NONE;
if (curr instanceof IErrorParser2) {
types = ((IErrorParser2) curr).getProcessLineBehaviour();
}
if ((types & IErrorParser2.KEEP_LONGLINES) == 0) {
// long lines are not given to parsers, unless it wants it
if (lineTrimmed.length() > 1000)
continue;
}
if ((types & IErrorParser2.KEEP_UNTRIMMED) !=0 ) {
// untrimmed lines
if (curr.processLine(line, this)) {
return;
}
continue;
}
// standard behavior (pre 5.1)
if (curr.processLine(lineTrimmed, this)) {
return;
}
}
@ -445,7 +460,10 @@ public class ErrorParserManager extends OutputStream {
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
String line = buffer.substring(0, i);
// get rid of any trailing '\r'
if (line.endsWith("\r")) //$NON-NLS-1$
line=line.substring(0,line.length()-1);
processLine(line);
previousLine = line;
buffer = buffer.substring(i + 1); // skip the \n and advance

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2008 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core;
/**
* Interface to provide flexibility for error parsers to parse unprocessed build output
*
* @since 5.1
*/
public interface IErrorParser2 extends IErrorParser {
/** Default behavior, lines are trimmed and cut by EOL and less or equal 1000 chars */
public static final int NONE = 0x0;
/** Do not trim output line */
public static final int KEEP_UNTRIMMED = 0x01;
/** Parser can process lines with unlimited length (default length is 1000) */
public static final int KEEP_LONGLINES = 0x04;
/**
* Defines how much output would be processed before calling {@link #processLine(String, ErrorParserManager)}
*
* @return combination of flags that describe parser expectations of input line
* @see #KEEP_UNTRIMMED
* @see #KEEP_LONGLINES
* */
int getProcessLineBehaviour();
}