From 91dba9031a05af2bb035db9d49ded895d011c2f1 Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Sat, 28 May 2011 05:17:34 +0000 Subject: [PATCH] bug 347534: CWD Locator misinforms ErrorParserManager in case of parallel builds done with -j option --- .../tests/ErrorParserFileMatchingTest.java | 212 +++++++++++++++++- .../cdt/internal/errorparsers/CWDLocator.java | 74 ++++-- 2 files changed, 258 insertions(+), 28 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java index 0f807293351..99a8b84f4bf 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java @@ -44,7 +44,7 @@ import org.eclipse.core.runtime.Platform; * properly locate and resolve filenames found in build output. */ public class ErrorParserFileMatchingTest extends TestCase { - private static final String MAKE_ERRORPARSER_ID = "org.eclipse.cdt.core.CWDLocator"; + private static final String CWD_LOCATOR_ID = "org.eclipse.cdt.core.CWDLocator"; private String mockErrorParserId = null; private final static String testName = "FindMatchingFilesTest"; @@ -1024,7 +1024,7 @@ public class ErrorParserFileMatchingTest extends TestCase { String lines = "make[0]: Entering directory `dir'\n" + cygwinFileName+":1:error\n"; - String[] errorParsers = {MAKE_ERRORPARSER_ID, mockErrorParserId }; + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; parseOutput(fProject, fProject.getLocation(), errorParsers, lines); assertEquals(1, errorList.size()); @@ -1139,7 +1139,7 @@ public class ErrorParserFileMatchingTest extends TestCase { String lines = "make[0]: Entering directory `Folder'\n" + fileName+":1:error\n"; - String[] errorParsers = {MAKE_ERRORPARSER_ID, mockErrorParserId }; + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; parseOutput(fProject, fProject.getLocation(), errorParsers, lines); assertEquals(1, errorList.size()); @@ -1166,7 +1166,7 @@ public class ErrorParserFileMatchingTest extends TestCase { String lines = "make[0]: Entering directory `" + absoluteDir + "'\n" + fileName+":1:error\n"; - String[] errorParsers = {MAKE_ERRORPARSER_ID, mockErrorParserId }; + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; parseOutput(fProject, fProject.getLocation(), errorParsers, lines); assertEquals(1, errorList.size()); @@ -1196,7 +1196,7 @@ public class ErrorParserFileMatchingTest extends TestCase { + "make[2]: Leaving directory `SubFolder'\n" + fileName+":1:error\n"; - String[] errorParsers = {MAKE_ERRORPARSER_ID, mockErrorParserId }; + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; parseOutput(fProject, fProject.getLocation(), errorParsers, lines); assertEquals(1, errorList.size()); @@ -1221,7 +1221,7 @@ public class ErrorParserFileMatchingTest extends TestCase { + "make[0]: Entering directory `Folder'\n" + fileName+":1:error\n"; - String[] errorParsers = {MAKE_ERRORPARSER_ID, mockErrorParserId }; + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; parseOutput(fProject, fProject.getLocation(), errorParsers, lines); assertEquals(2, errorList.size()); @@ -1240,6 +1240,206 @@ public class ErrorParserFileMatchingTest extends TestCase { } } + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_J() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make -j\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_J2() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make -j2\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_J_2() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make -j 2\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_J1() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make -j1\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/Folder/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_J_1() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make -j 1\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/Folder/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_Jobs() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make --jobs=2\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_Jobs1() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "make --jobs=1\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/Folder/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + + /** + * Checks if a file from error output can be found. + * + * @throws Exception... + */ + public void testDisablePushDirectoryOnParallelBuild_gmake() throws Exception { + String fileName = getName()+".c"; + ResourceHelper.createFolder(fProject, "Folder"); + ResourceHelper.createFile(fProject, fileName); + ResourceHelper.createFile(fProject, "Folder/"+fileName); + + String lines = "gmake384 -k -j all\n" + + "make[0]: Entering directory `Folder'\n" + + fileName+":1:error\n"; + + String[] errorParsers = {CWD_LOCATOR_ID, mockErrorParserId }; + parseOutput(fProject, fProject.getLocation(), errorParsers, lines); + assertEquals(1, errorList.size()); + + ProblemMarkerInfo problemMarkerInfo = errorList.get(0); + assertEquals("L/FindMatchingFilesTest/"+fileName,problemMarkerInfo.file.toString()); + assertEquals(1,problemMarkerInfo.lineNumber); + assertEquals("error",problemMarkerInfo.description); + } + /** * Checks if a file from error output can be found. * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/CWDLocator.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/CWDLocator.java index 7b954bde46f..e1324c82e04 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/CWDLocator.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/errorparsers/CWDLocator.java @@ -23,39 +23,69 @@ import org.eclipse.core.runtime.Path; * {@link ErrorParserManager}. The intention is to handle make output of commands "pushd" and "popd". */ public class CWDLocator extends AbstractErrorParser { + private static boolean enabled = true; + + @Override + public boolean processLine(String line, ErrorParserManager manager) { + int lineNumber = manager.getLineCounter(); + // enable on first line (can be previously disabled if processed parallel build) + if (lineNumber==1) + enabled = true; + + if (enabled) + return super.processLine(line, manager); + return false; + } + private static final ErrorPattern[] patterns = { - new ErrorPattern("make\\[(.*)\\]: Entering directory `(.*)'", 0, 0) { //$NON-NLS-1$ - @Override - protected boolean recordError(Matcher matcher, ErrorParserManager eoParser) { - int level; - try { - level = Integer.valueOf(matcher.group(1)).intValue(); - } catch (NumberFormatException e) { - level = 0; - } - String dir = matcher.group(2); - /* - * Sometimes make screws up the output, so "leave" events can't be seen. Double-check - * level here. - */ + // parallel build makes interleaved output and so this parser useless + // turn it off in that case + new ErrorPattern("^\\w*make.*\\s((-j)|(--jobs=))(\\s*\\d*)", 0, 0) { //$NON-NLS-1$ + @Override + protected boolean recordError(Matcher matcher, ErrorParserManager eoParser) { + String jobs = matcher.group(4).trim(); + if (!jobs.equals("1")) { //$NON-NLS-1$ + enabled = false; int parseLevel = eoParser.getDirectoryLevel(); - for (; level < parseLevel; level++) { + for (int level=0; level < parseLevel; level++) { eoParser.popDirectoryURI(); } - eoParser.pushDirectory(new Path(dir)); - return true; } - }, new ErrorPattern("make\\[.*\\]: Leaving directory", 0, 0) { //$NON-NLS-1$ - @Override - protected boolean recordError(Matcher matcher, ErrorParserManager eoParser) { + return false; + } + }, new ErrorPattern("make\\[(.*)\\]: Entering directory `(.*)'", 0, 0) { //$NON-NLS-1$ + @Override + protected boolean recordError(Matcher matcher, ErrorParserManager eoParser) { + int level; + try { + level = Integer.valueOf(matcher.group(1)).intValue(); + } catch (NumberFormatException e) { + level = 0; + } + String dir = matcher.group(2); + /* + * Sometimes make screws up the output, so "leave" events can't be seen. Double-check + * level here. + */ + int parseLevel = eoParser.getDirectoryLevel(); + for (; level < parseLevel; level++) { eoParser.popDirectoryURI(); - return true; } - }, + eoParser.pushDirectory(new Path(dir)); + return true; + } + }, new ErrorPattern("make\\[.*\\]: Leaving directory", 0, 0) { //$NON-NLS-1$ + @Override + protected boolean recordError(Matcher matcher, ErrorParserManager eoParser) { + eoParser.popDirectoryURI(); + return true; + } + }, }; public CWDLocator() { super(patterns); + enabled = true; } }