From 5d7f9bf0157cc03848276b92bdbbcbb5b2ef3a11 Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Fri, 28 Oct 2011 23:17:52 -0400 Subject: [PATCH] AbstractBuiltinSpecsDetector as IResourceChangeListener --- ...anguageSettingsProvidersMakeCoreTests.java | 1 + .../BuiltinSpecsDetectorTest.java | 419 ++++++++++ .../AbstractBuildCommandParser.java | 63 ++ .../AbstractBuiltinSpecsDetector.java | 583 +++++++++----- ...AbstractLanguageSettingsOutputScanner.java | 22 +- .../scannerconfig/GCCBuildCommandParser.java | 5 +- .../GCCBuildCommandParserOptionPage.java | 147 ---- .../BuiltinSpecsDetectorOptionPage.java | 66 +- .../tests/GCCBuiltinSpecsDetectorTest.java | 718 +++++------------- .../core/ExternalBuildRunner.java | 21 +- .../core/InternalBuildRunner.java | 9 +- .../core/ManagedBuildManager.java | 52 -- .../GCCBuiltinSpecsDetector.java | 10 +- .../ToolchainBuiltinSpecsDetector.java | 81 ++ .../LanguageSettingsSerializable.java | 22 +- .../internal/core/ConsoleOutputSniffer.java | 11 +- .../xlc/core/XlcBuiltinSpecsDetector.java | 4 +- 17 files changed, 1185 insertions(+), 1049 deletions(-) create mode 100644 build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/BuiltinSpecsDetectorTest.java create mode 100644 build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/scannerconfig/ToolchainBuiltinSpecsDetector.java diff --git a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllLanguageSettingsProvidersMakeCoreTests.java b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllLanguageSettingsProvidersMakeCoreTests.java index a681fc24fd4..511adb8428f 100644 --- a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllLanguageSettingsProvidersMakeCoreTests.java +++ b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllLanguageSettingsProvidersMakeCoreTests.java @@ -22,5 +22,6 @@ public class AllLanguageSettingsProvidersMakeCoreTests extends TestSuite { super(AllLanguageSettingsProvidersMakeCoreTests.class.getName()); addTestSuite(GCCBuildCommandParserTest.class); + addTestSuite(BuiltinSpecsDetectorTest.class); } } diff --git a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/BuiltinSpecsDetectorTest.java b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/BuiltinSpecsDetectorTest.java new file mode 100644 index 00000000000..a33e47724a3 --- /dev/null +++ b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/BuiltinSpecsDetectorTest.java @@ -0,0 +1,419 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Andrew Gvozdev 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: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ + package org.eclipse.cdt.make.scannerdiscovery; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.settings.model.CIncludeFileEntry; +import org.eclipse.cdt.core.settings.model.CIncludePathEntry; +import org.eclipse.cdt.core.settings.model.CLibraryFileEntry; +import org.eclipse.cdt.core.settings.model.CLibraryPathEntry; +import org.eclipse.cdt.core.settings.model.CMacroEntry; +import org.eclipse.cdt.core.settings.model.CMacroFileEntry; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; +import org.eclipse.cdt.core.settings.model.ICSettingEntry; +import org.eclipse.cdt.core.testplugin.ResourceHelper; +import org.eclipse.cdt.internal.core.XmlUtil; +import org.eclipse.cdt.make.core.scannerconfig.AbstractBuiltinSpecsDetector; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class BuiltinSpecsDetectorTest extends TestCase { + private static final String PROVIDER_ID = "provider.id"; + private static final String PROVIDER_NAME = "provider name"; + private static final String LANGUAGE_ID = "language.test.id"; + private static final String CUSTOM_PARAMETER = "customParameter"; + private static final String ELEM_TEST = "test"; + + // those attributes must match that in AbstractBuiltinSpecsDetector + private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$ + + private class MockBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector { + @Override + protected void startupForLanguage(String languageId) throws CoreException { + super.startupForLanguage(languageId); + } + @Override + protected void shutdownForLanguage() { + super.shutdownForLanguage(); + } + @Override + protected List parseForOptions(String line) { + return null; + } + @Override + protected AbstractOptionParser[] getOptionParsers() { + return null; + } + } + + private class MockBuiltinSpecsDetectorExecutedFlag extends AbstractBuiltinSpecsDetector { + @Override + protected List parseForOptions(String line) { + return null; + } + @Override + protected AbstractOptionParser[] getOptionParsers() { + return null; + } + @Override + protected void execute() { + super.execute(); + } + protected boolean isExecuted() { + return isExecuted; + } + } + + private class MockConsoleBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector { + @SuppressWarnings("nls") + private final AbstractOptionParser[] optionParsers = { + new MacroOptionParser("#define (\\S*) *(\\S*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), + }; + @Override + protected boolean runProgram(String command, String[] env, IPath workingDirectory, IProgressMonitor monitor, + OutputStream consoleOut, OutputStream consoleErr) throws CoreException, IOException { + printLine(consoleOut, "#define MACRO VALUE"); + consoleOut.close(); + consoleErr.close(); + return true; + } + @Override + protected IStatus runForEachLanguage(ICConfigurationDescription cfgDescription, IPath workingDirectory, + String[] env, IProgressMonitor monitor) { + return super.runForEachLanguage(cfgDescription, workingDirectory, env, monitor); + } + @Override + protected List parseForOptions(final String line) { + return new ArrayList() {{ add(line); }}; + } + @Override + protected AbstractOptionParser[] getOptionParsers() { + return optionParsers; + } + } + + @Override + protected void setUp() throws Exception { + } + + @Override + protected void tearDown() throws Exception { + ResourceHelper.cleanUp(); + } + + private ICConfigurationDescription[] getConfigurationDescriptions(IProject project) { + CoreModel coreModel = CoreModel.getDefault(); + ICProjectDescriptionManager mngr = coreModel.getProjectDescriptionManager(); + // project description + ICProjectDescription projectDescription = mngr.getProjectDescription(project); + assertNotNull(projectDescription); + assertEquals(1, projectDescription.getConfigurations().length); + // configuration description + ICConfigurationDescription[] cfgDescriptions = projectDescription.getConfigurations(); + return cfgDescriptions; + } + + public void testAbstractBuiltinSpecsDetector_GettersSetters() throws Exception { + // define mock detector + MockBuiltinSpecsDetectorExecutedFlag detector = new MockBuiltinSpecsDetectorExecutedFlag(); + + detector.configureProvider(PROVIDER_ID, PROVIDER_NAME, null, null, null); + assertEquals(PROVIDER_ID, detector.getId()); + assertEquals(PROVIDER_NAME, detector.getName()); + assertEquals(null, detector.getLanguageScope()); + assertEquals(null, detector.getSettingEntries(null, null, null)); + assertEquals(null, detector.getCustomParameter()); + assertEquals(false, detector.isExecuted()); + + List languages = new ArrayList(); + languages.add(LANGUAGE_ID); + List entries = new ArrayList(); + ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + entries.add(entry); + + detector.configureProvider(PROVIDER_ID, PROVIDER_NAME, languages, entries, CUSTOM_PARAMETER); + assertEquals(PROVIDER_ID, detector.getId()); + assertEquals(PROVIDER_NAME, detector.getName()); + assertEquals(languages, detector.getLanguageScope()); + assertEquals(entries, detector.getSettingEntries(null, null, null)); + assertEquals(CUSTOM_PARAMETER, detector.getCustomParameter()); + assertEquals(false, detector.isExecuted()); + + detector.execute(); + assertEquals(true, detector.isExecuted()); + } + + public void testAbstractBuiltinSpecsDetector_CloneAndEquals() throws Exception { + // define mock detector + class MockDetectorCloneable extends MockBuiltinSpecsDetectorExecutedFlag implements Cloneable { + @Override + public MockDetectorCloneable clone() throws CloneNotSupportedException { + return (MockDetectorCloneable) super.clone(); + } + @Override + public MockDetectorCloneable cloneShallow() throws CloneNotSupportedException { + return (MockDetectorCloneable) super.cloneShallow(); + } + } + + // create instance to compare to + MockDetectorCloneable detector = new MockDetectorCloneable(); + + List languages = new ArrayList(); + languages.add(LANGUAGE_ID); + List entries = new ArrayList(); + ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + entries.add(entry); + + // check clone after initialization + MockDetectorCloneable clone0 = detector.clone(); + assertTrue(detector.equals(clone0)); + + // configure provider + detector.configureProvider(PROVIDER_ID, PROVIDER_NAME, languages, entries, CUSTOM_PARAMETER); + assertEquals(false, detector.isConsoleEnabled()); + detector.setConsoleEnabled(true); + detector.execute(); + assertEquals(true, detector.isExecuted()); + assertFalse(detector.equals(clone0)); + + // check another clone after configuring + { + MockDetectorCloneable clone = detector.clone(); + assertTrue(detector.equals(clone)); + } + + // check custom parameter + { + MockDetectorCloneable clone = detector.clone(); + clone.setCustomParameter("changed"); + assertFalse(detector.equals(clone)); + } + + // check language scope + { + MockDetectorCloneable clone = detector.clone(); + clone.setLanguageScope(null); + assertFalse(detector.equals(clone)); + } + + // check console flag + { + MockDetectorCloneable clone = detector.clone(); + boolean isConsoleEnabled = clone.isConsoleEnabled(); + clone.setConsoleEnabled( ! isConsoleEnabled ); + assertFalse(detector.equals(clone)); + } + + // check isExecuted flag + { + MockDetectorCloneable clone = detector.clone(); + assertEquals(true, clone.isExecuted()); + clone.clear(); + assertEquals(false, clone.isExecuted()); + assertFalse(detector.equals(clone)); + } + + // check entries + { + MockDetectorCloneable clone = detector.clone(); + clone.setSettingEntries(null, null, null, null); + assertFalse(detector.equals(clone)); + } + + // check cloneShallow() + { + MockDetectorCloneable detector2 = detector.clone(); + MockDetectorCloneable clone = detector2.cloneShallow(); + assertEquals(false, clone.isExecuted()); + assertFalse(detector2.equals(clone)); + + detector2.setSettingEntries(null, null, null, null); + assertFalse(detector2.equals(clone)); + + clone.execute(); + assertTrue(detector2.equals(clone)); + } + } + + /** + */ + public void testAbstractBuiltinSpecsDetector_Serialize() throws Exception { + { + // create empty XML + Document doc = XmlUtil.newDocument(); + Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST); + + // load it to new provider + MockBuiltinSpecsDetectorExecutedFlag detector = new MockBuiltinSpecsDetectorExecutedFlag(); + detector.load(rootElement); + assertEquals(false, detector.isConsoleEnabled()); + } + + Element elementProvider; + { + // define mock detector + MockBuiltinSpecsDetectorExecutedFlag detector = new MockBuiltinSpecsDetectorExecutedFlag(); + assertEquals(false, detector.isConsoleEnabled()); + + // redefine the settings + detector.setConsoleEnabled(true); + assertEquals(true, detector.isConsoleEnabled()); + + // serialize in XML + Document doc = XmlUtil.newDocument(); + Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST); + elementProvider = detector.serialize(rootElement); + String xmlString = XmlUtil.toString(doc); + + assertTrue(xmlString.contains(ATTR_CONSOLE)); + } + { + // create another instance of the provider + MockBuiltinSpecsDetectorExecutedFlag detector = new MockBuiltinSpecsDetectorExecutedFlag(); + assertEquals(false, detector.isConsoleEnabled()); + + // load element + detector.load(elementProvider); + assertEquals(true, detector.isConsoleEnabled()); + } + } + + public void testAbstractBuiltinSpecsDetector_Nulls() throws Exception { + { + // test AbstractBuiltinSpecsDetector.processLine(...) flow + MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); + detector.startup(null); + detector.startupForLanguage(null); + detector.processLine(null, null); + detector.shutdownForLanguage(); + detector.shutdown(); + } + { + // test AbstractBuiltinSpecsDetector.processLine(...) flow + MockConsoleBuiltinSpecsDetector detector = new MockConsoleBuiltinSpecsDetector(); + detector.runForEachLanguage(null, null, null, null); + } + } + + public void testAbstractBuiltinSpecsDetector_RunConfiguration() throws Exception { + // Create model project and accompanied descriptions + String projectName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); + ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + MockConsoleBuiltinSpecsDetector detector = new MockConsoleBuiltinSpecsDetector(); + detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID);}}); + + detector.runForEachLanguage(cfgDescription, null, null, null); + assertFalse(detector.isEmpty()); + + List noentries = detector.getSettingEntries(null, null, null); + assertNull(noentries); + + List entries = detector.getSettingEntries(cfgDescription, null, LANGUAGE_ID); + ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + assertEquals(expected, entries.get(0)); + } + + public void testAbstractBuiltinSpecsDetector_RunGlobal() throws Exception { + MockConsoleBuiltinSpecsDetector detector = new MockConsoleBuiltinSpecsDetector(); + detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID);}}); + + detector.runForEachLanguage(null, null, null, null); + assertFalse(detector.isEmpty()); + + List entries = detector.getSettingEntries(null, null, LANGUAGE_ID); + ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + assertEquals(expected, entries.get(0)); + } + + public void testAbstractBuiltinSpecsDetector_GroupSettings() throws Exception { + // define benchmarks + final CIncludePathEntry includePath_1 = new CIncludePathEntry("/include/path_1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CIncludePathEntry includePath_2 = new CIncludePathEntry("/include/path_2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CIncludeFileEntry includeFile_1 = new CIncludeFileEntry(new Path("/include.file1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CIncludeFileEntry includeFile_2 = new CIncludeFileEntry(new Path("/include.file2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CMacroEntry macro_1 = new CMacroEntry("MACRO_1", "", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CMacroEntry macro_2 = new CMacroEntry("MACRO_2", "", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY |ICSettingEntry.UNDEFINED); + final CMacroFileEntry macroFile_1 = new CMacroFileEntry(new Path("/macro.file1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CMacroFileEntry macroFile_2 = new CMacroFileEntry(new Path("/macro.file2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CLibraryPathEntry libraryPath_1 = new CLibraryPathEntry(new Path("/lib/path_1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CLibraryPathEntry libraryPath_2 = new CLibraryPathEntry(new Path("/lib/path_2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CLibraryFileEntry libraryFile_1 = new CLibraryFileEntry("lib_1.a", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + final CLibraryFileEntry libraryFile_2 = new CLibraryFileEntry("lib_2.a", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); + + // Define mock detector adding unorganized entries + MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector() { + @Override + public boolean processLine(String line, ErrorParserManager epm) { + detectedSettingEntries.add(libraryFile_1); + detectedSettingEntries.add(libraryPath_1); + detectedSettingEntries.add(macroFile_1); + detectedSettingEntries.add(macro_1); + detectedSettingEntries.add(includeFile_1); + detectedSettingEntries.add(includePath_1); + + detectedSettingEntries.add(includePath_2); + detectedSettingEntries.add(includeFile_2); + detectedSettingEntries.add(macro_2); + detectedSettingEntries.add(macroFile_2); + detectedSettingEntries.add(libraryPath_2); + detectedSettingEntries.add(libraryFile_2); + return true; + } + }; + + // run specs detector + detector.startup(null); + detector.startupForLanguage(null); + detector.processLine("", null); + detector.shutdownForLanguage(); + detector.shutdown(); + + // compare benchmarks, expected well-sorted + List entries = detector.getSettingEntries(null, null, null); + + int i=0; + assertEquals(includePath_1, entries.get(i++)); + assertEquals(includePath_2, entries.get(i++)); + assertEquals(includeFile_1, entries.get(i++)); + assertEquals(includeFile_2, entries.get(i++)); + assertEquals(macro_1, entries.get(i++)); + assertEquals(macro_2, entries.get(i++)); + assertEquals(macroFile_1, entries.get(i++)); + assertEquals(macroFile_2, entries.get(i++)); + assertEquals(libraryPath_1, entries.get(i++)); + assertEquals(libraryPath_2, entries.get(i++)); + assertEquals(libraryFile_1, entries.get(i++)); + assertEquals(libraryFile_2, entries.get(i++)); + + assertEquals(12, entries.size()); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuildCommandParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuildCommandParser.java index 56b32c4cb62..6b7f21f3682 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuildCommandParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuildCommandParser.java @@ -24,6 +24,18 @@ import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.errorparsers.RegexErrorParser; import org.eclipse.cdt.core.errorparsers.RegexErrorPattern; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.internal.core.ConsoleOutputSniffer; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.core.runtime.jobs.Job; /** * TODO - class description @@ -103,12 +115,63 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting return options; } + public boolean processLine(String line) { + return processLine(line, null); + } + // This is redundant but let us keep it here to navigate in java code easier @Override public boolean processLine(String line, ErrorParserManager epm) { return super.processLine(line, epm); } + @Override + public void shutdown() { + scheduleSerializingJob(currentCfgDescription); + super.shutdown(); + } + + + private void scheduleSerializingJob(final ICConfigurationDescription cfgDescription) { + Job job = new Job("Serialize CDT language settings entries") { + @Override + protected IStatus run(IProgressMonitor monitor) { + // FIXME - remove thread name reassigning + Thread thread = getThread(); + String oldName = thread.getName(); + thread.setName("CDT LSP Serializer,BOP"); + + IStatus status = null; + try { + if (cfgDescription != null) { + LanguageSettingsProvidersSerializer.serializeLanguageSettings(cfgDescription.getProjectDescription()); + } else { + LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace(); + } + } catch (CoreException e) { + status = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error serializing language settings", e); + MakeCorePlugin.log(status); + } + + if (status == null) + status = Status.OK_STATUS; + + thread.setName(oldName); + return status; + } + }; + + ISchedulingRule rule = null; + if (currentProject != null) { + rule = currentProject.getFile(".settings/language.settings.xml"); + } + if (rule == null) { + rule = ResourcesPlugin.getWorkspace().getRoot(); + } + job.setRule(rule); + job.schedule(); + } + /** * Trivial Error Parser which allows highlighting of output lines matching the patterns * of this parser. Intended for better troubleshooting experience. diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java index 85f963f849e..96b3f81536c 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuiltinSpecsDetector.java @@ -21,63 +21,79 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CommandLauncher; import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.ICConsoleParser; import org.eclipse.cdt.core.ICommandLauncher; import org.eclipse.cdt.core.IConsoleParser; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.ProblemMarkerInfo; +import org.eclipse.cdt.core.index.IIndexManager; +import org.eclipse.cdt.core.language.settings.providers.ICListenerRegisterer; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.ILanguageDescriptor; import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.internal.core.ConsoleOutputSniffer; import org.eclipse.cdt.internal.core.XmlUtil; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.internal.core.MakeMessages; import org.eclipse.cdt.make.internal.core.StreamMonitor; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.ITool; -import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.utils.CommandLineUtil; import org.eclipse.cdt.utils.PathUtil; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.w3c.dom.Element; -public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSettingsOutputScanner { +public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSettingsOutputScanner + implements ICListenerRegisterer, IResourceChangeListener { + private static final int TICKS_STREAM_MONITOR = 100; + private static final int TICKS_CLEAN_MARKERS = 1; + private static final int TICKS_RUN_FOR_ONE_LANGUAGE = 10; + private static final int TICKS_SERIALIZATION = 1; + private static final int TICKS_SCALE = 100; private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ private static final String PLUGIN_CDT_MAKE_UI_ID = "org.eclipse.cdt.make.ui"; //$NON-NLS-1$ private static final String GMAKE_ERROR_PARSER_ID = "org.eclipse.cdt.core.GmakeErrorParser"; //$NON-NLS-1$ private static final String PATH_ENV = "PATH"; //$NON-NLS-1$ - private static final String ATTR_RUN_ONCE = "run-once"; //$NON-NLS-1$ private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$ protected static final String COMPILER_MACRO = "${COMMAND}"; //$NON-NLS-1$ protected static final String SPEC_FILE_MACRO = "${INPUTS}"; //$NON-NLS-1$ protected static final String SPEC_EXT_MACRO = "${EXT}"; //$NON-NLS-1$ - protected static final String SPEC_FILE_BASE = "spec."; //$NON-NLS-1$ + protected static final String SPEC_FILE_BASE = "spec"; //$NON-NLS-1$ private String currentCommandResolved = null; protected List detectedSettingEntries = null; + + protected boolean isExecuted = false; protected int collected = 0; - private boolean runOnce = true; private boolean isConsoleEnabled = false; protected java.io.File specFile = null; protected boolean preserveSpecFile = false; @@ -86,7 +102,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti protected URI buildDirURI = null; private class SDMarkerGenerator implements IMarkerGenerator { - protected static final String SCANNER_DISCOVERY_PROBLEM_MARKER = ManagedBuilderCorePlugin.PLUGIN_ID + ".scanner.discovery.problem"; //$NON-NLS-1$ + protected static final String SCANNER_DISCOVERY_PROBLEM_MARKER = MakeCorePlugin.PLUGIN_ID + ".scanner.discovery.problem"; //$NON-NLS-1$ protected static final String PROVIDER = "provider"; //$NON-NLS-1$ public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) { @@ -145,27 +161,23 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti } - /** - * TODO + * This ICConsoleParser handles each individual run for one language from + * {@link AbstractBuiltinSpecsDetector#runForEachLanguage(ICConfigurationDescription, IPath, String[], IProgressMonitor)} + * */ - protected abstract String getToolchainId(); - - @Override - public void configureProvider(String id, String name, List languages, List entries, String customParameter) { - super.configureProvider(id, name, languages, entries, customParameter); - - runOnce = true; + private class ConsoleParser implements ICConsoleParser { + public void startup(ICConfigurationDescription cfgDescription) throws CoreException { + // not used here, see instead startupForLanguage() in AbstractBuiltinSpecsDetector.runForEachLanguage(...) + } + public boolean processLine(String line) { + return AbstractBuiltinSpecsDetector.this.processLine(line, errorParserManager); + } + public void shutdown() { + // not used here, see instead shutdownForLanguage() in AbstractBuiltinSpecsDetector.runForEachLanguage(...) + } } - public void setRunOnce(boolean once) { - runOnce = once; - } - - public boolean isRunOnce() { - return runOnce; - } - public void setConsoleEnabled(boolean enable) { isConsoleEnabled = enable; } @@ -176,28 +188,21 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti protected String resolveCommand(String languageId) throws CoreException { String cmd = getCustomParameter(); - if (cmd!=null && (cmd.contains(COMPILER_MACRO) || cmd.contains(SPEC_FILE_MACRO) || cmd.contains(SPEC_EXT_MACRO))) { - String toolchainId = getToolchainId(); - ITool tool = getTool(toolchainId, languageId); - if (tool==null) { - IStatus status = new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Provider "+getId() - +" unable to find the compiler tool for language " + languageId - + "in toolchain " + toolchainId); - throw new CoreException(status); - } - if (cmd.contains(COMPILER_MACRO)) { - String compiler = getCompilerCommand(tool); - cmd = cmd.replace(COMPILER_MACRO, compiler); + String compiler = getCompilerCommand(languageId); + if (compiler!=null) + cmd = cmd.replace(COMPILER_MACRO, compiler); } if (cmd.contains(SPEC_FILE_MACRO)) { - String specFileName = getSpecFile(languageId, tool); - cmd = cmd.replace(SPEC_FILE_MACRO, specFileName); + String specFileName = getSpecFile(languageId); + if (specFileName!=null) + cmd = cmd.replace(SPEC_FILE_MACRO, specFileName); } if (cmd.contains(SPEC_EXT_MACRO)) { - String specFileExt = getSpecExt(languageId, tool); - cmd = cmd.replace(SPEC_EXT_MACRO, specFileExt); + String specFileExt = getSpecFileExtension(languageId); + if (specFileExt!=null) + cmd = cmd.replace(SPEC_EXT_MACRO, specFileExt); } } return cmd; @@ -234,83 +239,256 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti return buildDirURI; } - @Override - public void startup(ICConfigurationDescription cfgDescription) throws CoreException { - // for workspace provider cfgDescription is used to figure out the current project for build console + public void registerListener(ICConfigurationDescription cfgDescription) { currentCfgDescription = cfgDescription; - if (cfgDescription!=null) { - currentProject = cfgDescription.getProjectDescription().getProject(); + ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD); + // TODO - remove me + CCorePlugin.log(new Status(IStatus.INFO,CCorePlugin.PLUGIN_ID, + getPrefixForLog() + "Added listener [" + System.identityHashCode(this) + "] " + this)); + } + + public void unregisterListener() { + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); + // TODO - remove me + CCorePlugin.log(new Status(IStatus.INFO,CCorePlugin.PLUGIN_ID, + getPrefixForLog() + "Removed listener [" + System.identityHashCode(this) + "] " + this)); + } + + private String eventToString(IResourceChangeEvent event) { + String strType = null; + IResource rc = null; + if (event != null) { + int type = event.getType(); + switch (type) { + case IResourceChangeEvent.POST_CHANGE: strType = "POST_CHANGE";break; + case IResourceChangeEvent.PRE_CLOSE: strType = "PRE_CLOSE";break; + case IResourceChangeEvent.PRE_DELETE: strType = "PRE_DELETE";break; + case IResourceChangeEvent.PRE_BUILD: strType = "PRE_BUILD";break; + case IResourceChangeEvent.POST_BUILD: strType = "POST_BUILD";break; + case IResourceChangeEvent.PRE_REFRESH: strType = "PRE_REFRESH";break; + default: strType = "unknown";break; + } + strType += "=" + Integer.toHexString(type); + + IResourceDelta delta = event.getDelta(); + rc = delta!=null ? delta.getResource() : null; } + String result = "Event " + strType + ", " + rc; + return result; + } + + public void resourceChanged(IResourceChangeEvent event) { + System.out.println(eventToString(event)); + + // if (event.getType() != IResourceChangeEvent.PRE_BUILD) + // return; + // + // IResourceDelta delta = event.getDelta(); + // delta.getKind(); + // delta.getFlags(); + + execute(); + } + + protected void execute() { + if (isExecuted) { +// // TODO - remove me +// CCorePlugin.log(new Status(IStatus.INFO,CCorePlugin.PLUGIN_ID, +// getPrefixForLog() + "Already executed [" + System.identityHashCode(this) + "] " + this)); + return; + } + isExecuted = true; + + Job job = new Job("Discover compiler's built-in language settings") { + @Override + protected IStatus run(IProgressMonitor monitor) { + return runForEachLanguage(currentCfgDescription, null, null, monitor); + } + }; + + IProject ownerProject = null; + if (currentCfgDescription != null) { + ICProjectDescription prjDescription = currentCfgDescription.getProjectDescription(); + if (prjDescription != null) { + ownerProject = prjDescription.getProject(); + } + } + ISchedulingRule rule = null; + if (ownerProject != null) { + rule = ownerProject.getFile(".settings/language.settings.xml"); + } + if (rule == null) { + rule = ResourcesPlugin.getWorkspace().getRoot(); + } + job.setRule(rule); + job.schedule(); + + // TODO - remove me + CCorePlugin.log(new Status(IStatus.INFO,CCorePlugin.PLUGIN_ID, + getPrefixForLog() + "Execution scheduled [" + System.identityHashCode(this) + "] " + this)); + + } + + /** + * TODO + */ + protected IStatus runForEachLanguage(ICConfigurationDescription cfgDescription, IPath workingDirectory, + String[] env, IProgressMonitor monitor) { + + try { + startup(cfgDescription); + } catch (CoreException e) { + IStatus status = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error preparing to run Builtin Specs Detector", e); + MakeCorePlugin.log(status); + return status; + } + + MultiStatus status = new MultiStatus(MakeCorePlugin.PLUGIN_ID, IStatus.OK, "Problem running CDT Scanner Discovery provider " + getId(), null); + + boolean isChanged = false; + mappedRootURI = null; + buildDirURI = null; + + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + try { + + List languageIds = getLanguageScope(); + if (languageIds != null) { + int totalWork = TICKS_CLEAN_MARKERS + languageIds.size()*TICKS_RUN_FOR_ONE_LANGUAGE + TICKS_SERIALIZATION; + monitor.beginTask("CDT Scanner Discovery", totalWork * TICKS_SCALE); + + IResource markersResource = currentProject!= null ? currentProject : ResourcesPlugin.getWorkspace().getRoot(); + + // clear old markers + monitor.subTask("Clearing stale markers"); + try { + IMarker[] cur = markersResource.findMarkers(SDMarkerGenerator.SCANNER_DISCOVERY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + for (IMarker marker : cur) { + if (getId().equals(marker.getAttribute(SDMarkerGenerator.PROVIDER))) { + marker.delete(); + } + } + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + monitor.worked(TICKS_CLEAN_MARKERS * TICKS_SCALE); + + for (String languageId : languageIds) { + List oldEntries = getSettingEntries(cfgDescription, null, languageId); + try { + startupForLanguage(languageId); + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + runForLanguage(workingDirectory, env, new SubProgressMonitor(monitor, TICKS_RUN_FOR_ONE_LANGUAGE * TICKS_SCALE)); + if (monitor.isCanceled()) + throw new OperationCanceledException(); + } catch (CoreException e) { + IStatus s = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error running Builtin Specs Detector", e); + MakeCorePlugin.log(s); + status.merge(s); + } finally { + shutdownForLanguage(); + } + List newEntries = getSettingEntries(cfgDescription, null, languageId); + isChanged = isChanged || newEntries != oldEntries; + + } + } + + monitor.subTask("Serializing results"); + if (isChanged) { // avoids resource and settings change notifications + try { + if (currentCfgDescription != null) { + LanguageSettingsProvidersSerializer.serializeLanguageSettings(currentCfgDescription.getProjectDescription()); + } else { + LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace(); + } + } catch (CoreException e) { + IStatus s = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error serializing language settings", e); + MakeCorePlugin.log(s); + status.merge(s); + } + + // AG: FIXME - rather send event that ls settings changed + if (currentCfgDescription != null) { + ICProject icProject = CoreModel.getDefault().create(currentProject); + ICElement[] tuSelection = new ICElement[] {icProject}; + try { + CCorePlugin.getIndexManager().update(tuSelection, IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT); + } catch (CoreException e) { + IStatus s = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error updating CDT index", e); + MakeCorePlugin.log(s); + status.merge(s); + } + } else { + // TODO + } + } + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + monitor.worked(TICKS_SERIALIZATION * TICKS_SCALE); + } catch (OperationCanceledException e) { + if (!status.isOK()) { + MakeCorePlugin.log(status); + } + status.merge(new Status(IStatus.CANCEL, MakeCorePlugin.PLUGIN_ID, IStatus.OK, "Operation cancelled by user", e)); + } finally { + monitor.done(); + + // release resources + buildDirURI = null; + mappedRootURI = null; + shutdown(); + currentCfgDescription = cfgDescription; // current description gets cleared in super.shutdown(), keep it + } + + return status; + } + + protected void startupForLanguage(String languageId) throws CoreException { + currentLanguageId = languageId; + + specFile = null; // can get set in resolveCommand() + currentCommandResolved = resolveCommand(currentLanguageId); detectedSettingEntries = new ArrayList(); collected = 0; - currentCommandResolved = customParameter; - - specFile = null; - - currentCommandResolved = resolveCommand(currentLanguageId); - - mappedRootURI = null; - buildDirURI = null; } - @Override - public void shutdown() { - buildDirURI = null; - mappedRootURI = null; - - if (detectedSettingEntries!=null && detectedSettingEntries.size()>0) { - setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, detectedSettingEntries); + protected void shutdownForLanguage() { + if (detectedSettingEntries != null && detectedSettingEntries.size() > 0) { collected = detectedSettingEntries.size(); - IStatus status = new Status(IStatus.INFO, MakeCorePlugin.PLUGIN_ID, getClass().getSimpleName() - + " collected " + detectedSettingEntries.size() + " entries" + " for language " + currentLanguageId); - ManagedBuilderCorePlugin.log(status); + IStatus status = new Status(IStatus.INFO, MakeCorePlugin.PLUGIN_ID, getPrefixForLog() + + getClass().getSimpleName() + " collected " + detectedSettingEntries.size() + " entries" + " for language " + currentLanguageId); + MakeCorePlugin.log(status); + + setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, detectedSettingEntries); } detectedSettingEntries = null; - + + currentCommandResolved = null; if (specFile!=null && !preserveSpecFile) { specFile.delete(); specFile = null; } - - currentCommandResolved = null; - } - - public void run(IProject project, String languageId, IPath workingDirectory, String[] env, - IProgressMonitor monitor) throws CoreException, IOException { - if (isRunOnce() && !isEmpty()) { - return; - } - - currentProject = project; - currentLanguageId = languageId; - startup(null); - - run(workingDirectory, env, monitor); - } - - public void run(ICConfigurationDescription cfgDescription, String languageId, IPath workingDirectory, - String[] env, IProgressMonitor monitor) throws CoreException, IOException { - Assert.isNotNull(cfgDescription); - - if (isRunOnce() && !isEmpty()) { - return; - } - - currentLanguageId = languageId; - startup(cfgDescription); - - run(workingDirectory, env, monitor); - } - + currentLanguageId = null; + } + /** * TODO: test case for this function */ - private void run(IPath workingDirectory, String[] env, IProgressMonitor monitor) - throws CoreException, IOException { - + private void runForLanguage(IPath workingDirectory, String[] env, IProgressMonitor monitor) throws CoreException { IConsole console; if (isConsoleEnabled) { console = startProviderConsole(); @@ -322,59 +500,56 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti OutputStream cos = console.getOutputStream(); // Using GMAKE_ERROR_PARSER_ID as it can handle shell error messages - ErrorParserManager epm = new ErrorParserManager(currentProject, new SDMarkerGenerator(), new String[] {GMAKE_ERROR_PARSER_ID}); - epm.setOutputStream(cos); + errorParserManager = new ErrorParserManager(currentProject, new SDMarkerGenerator(), new String[] {GMAKE_ERROR_PARSER_ID}); + errorParserManager.setOutputStream(cos); - IResource markersResource = currentProject!= null ? currentProject : ResourcesPlugin.getWorkspace().getRoot(); - - // clear old markers - try { - IMarker[] cur = markersResource.findMarkers(SDMarkerGenerator.SCANNER_DISCOVERY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); - for (IMarker marker : cur) { - if (getId().equals(marker.getAttribute(SDMarkerGenerator.PROVIDER))) { - marker.delete(); - } - } - } catch (CoreException e) { - ManagedBuilderCorePlugin.log(e); - } - - - if (monitor==null) { + if (monitor == null) { monitor = new NullProgressMonitor(); } - StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 70), epm, 100); - OutputStream stdout = streamMon; - OutputStream stderr = streamMon; - - String msg = "Running scanner discovery: " + getName(); - monitor.subTask(msg); - printLine(stdout, "**** " + msg + " ****" + NEWLINE); - - ConsoleOutputSniffer sniffer = new ConsoleOutputSniffer(stdout, stderr, new IConsoleParser[] { this }); - OutputStream consoleOut = sniffer.getOutputStream(); - OutputStream consoleErr = sniffer.getErrorStream(); - - boolean isSuccess = false; + try { - isSuccess = runProgram(currentCommandResolved, env, workingDirectory, monitor, consoleOut, consoleErr); - } catch (Exception e) { - ManagedBuilderCorePlugin.log(e); - } - if (!isSuccess) { + // StreamMonitor will do monitor.beginTask(...) + StreamMonitor streamMon = new StreamMonitor(monitor, errorParserManager, TICKS_STREAM_MONITOR); + OutputStream stdout = streamMon; + OutputStream stderr = streamMon; + + String msg = "Running scanner discovery: " + getName(); + printLine(stdout, "**** " + msg + " ****" + NEWLINE); + + ConsoleParser consoleParser = new ConsoleParser(); + ConsoleOutputSniffer sniffer = new ConsoleOutputSniffer(stdout, stderr, new IConsoleParser[] { consoleParser }, errorParserManager); + OutputStream consoleOut = sniffer.getOutputStream(); + OutputStream consoleErr = sniffer.getErrorStream(); + + boolean isSuccess = false; try { - consoleOut.close(); - } catch (IOException e) { - ManagedBuilderCorePlugin.log(e); + isSuccess = runProgram(currentCommandResolved, env, workingDirectory, monitor, consoleOut, consoleErr); + } catch (Exception e) { + MakeCorePlugin.log(e); } - try { - consoleErr.close(); - } catch (IOException e) { - ManagedBuilderCorePlugin.log(e); + if (!isSuccess) { + try { + consoleOut.close(); + } catch (IOException e) { + MakeCorePlugin.log(e); + } + try { + consoleErr.close(); + } catch (IOException e) { + MakeCorePlugin.log(e); + } } + } finally { + // ensure monitor.done() is called in cases when StreamMonitor fails to do that + monitor.done(); } } + /** + * TODO + * Note that progress monitor life cycle is handled elsewhere. This method assumes that + * monitor.beginTask(...) has already been called. + */ protected boolean runProgram(String command, String[] env, IPath workingDirectory, IProgressMonitor monitor, OutputStream consoleOut, OutputStream consoleErr) throws CoreException, IOException { @@ -398,12 +573,15 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti System.arraycopy(cmdArray, 1, args, 0, args.length); } + if (monitor==null) { + monitor = new NullProgressMonitor(); + } Process p = launcher.execute(program, args, env, workingDirectory, monitor); if (p != null) { // Before launching give visual cues via the monitor monitor.subTask("Invoking command " + command); - if (launcher.waitAndRead(consoleOut, consoleErr, new SubProgressMonitor(monitor, 0)) != ICommandLauncher.OK) { + if (launcher.waitAndRead(consoleOut, consoleErr, monitor) != ICommandLauncher.OK) { errMsg = launcher.getErrorMessage(); } } else { @@ -431,7 +609,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti return false; } - printLine(consoleOut, NEWLINE + "**** Collected " + collected + " entries. ****"); + printLine(consoleOut, NEWLINE + "**** Collected " + detectedSettingEntries.size() + " entries. ****"); return true; } @@ -484,34 +662,19 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti return envPath; } - private ITool getTool(String toolchainId, String languageId) { - IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId); - if (toolchain != null) { - ITool[] tools = toolchain.getTools(); - for (ITool tool : tools) { - IInputType[] inputTypes = tool.getInputTypes(); - for (IInputType inType : inputTypes) { - String lang = inType.getLanguageId(tool); - if (languageId.equals(lang)) - return tool; - } - } - } - ManagedBuilderCorePlugin.error("Unable to find tool in toolchain="+toolchainId+" for language="+languageId); + protected String getCompilerCommand(String languageId) { + IStatus status = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, "Provider "+getId() + +" unable to find the compiler tool for language " + languageId); + MakeCorePlugin.log(new CoreException(status)); return null; } - private String getCompilerCommand(ITool tool) { - String compiler = tool.getToolCommand(); - if (compiler.length()==0) { - String msg = "Unable to find compiler command in toolchain="+getToolchainId(); - ManagedBuilderCorePlugin.error(msg); + protected String getSpecFile(String languageId) { + String specExt = getSpecFileExtension(languageId); + String ext = ""; //$NON-NLS-1$ + if (specExt != null) { + ext = '.' + specExt; } - return compiler; - } - - private String getSpecFile(String languageId, ITool tool) { - String ext = getSpecExt(languageId, tool); String specFileName = SPEC_FILE_BASE + ext; IPath workingLocation = MakeCorePlugin.getWorkingDirectory(); @@ -524,57 +687,91 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti try { specFile.createNewFile(); } catch (IOException e) { - ManagedBuilderCorePlugin.log(e); + MakeCorePlugin.log(e); } } return fileLocation.toString(); } - private String getSpecExt(String languageId, ITool tool) { - String ext = ""; - String[] srcFileExtensions = tool.getAllInputExtensions(); - if (srcFileExtensions!=null && srcFileExtensions.length>0) { - ext = srcFileExtensions[0]; + /** + * Determine file extension by language id. This implementation retrieves first extension + * from the list as there could be multiple extensions associated with the given language. + * + * @param languageId - given language ID. + * @return file extension associated with the language or {@code null} if not found. + */ + protected String getSpecFileExtension(String languageId) { + String ext = null; + ILanguageDescriptor langDescriptor = LanguageManager.getInstance().getLanguageDescriptor(languageId); + if (langDescriptor != null) { + IContentType[] contentTypes = langDescriptor.getContentTypes(); + if (contentTypes != null && contentTypes.length > 0) { + String[] fileExtensions = contentTypes[0].getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + if (fileExtensions != null && fileExtensions.length > 0) { + ext = fileExtensions[0]; + } + } } - if (ext.length()==0) { - ManagedBuilderCorePlugin.error("Unable to find file extension for language "+languageId); + + if (ext == null) { + MakeCorePlugin.log(new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, "Unable to find file extension for language "+languageId)); } return ext; } - protected void printLine(OutputStream stream, String msg) throws IOException { - stream.write((msg + NEWLINE).getBytes()); - stream.flush(); + protected void printLine(OutputStream stream, String msg) { + try { + stream.write((msg + NEWLINE).getBytes()); + stream.flush(); + } catch (IOException e) { + MakeCorePlugin.log(e); + } } @Override public Element serializeAttributes(Element parentElement) { Element elementProvider = super.serializeAttributes(parentElement); - elementProvider.setAttribute(ATTR_RUN_ONCE, Boolean.toString(runOnce)); elementProvider.setAttribute(ATTR_CONSOLE, Boolean.toString(isConsoleEnabled)); return elementProvider; } @Override - public void load(Element providerNode) { - super.load(providerNode); - - String runOnceValue = XmlUtil.determineAttributeValue(providerNode, ATTR_RUN_ONCE); - if (runOnceValue!=null) - runOnce = Boolean.parseBoolean(runOnceValue); - + public void loadAttributes(Element providerNode) { + super.loadAttributes(providerNode); + String consoleValue = XmlUtil.determineAttributeValue(providerNode, ATTR_CONSOLE); if (consoleValue!=null) isConsoleEnabled = Boolean.parseBoolean(consoleValue); } + @Override + public void loadEntries(Element providerNode) { + super.loadEntries(providerNode); + // TODO - test case for that or maybe introduce "isExecuted" attribute in XML? + if (!isEmpty()) + isExecuted = true; + } + + @Override + public void clear() { + super.clear(); + isExecuted = false; + } + + @Override + protected AbstractBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException { + AbstractBuiltinSpecsDetector clone = (AbstractBuiltinSpecsDetector) super.cloneShallow(); + clone.isExecuted = false; + return clone; + } + @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + (runOnce ? 1231 : 1237); result = prime * result + (isConsoleEnabled ? 1231 : 1237); + result = prime * result + (isExecuted ? 1231 : 1237); return result; } @@ -587,10 +784,10 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti if (!(obj instanceof AbstractBuiltinSpecsDetector)) return false; AbstractBuiltinSpecsDetector other = (AbstractBuiltinSpecsDetector) obj; - if (runOnce != other.runOnce) - return false; if (isConsoleEnabled != other.isConsoleEnabled) return false; + if (isExecuted != other.isExecuted) + return false; return true; } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java index 33d897402a2..30153820a62 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java @@ -226,10 +226,6 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null; } - public boolean processLine(String line) { - return processLine(line, null); - } - public void shutdown() { // release resources for garbage collector currentCfgDescription = null; @@ -307,12 +303,26 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett return false; } + // TODO - remove me + @Deprecated + protected String getPrefixForLog() { + String str; + if (currentCfgDescription!= null) { + IProject ownerProject = currentCfgDescription.getProjectDescription().getProject(); + str = ownerProject + ":" + currentCfgDescription.getName(); + } else { + str = "[global]"; + } + return str + ": "; + } + + protected void setSettingEntries(List entries) { setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, entries); // TODO - for debugging only, eventually remove - IStatus status = new Status(IStatus.INFO, MakeCorePlugin.PLUGIN_ID, getClass().getSimpleName() - + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + currentResource); + IStatus status = new Status(IStatus.INFO, MakeCorePlugin.PLUGIN_ID, getPrefixForLog() + + getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + currentResource); MakeCorePlugin.log(status); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/GCCBuildCommandParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/GCCBuildCommandParser.java index e9cff69143c..3c544f7d960 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/GCCBuildCommandParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/GCCBuildCommandParser.java @@ -16,8 +16,7 @@ import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditabl import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.make.core.scannerconfig.AbstractBuildCommandParser; -public class GCCBuildCommandParser extends AbstractBuildCommandParser implements - ILanguageSettingsEditableProvider { +public class GCCBuildCommandParser extends AbstractBuildCommandParser implements ILanguageSettingsEditableProvider { @SuppressWarnings("nls") static final AbstractOptionParser[] optionParsers = { new IncludePathOptionParser("-I\\s*([\"'])(.*)\\1", "$2"), @@ -51,7 +50,7 @@ public class GCCBuildCommandParser extends AbstractBuildCommandParser implements } public static class GCCBuildCommandPatternHighlighter extends AbstractBuildCommandParser.AbstractBuildCommandPatternHighlighter { - // ID of the parser taken from the extension point + // ID of the parser taken from the existing extension point private static final String GCC_BUILD_COMMAND_PARSER_EXT = "org.eclipse.cdt.make.core.build.command.parser.gcc"; //$NON-NLS-1$ public GCCBuildCommandPatternHighlighter() { diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/GCCBuildCommandParserOptionPage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/GCCBuildCommandParserOptionPage.java index d5bf8f74541..f1d169a92c6 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/GCCBuildCommandParserOptionPage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/GCCBuildCommandParserOptionPage.java @@ -30,7 +30,6 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; @@ -76,69 +75,7 @@ public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSetti composite.setLayoutData(gd); } - -// Group groupRun = new Group(composite, SWT.SHADOW_ETCHED_IN); -//// groupRun.setText("Language Settings Provider Options"); -// -// GridLayout gridLayoutRun = new GridLayout(); -//// GridLayout gridLayoutRun = new GridLayout(2, true); -//// gridLayoutRun.makeColumnsEqualWidth = false; -//// gridLayoutRun.marginRight = -10; -//// gridLayoutRun.marginLeft = -4; -// groupRun.setLayout(gridLayoutRun); -//// GridData gdRun = new GridData(GridData.FILL_HORIZONTAL); -//// gdRun.horizontalSpan = 2; -//// groupRun.setLayoutData(gdRun); - AbstractBuildCommandParser provider = getRawProvider(); -// { -// runOnceRadioButton = new Button(groupRun, SWT.RADIO); -// runOnceRadioButton.setText("Run only once"); //$NON-NLS-1$ -// // b1.setToolTipText(UIMessages.getString("EnvironmentTab.3")); //$NON-NLS-1$ -// GridData gd = new GridData(GridData.FILL_HORIZONTAL); -// gd.horizontalSpan = 3; -// runOnceRadioButton.setLayoutData(gd); -// runOnceRadioButton.setSelection(provider.isRunOnce()); -// runOnceRadioButton.setEnabled(fEditable); -// runOnceRadioButton.addSelectionListener(new SelectionAdapter() { -// @Override -// public void widgetSelected(SelectionEvent evt) { -// boolean runOnceEnabled = runOnceRadioButton.getSelection(); -// if (runOnceEnabled) { -// AbstractBuildCommandParser provider = getRawProvider(); -// if (runOnceEnabled != provider.isRunOnce()) { -// AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId); -// selectedProvider.setRunOnce(runOnceEnabled); -// providerTab.refreshItem(selectedProvider); -// } -// } -// } -// -// }); -// } -// { -// runEveryBuildRadioButton = new Button(groupRun, SWT.RADIO); -// runEveryBuildRadioButton.setText("Activate on every build"); //$NON-NLS-1$ -// runEveryBuildRadioButton.setSelection(!provider.isRunOnce()); -// runEveryBuildRadioButton.setEnabled(fEditable); -// GridData gd = new GridData(GridData.FILL_HORIZONTAL); -// gd.horizontalSpan = 3; -// runEveryBuildRadioButton.setLayoutData(gd); -// runEveryBuildRadioButton.addSelectionListener(new SelectionAdapter() { -// @Override -// public void widgetSelected(SelectionEvent evt) { -// boolean runEveryBuildEnabled = runEveryBuildRadioButton.getSelection(); -// if (runEveryBuildEnabled) { -// AbstractBuildCommandParser provider = getRawProvider(); -// if (runEveryBuildEnabled != !provider.isRunOnce()) { -// AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId); -// selectedProvider.setRunOnce(!runEveryBuildEnabled); -// providerTab.refreshItem(selectedProvider); -// } -// } -// } -// }); -// } // Compiler specs command { @@ -187,90 +124,6 @@ public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSetti // // }); // -// } - -// { -// final Button button = new Button(composite, SWT.PUSH); -// button.setFont(parent.getFont()); -// String text = fProvider.isEmpty() ? "Run Now (TODO)" : "Clear"; -// button.setText(text); -//// button.addSelectionListener(this); -// GridData data = new GridData(); -// data.horizontalSpan = 2; -//// data.horizontalAlignment = GridData.BEGINNING; -//// data.widthHint = 60; -// button.setLayoutData(data); -// // TODO -// button.setEnabled(fEditable && !fProvider.isEmpty()); -// -// button.addSelectionListener(new SelectionAdapter() { -// -// @Override -// public void widgetSelected(SelectionEvent evt) { -// if (fProvider.isEmpty()) { -// // TODO -// } else { -// fProvider.clear(); -// } -// // TODO -// button.setEnabled(fEditable && !fProvider.isEmpty()); -// String text = fProvider.isEmpty() ? "Run Now (TODO)" : "Clear"; -// button.setText(text); -// button.pack(); -// } -// -// }); -// -// } - -// // Compiler specs command -// { -// Label label = ControlFactory.createLabel(composite, "Parsing rules:"); -// GridData gd = new GridData(); -// gd.horizontalSpan = 2; -// label.setLayoutData(gd); -//// Label newLabel = new Label(composite, SWT.NONE); -////// ((GridData) newLabel.getLayoutData()).horizontalSpan = 1; -//// newLabel.setText("Command to get compiler specs:"); -// } - - -// createPatternsTable(group, composite); - - - - - - - - -// Group group = new Group(parent, SWT.SHADOW_ETCHED_IN); -// group.setText(DialogsMessages.RegexErrorParserOptionPage_Title); -// -// GridLayout gridLayout = new GridLayout(2, true); -// gridLayout.makeColumnsEqualWidth = false; -// gridLayout.marginRight = -10; -// gridLayout.marginLeft = -4; -// group.setLayout(gridLayout); -// group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); -// -// Composite composite = new Composite(group, SWT.NONE); -// GridLayout layout = new GridLayout(); -// layout.numColumns = 2; -// layout.marginWidth = 1; -// layout.marginHeight = 1; -// layout.marginRight = 1; -// composite.setLayout(layout); -// composite.setLayoutData(new GridData(GridData.FILL_BOTH)); -// Dialog.applyDialogFont(composite); -// -// if (!fEditable) -// createLinkToPreferences(composite); -// -// createPatternsTable(group, composite); -// -// if (fEditable) { -// createButtons(composite); // } { diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/BuiltinSpecsDetectorOptionPage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/BuiltinSpecsDetectorOptionPage.java index 1774569dda3..f4bca39a44a 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/BuiltinSpecsDetectorOptionPage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/BuiltinSpecsDetectorOptionPage.java @@ -44,8 +44,6 @@ public final class BuiltinSpecsDetectorOptionPage extends AbstractLanguageSettin private Text inputCommand; private StatusMessageLine fStatusLine; - private Button runOnceRadioButton; - private Button runEveryBuildRadioButton; private Button allocateConsoleCheckBox; /* @@ -58,7 +56,7 @@ public final class BuiltinSpecsDetectorOptionPage extends AbstractLanguageSettin // Composite optionsPageComposite = new Composite(composite, SWT.NULL); fEditable = parent.isEnabled(); - final Composite composite = new Composite(parent, SWT.NONE); + Composite composite = new Composite(parent, SWT.NONE); { GridLayout layout = new GridLayout(); layout.numColumns = 2; @@ -74,69 +72,7 @@ public final class BuiltinSpecsDetectorOptionPage extends AbstractLanguageSettin composite.setLayoutData(gd); } - - Group groupRun = new Group(composite, SWT.SHADOW_ETCHED_IN); -// groupRun.setText("Language Settings Provider Options"); - - GridLayout gridLayoutRun = new GridLayout(); -// GridLayout gridLayoutRun = new GridLayout(2, true); -// gridLayoutRun.makeColumnsEqualWidth = false; -// gridLayoutRun.marginRight = -10; -// gridLayoutRun.marginLeft = -4; - groupRun.setLayout(gridLayoutRun); -// GridData gdRun = new GridData(GridData.FILL_HORIZONTAL); -// gdRun.horizontalSpan = 2; -// groupRun.setLayoutData(gdRun); - AbstractBuiltinSpecsDetector provider = getRawProvider(); - { - runOnceRadioButton = new Button(groupRun, SWT.RADIO); - runOnceRadioButton.setText("Run only once"); //$NON-NLS-1$ - // b1.setToolTipText(UIMessages.getString("EnvironmentTab.3")); //$NON-NLS-1$ - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 3; - runOnceRadioButton.setLayoutData(gd); - runOnceRadioButton.setSelection(provider.isRunOnce()); - runOnceRadioButton.setEnabled(fEditable); - runOnceRadioButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent evt) { - boolean runOnceEnabled = runOnceRadioButton.getSelection(); - if (runOnceEnabled) { - AbstractBuiltinSpecsDetector provider = getRawProvider(); - if (runOnceEnabled != provider.isRunOnce()) { - AbstractBuiltinSpecsDetector selectedProvider = getWorkingCopy(providerId); - selectedProvider.setRunOnce(runOnceEnabled); - providerTab.refreshItem(selectedProvider); - } - } - } - - }); - } - { - runEveryBuildRadioButton = new Button(groupRun, SWT.RADIO); - runEveryBuildRadioButton.setText("Activate on every build"); //$NON-NLS-1$ - runEveryBuildRadioButton.setSelection(!provider.isRunOnce()); - runEveryBuildRadioButton.setEnabled(fEditable); - GridData gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = 3; - runEveryBuildRadioButton.setLayoutData(gd); - runEveryBuildRadioButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent evt) { - boolean runEveryBuildEnabled = runEveryBuildRadioButton.getSelection(); - if (runEveryBuildEnabled) { - AbstractBuiltinSpecsDetector provider = getRawProvider(); - if (runEveryBuildEnabled != !provider.isRunOnce()) { - AbstractBuiltinSpecsDetector selectedProvider = getWorkingCopy(providerId); - selectedProvider.setRunOnce(!runEveryBuildEnabled); - providerTab.refreshItem(selectedProvider); - } - } - } - }); - } // Compiler specs command { diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/GCCBuiltinSpecsDetectorTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/GCCBuiltinSpecsDetectorTest.java index f33e8d91bdc..104a80775f4 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/GCCBuiltinSpecsDetectorTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/GCCBuiltinSpecsDetectorTest.java @@ -10,65 +10,50 @@ *******************************************************************************/ package org.eclipse.cdt.build.core.scannerconfig.tests; -import java.io.IOException; -import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; -import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.settings.model.CIncludeFileEntry; import org.eclipse.cdt.core.settings.model.CIncludePathEntry; -import org.eclipse.cdt.core.settings.model.CLibraryFileEntry; -import org.eclipse.cdt.core.settings.model.CLibraryPathEntry; import org.eclipse.cdt.core.settings.model.CMacroEntry; -import org.eclipse.cdt.core.settings.model.CMacroFileEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.testplugin.ResourceHelper; -import org.eclipse.cdt.internal.core.XmlUtil; -import org.eclipse.cdt.make.core.scannerconfig.AbstractBuiltinSpecsDetector; import org.eclipse.cdt.managedbuilder.internal.scannerconfig.GCCBuiltinSpecsDetector; import org.eclipse.cdt.managedbuilder.internal.scannerconfig.GCCBuiltinSpecsDetectorCygwin; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; -import org.w3c.dom.Document; -import org.w3c.dom.Element; public class GCCBuiltinSpecsDetectorTest extends TestCase { - private static final String PROVIDER_ID = "provider.id"; - private static final String PROVIDER_NAME = "provider name"; - private static final String LANGUAGE_ID = "language.test.id"; private static final String LANGUAGE_ID_C = GCCLanguage.ID; - private static final String LANGUAGE_ID_CPP = GPPLanguage.ID; - private static final String CUSTOM_PARAMETER = "customParameter"; - private static final String ELEM_TEST = "test"; - // those attributes must match that in AbstractBuiltinSpecsDetector - private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$ - private static final String ATTR_RUN_ONCE = "run-once"; //$NON-NLS-1$ + class MockGCCBuiltinSpecsDetector extends GCCBuiltinSpecsDetector { + @Override + public void startupForLanguage(String languageId) throws CoreException { + super.startupForLanguage(languageId); + } + @Override + public void shutdownForLanguage() { + super.shutdownForLanguage(); + } + } - private class MockBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector { + class MockGCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetectorCygwin { @Override - protected String getToolchainId() { - return null; + public void startupForLanguage(String languageId) throws CoreException { + super.startupForLanguage(languageId); } @Override - protected List parseForOptions(String line) { - return null; - } - @Override - protected AbstractOptionParser[] getOptionParsers() { - return null; + public void shutdownForLanguage() { + super.shutdownForLanguage(); } } @@ -93,540 +78,167 @@ public class GCCBuiltinSpecsDetectorTest extends TestCase { return cfgDescriptions; } - public void testAbstractBuiltinSpecsDetector_GettersSetters() throws Exception { - // define mock detector - MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); - - detector.configureProvider(PROVIDER_ID, PROVIDER_NAME, null, null, null); - assertEquals(PROVIDER_ID, detector.getId()); - assertEquals(PROVIDER_NAME, detector.getName()); - assertEquals(null, detector.getLanguageScope()); - assertEquals(null, detector.getSettingEntries(null, null, null)); - assertEquals(null, detector.getCustomParameter()); - - List languages = new ArrayList(); - languages.add(LANGUAGE_ID); - List entries = new ArrayList(); - ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - entries.add(entry); - - detector.configureProvider(PROVIDER_ID, PROVIDER_NAME, languages, entries, CUSTOM_PARAMETER); - assertEquals(PROVIDER_ID, detector.getId()); - assertEquals(PROVIDER_NAME, detector.getName()); - assertEquals(languages, detector.getLanguageScope()); - assertEquals(entries, detector.getSettingEntries(null, null, null)); - assertEquals(CUSTOM_PARAMETER, detector.getCustomParameter()); - - assertEquals(true, detector.isRunOnce()); - detector.setRunOnce(false); - assertEquals(false, detector.isRunOnce()); - } - - public void testAbstractBuiltinSpecsDetector_CloneAndEquals() throws Exception { - // define mock detector - class MockDetectorCloneable extends MockBuiltinSpecsDetector implements Cloneable { - @Override - public MockDetectorCloneable clone() throws CloneNotSupportedException { - return (MockDetectorCloneable) super.clone(); - } - @Override - public MockDetectorCloneable cloneShallow() throws CloneNotSupportedException { - return (MockDetectorCloneable) super.cloneShallow(); - } - } - - // create instance to compare to - MockDetectorCloneable detector = new MockDetectorCloneable(); - - List languages = new ArrayList(); - languages.add(LANGUAGE_ID); - List entries = new ArrayList(); - ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - entries.add(entry); - - // check clone after initialization - MockDetectorCloneable clone0 = detector.clone(); - assertTrue(detector.equals(clone0)); - - // configure provider - detector.configureProvider(PROVIDER_ID, PROVIDER_NAME, languages, entries, CUSTOM_PARAMETER); - assertEquals(true, detector.isRunOnce()); - detector.setRunOnce(false); - assertFalse(detector.equals(clone0)); - - // check another clone after configuring - { - MockDetectorCloneable clone = detector.clone(); - assertTrue(detector.equals(clone)); - } - - // check custom parameter - { - MockDetectorCloneable clone = detector.clone(); - clone.setCustomParameter("changed"); - assertFalse(detector.equals(clone)); - } - - // check language scope - { - MockDetectorCloneable clone = detector.clone(); - clone.setLanguageScope(null); - assertFalse(detector.equals(clone)); - } - - // check 'run once' flag - { - MockDetectorCloneable clone = detector.clone(); - boolean runOnce = clone.isRunOnce(); - clone.setRunOnce( ! runOnce ); - assertFalse(detector.equals(clone)); - } - - // check console flag - { - MockDetectorCloneable clone = detector.clone(); - boolean isConsoleEnabled = clone.isConsoleEnabled(); - clone.setConsoleEnabled( ! isConsoleEnabled ); - assertFalse(detector.equals(clone)); - } - - // check entries - { - MockDetectorCloneable clone = detector.clone(); - clone.setSettingEntries(null, null, null, null); - assertFalse(detector.equals(clone)); - } - - // check cloneShallow() - { - MockDetectorCloneable detector2 = detector.clone(); - MockDetectorCloneable clone = detector2.cloneShallow(); - assertFalse(detector2.equals(clone)); - detector2.setSettingEntries(null, null, null, null); - assertTrue(detector2.equals(clone)); - } - - } - - /** - */ - public void testAbstractBuiltinSpecsDetector_Serialize() throws Exception { - { - // create empty XML - Document doc = XmlUtil.newDocument(); - Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST); - - // load it to new provider - MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); - detector.load(rootElement); - assertEquals(true, detector.isRunOnce()); - assertEquals(false, detector.isConsoleEnabled()); - } - - Element elementProvider; - { - // define mock detector - MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); - assertEquals(true, detector.isRunOnce()); - assertEquals(false, detector.isConsoleEnabled()); - - // redefine the settings - detector.setRunOnce(false); - assertEquals(false, detector.isRunOnce()); - detector.setConsoleEnabled(true); - assertEquals(true, detector.isConsoleEnabled()); - - // serialize in XML - Document doc = XmlUtil.newDocument(); - Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST); - elementProvider = detector.serialize(rootElement); - String xmlString = XmlUtil.toString(doc); - - assertTrue(xmlString.contains(ATTR_RUN_ONCE)); - assertTrue(xmlString.contains(ATTR_CONSOLE)); - } - { - // create another instance of the provider - MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); - assertEquals(true, detector.isRunOnce()); - assertEquals(false, detector.isConsoleEnabled()); - - // load element - detector.load(elementProvider); - assertEquals(false, detector.isRunOnce()); - assertEquals(true, detector.isConsoleEnabled()); - } - } - - - - public void testAbstractBuiltinSpecsDetector_Nulls() throws Exception { - { - // test AbstractBuiltinSpecsDetector.run(...); - MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); - detector.run((IProject)null, null, null, null, null); - // Do not test with (ICConfigurationDescription)null as it is not allowed - } - - { - // test AbstractBuiltinSpecsDetector.processLine(...) flow - MockBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector(); - detector.startup(null); - detector.processLine(null); - detector.shutdown(); - } - - } - - public void testAbstractBuiltinSpecsDetector_RunConfiguration() throws Exception { - // Create model project and accompanied descriptions - String projectName = getName(); - IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); - ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); - ICConfigurationDescription cfgDescription = cfgDescriptions[0]; - - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector() { - @Override - protected boolean runProgram(String command, String[] env, IPath workingDirectory, IProgressMonitor monitor, - OutputStream consoleOut, OutputStream consoleErr) throws CoreException, IOException { - printLine(consoleOut, "#define MACRO VALUE"); - consoleOut.close(); - consoleErr.close(); - return true; - } - }; - - detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID);}}); - - detector.run(cfgDescription, LANGUAGE_ID, null, null, null); - assertFalse(detector.isEmpty()); - - List noentries = detector.getSettingEntries(null, null, null); - assertNull(noentries); - - List entries = detector.getSettingEntries(cfgDescription, null, LANGUAGE_ID); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); - } - - public void testAbstractBuiltinSpecsDetector_RunProject() throws Exception { - // Create model project and accompanied descriptions - String projectName = getName(); - IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); - - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector() { - @Override - protected boolean runProgram(String command, String[] env, IPath workingDirectory, IProgressMonitor monitor, - OutputStream consoleOut, OutputStream consoleErr) throws CoreException, IOException { - printLine(consoleOut, "#define MACRO VALUE"); - consoleOut.close(); - consoleErr.close(); - return true; - } - }; - - detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID);}}); - - detector.run(project, LANGUAGE_ID, null, null, null); - assertFalse(detector.isEmpty()); - - List entries = detector.getSettingEntries(null, null, LANGUAGE_ID); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); - } - - public void testAbstractBuiltinSpecsDetector_RunGlobal() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector() { - @Override - protected boolean runProgram(String command, String[] env, IPath workingDirectory, IProgressMonitor monitor, - OutputStream consoleOut, OutputStream consoleErr) throws CoreException, IOException { - printLine(consoleOut, "#define MACRO VALUE"); - consoleOut.close(); - consoleErr.close(); - return true; - } - }; - - detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID);}}); - - detector.run((IProject)null, LANGUAGE_ID, null, null, null); - assertFalse(detector.isEmpty()); - - List entries = detector.getSettingEntries(null, null, LANGUAGE_ID); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); - } - - public void testAbstractBuiltinSpecsDetector_RunOnce() throws Exception { - // Create model project and accompanied descriptions - String projectName = getName(); - IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); - ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); - ICConfigurationDescription cfgDescription = cfgDescriptions[0]; - - // Define mock detector which collects number of entries equal to count - AbstractBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector() { - int count=0; - @Override - public boolean processLine(String line) { - count++; - for (int i=0;i entries = detector.getSettingEntries(null, null, LANGUAGE_ID_C); - assertEquals(1, entries.size()); - } - - // run second time - detector.run(project, LANGUAGE_ID_C, null, null, null); - { - List entries = detector.getSettingEntries(null, null, LANGUAGE_ID_C); - assertEquals(2, entries.size()); - } - - // set to run once - detector.setRunOnce(true); - assertEquals(true, detector.isRunOnce()); - assertFalse(detector.isEmpty()); - - detector.run(project, LANGUAGE_ID_C, null, null, null); - { - // should not collect when provider is not empty - List entries = detector.getSettingEntries(null, null, LANGUAGE_ID_C); - assertEquals(2, entries.size()); - } - - detector.run(cfgDescription, LANGUAGE_ID_C, null, null, null); - { - // should not collect when provider is not empty - List entries = detector.getSettingEntries(null, null, LANGUAGE_ID_C); - assertEquals(2, entries.size()); - } - } - - public void testAbstractBuiltinSpecsDetector_Launch() throws Exception { - // Create model project and accompanied descriptions - String projectName = getName(); - IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); - ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); - - ICConfigurationDescription cfgDescription = cfgDescriptions[0]; - - AbstractBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector() { - @Override - public boolean processLine(String line) { - // pretending that we parsed the line - detectedSettingEntries.add(new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY)); - return true; - } - }; - detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID);}}); - detector.setCustomParameter("echo #define MACRO VALUE"); - - detector.run(cfgDescription, LANGUAGE_ID, null, null, null); - - List noentries = detector.getSettingEntries(null, null, null); - assertNull(noentries); - - List entries = detector.getSettingEntries(cfgDescription, null, LANGUAGE_ID); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); - } - - public void testAbstractBuiltinSpecsDetector_GroupSettings() throws Exception { - // define benchmarks - final CIncludePathEntry includePath_1 = new CIncludePathEntry("/include/path_1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CIncludePathEntry includePath_2 = new CIncludePathEntry("/include/path_2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CIncludeFileEntry includeFile_1 = new CIncludeFileEntry(new Path("/include.file1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CIncludeFileEntry includeFile_2 = new CIncludeFileEntry(new Path("/include.file2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CMacroEntry macro_1 = new CMacroEntry("MACRO_1", "", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CMacroEntry macro_2 = new CMacroEntry("MACRO_2", "", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY |ICSettingEntry.UNDEFINED); - final CMacroFileEntry macroFile_1 = new CMacroFileEntry(new Path("/macro.file1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CMacroFileEntry macroFile_2 = new CMacroFileEntry(new Path("/macro.file2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CLibraryPathEntry libraryPath_1 = new CLibraryPathEntry(new Path("/lib/path_1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CLibraryPathEntry libraryPath_2 = new CLibraryPathEntry(new Path("/lib/path_2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CLibraryFileEntry libraryFile_1 = new CLibraryFileEntry("lib_1.a", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - final CLibraryFileEntry libraryFile_2 = new CLibraryFileEntry("lib_2.a", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - - // Define mock detector adding unorganized entries - AbstractBuiltinSpecsDetector detector = new MockBuiltinSpecsDetector() { - @Override - public boolean processLine(String line) { - detectedSettingEntries.add(libraryFile_1); - detectedSettingEntries.add(libraryPath_1); - detectedSettingEntries.add(macroFile_1); - detectedSettingEntries.add(macro_1); - detectedSettingEntries.add(includeFile_1); - detectedSettingEntries.add(includePath_1); - - detectedSettingEntries.add(includePath_2); - detectedSettingEntries.add(includeFile_2); - detectedSettingEntries.add(macro_2); - detectedSettingEntries.add(macroFile_2); - detectedSettingEntries.add(libraryPath_2); - detectedSettingEntries.add(libraryFile_2); - return true; - } - }; - - // run specs detector - detector.startup(null); - detector.processLine(""); - detector.shutdown(); - - - // compare benchmarks, expected well-sorted - List entries = detector.getSettingEntries(null, null, null); - - int i=0; - assertEquals(includePath_1, entries.get(i++)); - assertEquals(includePath_2, entries.get(i++)); - assertEquals(includeFile_1, entries.get(i++)); - assertEquals(includeFile_2, entries.get(i++)); - assertEquals(macro_1, entries.get(i++)); - assertEquals(macro_2, entries.get(i++)); - assertEquals(macroFile_1, entries.get(i++)); - assertEquals(macroFile_2, entries.get(i++)); - assertEquals(libraryPath_1, entries.get(i++)); - assertEquals(libraryPath_2, entries.get(i++)); - assertEquals(libraryFile_1, entries.get(i++)); - assertEquals(libraryFile_2, entries.get(i++)); - - assertEquals(12, entries.size()); - } - - public void testGCCBuiltinSpecsDetector_Macro_NoValue() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); - - detector.startup(null); - detector.processLine("#define MACRO"); - detector.shutdown(); - - List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", null, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); - } - public void testGCCBuiltinSpecsDetector_ResolvedCommand() throws Exception { - class MockGCCBuiltinSpecsDetector extends GCCBuiltinSpecsDetector { + class MockGCCBuiltinSpecsDetectorLocal extends GCCBuiltinSpecsDetector { @Override public String resolveCommand(String languageId) throws CoreException { return super.resolveCommand(languageId); } } { - MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal(); detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); detector.setCustomParameter("${COMMAND} -E -P -v -dD ${INPUTS}"); String resolvedCommand = detector.resolveCommand(LANGUAGE_ID_C); assertTrue(resolvedCommand.startsWith("gcc -E -P -v -dD ")); assertTrue(resolvedCommand.endsWith("spec.c")); - detector.shutdown(); } { - MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal(); detector.setLanguageScope(new ArrayList() {{add(LANGUAGE_ID_C);}}); detector.setCustomParameter("${COMMAND} -E -P -v -dD file.${EXT}"); String resolvedCommand = detector.resolveCommand(LANGUAGE_ID_C); assertTrue(resolvedCommand.startsWith("gcc -E -P -v -dD ")); assertTrue(resolvedCommand.endsWith("file.c")); - detector.shutdown(); } } - public void testGCCBuiltinSpecsDetector_Macro_NoArgs() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + public void testGCCBuiltinSpecsDetector_Macro_NoValue() throws Exception { + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#define MACRO VALUE"); + detector.startupForLanguage(null); + detector.processLine("#define MACRO", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CMacroEntry("MACRO", null, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); + } + + public void testGCCBuiltinSpecsDetector_Macro_Simple() throws Exception { + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); + + detector.startup(null); + detector.startupForLanguage(null); + detector.processLine("#define MACRO VALUE", null); + detector.shutdownForLanguage(); + detector.shutdown(); + + List entries = detector.getSettingEntries(null, null, null); + assertEquals(new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); } public void testGCCBuiltinSpecsDetector_Macro_Const() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#define MACRO (3)"); + detector.startupForLanguage(null); + detector.processLine("#define MACRO (3)", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "(3)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CMacroEntry("MACRO", "(3)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); + } + + public void testGCCBuiltinSpecsDetector_Macro_WhiteSpaces() throws Exception { + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); + + detector.startup(null); + detector.startupForLanguage(null); + detector.processLine("#define \t MACRO_1 VALUE", null); + detector.processLine("#define MACRO_2 \t VALUE", null); + detector.processLine("#define MACRO_3 VALUE \t", null); + detector.shutdownForLanguage(); + detector.shutdown(); + + List entries = detector.getSettingEntries(null, null, null); + int index = 0; + assertEquals(new CMacroEntry("MACRO_1", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CMacroEntry("MACRO_2", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CMacroEntry("MACRO_3", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(index, entries.size()); } public void testGCCBuiltinSpecsDetector_Macro_EmptyArgList() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#define MACRO() VALUE"); + detector.startupForLanguage(null); + detector.processLine("#define MACRO() VALUE", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO()", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CMacroEntry("MACRO()", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); } public void testGCCBuiltinSpecsDetector_Macro_ParamUnused() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#define MACRO(X) VALUE"); + detector.startupForLanguage(null); + detector.processLine("#define MACRO(X) VALUE", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO(X)", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CMacroEntry("MACRO(X)", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); } public void testGCCBuiltinSpecsDetector_Macro_ParamSpace() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#define MACRO(P1, P2) VALUE(P1, P2)"); + detector.startupForLanguage(null); + detector.processLine("#define MACRO(P1, P2) VALUE(P1, P2)", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CMacroEntry("MACRO(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); } public void testGCCBuiltinSpecsDetector_Macro_ArgsNoValue() throws Exception { - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#define MACRO(P1, P2) "); + detector.startupForLanguage(null); + detector.processLine("#define MACRO(P1, P2) ", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - ICLanguageSettingEntry expected = new CMacroEntry("MACRO(P1, P2)", null, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CMacroEntry("MACRO(P1, P2)", null, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); + assertEquals(1, entries.size()); + } + + public void testGCCBuiltinSpecsDetector_Macro_Args_WhiteSpaces() throws Exception { + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); + + detector.startup(null); + detector.startupForLanguage(null); + detector.processLine("#define \t MACRO_1(P1, P2) VALUE(P1, P2)", null); + detector.processLine("#define MACRO_2(P1, P2) \t VALUE(P1, P2)", null); + detector.processLine("#define MACRO_3(P1, P2) VALUE(P1, P2) \t", null); + detector.shutdownForLanguage(); + detector.shutdown(); + + List entries = detector.getSettingEntries(null, null, null); + int index = 0; + assertEquals(new CMacroEntry("MACRO_1(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CMacroEntry("MACRO_2(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CMacroEntry("MACRO_3(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(index, entries.size()); } public void testGCCBuiltinSpecsDetector_Includes() throws Exception { @@ -644,39 +256,64 @@ public class GCCBuiltinSpecsDetectorTest extends TestCase { ResourceHelper.createFolder(project, "/misplaced/include3"); String loc = tmpPath.toString(); - GCCBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); + detector.startupForLanguage(null); - detector.processLine(" "+loc+"/misplaced/include1"); - detector.processLine("#include \"...\" search starts here:"); - detector.processLine(" "+loc+"/local/include"); - detector.processLine("#include <...> search starts here:"); - detector.processLine(" "+loc+"/usr/include"); - detector.processLine(" "+loc+"/usr/include/../include2"); - detector.processLine(" "+loc+"/missing/folder"); - detector.processLine(" "+loc+"/Library/Frameworks (framework directory)"); - detector.processLine("End of search list."); - detector.processLine(" "+loc+"/misplaced/include2"); - detector.processLine("Framework search starts here:"); - detector.processLine(" "+loc+"/System/Library/Frameworks"); - detector.processLine("End of framework search list."); - detector.processLine(" "+loc+"/misplaced/include3"); + detector.processLine(" "+loc+"/misplaced/include1", null); + detector.processLine("#include \"...\" search starts here:", null); + detector.processLine(" "+loc+"/local/include", null); + detector.processLine("#include <...> search starts here:", null); + detector.processLine(" "+loc+"/usr/include", null); + detector.processLine(" "+loc+"/usr/include/../include2", null); + detector.processLine(" "+loc+"/missing/folder", null); + detector.processLine(" "+loc+"/Library/Frameworks (framework directory)", null); + detector.processLine("End of search list.", null); + detector.processLine(" "+loc+"/misplaced/include2", null); + detector.processLine("Framework search starts here:", null); + detector.processLine(" "+loc+"/System/Library/Frameworks", null); + detector.processLine("End of framework search list.", null); + detector.processLine(" "+loc+"/misplaced/include3", null); + detector.shutdownForLanguage(); detector.shutdown(); List entries = detector.getSettingEntries(null, null, null); - assertEquals(new CIncludePathEntry(loc+"/local/include", ICSettingEntry.LOCAL | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - entries.get(0)); - assertEquals(new CIncludePathEntry(loc+"/usr/include", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - entries.get(1)); - assertEquals(new CIncludePathEntry(loc+"/usr/include2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - entries.get(2)); - assertEquals(new CIncludePathEntry(loc+"/missing/folder", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - entries.get(3)); - assertEquals(new CIncludePathEntry(loc+"/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - entries.get(4)); - assertEquals(new CIncludePathEntry(loc+"/System/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - entries.get(5)); - assertEquals(6, entries.size()); + int index = 0; + assertEquals(new CIncludePathEntry(loc+"/local/include", ICSettingEntry.LOCAL | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/usr/include", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/usr/include2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/missing/folder", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/System/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(index, entries.size()); + } + + public void testGCCBuiltinSpecsDetector_Includes_WhiteSpaces() throws Exception { + String loc = ResourceHelper.createTemporaryFolder().toString(); + + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); + detector.startup(null); + detector.startupForLanguage(null); + + detector.processLine("#include \"...\" search starts here:", null); + detector.processLine(" \t "+loc+"/local/include", null); + detector.processLine("#include <...> search starts here:", null); + detector.processLine(loc+"/usr/include", null); + detector.processLine(" "+loc+"/Library/Frameworks \t (framework directory)", null); + detector.processLine("End of search list.", null); + detector.processLine("Framework search starts here:", null); + detector.processLine(" "+loc+"/System/Library/Frameworks \t ", null); + detector.processLine("End of framework search list.", null); + detector.shutdownForLanguage(); + detector.shutdown(); + + List entries = detector.getSettingEntries(null, null, null); + int index = 0; + assertEquals(new CIncludePathEntry(loc+"/local/include", ICSettingEntry.LOCAL | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/usr/include", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(new CIncludePathEntry(loc+"/System/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++)); + assertEquals(index, entries.size()); } public void testGCCBuiltinSpecsDetector_Includes_SymbolicLinkUp() throws Exception { @@ -694,18 +331,19 @@ public class GCCBuiltinSpecsDetectorTest extends TestCase { IPath linkPath = dir1.append("linked"); ResourceHelper.createSymbolicLink(linkPath, dir2); - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector(); + MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector(); detector.startup(null); - detector.processLine("#include <...> search starts here:"); - detector.processLine(" "+linkPath.toString()+"/.."); - detector.processLine("End of search list."); + detector.startupForLanguage(null); + detector.processLine("#include <...> search starts here:", null); + detector.processLine(" "+linkPath.toString()+"/..", null); + detector.processLine("End of search list.", null); + detector.shutdownForLanguage(); detector.shutdown(); // check populated entries List entries = detector.getSettingEntries(null, null, null); - CIncludePathEntry expected = new CIncludePathEntry(dir2.removeLastSegments(1), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY); - assertEquals(expected, entries.get(0)); + assertEquals(new CIncludePathEntry(dir2.removeLastSegments(1), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); assertEquals(1, entries.size()); } @@ -720,19 +358,20 @@ public class GCCBuiltinSpecsDetectorTest extends TestCase { } assertTrue("windowsLocation=["+windowsLocation+"]", new Path(windowsLocation).getDevice()!=null); - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetectorCygwin(); + MockGCCBuiltinSpecsDetectorCygwin detector = new MockGCCBuiltinSpecsDetectorCygwin(); detector.startup(null); - detector.processLine("#include <...> search starts here:"); - detector.processLine(" /usr/include"); - detector.processLine("End of search list."); + detector.startupForLanguage(null); + detector.processLine("#include <...> search starts here:", null); + detector.processLine(" /usr/include", null); + detector.processLine("End of search list.", null); + detector.shutdownForLanguage(); detector.shutdown(); // check populated entries List entries = detector.getSettingEntries(null, null, null); assertEquals(new CIncludePathEntry(new Path(windowsLocation), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0)); assertEquals(1, entries.size()); - } public void testGCCBuiltinSpecsDetector_Cygwin_Configuration() throws Exception { @@ -746,19 +385,20 @@ public class GCCBuiltinSpecsDetectorTest extends TestCase { } assertTrue("windowsLocation=["+windowsLocation+"]", new Path(windowsLocation).getDevice()!=null); - // Create model project and folders to test String projectName = getName(); IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); ICConfigurationDescription cfgDescription = cfgDescriptions[0]; - AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetectorCygwin(); + MockGCCBuiltinSpecsDetectorCygwin detector = new MockGCCBuiltinSpecsDetectorCygwin(); detector.startup(cfgDescription); - detector.processLine("#include <...> search starts here:"); - detector.processLine(" /usr/include"); - detector.processLine("End of search list."); + detector.startupForLanguage(null); + detector.processLine("#include <...> search starts here:", null); + detector.processLine(" /usr/include", null); + detector.processLine("End of search list.", null); + detector.shutdownForLanguage(); detector.shutdown(); // check populated entries diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ExternalBuildRunner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ExternalBuildRunner.java index fbb9244be9e..36e2fb59281 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ExternalBuildRunner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ExternalBuildRunner.java @@ -33,7 +33,6 @@ import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; -import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager_TBD; import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.resources.IConsole; @@ -134,11 +133,6 @@ public class ExternalBuildRunner extends AbstractBuildRunner { Map envMap = getEnvironment(builder); String[] env = getEnvStrings(envMap); - ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(configuration); - if (kind!=IncrementalProjectBuilder.CLEAN_BUILD) { - ManagedBuildManager.runBuiltinSpecsDetectors(cfgDescription, workingDirectory, env, monitor); - } - consoleHeader[1] = configuration.getName(); consoleHeader[2] = project.getName(); buf.append(NEWLINE); @@ -213,14 +207,6 @@ public class ExternalBuildRunner extends AbstractBuildRunner { errMsg = launcher.getErrorMessage(); monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Updating_project")); //$NON-NLS-1$ - // AG: FIXME -// try { -// LanguageSettingsManager.serialize(cfgDescription); -// } catch (CoreException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } - try { // Do not allow the cancel of the refresh, since the builder is external // to Eclipse, files may have been created/modified and we will be out-of-sync. @@ -273,11 +259,6 @@ public class ExternalBuildRunner extends AbstractBuildRunner { consoleOut.close(); consoleErr.close(); cos.close(); - if (kind!=IncrementalProjectBuilder.CLEAN_BUILD) { - LanguageSettingsManager_TBD.serializeWorkspaceProviders(); - ICProjectDescription prjDescription = CCorePlugin.getDefault().getProjectDescription(project, false); - LanguageSettingsProvidersSerializer.serializeLanguageSettings(prjDescription); - } } } catch (Exception e) { ManagedBuilderCorePlugin.log(e); @@ -422,7 +403,7 @@ public class ExternalBuildRunner extends AbstractBuildRunner { if(clParserList.size() != 0){ IConsoleParser[] parsers = clParserList.toArray(new IConsoleParser[clParserList.size()]); - return new ConsoleOutputSniffer(outputStream, errorStream, parsers); + return new ConsoleOutputSniffer(outputStream, errorStream, parsers, epm); } return null; diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java index 5e179f38444..949bd36d05c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/InternalBuildRunner.java @@ -23,7 +23,6 @@ import org.eclipse.cdt.core.ConsoleOutputStream; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; -import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager_TBD; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; @@ -159,9 +158,8 @@ public class InternalBuildRunner extends AbstractBuildRunner { } if (kind!=IncrementalProjectBuilder.CLEAN_BUILD) { + // TODO - AG - sanity check? elaborate ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(configuration); - ManagedBuildManager.runBuiltinSpecsDetectors(cfgDescription, workingDirectory, env, monitor); - List providers = cfgDescription.getLanguageSettingProviders(); for (ILanguageSettingsProvider provider : providers) { if (provider instanceof AbstractBuildCommandParser) { @@ -248,11 +246,6 @@ public class InternalBuildRunner extends AbstractBuildRunner { consoleOutStream.flush(); epmOutputStream.close(); epmOutputStream = null; - if (kind!=IncrementalProjectBuilder.CLEAN_BUILD) { - LanguageSettingsManager_TBD.serializeWorkspaceProviders(); - ICProjectDescription prjDescription = CCorePlugin.getDefault().getProjectDescription(project, false); - LanguageSettingsProvidersSerializer.serializeLanguageSettings(prjDescription); - } // Generate any error markers that the build has discovered monitor.subTask(ManagedMakeMessages diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java index 6e833544aa8..f016158c2a4 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java @@ -49,14 +49,11 @@ import javax.xml.transform.stream.StreamResult; import org.eclipse.cdt.core.AbstractCExtension; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager_TBD; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModelUtil; -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; @@ -66,7 +63,6 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.XmlStorageUtil; import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; -import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty; import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyManager; import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentBuildPathsChangeListener; @@ -4804,52 +4800,4 @@ public class ManagedBuildManager extends AbstractCExtension { return false; } - /** - * TODO - better home? - */ - static public void runBuiltinSpecsDetectors(ICConfigurationDescription cfgDescription, IPath workingDirectory, - String[] env, IProgressMonitor monitor) { - IProject project = cfgDescription.getProjectDescription().getProject(); - List languageIds = LanguageSettingsManager.getLanguages(project, cfgDescription); - if (languageIds.isEmpty()) { - return; - } - - for (ILanguageSettingsProvider provider : cfgDescription.getLanguageSettingProviders()) { - ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider); - if (rawProvider instanceof ILanguageSettingsBuiltinSpecsDetector) { - ILanguageSettingsBuiltinSpecsDetector detector = (ILanguageSettingsBuiltinSpecsDetector)rawProvider; - boolean isWorkspaceProvider = LanguageSettingsManager.isWorkspaceProvider(provider); - for (String languageId : languageIds) { - if (detector.getLanguageScope()==null || detector.getLanguageScope().contains(languageId)) { - try { - if (isWorkspaceProvider) { - detector.run((IProject)null, languageId, workingDirectory, env, monitor); - } else { - detector.run(cfgDescription, languageId, workingDirectory, env, monitor); - } - // detector.shutdown() is called from ConsoleOutputSniffer - } catch (Throwable e) { - IStatus status = new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID, "Internal error in BuiltinSpecsDetector "+detector.getId(), e); - MakeCorePlugin.log(status); - } - } - } - } - } - - - // AG: FIXME -// LanguageSettingsManager.serialize(cfgDescription); - // AG: FIXME - rather send event that ls settings changed - ICProject icProject = CoreModel.getDefault().create(project); - ICElement[] tuSelection = new ICElement[] {icProject}; - try { - CCorePlugin.getIndexManager().update(tuSelection, IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT); - } catch (CoreException e) { - IStatus status = new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Error updating CDT index", e); - ManagedBuilderCorePlugin.log(status); - } - } - } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/GCCBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/GCCBuiltinSpecsDetector.java index 82d2f92570b..0fe79bb509f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/GCCBuiltinSpecsDetector.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/GCCBuiltinSpecsDetector.java @@ -17,7 +17,7 @@ import java.util.List; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICSettingEntry; -import org.eclipse.cdt.make.core.scannerconfig.AbstractBuiltinSpecsDetector; +import org.eclipse.cdt.managedbuilder.scannerconfig.ToolchainBuiltinSpecsDetector; import org.eclipse.core.runtime.CoreException; /** @@ -25,8 +25,8 @@ import org.eclipse.core.runtime.CoreException; * to GCC toolchain {@code cdt.managedbuild.toolchain.gnu.base}. * */ -public class GCCBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector implements ILanguageSettingsEditableProvider { - // must match the toolchain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point +public class GCCBuiltinSpecsDetector extends ToolchainBuiltinSpecsDetector implements ILanguageSettingsEditableProvider { + // ID must match the toolchain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point private static final String GCC_TOOLCHAIN_ID = "cdt.managedbuild.toolchain.gnu.base"; //$NON-NLS-1$ private enum State {NONE, EXPECTING_LOCAL_INCLUDE, EXPECTING_SYSTEM_INCLUDE, EXPECTING_FRAMEWORKS} @@ -37,8 +37,8 @@ public class GCCBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector implem new IncludePathOptionParser("#include \"(\\S.*)\"", "$1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.LOCAL), new IncludePathOptionParser("#include <(\\S.*)>", "$1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), new IncludePathOptionParser("#framework <(\\S.*)>", "$1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.FRAMEWORKS_MAC), - new MacroOptionParser("#define (\\S*\\(.*?\\)) *(.*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), - new MacroOptionParser("#define (\\S*) *(.*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), + new MacroOptionParser("#define\\s+(\\S*\\(.*?\\))\\s*(.*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), + new MacroOptionParser("#define\\s+(\\S*)\\s*(\\S*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), }; @Override diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/scannerconfig/ToolchainBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/scannerconfig/ToolchainBuiltinSpecsDetector.java new file mode 100644 index 00000000000..c8fb17ca9be --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/scannerconfig/ToolchainBuiltinSpecsDetector.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 Andrew Gvozdev 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: + * Andrew Gvozdev - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.managedbuilder.scannerconfig; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.make.core.scannerconfig.AbstractBuiltinSpecsDetector; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; + +public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector { + private Map toolMap = new HashMap(); + /** + * TODO + */ + protected abstract String getToolchainId(); + + private ITool getTool(String languageId) { + ITool langTool = toolMap.get(languageId); + if (langTool != null) { + return langTool; + } + + String toolchainId = getToolchainId(); + IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId); + if (toolchain != null) { + ITool[] tools = toolchain.getTools(); + for (ITool tool : tools) { + IInputType[] inputTypes = tool.getInputTypes(); + for (IInputType inType : inputTypes) { + String lang = inType.getLanguageId(tool); + if (languageId.equals(lang)) { + toolMap.put(languageId, tool); + return tool; + } + } + } + } + ManagedBuilderCorePlugin.error("Unable to find tool in toolchain="+toolchainId+" for language="+languageId); + return null; + } + + @Override + protected String getCompilerCommand(String languageId) { + ITool tool = getTool(languageId); + String compiler = tool.getToolCommand(); + if (compiler.length() == 0) { + String msg = "Unable to find compiler command in toolchain="+getToolchainId(); + ManagedBuilderCorePlugin.error(msg); + } + return compiler; + } + + @Override + protected String getSpecFileExtension(String languageId) { + String ext = null; + ITool tool = getTool(languageId); + String[] srcFileExtensions = tool.getAllInputExtensions(); + if (srcFileExtensions != null && srcFileExtensions.length > 0) { + ext = srcFileExtensions[0]; + } + if (ext == null || ext.length() == 0) { + ManagedBuilderCorePlugin.error("Unable to find file extension for language "+languageId); + } + return ext; + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializable.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializable.java index c4ea03d986b..d9e92b444b4 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializable.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializable.java @@ -584,13 +584,10 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider { } /** - * Shallow clone of the provider. "Shallow" is defined here as the exact copy except that - * the copy will have zero language settings entries. - * - * @return shallow copy of the provider. - * @throws CloneNotSupportedException in case {@link #clone()} throws the exception. + * See {@link #cloneShallow()}. This method is extracted + * to avoid expressing {@link #clone()} via {@link #cloneShallow()}. */ - protected LanguageSettingsSerializable cloneShallow() throws CloneNotSupportedException { + private LanguageSettingsSerializable cloneShallowInternal() throws CloneNotSupportedException { LanguageSettingsSerializable clone = (LanguageSettingsSerializable)super.clone(); if (languageScope!=null) clone.languageScope = new ArrayList(languageScope); @@ -599,9 +596,20 @@ public class LanguageSettingsSerializable extends LanguageSettingsBaseProvider { return clone; } + /** + * Shallow clone of the provider. "Shallow" is defined here as the exact copy except that + * the copy will have zero language settings entries. + * + * @return shallow copy of the provider. + * @throws CloneNotSupportedException in case {@link #clone()} throws the exception. + */ + protected LanguageSettingsSerializable cloneShallow() throws CloneNotSupportedException { + return cloneShallowInternal(); + } + @Override protected LanguageSettingsSerializable clone() throws CloneNotSupportedException { - LanguageSettingsSerializable clone = cloneShallow(); + LanguageSettingsSerializable clone = cloneShallowInternal(); clone.fStorage = cloneStorage(); return clone; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ConsoleOutputSniffer.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ConsoleOutputSniffer.java index 85d1dc3c62b..636fe70164e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ConsoleOutputSniffer.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ConsoleOutputSniffer.java @@ -130,6 +130,8 @@ public class ConsoleOutputSniffer { private OutputStream consoleErrorStream; private IConsoleParser[] parsers; + private ErrorParserManager errorParserManager = null; + public ConsoleOutputSniffer(IConsoleParser[] parsers) { this.parsers = parsers; } @@ -140,6 +142,11 @@ public class ConsoleOutputSniffer { this.consoleErrorStream = errorStream; } + public ConsoleOutputSniffer(OutputStream outputStream, OutputStream errorStream, IConsoleParser[] parsers, ErrorParserManager epm) { + this(outputStream, errorStream, parsers); + this.errorParserManager = epm; + } + /** * Returns an output stream that will be sniffed. * This stream should be hooked up so the command @@ -188,10 +195,10 @@ public class ConsoleOutputSniffer { private synchronized void processLine(String line) { for (IConsoleParser parser : parsers) { try { - if (consoleOutputStream instanceof ErrorParserManager && parser instanceof IErrorParser ) { + if (parser instanceof IErrorParser) { // IErrorParser interface is used here only with purpose to pass ErrorParserManager // which keeps track of CWD and provides useful methods for locating files - ((IErrorParser)parser).processLine(line, (ErrorParserManager) consoleOutputStream); + ((IErrorParser)parser).processLine(line, errorParserManager); } else { parser.processLine(line); } diff --git a/xlc/org.eclipse.cdt.managedbuilder.xlc.core/src/org/eclipse/cdt/managedbuilder/xlc/core/XlcBuiltinSpecsDetector.java b/xlc/org.eclipse.cdt.managedbuilder.xlc.core/src/org/eclipse/cdt/managedbuilder/xlc/core/XlcBuiltinSpecsDetector.java index 5e1075551cc..b2fc7ca939d 100644 --- a/xlc/org.eclipse.cdt.managedbuilder.xlc.core/src/org/eclipse/cdt/managedbuilder/xlc/core/XlcBuiltinSpecsDetector.java +++ b/xlc/org.eclipse.cdt.managedbuilder.xlc.core/src/org/eclipse/cdt/managedbuilder/xlc/core/XlcBuiltinSpecsDetector.java @@ -18,7 +18,7 @@ import java.util.regex.Pattern; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider; import org.eclipse.cdt.core.settings.model.ICSettingEntry; -import org.eclipse.cdt.make.core.scannerconfig.AbstractBuiltinSpecsDetector; +import org.eclipse.cdt.managedbuilder.scannerconfig.ToolchainBuiltinSpecsDetector; /** @@ -38,7 +38,7 @@ rm /tmp/xlcW2lt4Jic * to GCC toolchain {@code cdt.managedbuild.toolchain.gnu.base}. * */ -public class XlcBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector implements ILanguageSettingsEditableProvider { +public class XlcBuiltinSpecsDetector extends ToolchainBuiltinSpecsDetector implements ILanguageSettingsEditableProvider { // must match the toolchain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point // FIXME - ill defined XLC toolchain // private static final String XLC_TOOLCHAIN_ID = "cdt.managedbuild.toolchain.xlc.exe.debug"; //$NON-NLS-1$