mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-02 13:55:39 +02:00
[54812] - added API for untrimmed build output
This commit is contained in:
parent
ee1e58259d
commit
e91a1c6dc9
3 changed files with 355 additions and 6 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -201,14 +201,29 @@ public class ErrorParserManager extends OutputStream {
|
||||||
if (fErrorParsers.size() == 0)
|
if (fErrorParsers.size() == 0)
|
||||||
return;
|
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
|
String lineTrimmed = line.trim();
|
||||||
if (line.length() > 1000)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (IErrorParser[] parsers : fErrorParsers.values()) {
|
for (IErrorParser[] parsers : fErrorParsers.values()) {
|
||||||
for (IErrorParser curr : parsers) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,7 +460,10 @@ public class ErrorParserManager extends OutputStream {
|
||||||
String buffer = currentLine.toString();
|
String buffer = currentLine.toString();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while ((i = buffer.indexOf('\n')) != -1) {
|
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);
|
processLine(line);
|
||||||
previousLine = line;
|
previousLine = line;
|
||||||
buffer = buffer.substring(i + 1); // skip the \n and advance
|
buffer = buffer.substring(i + 1); // skip the \n and advance
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue