diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ErrorParserManagerTest.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ErrorParserManagerTest.java new file mode 100644 index 00000000000..babeebb87b7 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ErrorParserManagerTest.java @@ -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 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(); + 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 = "" + "" + + ""; + 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); + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java index 9fb2f962998..c6c49be890c 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java @@ -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 diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IErrorParser2.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IErrorParser2.java new file mode 100644 index 00000000000..cab5d63cf51 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IErrorParser2.java @@ -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(); +}