diff --git a/build/org.eclipse.cdt.make.core.tests/plugin.xml b/build/org.eclipse.cdt.make.core.tests/plugin.xml
new file mode 100644
index 00000000000..f0a7adef70f
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core.tests/plugin.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllSD80Tests.java b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllSD80Tests.java
new file mode 100644
index 00000000000..f4b900a04c7
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/AllSD80Tests.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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 junit.framework.TestSuite;
+
+public class AllSD80Tests extends TestSuite {
+
+ public static TestSuite suite() {
+ return new AllSD80Tests();
+ }
+
+ public AllSD80Tests() {
+ super(AllSD80Tests.class.getName());
+
+ addTestSuite(GCCBuildCommandParserTest.class);
+ }
+}
diff --git a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/GCCBuildCommandParserTest.java b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/GCCBuildCommandParserTest.java
new file mode 100644
index 00000000000..1f71546aaca
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/GCCBuildCommandParserTest.java
@@ -0,0 +1,1904 @@
+/*******************************************************************************
+ * 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.make.scannerdiscovery;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+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.ICLanguageSetting;
+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.internal.core.settings.model.CProjectDescriptionManager;
+import org.eclipse.cdt.make.core.scannerconfig.AbstractBuildCommandParser;
+import org.eclipse.cdt.make.core.scannerconfig.GCCBuildCommandParser;
+import org.eclipse.cdt.make.core.scannerconfig.ILanguageSettingsBuildOutputScanner;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
+import org.eclipse.core.runtime.content.IContentTypeSettings;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class GCCBuildCommandParserTest extends TestCase {
+ // ID of the parser taken from the extension point
+ private static final String GCC_BUILD_COMMAND_PARSER_EXT = "org.eclipse.cdt.make.core.build.command.parser.gcc"; //$NON-NLS-1$
+
+ private static final String ELEM_TEST = "test";
+ private static final String LANG_CPP = "org.eclipse.cdt.core.g++";
+
+ // those attributes must match that in AbstractBuiltinSpecsDetector
+ private static final String ATTR_EXPAND_RELATIVE_PATHS = "expand-relative-paths"; //$NON-NLS-1$
+
+ private class MockBuildCommandParser extends AbstractBuildCommandParser implements Cloneable {
+ @Override
+ protected AbstractOptionParser[] getOptionParsers() {
+ return new AbstractOptionParser[] {};
+ }
+ @Override
+ public MockBuildCommandParser cloneShallow() throws CloneNotSupportedException {
+ return (MockBuildCommandParser) super.cloneShallow();
+ }
+ @Override
+ public MockBuildCommandParser clone() throws CloneNotSupportedException {
+ return (MockBuildCommandParser) super.clone();
+ }
+ }
+
+ @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;
+ }
+
+ /**
+ * Sets build working directory for DefaultSettingConfiguration being tested.
+ */
+ private void setBuilderCWD(IProject project, IPath buildCWD) throws CoreException {
+ CProjectDescriptionManager manager = CProjectDescriptionManager.getInstance();
+ {
+ ICProjectDescription prjDescription = manager.getProjectDescription(project, true);
+ assertNotNull(prjDescription);
+ ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration();
+ assertNotNull(cfgDescription);
+
+ cfgDescription.getBuildSetting().setBuilderCWD(buildCWD);
+ manager.setProjectDescription(project, prjDescription);
+ // doublecheck builderCWD
+ IPath actualBuildCWD = cfgDescription.getBuildSetting().getBuilderCWD();
+ assertEquals(buildCWD, actualBuildCWD);
+ }
+ {
+ // triplecheck builderCWD for different project/configuration descriptions
+ ICProjectDescription prjDescription = CProjectDescriptionManager.getInstance().getProjectDescription(project, false);
+ assertNotNull(prjDescription);
+ ICConfigurationDescription cfgDescription = prjDescription.getDefaultSettingConfiguration();
+ assertNotNull(cfgDescription);
+
+ }
+ }
+
+ private void setReference(IProject project, final IProject projectReferenced) throws CoreException {
+ {
+ 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();
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ final ICConfigurationDescription cfgDescriptionReferenced = getConfigurationDescriptions(projectReferenced)[0];
+ cfgDescription.setReferenceInfo(new HashMap() {{ put(projectReferenced.getName(), cfgDescriptionReferenced.getId()); }});
+ coreModel.setProjectDescription(project, projectDescription);
+ }
+
+ {
+ // doublecheck that it's set as expected
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+ Map refs = cfgDescription.getReferenceInfo();
+ assertEquals(1, refs.size());
+ Set referencedProjectsNames = new LinkedHashSet(refs.keySet());
+ assertEquals(projectReferenced.getName(), referencedProjectsNames.toArray()[0]);
+ }
+
+ }
+
+
+ public void testAbstractBuildCommandParser_CloneAndEquals() throws Exception {
+ // create instance to compare to
+ MockBuildCommandParser parser = new MockBuildCommandParser();
+ assertEquals(true, parser.isResolvingPaths());
+
+ // check clone after initialization
+ MockBuildCommandParser clone0 = parser.clone();
+ assertTrue(parser.equals(clone0));
+
+ // configure provider
+ parser.setResolvingPaths(false);
+ assertFalse(parser.equals(clone0));
+
+ // check another clone after configuring
+ {
+ MockBuildCommandParser clone = parser.clone();
+ assertTrue(parser.equals(clone));
+ }
+
+ // check 'expand relative paths' flag
+ {
+ MockBuildCommandParser clone = parser.clone();
+ boolean expandRelativePaths = clone.isResolvingPaths();
+ clone.setResolvingPaths( ! expandRelativePaths );
+ assertFalse(parser.equals(clone));
+ }
+
+ // check cloneShallow()
+ {
+ MockBuildCommandParser parser2 = parser.clone();
+ MockBuildCommandParser clone = parser2.cloneShallow();
+ assertTrue(parser2.equals(clone));
+ }
+
+ }
+
+ public void testAbstractBuildCommandParser_Serialize() throws Exception {
+ {
+ // create empty XML
+ Document doc = XmlUtil.newDocument();
+ Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
+
+ // load it to new provider
+ MockBuildCommandParser parser = new MockBuildCommandParser();
+ parser.load(rootElement);
+ assertEquals(true, parser.isResolvingPaths());
+ }
+
+ Element elementProvider;
+ {
+ // define mock parser
+ MockBuildCommandParser parser = new MockBuildCommandParser();
+ assertEquals(true, parser.isResolvingPaths());
+
+ // redefine the settings
+ parser.setResolvingPaths(false);
+ assertEquals(false, parser.isResolvingPaths());
+
+ // serialize in XML
+ Document doc = XmlUtil.newDocument();
+ Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
+ elementProvider = parser.serialize(rootElement);
+ String xmlString = XmlUtil.toString(doc);
+
+ assertTrue(xmlString.contains(ATTR_EXPAND_RELATIVE_PATHS));
+ }
+ {
+ // create another instance of the provider
+ MockBuildCommandParser parser = new MockBuildCommandParser();
+ assertEquals(true, parser.isResolvingPaths());
+
+ // load element
+ parser.load(elementProvider);
+ assertEquals(false, parser.isResolvingPaths());
+ }
+ }
+
+ public void testAbstractBuildCommandParser_Nulls() throws Exception {
+ MockBuildCommandParser parser = new MockBuildCommandParser();
+ parser.startup(null);
+ parser.processLine(null);
+ parser.shutdown();
+
+ List entries = parser.getSettingEntries(null, null, null);
+ assertNull(entries);
+ }
+
+ public void testAbstractBuildCommandParser_Basic() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ final IFile file=ResourceHelper.createFile(project, "file.cpp");
+
+ // create test class
+ ILanguageSettingsBuildOutputScanner parser = new MockBuildCommandParser() {
+ @Override
+ public boolean processLine(String line, ErrorParserManager epm) {
+ // pretending that we parsed the line
+ currentResource = file;
+ List entries = new ArrayList();
+ ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN);
+ entries.add(entry);
+ setSettingEntries(entries);
+ return true;
+ }
+ };
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -DMACRO=VALUE file.cpp");
+ parser.shutdown();
+
+ // sanity check that it does not return same values for all inputs
+ List noentries = parser.getSettingEntries(null, null, null);
+ assertNull(noentries);
+
+ // check populated entries
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CMacroEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN);
+ assertEquals(expected, entries.get(0));
+ }
+
+// public void testGCCBuildCommandParser_Nulls() throws Exception {
+// GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+// parser.startup(null);
+// parser.processLine(null);
+// parser.shutdown();
+//
+// List entries = parser.getSettingEntries(null, null, null);
+// assertNull(entries);
+// }
+
+ /**
+ */
+ public void testOneEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ IPath path = new Path("/path0").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+ }
+
+ /**
+ */
+ public void testGccFlavors() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file1=ResourceHelper.createFile(project, "file1.cpp");
+ IFile file2=ResourceHelper.createFile(project, "file2.cpp");
+ IFile file3=ResourceHelper.createFile(project, "file3.cpp");
+ IFile file4=ResourceHelper.createFile(project, "file4.cpp");
+ IFile file5=ResourceHelper.createFile(project, "file5.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file1.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 file1.cpp");
+ parser.processLine("gcc-4.2 -I/path0 file2.cpp");
+ parser.processLine("g++ -I/path0 file3.cpp");
+ parser.processLine("c++ -I/path0 file4.cpp");
+ parser.processLine("\"gcc\" -I/path0 file5.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file1, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ }
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file2, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ }
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file3, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ }
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file4, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ }
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file5, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testCIncludePathEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc"
+ // regular
+ + " -I/path0 "
+ // space after -I
+ + " -I /path1 "
+ // unknown option, should be ignored
+ + " -? "
+ // double-quoted path with spaces
+ + " -I\"/path with spaces\""
+ // single-quoted path with spaces
+ + " -I'/path with spaces2'"
+ // second single-quoted and space after -I
+ + " -I '/path with spaces3'"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ IPath path = new Path("/path0").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+ {
+ IPath path = new Path("/path1").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(1);
+ assertEquals(expected, entry);
+ }
+ {
+ IPath path = new Path("/path with spaces").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(2);
+ assertEquals(expected, entry);
+ }
+ {
+ IPath path = new Path("/path with spaces2").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(3);
+ assertEquals(expected, entry);
+ }
+ {
+ IPath path = new Path("/path with spaces3").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(4);
+ assertEquals(expected, entry);
+ }
+ }
+
+ /**
+ */
+ public void testCMacroEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -DMACRO0"
+ + " -DMACRO1=value"
+ + " -DMACRO2=\"value with spaces\""
+ + " -DMACRO3='value with spaces'"
+ + " -DMACRO4='\"quoted value\"'"
+ + " -D'MACRO5=\"quoted value\"'"
+ + " -DMACRO6=\\\"escape-quoted value\\\""
+ + " -DMACRO7=\"'single-quoted value'\""
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO0", "", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO1", "value", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(1);
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO2", "value with spaces", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(2);
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO3", "value with spaces", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(3);
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO4", "\"quoted value\"", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(4);
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO5", "\"quoted value\"", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(5);
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO6", "\"escape-quoted value\"", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(6);
+ assertEquals(expected, entry);
+ }
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO7", "'single-quoted value'", 0);
+ CMacroEntry entry = (CMacroEntry)entries.get(7);
+ assertEquals(expected, entry);
+ }
+ }
+
+ /**
+ */
+ public void testCMacroEntry_undef() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -UMACRO"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CMacroEntry("MACRO", null, ICSettingEntry.UNDEFINED), entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testCIncludeFileEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -include /include.file1"
+ + " -include '/include.file with spaces'"
+ + " -include ../../include.file2"
+ + " -include include.file3"
+ + " -include ../../include-file-with-dashes"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ IPath incFile = new Path("/include.file1").setDevice(project.getLocation().getDevice());
+ CIncludeFileEntry expected = new CIncludeFileEntry(incFile, 0);
+ CIncludeFileEntry entry = (CIncludeFileEntry)entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+
+ {
+ IPath incFile = new Path("/include.file with spaces").setDevice(project.getLocation().getDevice());
+ assertEquals(new CIncludeFileEntry(incFile, 0), entries.get(1));
+ }
+ {
+ assertEquals(new CIncludeFileEntry(project.getLocation().removeLastSegments(2).append("include.file2"), 0), entries.get(2));
+ assertEquals(new CIncludeFileEntry(project.getFullPath().append("include.file3"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(3));
+ assertEquals(new CIncludeFileEntry(project.getLocation().removeLastSegments(2).append("include-file-with-dashes"), 0), entries.get(4));
+ }
+ }
+
+ /**
+ */
+ public void testCMacroFileEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -macros macro.file file.cpp");
+ parser.processLine("gcc "
+ + " -macros /macro.file"
+ + " -macros '/macro.file with spaces'"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ IPath path = new Path("/macro.file").setDevice(project.getLocation().getDevice());
+ CMacroFileEntry expected = new CMacroFileEntry(path, 0);
+ CMacroFileEntry entry = (CMacroFileEntry)entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+ {
+ IPath path = new Path("/macro.file with spaces").setDevice(project.getLocation().getDevice());
+ CMacroFileEntry expected = new CMacroFileEntry(path, 0);
+ CMacroFileEntry entry = (CMacroFileEntry)entries.get(1);
+ assertEquals(expected, entry);
+ }
+ }
+
+ /**
+ */
+ public void testCLibraryPathEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -L/path0"
+ + " -L'/path with spaces'"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ IPath path = new Path("/path0").setDevice(project.getLocation().getDevice());
+ CLibraryPathEntry expected = new CLibraryPathEntry(path, 0);
+ CLibraryPathEntry entry = (CLibraryPathEntry)entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+ {
+ IPath path = new Path("/path with spaces").setDevice(project.getLocation().getDevice());
+ CLibraryPathEntry expected = new CLibraryPathEntry(path, 0);
+ CLibraryPathEntry entry = (CLibraryPathEntry)entries.get(1);
+ assertEquals(expected, entry);
+ }
+ }
+
+ /**
+ */
+ public void testCLibraryFileEntry() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -ldomain file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CLibraryFileEntry expected = new CLibraryFileEntry("libdomain.a", 0);
+ CLibraryFileEntry entry = (CLibraryFileEntry) entries.get(0);
+ assertEquals(expected.getName(), entry.getName());
+ assertEquals(expected.getValue(), entry.getValue());
+ assertEquals(expected.getKind(), entry.getKind());
+ assertEquals(expected.getFlags(), entry.getFlags());
+ assertEquals(expected, entry);
+ }
+
+ /**
+ */
+ public void testMixedSettingEntries() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc"
+ + " -I/path0 "
+ + " -DMACRO1=value"
+ + " -v"
+ + " -ldomain"
+ + " -E"
+ + " -I /path1 "
+ + " -DMACRO2=\"value with spaces\""
+ + " -I\"/path with spaces\""
+ + " -o file.exe"
+ + " -L/usr/lib"
+ + " file.cpp"
+ + " -mtune=pentiumpro"
+ );
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+// + " -I/path0 "
+ {
+ IPath path = new Path("/path0").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ assertEquals(expected, entries.get(0));
+ }
+// + " -DMACRO1=value"
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO1", "value", 0);
+ assertEquals(expected, entries.get(1));
+ }
+// + " -ldomain"
+ {
+ CLibraryFileEntry expected = new CLibraryFileEntry("libdomain.a", 0);
+ assertEquals(expected, entries.get(2));
+ }
+// + " -I /path1 "
+ {
+ IPath path = new Path("/path1").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ assertEquals(expected, entries.get(3));
+ }
+// + " -DMACRO2=\"value with spaces\""
+ {
+ CMacroEntry expected = new CMacroEntry("MACRO2", "value with spaces", 0);
+ assertEquals(expected, entries.get(4));
+ }
+// + " -I\"/path with spaces\""
+ {
+ IPath path = new Path("/path with spaces").setDevice(project.getLocation().getDevice());
+ CIncludePathEntry expected = new CIncludePathEntry(path, 0);
+ assertEquals(expected, entries.get(5));
+ }
+// + " -L/usr/lib"
+ {
+ IPath path = new Path("/usr/lib").setDevice(project.getLocation().getDevice());
+ CLibraryPathEntry expected = new CLibraryPathEntry(path, 0);
+ assertEquals(expected, entries.get(6));
+ }
+
+ assertEquals(7, entries.size());
+ }
+
+ /**
+ */
+ public void testFileMissing() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 missing.cpp");
+ parser.shutdown();
+
+ // check entries
+ assertTrue(parser.isEmpty());
+ }
+
+ /**
+ */
+ public void testFileAbsolutePath() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + "-I/path0 "
+ + "-I. "
+ + file.getLocation().toOSString());
+ parser.shutdown();
+
+ // check entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ assertEquals(new CIncludePathEntry(project.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ }
+ }
+
+ /**
+ */
+ public void testFileAbsolutePath_NoProject() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(null);
+ parser.processLine("gcc "
+ + "-I/path0 "
+ + "-I. "
+ + file.getLocation().toOSString());
+ parser.shutdown();
+
+ // check entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(null, file, languageId);
+ assertEquals(new CIncludePathEntry(path0, 0), entries.get(0));
+ assertEquals(new CIncludePathEntry(file.getParent().getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ }
+ }
+
+ /**
+ */
+ public void testFileWithSpaces() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file1=ResourceHelper.createFile(project, "file with spaces 1.cpp");
+ IFile file2=ResourceHelper.createFile(project, "file with spaces 2.cpp");
+ IFile file3=ResourceHelper.createFile(project, "file with spaces 3.cpp");
+ IFile file4=ResourceHelper.createFile(project, "file with spaces 4.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file1.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 'file with spaces 1.cpp'");
+ parser.processLine("gcc -I/path0 \"file with spaces 2.cpp\"");
+ parser.processLine("gcc -I/path0 'file with spaces 3.cpp'\n");
+ parser.processLine("gcc -I/path0 'file with spaces 4.cpp'\r\n");
+ parser.shutdown();
+
+ // check populated entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ // in single quotes
+ List entries = parser.getSettingEntries(cfgDescription, file1, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ {
+ // in double quotes
+ List entries = parser.getSettingEntries(cfgDescription, file2, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ {
+ // Unix EOL
+ List entries = parser.getSettingEntries(cfgDescription, file3, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ {
+ // Windows EOL
+ List entries = parser.getSettingEntries(cfgDescription, file4, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testEndOfLine() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file0=ResourceHelper.createFile(project, "file0.cpp");
+ IFile file1=ResourceHelper.createFile(project, "file1.cpp");
+ IFile file2=ResourceHelper.createFile(project, "file2.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file0.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 file0.cpp");
+ parser.processLine("gcc -I/path0 file1.cpp\n");
+ parser.processLine("gcc -I/path0 file2.cpp\r\n");
+ parser.shutdown();
+
+ // check populated entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file0, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(0);
+ assertEquals(expected, entry);
+ }
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file1, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(0);
+ assertEquals(expected, entry);
+ }
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file2, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ CIncludePathEntry entry = (CIncludePathEntry)entries.get(0);
+ assertEquals(expected, entry);
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_DriveLetter() throws Exception {
+ // do not test on non-windows systems where drive letters are not supported
+ if (! Platform.getOS().equals(Platform.OS_WIN32))
+ return;
+
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ parser.setResolvingPaths(true);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -IC:\\path"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ IPath path0 = new Path("C:\\path").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_ExpandRelativePath() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ IFolder folder=ResourceHelper.createFolder(project, "Folder");
+ IFolder folderComposite=ResourceHelper.createFolder(project, "Folder-Icomposite");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ parser.setResolvingPaths(true);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -I.."
+ + " -IFolder"
+ + " -IFolder-Icomposite" // to test case when "-I" is a part of folder name
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ // check that relative paths are relative to CWD which is the location of the project
+ assertEquals(new CIncludePathEntry(project.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(project.getLocation().removeLastSegments(1), 0), entries.get(1));
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(2));
+ assertEquals(new CIncludePathEntry(folderComposite.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(3));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_DoNotExpandRelativePath() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ @SuppressWarnings("unused")
+ IFolder folder=ResourceHelper.createFolder(project, "Folder");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser with expandRelativePaths=false
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ parser.setResolvingPaths(false);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -I.."
+ + " -IFolder"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(".", 0), entries.get(0));
+ assertEquals(new CIncludePathEntry("..", 0), entries.get(1));
+ assertEquals(new CIncludePathEntry("Folder", 0), entries.get(2));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_DuplicatePath() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ IFolder folder=ResourceHelper.createFolder(project, "Folder");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ parser.setResolvingPaths(true);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -IFolder"
+ + " -IFolder"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(1, entries.size());
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_FollowCWD() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFolder buildDir=ResourceHelper.createFolder(project, "BuildDir");
+ IFolder folder=ResourceHelper.createFolder(project, "BuildDir/Folder");
+ IFile file=ResourceHelper.createFile(project, "BuildDir/file.cpp");
+ @SuppressWarnings("unused")
+ IFile fakeFile=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+ epm.pushDirectoryURI(buildDir.getLocationURI());
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -I.."
+ + " -I../../.."
+ + " -IFolder"
+ + " -IMissingFolder"
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath().removeLastSegments(1), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ assertEquals(new CIncludePathEntry(buildDir.getLocation().removeLastSegments(3), 0), entries.get(2));
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(3));
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath().append("MissingFolder"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(4));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_GuessCWD() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFolder folder=ResourceHelper.createFolder(project, "BuildDir/Folder");
+ IFile file=ResourceHelper.createFile(project, "BuildDir/file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -IFolder"
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ }
+
+ /**
+ */
+ public void testPathEntry_NonExistentCWD_Workspace() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFolder buildDir=project.getFolder("Missing/Folder");
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+ epm.pushDirectoryURI(buildDir.getLocationURI());
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -I.."
+ + " -IFolder"
+ + " ../file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath().removeLastSegments(1), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath().append("Folder"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(2));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_NonExistentCWD_Filesystem() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+ URI uriBuildDir = new URI("file:/non-existing/path");
+ epm.pushDirectoryURI(uriBuildDir);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -I.."
+ + " -IFolder"
+ + " ../file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ IPath buildPath = new Path(uriBuildDir.getPath()).setDevice(project.getLocation().getDevice());
+ assertEquals(new CIncludePathEntry(buildPath, 0), entries.get(0));
+ assertEquals(new CIncludePathEntry(buildPath.removeLastSegments(1), 0), entries.get(1));
+ assertEquals(new CIncludePathEntry(buildPath.append("Folder"), 0), entries.get(2));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_MappedRemoteFolder() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFolder buildDir=ResourceHelper.createFolder(project, "Local/BuildDir");
+ IFolder folder=ResourceHelper.createFolder(project, "Local/BuildDir/Folder");
+ IFolder folder2=ResourceHelper.createFolder(project, "Local/BuildDir/Folder2");
+ IFile file=ResourceHelper.createFile(project, "Local/BuildDir/file.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+ URI uriBuildDir = new URI("file:/BuildDir");
+ epm.pushDirectoryURI(uriBuildDir);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -I/BuildDir/Folder"
+ + " -I../BuildDir/Folder2"
+ + " -I/BuildDir/MissingFolder"
+ + " -I../BuildDir/MissingFolder2"
+ + " /BuildDir/file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ assertEquals(new CIncludePathEntry(folder2.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(2));
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath().append("MissingFolder"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(3));
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath().append("MissingFolder2"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(4));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_MappedFolderInProject() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "BuildDir/file.cpp");
+ IFolder mappedFolder=ResourceHelper.createFolder(project, "Mapped/Folder");
+ IFolder folder=ResourceHelper.createFolder(project, "Mapped/Folder/Subfolder");
+ @SuppressWarnings("unused")
+ IFolder ambiguousFolder1=ResourceHelper.createFolder(project, "One/Ambiguous/Folder");
+ @SuppressWarnings("unused")
+ IFolder ambiguousFolder2=ResourceHelper.createFolder(project, "Another/Ambiguous/Folder");
+
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I/Folder/Subfolder"
+ + " -I/Mapped/Folder"
+ + " -I/Ambiguous/Folder"
+ + " -I/Missing/Folder"
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(mappedFolder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ }
+ {
+ IPath path = new Path("/Ambiguous/Folder").setDevice(file.getLocation().getDevice());
+ assertEquals(new CIncludePathEntry(path, 0), entries.get(2));
+ }
+ {
+ IPath path = new Path("/Missing/Folder").setDevice(file.getLocation().getDevice());
+ assertEquals(new CIncludePathEntry(path, 0), entries.get(3));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_MappedFolderInAnotherProject() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ // create files and folders
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+ // another project
+ IProject anotherProject = ResourceHelper.createCDTProjectWithConfig(projectName+"-another");
+ IFolder folder=ResourceHelper.createFolder(anotherProject, "Mapped/Folder/Subfolder");
+ @SuppressWarnings("unused")
+ IFolder ambiguousFolder1=ResourceHelper.createFolder(anotherProject, "One/Ambiguous/Folder");
+ @SuppressWarnings("unused")
+ IFolder ambiguousFolder2=ResourceHelper.createFolder(anotherProject, "Another/Ambiguous/Folder");
+
+
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I/Folder/Subfolder"
+ + " -I/Ambiguous/Folder"
+ + " -I/Missing/Folder"
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ }
+ {
+ IPath path = new Path("/Ambiguous/Folder").setDevice(file.getLocation().getDevice());
+ assertEquals(new CIncludePathEntry(path, 0), entries.get(1));
+ }
+ {
+ IPath path = new Path("/Missing/Folder").setDevice(file.getLocation().getDevice());
+ assertEquals(new CIncludePathEntry(path, 0), entries.get(2));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_MappedFolderInReferencedProject() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+
+ // create main project
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+
+ // create another project (non-referenced)
+ IProject anotherProject = ResourceHelper.createCDTProjectWithConfig(projectName+"-another");
+ @SuppressWarnings("unused")
+ IFolder folderInAnotherProject=ResourceHelper.createFolder(anotherProject, "Mapped/Folder/Subfolder");
+
+ // create referenced project
+ IProject referencedProject = ResourceHelper.createCDTProjectWithConfig(projectName+"-referenced");
+ IFolder folderInReferencedProject=ResourceHelper.createFolder(referencedProject, "Mapped/Folder/Subfolder");
+ @SuppressWarnings("unused")
+ IFolder ambiguousFolder1=ResourceHelper.createFolder(referencedProject, "One/Ambiguous/Folder");
+ @SuppressWarnings("unused")
+ IFolder ambiguousFolder2=ResourceHelper.createFolder(referencedProject, "Another/Ambiguous/Folder");
+
+ setReference(project, referencedProject);
+
+ // get cfgDescription and language to work with
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I/Folder/Subfolder"
+ + " -I/Ambiguous/Folder"
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(folderInReferencedProject.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+
+ IPath path = new Path("/Ambiguous/Folder").setDevice(file.getLocation().getDevice());
+ assertEquals(new CIncludePathEntry(path, 0), entries.get(1));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_NavigateSymbolicLinkUpAbsolute() throws Exception {
+ // do not test on systems where symbolic links are not supported
+ if (!ResourceHelper.isSymbolicLinkSupported())
+ return;
+
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ String languageId = LANG_CPP;
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+
+ // create link on the filesystem
+ IPath dir1 = ResourceHelper.createTemporaryFolder();
+ IPath dir2 = dir1.removeLastSegments(1);
+ IPath linkPath = dir1.append("linked");
+ ResourceHelper.createSymbolicLink(linkPath, dir2);
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ // "../" should navigate along filesystem path, not along the link itself
+ parser.processLine("gcc -I"+linkPath.toString()+"/.."+" file.cpp", epm);
+ parser.shutdown();
+
+ // check populated entries
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(dir2.removeLastSegments(1), 0);
+ assertEquals(expected, entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_NavigateSymbolicLinkUpRelative() throws Exception {
+ // do not test on systems where symbolic links are not supported
+ if (!ResourceHelper.isSymbolicLinkSupported())
+ return;
+
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ String languageId = LANG_CPP;
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+
+ // create link
+ IFolder folder = ResourceHelper.createFolder(project, "folder");
+ IFolder subfolder = ResourceHelper.createFolder(project, "folder/subfolder");
+ IPath linkPath = project.getLocation().append("linked");
+ ResourceHelper.createSymbolicLink(linkPath, subfolder.getLocation());
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ // "../" should navigate along filesystem path, not along the link itself
+ parser.processLine("gcc -Ilinked/.."+" file.cpp", epm);
+ parser.shutdown();
+
+ // check populated entries
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED);
+ assertEquals(expected, entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_BuildDirDefinedByConfiguration_RelativePath() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ // Create resources trying to confuse the parser
+ @SuppressWarnings("unused")
+ IFile fileInProjectRoot=ResourceHelper.createFile(project, "file.cpp");
+ @SuppressWarnings("unused")
+ IFolder includeDirInProjectRoot=ResourceHelper.createFolder(project, "include");
+ // Create resources meant to be found
+ IFolder buildDir=ResourceHelper.createFolder(project, "BuildDir");
+ IFile file=ResourceHelper.createFile(project, "BuildDir/file.cpp");
+ IFolder includeDir=ResourceHelper.createFolder(project, "BuildDir/include");
+ // Change build dir
+ setBuilderCWD(project, buildDir.getLocation());
+
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -Iinclude"
+ + " file.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(includeDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_BuildDirDefinedByConfiguration_AbsolutePath() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ // Create resources trying to confuse the parser
+ @SuppressWarnings("unused")
+ IFile fileInProjectRoot=ResourceHelper.createFile(project, "file.cpp");
+ @SuppressWarnings("unused")
+ IFolder includeDirInProjectRoot=ResourceHelper.createFolder(project, "include");
+ // Create resources meant to be found
+ IFolder buildDir=ResourceHelper.createFolder(project, "BuildDir");
+ IFile file=ResourceHelper.createFile(project, "BuildDir/file.cpp");
+ IFolder includeDir=ResourceHelper.createFolder(project, "BuildDir/include");
+ // Change build dir
+ setBuilderCWD(project, buildDir.getLocation());
+
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I."
+ + " -Iinclude"
+ + " " + file.getLocation().toOSString()
+ );
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ assertEquals(new CIncludePathEntry(buildDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(includeDir.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(1));
+ }
+
+ }
+
+ public void testContentType_None() throws Exception {
+ MockBuildCommandParser parser = new MockBuildCommandParser() {
+ @Override
+ protected String parseForResourceName(String line) {
+ return "file.wrong-content-type";
+ }
+ };
+ parser.startup(null);
+ parser.processLine("gcc file.wrong-content-type");
+ parser.shutdown();
+
+ List entries = parser.getSettingEntries(null, null, null);
+ assertNull(entries);
+ }
+
+ /**
+ */
+ public void testContentType_Mismatch() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+ ResourceHelper.createFile(project, "file.c");
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ // restrict the parser's language scope to C++ only
+ parser.setLanguageScope(new ArrayList() {{add(LANG_CPP);}});
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 file.c");
+ parser.shutdown();
+
+ assertTrue(parser.isEmpty());
+ }
+
+ /**
+ */
+ public void testContentType_FileExtensions() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ String languageId = LANG_CPP;
+ // add custom extension to C++ content type
+ IContentTypeManager manager = Platform.getContentTypeManager();
+ IContentType contentType = manager.findContentTypeFor("file.cpp");
+ contentType.addFileSpec("x++", IContentTypeSettings.FILE_EXTENSION_SPEC);
+
+ IFile file=ResourceHelper.createFile(project, "file.x++");
+ IContentType contentTypeX = manager.findContentTypeFor("file.x++");
+ assertEquals(contentType, contentTypeX);
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 file.x++");
+ parser.shutdown();
+
+ // check populated entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testUpperCase() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ String languageId = LANG_CPP;
+
+ IFile file=ResourceHelper.createFile(project, "file.cpp");
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc -I/path0 FILE.CPP", epm);
+ parser.shutdown();
+
+ // check populated entries
+ IPath path0 = new Path("/path0").setDevice(project.getLocation().getDevice());
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ CIncludePathEntry expected = new CIncludePathEntry(path0, 0);
+ assertEquals(expected, entries.get(0));
+ }
+ }
+
+ /**
+ */
+ public void testBoostBjam() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ IFile file=ResourceHelper.createFile(project, "libs/python/src/numeric.cpp");
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+
+ // parse line
+ parser.startup(cfgDescription);
+ // "g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -g -mthreads -DBOOST_ALL_NO_LIB=1 -DBOOST_PYTHON_SOURCE -DBOOST_PYTHON_STATIC_LIB -I"." -I"/Python25/Include" -c -o "bin.v2/libs/python/build/gcc-mingw-3.4.5/debug/link-static/threading-multi/numeric.o" "libs/python/src/numeric.cpp"
+ parser.processLine(" \"g++\"" +
+ " -ftemplate-depth-128 -O0 -fno-inline -Wall -g -mthreads" +
+ " -DBOOST_ALL_NO_LIB=1" +
+ " -DBOOST_PYTHON_SOURCE" +
+ " -DBOOST_PYTHON_STATIC_LIB" +
+ " -I\".\"" +
+ " -I\"/Python1025/Include\"" +
+ " -c -o \"bin.v2/libs/python/build/gcc-mingw-3.4.5/debug/link-static/threading-multi/numeric.o\"" +
+ " libs/python/src/numeric.cpp");
+ parser.shutdown();
+
+ // check populated entries
+ {
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ assertEquals(new CMacroEntry("BOOST_ALL_NO_LIB", "1", 0), entries.get(0));
+ assertEquals(new CMacroEntry("BOOST_PYTHON_SOURCE", "", 0), entries.get(1));
+ assertEquals(new CMacroEntry("BOOST_PYTHON_STATIC_LIB", "", 0), entries.get(2));
+ assertEquals(new CIncludePathEntry(project.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(3));
+ assertEquals(new CIncludePathEntry(new Path("/Python1025/Include").setDevice(project.getLocation().getDevice()), 0), entries.get(4));
+ assertEquals(5, entries.size());
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_Efs() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ // create folder structure
+ @SuppressWarnings("unused")
+ IFolder buildDir=ResourceHelper.createEfsFolder(project, "BuildDir", new URI("mem:/EfsProject/BuildDir"));
+ IFolder folder=ResourceHelper.createEfsFolder(project, "BuildDir/Folder", new URI("mem:/EfsProject/BuildDir/Folder"));
+ IFile file=ResourceHelper.createEfsFile(project, "BuildDir/file.cpp", new URI("mem:/EfsProject/BuildDir/file.cpp"));
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -IFolder"
+ + " -I/Absolute/Folder"
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ String device = project.getLocation().getDevice();
+ assertEquals(new CIncludePathEntry(folder.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(0));
+ assertEquals(new CIncludePathEntry(new Path("/Absolute/Folder").setDevice(device), 0), entries.get(1));
+ }
+ }
+
+ /**
+ */
+ public void testPathEntry_EfsMappedFolder() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+
+ // create folder structure
+ @SuppressWarnings("unused")
+ IFolder buildDir=ResourceHelper.createEfsFolder(project, "BuildDir", new URI("mem:/MappedEfsProject/BuildDir"));
+ @SuppressWarnings("unused")
+ IFolder folder=ResourceHelper.createEfsFolder(project, "BuildDir/Folder", new URI("mem:/MappedEfsProject/BuildDir/Folder"));
+ IFile file=ResourceHelper.createEfsFile(project, "BuildDir/file.cpp", new URI("mem:/MappedEfsProject/BuildDir/file.cpp"));
+ ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true);
+ String languageId = ls.getLanguageId();
+
+ // create GCCBuildCommandParser
+ GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT);
+ ErrorParserManager epm = new ErrorParserManager(project, null);
+
+ // parse line
+ parser.startup(cfgDescription);
+ parser.processLine("gcc "
+ + " -I/BeingMappedFrom/Folder" // mapped to local folder in EFSExtensionProvider extension point
+ + " file.cpp",
+ epm);
+ parser.shutdown();
+
+ // check populated entries
+ List entries = parser.getSettingEntries(cfgDescription, file, languageId);
+ {
+ String device = project.getLocation().getDevice();
+ assertEquals(new CIncludePathEntry(new Path("/LocallyMappedTo/Folder").setDevice(device), 0), entries.get(0));
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/ScannerDiscoveryTests.java b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/ScannerDiscoveryTests.java
index 973802190a0..75eed421b16 100644
--- a/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/ScannerDiscoveryTests.java
+++ b/build/org.eclipse.cdt.make.core.tests/src/org/eclipse/cdt/make/scannerdiscovery/ScannerDiscoveryTests.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2009 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:
- * Markus Schorn - initial API and implementation
+ * Andrew Gvozdev - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.make.scannerdiscovery;
diff --git a/build/org.eclipse.cdt.make.core/plugin.xml b/build/org.eclipse.cdt.make.core/plugin.xml
index 03f6d45a78a..d9ac29dfc6d 100644
--- a/build/org.eclipse.cdt.make.core/plugin.xml
+++ b/build/org.eclipse.cdt.make.core/plugin.xml
@@ -182,5 +182,14 @@
class="org.eclipse.cdt.make.internal.core.dataprovider.MakeConfigurationDataProvider"
/>
+
+
+
+
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
new file mode 100644
index 00000000000..e6a9d2de807
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractBuildCommandParser.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.make.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.IErrorParser2;
+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;
+
+public abstract class AbstractBuildCommandParser extends AbstractLanguageSettingsOutputScanner implements
+ ILanguageSettingsBuildOutputScanner {
+
+ private static final Pattern OPTIONS_PATTERN = Pattern.compile("-[^\\s\"']*(\\s*((\".*?\")|('.*?')|([^-\\s][^\\s]+)))?"); //$NON-NLS-1$
+ private static final int OPTION_GROUP = 0;
+
+ /**
+ * Note: design patterns to keep file group the same and matching {@link #FILE_GROUP}
+ */
+ @SuppressWarnings("nls")
+ private static final String[] PATTERN_TEMPLATES = {
+ "\\s*\"?${COMPILER_PATTERN}\"?.*\\s" + "()([^'\"\\s]*\\.${EXTENSIONS_PATTERN})(\\s.*)?[\r\n]*", // compiling unquoted file
+ "\\s*\"?${COMPILER_PATTERN}\"?.*\\s" + "(['\"])(.*\\.${EXTENSIONS_PATTERN})\\${COMPILER_GROUPS+1}(\\s.*)?[\r\n]*" // compiling quoted file
+ };
+ private static final int FILE_GROUP = 2;
+
+
+ @SuppressWarnings("nls")
+ private String getCompilerCommandPattern() {
+ String parameter = getCustomParameter();
+ return "(" + parameter + ")";
+ }
+
+ private int adjustFileGroup() {
+ return countGroups(getCompilerCommandPattern()) + FILE_GROUP;
+ }
+
+ private String makePattern(String template) {
+ @SuppressWarnings("nls")
+ String pattern = template
+ .replace("${COMPILER_PATTERN}", getCompilerCommandPattern())
+ .replace("${EXTENSIONS_PATTERN}", getPatternFileExtensions())
+ .replace("${COMPILER_GROUPS+1}", new Integer(countGroups(getCompilerCommandPattern()) + 1).toString());
+ return pattern;
+ }
+
+ @Override
+ protected String parseForResourceName(String line) {
+ if (line==null) {
+ return null;
+ }
+
+ for (String template : PATTERN_TEMPLATES) {
+ String pattern = makePattern(template);
+ Matcher fileMatcher = Pattern.compile(pattern).matcher(line);
+ if (fileMatcher.matches()) {
+ int fileGroup = adjustFileGroup();
+ String sourceFileName = fileMatcher.group(fileGroup);
+ return sourceFileName;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected List parseForOptions(String line) {
+ if (line==null || currentResource==null) {
+ return null;
+ }
+
+ List options = new ArrayList();
+ Matcher optionMatcher = OPTIONS_PATTERN.matcher(line);
+ while (optionMatcher.find()) {
+ String option = optionMatcher.group(OPTION_GROUP);
+ if (option!=null) {
+ options.add(option);
+ }
+ }
+ return options;
+ }
+
+ // 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);
+ }
+
+ /**
+ * Trivial Error Parser which allows highlighting of output lines matching the patterns
+ * of this parser. Intended for better troubleshooting experience.
+ * Implementers are supposed to add the error parser as an extension. Initialize with
+ * build command parser extension ID.
+ */
+ protected static abstract class AbstractBuildCommandPatternHighlighter extends RegexErrorParser implements IErrorParser2 {
+ public AbstractBuildCommandPatternHighlighter(String buildCommandParserPluginExtension) {
+ init(buildCommandParserPluginExtension);
+ }
+
+ protected void init(String buildCommandParserId) {
+ AbstractBuildCommandParser buildCommandParser = (AbstractBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(buildCommandParserId);
+ for (String template : PATTERN_TEMPLATES) {
+ String pattern = buildCommandParser.makePattern(template);
+ String fileExpr = "$"+buildCommandParser.adjustFileGroup(); //$NON-NLS-1$
+ String descExpr = "$0"; //$NON-NLS-1$
+ addPattern(new RegexErrorPattern(pattern, fileExpr, null, descExpr, null, IMarkerGenerator.SEVERITY_WARNING, true));
+ }
+ }
+
+ public int getProcessLineBehaviour() {
+ return KEEP_LONGLINES;
+ }
+ }
+
+
+}
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
new file mode 100644
index 00000000000..4f30aaba5f5
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/AbstractLanguageSettingsOutputScanner.java
@@ -0,0 +1,821 @@
+/*******************************************************************************
+ * 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.make.core.scannerconfig;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsSerializable;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.LanguageManager;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.core.settings.model.util.CDataUtil;
+import org.eclipse.cdt.internal.core.XmlUtil;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.utils.EFSExtensionManager;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
+import org.w3c.dom.Element;
+
+public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSettingsSerializable implements
+ ILanguageSettingsOutputScanner {
+
+ protected static final String ATTR_EXPAND_RELATIVE_PATHS = "expand-relative-paths"; //$NON-NLS-1$
+
+ protected ICConfigurationDescription currentCfgDescription = null;
+ protected IProject currentProject = null;
+ protected IResource currentResource = null;
+ protected String currentLanguageId = null;
+
+ protected ErrorParserManager errorParserManager = null;
+ protected String parsedResourceName = null;
+ protected boolean isResolvingPaths = true;
+
+ protected static abstract class AbstractOptionParser {
+ protected final Pattern pattern;
+ protected final String patternStr;
+ protected String nameExpression;
+ protected String valueExpression;
+ protected int extraFlag = 0;
+ protected int kind = 0;
+ private String parsedName;
+ private String parsedValue;
+
+ public AbstractOptionParser(int kind, String pattern, String nameExpression, String valueExpression, int extraFlag) {
+ this.kind = kind;
+ this.patternStr = pattern;
+ this.nameExpression = nameExpression;
+ this.valueExpression = valueExpression;
+ this.extraFlag = extraFlag;
+
+ this.pattern = Pattern.compile(pattern);
+ }
+
+ public ICLanguageSettingEntry createEntry(String name, String value, int flag) {
+ return (ICLanguageSettingEntry) CDataUtil.createEntry(kind, name, value, null, flag | extraFlag);
+ }
+
+ /**
+ * TODO: explain
+ */
+ protected String extractOption(String input) {
+ @SuppressWarnings("nls")
+ String option = input.replaceFirst("(" + patternStr + ").*", "$1");
+ return option;
+ }
+
+ protected String parseStr(Matcher matcher, String str) {
+ if (str != null)
+ return matcher.replaceAll(str);
+ return null;
+ }
+
+ protected boolean isPathKind() {
+ return kind == ICSettingEntry.INCLUDE_PATH || kind == ICSettingEntry.INCLUDE_FILE
+ || kind == ICSettingEntry.MACRO_FILE || kind == ICSettingEntry.LIBRARY_PATH;
+ }
+
+ public boolean parseOption(String option) {
+ String opt = extractOption(option);
+ Matcher matcher = pattern.matcher(opt);
+ boolean isMatch = matcher.matches();
+ if (isMatch) {
+ parsedName = parseStr(matcher, nameExpression);
+ parsedValue = parseStr(matcher, valueExpression);
+ }
+ return isMatch;
+ }
+
+ }
+
+ protected static class IncludePathOptionParser extends AbstractOptionParser {
+ public IncludePathOptionParser(String pattern, String nameExpression) {
+ super(ICLanguageSettingEntry.INCLUDE_PATH, pattern, nameExpression, nameExpression, 0);
+ }
+ public IncludePathOptionParser(String pattern, String nameExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.INCLUDE_PATH, pattern, nameExpression, nameExpression, extraFlag);
+ }
+ }
+
+ protected static class IncludeFileOptionParser extends AbstractOptionParser {
+ public IncludeFileOptionParser(String pattern, String nameExpression) {
+ super(ICLanguageSettingEntry.INCLUDE_FILE, pattern, nameExpression, nameExpression, 0);
+ }
+ public IncludeFileOptionParser(String pattern, String nameExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.INCLUDE_FILE, pattern, nameExpression, nameExpression, extraFlag);
+ }
+ }
+
+ protected static class MacroOptionParser extends AbstractOptionParser {
+ public MacroOptionParser(String pattern, String nameExpression, String valueExpression) {
+ super(ICLanguageSettingEntry.MACRO, pattern, nameExpression, valueExpression, 0);
+ }
+ public MacroOptionParser(String pattern, String nameExpression, String valueExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.MACRO, pattern, nameExpression, valueExpression, extraFlag);
+ }
+ public MacroOptionParser(String pattern, String nameExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.MACRO, pattern, nameExpression, null, extraFlag);
+ }
+ }
+
+ protected static class MacroFileOptionParser extends AbstractOptionParser {
+ public MacroFileOptionParser(String pattern, String nameExpression) {
+ super(ICLanguageSettingEntry.MACRO_FILE, pattern, nameExpression, nameExpression, 0);
+ }
+ public MacroFileOptionParser(String pattern, String nameExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.MACRO_FILE, pattern, nameExpression, nameExpression, extraFlag);
+ }
+ }
+
+ protected static class LibraryPathOptionParser extends AbstractOptionParser {
+ public LibraryPathOptionParser(String pattern, String nameExpression) {
+ super(ICLanguageSettingEntry.LIBRARY_PATH, pattern, nameExpression, nameExpression, 0);
+ }
+ public LibraryPathOptionParser(String pattern, String nameExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.LIBRARY_PATH, pattern, nameExpression, nameExpression, extraFlag);
+ }
+ }
+
+ protected static class LibraryFileOptionParser extends AbstractOptionParser {
+ public LibraryFileOptionParser(String pattern, String nameExpression) {
+ super(ICLanguageSettingEntry.LIBRARY_FILE, pattern, nameExpression, nameExpression, 0);
+ }
+ public LibraryFileOptionParser(String pattern, String nameExpression, int extraFlag) {
+ super(ICLanguageSettingEntry.LIBRARY_FILE, pattern, nameExpression, nameExpression, extraFlag);
+ }
+ }
+
+ /**
+ * Parse the line returning the resource name as appears in the output.
+ * This is the resource where {@link ICLanguageSettingEntry} list is being added.
+ *
+ * @param line - one input line from the output stripped from end of line characters.
+ * @return the resource name as appears in the output or {@code null}.
+ * Note that {@code null} can have different semantics and can mean "no resource found"
+ * or "applicable to any resource". By default "no resource found" is used in this
+ * abstract class but extenders can handle otherwise.
+ */
+ protected abstract String parseForResourceName(String line);
+
+ /**
+ * Parse the line returning the list of substrings to be treated each as input to
+ * the option parsers. It is assumed that each substring presents one
+ * {@link ICLanguageSettingEntry} (for example compiler options {@code -I/path} or
+ * {@code -DMACRO=1}.
+ *
+ * @param line - one input line from the output stripped from end of line characters.
+ * @return list of substrings representing language settings entries.
+ */
+ protected abstract List parseForOptions(String line);
+
+ /**
+ * @return array of option parsers defining how to parse a string to
+ * {@link ICLanguageSettingEntry}.
+ * See {@link AbstractOptionParser} and its specific extenders.
+ */
+ protected abstract AbstractOptionParser[] getOptionParsers();
+
+ public boolean isResolvingPaths() {
+ return isResolvingPaths;
+ }
+
+ public void setResolvingPaths(boolean resolvePaths) {
+ this.isResolvingPaths = resolvePaths;
+ }
+
+
+ public void startup(ICConfigurationDescription cfgDescription) throws CoreException {
+ currentCfgDescription = cfgDescription;
+ currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null;
+ }
+
+ public boolean processLine(String line) {
+ return processLine(line, null);
+ }
+
+ public void shutdown() {
+ }
+
+ public boolean processLine(String line, ErrorParserManager epm) {
+ errorParserManager = epm;
+ parsedResourceName = parseForResourceName(line);
+
+ currentLanguageId = determineLanguage(parsedResourceName);
+ if (!isLanguageInScope(currentLanguageId))
+ return false;
+
+ currentResource = findResource(parsedResourceName);
+
+ /**
+ * Where source tree starts if mapped. This kind of mapping is useful for example in cases when
+ * the absolute path to the source file on the remote system is simulated inside a project in the
+ * workspace.
+ */
+ URI mappedRootURI = null;
+ URI buildDirURI = null;
+
+ if (isResolvingPaths) {
+ if (currentResource!=null) {
+ mappedRootURI = getMappedRootURI(currentResource, parsedResourceName);
+ }
+ buildDirURI = getBuildDirURI(mappedRootURI);
+ }
+
+ List entries = new ArrayList();
+
+ List options = parseForOptions(line);
+ if (options!=null) {
+ for (String option : options) {
+ for (AbstractOptionParser optionParser : getOptionParsers()) {
+ try {
+ if (optionParser.parseOption(option)) {
+ ICLanguageSettingEntry entry = null;
+ if (isResolvingPaths && optionParser.isPathKind()) {
+ URI baseURI = new Path(optionParser.parsedName).isAbsolute() ? mappedRootURI : buildDirURI;
+ entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI);
+ } else {
+ entry = optionParser.createEntry(optionParser.parsedName, optionParser.parsedValue, 0);
+ }
+
+ if (entry != null && !entries.contains(entry)) {
+ entries.add(entry);
+ break;
+ }
+ }
+ } catch (Throwable e) {
+ // protect from rogue parsers extending this class
+ MakeCorePlugin.log(e);
+ }
+ }
+ }
+ if (entries.size() > 0) {
+ setSettingEntries(entries);
+ } else {
+ setSettingEntries(null);
+ }
+ }
+ return false;
+ }
+
+ 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);
+ MakeCorePlugin.log(status);
+ }
+
+ protected String determineLanguage(String parsedResourceName) {
+ if (parsedResourceName==null)
+ return null;
+
+ String fileName = new Path(parsedResourceName).lastSegment().toString();
+ IContentTypeManager manager = Platform.getContentTypeManager();
+ IContentType contentType = manager.findContentTypeFor(fileName);
+ if (contentType==null)
+ return null;
+
+ ILanguage lang = LanguageManager.getInstance().getLanguage(contentType);
+ if (lang==null)
+ return null;
+
+ return lang.getId();
+ }
+
+ protected boolean isLanguageInScope(String languageId) {
+ List languageIds = getLanguageScope();
+ return languageIds == null || languageIds.contains(languageId);
+ }
+
+ protected String getPatternFileExtensions() {
+ IContentTypeManager manager = Platform.getContentTypeManager();
+
+ Set fileExts = new HashSet();
+
+ IContentType contentTypeCpp = manager.getContentType("org.eclipse.cdt.core.cxxSource"); //$NON-NLS-1$
+ fileExts.addAll(Arrays.asList(contentTypeCpp.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)));
+
+ IContentType contentTypeC = manager.getContentType("org.eclipse.cdt.core.cSource"); //$NON-NLS-1$
+ fileExts.addAll(Arrays.asList(contentTypeC.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)));
+
+ String pattern = expressionLogicalOr(fileExts);
+
+ return pattern;
+ }
+
+ private ICLanguageSettingEntry createResolvedPathEntry(AbstractOptionParser optionParser,
+ String parsedPath, int flag, URI baseURI) {
+
+ ICLanguageSettingEntry entry;
+ String resolvedPath = null;
+
+ URI uri = determineURI(parsedPath, baseURI);
+ IResource rc = null;
+ if (uri != null && uri.isAbsolute()) {
+ rc = findResourceForLocationURI(uri, optionParser.kind, currentProject);
+ }
+ if (rc != null) {
+ IPath path = rc.getFullPath();
+ resolvedPath = path.toString();
+ flag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED;
+ } else {
+ IPath path = getFilesystemLocation(uri);
+ if (path != null && new File(path.toString()).exists()) {
+ resolvedPath = path.toString();
+ }
+ if (resolvedPath == null) {
+ Set referencedProjectsNames = new LinkedHashSet();
+ if (currentCfgDescription!=null) {
+ Map refs = currentCfgDescription.getReferenceInfo();
+ referencedProjectsNames.addAll(refs.keySet());
+ }
+ IResource resource = resolveResourceInWorkspace(parsedPath, currentProject, referencedProjectsNames);
+ if (resource != null) {
+ path = resource.getFullPath();
+ resolvedPath = path.toString();
+ flag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED;
+ }
+ }
+ if (resolvedPath==null && path!=null) {
+ resolvedPath = path.toString();
+ }
+ }
+
+ if (resolvedPath==null) {
+ resolvedPath = parsedPath;
+ }
+
+ entry = optionParser.createEntry(resolvedPath, resolvedPath, flag);
+ return entry;
+ }
+
+ private IResource findResource(String parsedResourceName) {
+ if (parsedResourceName==null)
+ return null;
+
+ IResource sourceFile = null;
+
+ // try ErrorParserManager
+ if (errorParserManager != null) {
+ sourceFile = errorParserManager.findFileName(parsedResourceName);
+ }
+ // try to find absolute path in the workspace
+ if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) {
+ URI uri = org.eclipse.core.filesystem.URIUtil.toURI(parsedResourceName);
+ sourceFile = findFileForLocationURI(uri, currentProject);
+ }
+ // try path relative to build dir from configuration
+ if (sourceFile == null && currentCfgDescription != null) {
+ IPath builderCWD = currentCfgDescription.getBuildSetting().getBuilderCWD();
+ if (builderCWD!=null) {
+ IPath path = builderCWD.append(parsedResourceName);
+ URI uri = org.eclipse.core.filesystem.URIUtil.toURI(path);
+ sourceFile = findFileForLocationURI(uri, currentProject);
+ }
+ }
+ // try path relative to the project
+ if (sourceFile == null && currentProject != null) {
+ sourceFile = currentProject.findMember(parsedResourceName);
+ }
+ return sourceFile;
+ }
+
+ private URI getBuildDirURI(URI mappedRootURI) {
+ URI buildDirURI = null;
+
+ URI cwdURI = null;
+ if (currentResource!=null && parsedResourceName!=null && !new Path(parsedResourceName).isAbsolute()) {
+ cwdURI = findBaseLocationURI(currentResource.getLocationURI(), parsedResourceName);
+ }
+ if (cwdURI == null && errorParserManager != null) {
+ cwdURI = errorParserManager.getWorkingDirectoryURI();
+ }
+
+ String cwdPath = cwdURI != null ? EFSExtensionManager.getDefault().getPathFromURI(cwdURI) : null;
+ if (cwdPath != null && mappedRootURI != null) {
+ buildDirURI = EFSExtensionManager.getDefault().append(mappedRootURI, cwdPath);
+ } else {
+ buildDirURI = cwdURI;
+ }
+
+ if (buildDirURI == null && currentCfgDescription != null) {
+ IPath builderCWD = currentCfgDescription.getBuildSetting().getBuilderCWD();
+ buildDirURI = org.eclipse.core.filesystem.URIUtil.toURI(builderCWD);
+ }
+
+ if (buildDirURI == null && currentProject != null) {
+ buildDirURI = currentProject.getLocationURI();
+ }
+
+ if (buildDirURI == null && currentResource != null) {
+ IContainer container;
+ if (currentResource instanceof IContainer) {
+ container = (IContainer) currentResource;
+ } else {
+ container = currentResource.getParent();
+ }
+ buildDirURI = container.getLocationURI();
+ }
+ return buildDirURI;
+ }
+
+ /**
+ * Determine URI appending to baseURI when possible.
+ *
+ * @param pathStr - path to the resource, can be absolute or relative
+ * @param baseURI - base {@link URI} where path to the resource is rooted
+ * @return {@link URI} of the resource
+ */
+ private static URI determineURI(String pathStr, URI baseURI) {
+ URI uri = null;
+
+ if (baseURI==null) {
+ if (new Path(pathStr).isAbsolute()) {
+ uri = resolvePathFromBaseLocation(pathStr, Path.ROOT);
+ }
+ } else if (baseURI.getScheme().equals(EFS.SCHEME_FILE)) {
+ // location on the local filesystem
+ IPath baseLocation = org.eclipse.core.filesystem.URIUtil.toPath(baseURI);
+ // careful not to use Path here but 'pathStr' as String as we want to properly navigate symlinks
+ uri = resolvePathFromBaseLocation(pathStr, baseLocation);
+ } else {
+ // use canonicalized path here, in particular replace all '\' with '/' for Windows paths
+ Path path = new Path(pathStr);
+ uri = EFSExtensionManager.getDefault().append(baseURI, path.toString());
+ }
+
+ if (uri == null) {
+ // if everything fails just wrap string to URI
+ uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr);
+ }
+ return uri;
+ }
+
+ private static IResource resolveResourceInWorkspace(String parsedName, IProject preferredProject, Set referencedProjectsNames) {
+ IPath path = new Path(parsedName);
+ if (path.equals(new Path(".")) || path.equals(new Path(".."))) { //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ // prefer current project
+ if (preferredProject!=null) {
+ List result = findPathInFolder(path, preferredProject);
+ int size = result.size();
+ if (size==1) { // found the one
+ return result.get(0);
+ } else if (size>1) { // ambiguous
+ return null;
+ }
+ }
+
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+ // then prefer referenced projects
+ if (referencedProjectsNames.size() > 0) {
+ IResource rc = null;
+ for (String prjName : referencedProjectsNames) {
+ IProject prj = root.getProject(prjName);
+ if (prj.isOpen()) {
+ List result = findPathInFolder(path, prj);
+ int size = result.size();
+ if (size==1 && rc==null) {
+ rc = result.get(0);
+ } else if (size > 0) {
+ // ambiguous
+ rc = null;
+ break;
+ }
+ }
+ }
+ if (rc!=null) {
+ return rc;
+ }
+ }
+
+ // then check all other projects in workspace
+ IProject[] projects = root.getProjects();
+ if (projects.length > 0) {
+ IResource rc = null;
+ for (IProject prj : projects) {
+ if (!prj.equals(preferredProject) && !referencedProjectsNames.contains(prj.getName()) && prj.isOpen()) {
+ List result = findPathInFolder(path, prj);
+ int size = result.size();
+ if (size==1 && rc==null) {
+ rc = result.get(0);
+ } else if (size > 0) {
+ // ambiguous
+ rc = null;
+ break;
+ }
+ }
+ }
+ if (rc!=null) {
+ return rc;
+ }
+ }
+
+ // not found or ambiguous
+ return null;
+ }
+
+ private static List findPathInFolder(IPath path, IContainer folder) {
+ List paths = new ArrayList();
+ IResource resource = folder.findMember(path);
+ if (resource != null) {
+ paths.add(resource);
+ }
+
+ try {
+ for (IResource res : folder.members()) {
+ if (res instanceof IContainer) {
+ paths.addAll(findPathInFolder(path, (IContainer) res));
+ }
+ }
+ } catch (CoreException e) {
+ // ignore
+ }
+
+ return paths;
+ }
+
+ private static IResource findFileForLocationURI(URI uri, IProject preferredProject) {
+ IResource sourceFile;
+ IResource result = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IResource[] resources = root.findFilesForLocationURI(uri);
+ if (resources.length > 0) {
+ result = resources[0];
+ if (preferredProject!=null) {
+ for (IResource rc : resources) {
+ if (rc.getProject().equals(preferredProject)) {
+ result = rc;
+ break;
+ }
+ }
+ }
+ }
+ sourceFile = result;
+ return sourceFile;
+ }
+
+ private static URI findBaseLocationURI(URI fileURI, String relativeFileName) {
+ URI cwdURI = null;
+ String path = fileURI.getPath();
+
+ String[] segments = relativeFileName.split("[/\\\\]"); //$NON-NLS-1$
+
+ // start removing segments from the end of the path
+ for (int i = segments.length - 1; i >= 0; i--) {
+ String lastSegment = segments[i];
+ if (lastSegment.length() > 0 && !lastSegment.equals(".")) { //$NON-NLS-1$
+ if (lastSegment.equals("..")) { //$NON-NLS-1$
+ // navigating ".." in the other direction is ambiguous, bailing out
+ return null;
+ } else {
+ if (path.endsWith("/" + lastSegment)) { //$NON-NLS-1$
+ int pos = path.lastIndexOf(lastSegment);
+ path = path.substring(0, pos);
+ continue;
+ } else {
+ // ouch, relativeFileName does not match fileURI, bailing out
+ return null;
+ }
+ }
+ }
+ }
+
+ try {
+ cwdURI = new URI(fileURI.getScheme(), fileURI.getUserInfo(), fileURI.getHost(),
+ fileURI.getPort(), path, fileURI.getQuery(), fileURI.getFragment());
+ } catch (URISyntaxException e) {
+ // It should be valid URI here or something is wrong
+ MakeCorePlugin.log(e);
+ }
+
+ return cwdURI;
+ }
+
+ /**
+ * In case when absolute path is mapped to the source tree in a project
+ * this function will try to figure mapping and return "mapped root",
+ * i.e URI where the root path would be mapped. The mapped root will be
+ * used to prepend to other "absolute" paths where appropriate.
+ *
+ * @param sourceFile - a resource referred by parsed path
+ * @param parsedResourceName - path as appears in the output
+ * @return mapped path as URI
+ */
+ private static URI getMappedRootURI(IResource sourceFile, String parsedResourceName) {
+ URI fileURI = sourceFile.getLocationURI();
+ String mappedRoot = "/"; //$NON-NLS-1$
+
+ if (parsedResourceName!=null) {
+ IPath parsedSrcPath = new Path(parsedResourceName);
+ if (parsedSrcPath.isAbsolute()) {
+ IPath absPath = sourceFile.getLocation();
+ int absSegmentsCount = absPath.segmentCount();
+ int relSegmentsCount = parsedSrcPath.segmentCount();
+ if (absSegmentsCount >= relSegmentsCount) {
+ IPath ending = absPath.removeFirstSegments(absSegmentsCount - relSegmentsCount);
+ ending = ending.setDevice(parsedSrcPath.getDevice()).makeAbsolute();
+ if (ending.equals(parsedSrcPath.makeAbsolute())) {
+ mappedRoot = absPath.removeLastSegments(relSegmentsCount).toString();
+ }
+ }
+ }
+ }
+ URI uri = EFSExtensionManager.getDefault().createNewURIFromPath(fileURI, mappedRoot);
+ return uri;
+ }
+
+ /**
+ * The manipulations here are done to resolve "../" navigation for symbolic links where "link/.." cannot
+ * be collapsed as it must follow the real filesystem path. {@link java.io.File#getCanonicalPath()} deals
+ * with that correctly but {@link Path} or {@link URI} try to normalize the path which would be incorrect
+ * here.
+ */
+ private static URI resolvePathFromBaseLocation(String name, IPath baseLocation) {
+ String pathName = name;
+ if (baseLocation != null && !baseLocation.isEmpty()) {
+ String device = new Path(pathName).getDevice();
+ if (device != null && device.length() > 0) {
+ pathName = pathName.substring(device.length());
+ }
+ pathName = pathName.replace(File.separatorChar, '/');
+
+ baseLocation = baseLocation.addTrailingSeparator();
+ if (pathName.startsWith("/")) { //$NON-NLS-1$
+ pathName = pathName.substring(1);
+ }
+ pathName = baseLocation.toString() + pathName;
+ }
+
+ try {
+ File file = new File(pathName);
+ file = file.getCanonicalFile();
+ return file.toURI();
+ } catch (IOException e) {
+ // if error just leave it as is
+ }
+
+ URI uri = org.eclipse.core.filesystem.URIUtil.toURI(pathName);
+ return uri;
+ }
+
+ private static IResource findResourceForLocationURI(URI uri, int kind, IProject preferredProject) {
+ if (uri==null)
+ return null;
+
+ IResource resource = null;
+
+ switch (kind) {
+ case ICSettingEntry.INCLUDE_PATH:
+ case ICSettingEntry.LIBRARY_PATH:
+ resource = findContainerForLocationURI(uri, preferredProject);
+ break;
+ case ICSettingEntry.INCLUDE_FILE:
+ case ICSettingEntry.MACRO_FILE:
+ resource = findFileForLocationURI(uri, preferredProject);
+ break;
+ }
+
+ return resource;
+ }
+
+ private static IResource findContainerForLocationURI(URI uri, IProject preferredProject) {
+ IResource resource = null;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IResource[] resources = root.findContainersForLocationURI(uri);
+ if (resources.length > 0) {
+ for (IResource rc : resources) {
+ if ((rc instanceof IProject || rc instanceof IFolder)) { // treat IWorkspaceRoot as non-workspace path
+ IProject prj = rc instanceof IProject ? (IProject)rc : rc.getProject();
+ if (prj.equals(preferredProject)) {
+ resource = rc;
+ break;
+ }
+ if (resource==null) {
+ resource=rc; // to be deterministic the first qualified resource has preference
+ }
+ }
+ }
+ }
+ return resource;
+ }
+
+ private static IPath getFilesystemLocation(URI uri) {
+ if (uri==null)
+ return null;
+
+ // EFSExtensionManager mapping
+ String pathStr = EFSExtensionManager.getDefault().getMappedPath(uri);
+ uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr);
+
+ try {
+ File file = new java.io.File(uri);
+ String canonicalPathStr = file.getCanonicalPath();
+ return new Path(canonicalPathStr);
+ } catch (Exception e) {
+ MakeCorePlugin.log(e);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("nls")
+ private static String expressionLogicalOr(Set fileExts) {
+ String pattern = "(";
+ for (String ext : fileExts) {
+ if (pattern.length() != 1)
+ pattern += "|";
+ pattern += "(" + Pattern.quote(ext) + ")";
+ ext = ext.toUpperCase();
+ if (!fileExts.contains(ext)) {
+ pattern += "|(" + Pattern.quote(ext) + ")";
+ }
+ }
+ pattern += ")";
+ return pattern;
+ }
+
+ protected static int countGroups(String str) {
+ @SuppressWarnings("nls")
+ int count = str.replaceAll("[^\\(]", "").length();
+ return count;
+ }
+
+ @Override
+ public Element serialize(Element parentElement) {
+ Element elementProvider = super.serialize(parentElement);
+ elementProvider.setAttribute(ATTR_EXPAND_RELATIVE_PATHS, Boolean.toString(isResolvingPaths));
+ return elementProvider;
+ }
+
+ @Override
+ public void load(Element providerNode) {
+ super.load(providerNode);
+
+ String expandRelativePathsValue = XmlUtil.determineAttributeValue(providerNode, ATTR_EXPAND_RELATIVE_PATHS);
+ if (expandRelativePathsValue!=null)
+ isResolvingPaths = Boolean.parseBoolean(expandRelativePathsValue);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + (isResolvingPaths ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AbstractLanguageSettingsOutputScanner other = (AbstractLanguageSettingsOutputScanner) obj;
+ if (isResolvingPaths != other.isResolvingPaths)
+ return false;
+ return true;
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/GCCBuildCommandParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/GCCBuildCommandParser.java
new file mode 100644
index 00000000000..1594c0b1898
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/GCCBuildCommandParser.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.make.core.scannerconfig;
+
+
+import org.eclipse.cdt.core.errorparsers.RegexErrorPattern;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider;
+
+public class GCCBuildCommandParser extends AbstractBuildCommandParser implements
+ ILanguageSettingsEditableProvider {
+ @SuppressWarnings("nls")
+ static final AbstractOptionParser[] optionParsers = {
+ new IncludePathOptionParser("-I\\s*([\"'])(.*)\\1", "$2"),
+ new IncludePathOptionParser("-I\\s*([^\\s\"']*)", "$1"),
+ new IncludeFileOptionParser("-include\\s*([\"'])(.*)\\1", "$2"),
+ new IncludeFileOptionParser("-include\\s*([^\\s\"']*)", "$1"),
+ new MacroOptionParser("-D\\s*([\"'])([^=]*)(=(.*))?\\1", "$2", "$4"),
+ new MacroOptionParser("-D\\s*([^\\s=\"']*)=(\\\\([\"']))(.*?)\\2", "$1", "$3$4$3"),
+ new MacroOptionParser("-D\\s*([^\\s=\"']*)=([\"'])(.*?)\\2", "$1", "$3"),
+ new MacroOptionParser("-D\\s*([^\\s=\"']*)(=([^\\s\"']*))?", "$1", "$3"),
+ new MacroOptionParser("-U\\s*([^\\s=\"']*)", "$1", ICSettingEntry.UNDEFINED),
+ new MacroFileOptionParser("-macros\\s*([\"'])(.*)\\1", "$2"),
+ new MacroFileOptionParser("-macros\\s*([^\\s\"']*)", "$1"),
+ new LibraryPathOptionParser("-L\\s*([\"'])(.*)\\1", "$2"),
+ new LibraryPathOptionParser("-L\\s*([^\\s\"']*)", "$1"),
+ new LibraryFileOptionParser("-l\\s*([^\\s\"']*)", "lib$1.a"), };
+
+ @Override
+ protected AbstractOptionParser[] getOptionParsers() {
+ return optionParsers;
+ }
+
+ @Override
+ public GCCBuildCommandParser cloneShallow() throws CloneNotSupportedException {
+ return (GCCBuildCommandParser) super.cloneShallow();
+ }
+
+ @Override
+ public GCCBuildCommandParser clone() throws CloneNotSupportedException {
+ return (GCCBuildCommandParser) super.clone();
+ }
+
+ public static class GCCBuildCommandPatternHighlighter extends AbstractBuildCommandParser.AbstractBuildCommandPatternHighlighter {
+ // ID of the parser taken from the 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() {
+ super(GCC_BUILD_COMMAND_PARSER_EXT);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ GCCBuildCommandPatternHighlighter that = new GCCBuildCommandPatternHighlighter();
+ that.setId(getId());
+ that.setName(getName());
+ for (RegexErrorPattern pattern : getPatterns()) {
+ that.addPattern((RegexErrorPattern)pattern.clone());
+ }
+ return that;
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsBuildOutputScanner.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsBuildOutputScanner.java
new file mode 100644
index 00000000000..51615891c53
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsBuildOutputScanner.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 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.core.scannerconfig;
+
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.IErrorParser;
+import org.eclipse.cdt.internal.core.ConsoleOutputSniffer;
+
+/**
+ * Note: IErrorParser interface is used here to work around {@link ConsoleOutputSniffer} having
+ * no access from CDT core to build packages.
+ */
+public interface ILanguageSettingsBuildOutputScanner extends ILanguageSettingsOutputScanner, IErrorParser {
+
+ /**
+ * This method is expected to populate this.settingEntries with specific values
+ * parsed from supplied lines.
+ */
+ public boolean processLine(String line, ErrorParserManager epm);
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsBuiltinSpecsDetector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsBuiltinSpecsDetector.java
new file mode 100644
index 00000000000..e094fb18dc6
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsBuiltinSpecsDetector.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 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.core.scannerconfig;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public interface ILanguageSettingsBuiltinSpecsDetector extends ILanguageSettingsProvider {
+ public List getLanguageScope();
+ public void run(IProject project, String languageId, IPath workingDirectory, String[] env, IProgressMonitor monitor) throws CoreException, IOException;
+ public void run(ICConfigurationDescription cfgDescription, String languageId, IPath workingDirectory, String[] env, IProgressMonitor monitor) throws CoreException, IOException;
+}
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsOutputScanner.java
new file mode 100644
index 00000000000..642322f2d36
--- /dev/null
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ILanguageSettingsOutputScanner.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2009 Andrew Gvozdev (Quoin Inc.) 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 (Quoin Inc.) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.make.core.scannerconfig;
+
+import java.util.List;
+
+import org.eclipse.cdt.core.ICConsoleParser;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * TODO: Is this interface superfluous?
+ */
+public interface ILanguageSettingsOutputScanner extends ILanguageSettingsProvider, ICConsoleParser {
+
+ // Inherited from ICConsoleParser
+ public void startup(ICConfigurationDescription cfgDescription) throws CoreException;
+ public boolean processLine(String line);
+ public void shutdown();
+
+ // Inherited from ICLanguageSettingsProvider
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId);
+}
diff --git a/build/org.eclipse.cdt.make.ui/icons/obj16/inspect_system.gif b/build/org.eclipse.cdt.make.ui/icons/obj16/inspect_system.gif
new file mode 100644
index 00000000000..d68100a7488
Binary files /dev/null and b/build/org.eclipse.cdt.make.ui/icons/obj16/inspect_system.gif differ
diff --git a/build/org.eclipse.cdt.make.ui/icons/obj16/log_obj.gif b/build/org.eclipse.cdt.make.ui/icons/obj16/log_obj.gif
new file mode 100644
index 00000000000..aebeab820d8
Binary files /dev/null and b/build/org.eclipse.cdt.make.ui/icons/obj16/log_obj.gif differ
diff --git a/build/org.eclipse.cdt.make.ui/icons/obj16/search.gif b/build/org.eclipse.cdt.make.ui/icons/obj16/search.gif
new file mode 100644
index 00000000000..d540a01f4d9
Binary files /dev/null and b/build/org.eclipse.cdt.make.ui/icons/obj16/search.gif differ
diff --git a/build/org.eclipse.cdt.make.ui/plugin.properties b/build/org.eclipse.cdt.make.ui/plugin.properties
index 21b341f00ec..4db795b46c4 100644
--- a/build/org.eclipse.cdt.make.ui/plugin.properties
+++ b/build/org.eclipse.cdt.make.ui/plugin.properties
@@ -44,6 +44,9 @@ PreferenceBuildSettings.name=Settings
ErrorParsersTab.name=Error Parsers
ErrorParsersTab.tooltip=Error Parsers scan build output and report errors in Problems view
+LanguageSettingsProvidersTab.name=Discovery
+LanguageSettingsProvidersTab.tooltip=Language settings providers
+
PreferenceMakeProject.name=New Make Projects
PreferenceMake.name=Make Targets
PreferenceMakefileEditor.name=Makefile Editor
diff --git a/build/org.eclipse.cdt.make.ui/plugin.xml b/build/org.eclipse.cdt.make.ui/plugin.xml
index 002d57859e9..c9c87cb44f6 100644
--- a/build/org.eclipse.cdt.make.ui/plugin.xml
+++ b/build/org.eclipse.cdt.make.ui/plugin.xml
@@ -470,6 +470,14 @@
tooltip="%ErrorParsersTab.tooltip"
weight="020">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
new file mode 100644
index 00000000000..d5bf8f74541
--- /dev/null
+++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/GCCBuildCommandParserOptionPage.java
@@ -0,0 +1,370 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.internal.ui.preferences;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.internal.ui.language.settings.providers.AbstractLanguageSettingProviderOptionPage;
+import org.eclipse.cdt.internal.ui.newui.StatusMessageLine;
+import org.eclipse.cdt.make.core.scannerconfig.AbstractBuildCommandParser;
+import org.eclipse.cdt.utils.ui.controls.ControlFactory;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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;
+
+/**
+ * Options page for TODO
+ *
+ */
+public final class GCCBuildCommandParserOptionPage extends AbstractLanguageSettingProviderOptionPage {
+ private boolean fEditable;
+
+ private Text inputCommand;
+
+ private StatusMessageLine fStatusLine;
+ private Button runOnceRadioButton;
+ private Button runEveryBuildRadioButton;
+ private Button expandRelativePathCheckBox;
+ private Button applyToProjectCheckBox;
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+// Composite optionsPageComposite = new Composite(composite, SWT.NULL);
+ fEditable = parent.isEnabled();
+
+ final Composite composite = new Composite(parent, 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);
+
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ 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
+ {
+ Label label = ControlFactory.createLabel(composite, "Compiler command pattern:");
+ GridData gd = new GridData();
+ gd.horizontalSpan = 1;
+ label.setLayoutData(gd);
+ label.setEnabled(fEditable);
+ }
+
+ {
+ inputCommand = ControlFactory.createTextField(composite, SWT.SINGLE | SWT.BORDER);
+ String customParameter = provider.getCustomParameter();
+ inputCommand.setText(customParameter!=null ? customParameter : "");
+
+ GridData gd = new GridData();
+ gd.horizontalSpan = 1;
+ gd.grabExcessHorizontalSpace = true;
+ gd.horizontalAlignment = SWT.FILL;
+ inputCommand.setLayoutData(gd);
+ inputCommand.setEnabled(fEditable);
+
+ inputCommand.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String text = inputCommand.getText();
+ AbstractBuildCommandParser provider = getRawProvider();
+ if (!text.equals(provider.getCustomParameter())) {
+ AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
+ selectedProvider.setCustomParameter(text);
+ providerTab.refreshItem(selectedProvider);
+ }
+ }
+ });
+ }
+
+// {
+// Button button = ControlFactory.createPushButton(composite, "Browse...");
+// button.setEnabled(fEditable);
+// button.addSelectionListener(new SelectionAdapter() {
+//
+// @Override
+// public void widgetSelected(SelectionEvent evt) {
+//// handleAddr2LineButtonSelected();
+// //updateLaunchConfigurationDialog();
+// }
+//
+// });
+//
+// }
+
+// {
+// 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);
+// }
+
+ {
+ expandRelativePathCheckBox = new Button(composite, SWT.CHECK);
+ expandRelativePathCheckBox.setText("Use heuristics to resolve paths");
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ expandRelativePathCheckBox.setLayoutData(gd);
+
+ expandRelativePathCheckBox.setSelection(provider.isResolvingPaths());
+ expandRelativePathCheckBox.setEnabled(fEditable);
+ expandRelativePathCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = expandRelativePathCheckBox.getSelection();
+ AbstractBuildCommandParser provider = getRawProvider();
+ if (enabled != provider.isResolvingPaths()) {
+ AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
+ selectedProvider.setResolvingPaths(enabled);
+ providerTab.refreshItem(selectedProvider);
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ });
+
+ }
+
+ {
+ applyToProjectCheckBox = new Button(composite, SWT.CHECK);
+ applyToProjectCheckBox.setText("Apply discovered settings on project level");
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ applyToProjectCheckBox.setLayoutData(gd);
+
+// applyToProjectCheckBox.setSelection(provider.isExpandRelativePaths());
+// applyToProjectCheckBox.setEnabled(fEditable);
+ applyToProjectCheckBox.setSelection(false);
+ applyToProjectCheckBox.setEnabled(false);
+ applyToProjectCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = applyToProjectCheckBox.getSelection();
+ AbstractBuildCommandParser provider = getRawProvider();
+ if (enabled != provider.isResolvingPaths()) {
+ AbstractBuildCommandParser selectedProvider = getWorkingCopy(providerId);
+ selectedProvider.setResolvingPaths(enabled);
+ providerTab.refreshItem(selectedProvider);
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ });
+
+ }
+
+// // Status line
+// if (fEditable) {
+// fStatusLine = new StatusMessageLine(composite, SWT.LEFT, 2);
+// IStatus status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID, "Note that currently not all options are persisted (FIXME)");
+// fStatusLine.setErrorStatus(status);
+// }
+
+ setControl(composite);
+ }
+
+ private AbstractBuildCommandParser getRawProvider() {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getRawProvider(providerTab.getProvider(providerId));
+ Assert.isTrue(provider instanceof AbstractBuildCommandParser);
+ return (AbstractBuildCommandParser) provider;
+ }
+
+ private AbstractBuildCommandParser getWorkingCopy(String providerId) {
+ ILanguageSettingsProvider provider = providerTab.getWorkingCopy(providerId);
+ Assert.isTrue(provider instanceof AbstractBuildCommandParser);
+ return (AbstractBuildCommandParser) provider;
+ }
+
+ @Override
+ public void performApply(IProgressMonitor monitor) throws CoreException {
+ // handled by LanguageSettingsProviderTab
+ }
+
+ @Override
+ public void performDefaults() {
+ // handled by LanguageSettingsProviderTab
+ }
+
+}
diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/ScannerDiscoveryConsole.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/ScannerDiscoveryConsole.java
new file mode 100644
index 00000000000..e5590d9fd43
--- /dev/null
+++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/scannerconfig/ScannerDiscoveryConsole.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.internal.ui.scannerconfig;
+
+import java.net.URL;
+
+import org.eclipse.cdt.internal.ui.buildconsole.CBuildConsole;
+import org.eclipse.cdt.internal.ui.language.settings.providers.LanguageSettingsProviderAssociation;
+
+public class ScannerDiscoveryConsole extends CBuildConsole {
+
+ /**
+ * {@inheritDoc}
+ * @param consoleId - a console ID is expected here which then is used as menu context ID.
+ * @param defaultIconUrl - if {@code LanguageSettingsProviderAssociation} extension point
+ * defines URL by provider id, {@code defaultIconUrl} will be ignored and the URL from the extension
+ * point will be used. If not, supplied {@code defaultIconUrl} will be used.
+ */
+ @Override
+ public void init(String consoleId, String name, URL defaultIconUrl) {
+ URL iconUrl = LanguageSettingsProviderAssociation.getImageUrl(consoleId);
+ if (iconUrl==null) {
+ iconUrl = defaultIconUrl;
+ }
+
+ super.init(consoleId, name, iconUrl);
+ }
+
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java
index 65fdaadca1d..6ea149057a4 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/tests/suite/AllManagedBuildTests.java
@@ -16,6 +16,7 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.cdt.build.core.scannerconfig.tests.CfgScannerConfigProfileManagerTests;
+import org.eclipse.cdt.build.core.scannerconfig.tests.GCCBuiltinSpecsDetectorTest;
import org.eclipse.cdt.build.core.scannerconfig.tests.GCCSpecsConsoleParserTest;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
@@ -59,6 +60,7 @@ public class AllManagedBuildTests {
// build.core.scannerconfig.tests
suite.addTest(CfgScannerConfigProfileManagerTests.suite());
suite.addTestSuite(GCCSpecsConsoleParserTest.class);
+ suite.addTestSuite(GCCBuiltinSpecsDetectorTest.class);
// managedbuilder.core.tests
suite.addTest(ManagedBuildCoreTests20.suite());
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/AllSD80Tests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/AllSD80Tests.java
new file mode 100644
index 00000000000..d339b469792
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/AllSD80Tests.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.build.core.scannerconfig.tests;
+
+import org.eclipse.cdt.build.core.scannerconfig.tests.GCCBuiltinSpecsDetectorTest;
+
+import junit.framework.TestSuite;
+
+public class AllSD80Tests extends TestSuite {
+
+ public static TestSuite suite() {
+ return new AllSD80Tests();
+ }
+
+ public AllSD80Tests() {
+ super(AllSD80Tests.class.getName());
+
+ addTestSuite(GCCBuiltinSpecsDetectorTest.class);
+ }
+}
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
new file mode 100644
index 00000000000..5e5ff994266
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/build/core/scannerconfig/tests/GCCBuiltinSpecsDetectorTest.java
@@ -0,0 +1,659 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.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.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.managedbuilder.internal.scannerconfig.AbstractBuiltinSpecsDetector;
+import org.eclipse.cdt.managedbuilder.internal.scannerconfig.GCCBuiltinSpecsDetector;
+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 = "org.eclipse.cdt.core.gcc";
+ private static final String LANGUAGE_ID_CPP = "org.eclipse.cdt.core.g++";
+ 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$
+
+ private class MockBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector {
+ @Override
+ protected String getToolchainId() {
+ return null;
+ }
+ @Override
+ protected List parseForOptions(String line) {
+ return null;
+ }
+ @Override
+ protected AbstractOptionParser[] getOptionParsers() {
+ return null;
+ }
+ }
+
+ @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
+ 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_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_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 {
+ @Override
+ public String resolveCommand(String languageId) throws CoreException {
+ return super.resolveCommand(languageId);
+ }
+ }
+ {
+ MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
+ 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();
+ 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();
+
+ detector.startup(null);
+ detector.processLine("#define MACRO VALUE");
+ detector.shutdown();
+
+ List entries = detector.getSettingEntries(null, null, null);
+ ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
+ assertEquals(expected, entries.get(0));
+ }
+
+ public void testGCCBuiltinSpecsDetector_Macro_Const() throws Exception {
+ AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+
+ detector.startup(null);
+ detector.processLine("#define MACRO (3)");
+ detector.shutdown();
+
+ List entries = detector.getSettingEntries(null, null, null);
+ ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "(3)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
+ assertEquals(expected, entries.get(0));
+ }
+
+ public void testGCCBuiltinSpecsDetector_Macro_EmptyArgList() throws Exception {
+ AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+
+ detector.startup(null);
+ detector.processLine("#define MACRO() VALUE");
+ detector.shutdown();
+
+ List entries = detector.getSettingEntries(null, null, null);
+ ICLanguageSettingEntry expected = new CMacroEntry("MACRO()", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
+ assertEquals(expected, entries.get(0));
+ }
+
+ public void testGCCBuiltinSpecsDetector_Macro_ParamUnused() throws Exception {
+ AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+
+ detector.startup(null);
+ detector.processLine("#define MACRO(X) VALUE");
+ 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));
+ }
+
+ public void testGCCBuiltinSpecsDetector_Macro_ParamSpace() throws Exception {
+ AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+
+ detector.startup(null);
+ detector.processLine("#define MACRO(P1, P2) VALUE(P1, P2)");
+ 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));
+ }
+
+ public void testGCCBuiltinSpecsDetector_Macro_ArgsNoValue() throws Exception {
+ AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+
+ detector.startup(null);
+ detector.processLine("#define MACRO(P1, P2) ");
+ 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));
+ }
+
+ public void testGCCBuiltinSpecsDetector_Includes() throws Exception {
+ // Create model project and folders to test
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProject(projectName);
+ IPath tmpPath = ResourceHelper.createTemporaryFolder();
+ ResourceHelper.createFolder(project, "/misplaced/include1");
+ ResourceHelper.createFolder(project, "/local/include");
+ ResourceHelper.createFolder(project, "/usr/include");
+ ResourceHelper.createFolder(project, "/usr/include2");
+ ResourceHelper.createFolder(project, "/misplaced/include2");
+ ResourceHelper.createFolder(project, "/System/Library/Frameworks");
+ ResourceHelper.createFolder(project, "/Library/Frameworks");
+ ResourceHelper.createFolder(project, "/misplaced/include3");
+ String loc = tmpPath.toString();
+
+ GCCBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+ detector.startup(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 search list.");
+ detector.processLine(" "+loc+"/misplaced/include3");
+ 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());
+ }
+
+ public void testGCCBuiltinSpecsDetector_Includes_SymbolicLinkUp() throws Exception {
+ // do not test on systems where symbolic links are not supported
+ if (!ResourceHelper.isSymbolicLinkSupported())
+ return;
+
+ // Create model project and folders to test
+ String projectName = getName();
+ @SuppressWarnings("unused")
+ IProject project = ResourceHelper.createCDTProject(projectName);
+ // create link on the filesystem
+ IPath dir1 = ResourceHelper.createTemporaryFolder();
+ IPath dir2 = dir1.removeLastSegments(1);
+ IPath linkPath = dir1.append("linked");
+ ResourceHelper.createSymbolicLink(linkPath, dir2);
+
+ AbstractBuiltinSpecsDetector detector = new GCCBuiltinSpecsDetector();
+
+ detector.startup(null);
+ detector.processLine("#include <...> search starts here:");
+ detector.processLine(" "+linkPath.toString()+"/..");
+ detector.processLine("End of search list.");
+ 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(1, entries.size());
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml
index 532aee8a5f0..fa816ec68e8 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml
@@ -308,6 +308,7 @@
@@ -597,6 +598,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd
index 83e75654f87..842d0059706 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd
+++ b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd
@@ -263,7 +263,16 @@ Specifying this attribute is fully equivalent to specifying the "org.eclips
- The semi-colon separated list of the default error parsers to be used with this configuration. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. The list of error parsers to be used may be changed by the user on a per-configuration basis. When specified, this overrides the tool-chain errorParsers attribute.
+ The semi-colon separated list of the default error parsers to be used with this configuration. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. The list of error parsers to be used may be changed by the user on a per-configuration basis. When specified, this overrides the tool-chain errorParsers attribute.
+
+
+
+
+
+
+ Semicolon-separated list of providers ID implementing ILanguageSettingProvider interface.
+This field could be amended with toolchain-level providers list by using ${Toolchain} keyword. Provider ID can be prefixed with "*", in this case shared instance of the provider defined on workspace level is used. Also provider ID can be prefixed with "-" which will cause id to be removed from the preceeding list including providers defined with ${Toolchain} keyword.
+If this field is not specified, "*org.eclipse.cdt.managedbuilder.core.LanguageSettingsProvider" (MBS Language Settings Provider) is used by default.
@@ -405,7 +414,15 @@ Specifying this attribute is fully equivalent to specifying the "org.eclips
- The semi-colon separated list of the default error parsers to be used with this tool-chain. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. When specified, this overrides the tool errorParsers attributes of the tool children of the tool-chain and the builder child of the tool-chain.
+ The semi-colon separated list of the default error parsers to be used with this tool-chain. The list is ordered with the first error parser on the list invoked first, the second error parser second, and so on. The list may contain the error parsers defined by CDT and/or other installed error parser extensions. When specified, this overrides the tool errorParsers attributes of the tool children of the tool-chain and the builder child of the tool-chain.
+
+
+
+
+
+
+ Semicolon-separated list of providers ID implementing ILanguageSettingProvider interface. Provider ID can be prefixed with "*", in this case shared instance of the provider defined on workspace level is used.
+This list could be adjusted on configuration level in the corresponding attribute.
@@ -732,14 +749,14 @@ The pathConverter of a toolchain applies for all tools of the toolchain except i
- Specifies whether this Tool represents a user-define custom build step. The default is false. When True, the default value of the commandLinePattern attribute changes to “$(command)”.
+ Specifies whether this Tool represents a user-define custom build step. The default is false. When True, the default value of the commandLinePattern attribute changes to “$(command)�.
- Specifies a string that is written to the build output prior to each invocation of the tool. The default value is “Invoking tool-name (tool-id)…”
+ Specifies a string that is written to the build output prior to each invocation of the tool. The default value is “Invoking tool-name (tool-id)…�
@@ -1066,7 +1083,7 @@ Overrides language id specified with the languageId attribute.
- The id of the input type that is used in determining the build “rules” for the output type and for the default name of the output file. The default is the input type with primaryInput == true.
+ The id of the input type that is used in determining the build “rules� for the output type and for the default name of the output file. The default is the input type with primaryInput == true.
@@ -1080,7 +1097,7 @@ Overrides language id specified with the languageId attribute.
- Some tools produce files with a special prefix that must be specified. For example, a librarian on POSIX systems expects the output to be libtarget.a, so 'lib' would be the prefix. The default is to use the Tool “outputPrefix” attribute if primaryOutput is True, otherwise the default is an empty string. This attribute supports MBS configuration context macros.
+ Some tools produce files with a special prefix that must be specified. For example, a librarian on POSIX systems expects the output to be libtarget.a, so 'lib' would be the prefix. The default is to use the Tool “outputPrefix� attribute if primaryOutput is True, otherwise the default is an empty string. This attribute supports MBS configuration context macros.
@@ -2016,11 +2033,11 @@ If the "buildPathResolver" attribute is specified, the "pathDelim
Represents the applicability type for this enablement.
Can contain the following values:
-UI_VISIBILITY – the given enablement expression specifies whether the option is to be visible in UI,
-UI_ENABLEMENT – the given enablement expression specifies the enable state of the controls that represent the option in UI,
-CMD_USAGE – the given enablement expression specifies whether the option is to be used in command line
+UI_VISIBILITY – the given enablement expression specifies whether the option is to be visible in UI,
+UI_ENABLEMENT – the given enablement expression specifies the enable state of the controls that represent the option in UI,
+CMD_USAGE – the given enablement expression specifies whether the option is to be used in command line
CONTAINER_ATTRIBUTE - the given enablement expressions specifies thecontainer attribute value
-ALL – this value means the combination of all the above values.
+ALL – this value means the combination of all the above values.
Several types could be specified simultaneously using the "|" as a delimiter, e.g.:
type="UI_VISIBILITY|CMD_USAGE"
@@ -2154,7 +2171,7 @@ Default value is true.
- Specifies the expected value. If the current option value matches the value specified in this attribute, the checkOption element is treated as true, otherwise – as false.
+ Specifies the expected value. If the current option value matches the value specified in this attribute, the checkOption element is treated as true, otherwise – as false.
The expected value could be specified either as a string that may contain build macros or as a regular expression. During the comparison, the build macros are resolved and the option value is checked to match the resulting string or regular expression. The way the expected value is specified and treated depends on the value of the isRegex attribute
@@ -2169,14 +2186,14 @@ The expected value could be specified either as a string that may contain build
- The id of the option which is to be compared with the option specified with the “optionId” attribute. The default is the id of the option that holds this expression. If the “value” attribute is specified, both the “otherOptionId” and the “otherHolderId” attributes are ignored. When searching for the option to be checked, MBS will examine all the options the holder contains along with all superclasses of each option to find the option with the specified id.
+ The id of the option which is to be compared with the option specified with the “optionId� attribute. The default is the id of the option that holds this expression. If the “value� attribute is specified, both the “otherOptionId� and the “otherHolderId� attributes are ignored. When searching for the option to be checked, MBS will examine all the options the holder contains along with all superclasses of each option to find the option with the specified id.
- The option holder id that holds the option specified with the “otherOptionId” attribute. The default is the id of the holder that holds the container of this expression. If the “value” attribute is specified, both the “otherOptionId” and the “otherHolderId” attributes are ingnored. When searching for the needed holder, MBS will examine all the holders the current configuration contains along with all superclasses of each holder in order to find the holder with the specified id.
+ The option holder id that holds the option specified with the “otherOptionId� attribute. The default is the id of the holder that holds the container of this expression. If the “value� attribute is specified, both the “otherOptionId� and the “otherHolderId� attributes are ingnored. When searching for the needed holder, MBS will examine all the holders the current configuration contains along with all superclasses of each holder in order to find the holder with the specified id.
@@ -2200,7 +2217,7 @@ The expected value could be specified either as a string that may contain build
- Specifies the expected value. If the current string specified in the “string” attribute matches the value specified in this attribute, the checkString element is treated as true, otherwise – as false.
+ Specifies the expected value. If the current string specified in the “string� attribute matches the value specified in this attribute, the checkString element is treated as true, otherwise – as false.
The expected value could be specified either as a string that might contain the build macros or as a regular expression.
The way the value is specified and treated depends on the value of the isRegex attribute.
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig2/CfgScannerConfigProfileManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig2/CfgScannerConfigProfileManager.java
index bef0ef6047f..632659b2a55 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig2/CfgScannerConfigProfileManager.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig2/CfgScannerConfigProfileManager.java
@@ -10,8 +10,14 @@
*******************************************************************************/
package org.eclipse.cdt.build.internal.core.scannerconfig2;
+import java.util.Collection;
+import java.util.Map;
+
import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigScope;
import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfile;
@@ -44,4 +50,34 @@ public class CfgScannerConfigProfileManager {
return new CfgInfoContext(cfg).toInfoContext();
return new InfoContext(project);
}
+
+ public static boolean disableScannerDiscovery(IConfiguration cfg) {
+ boolean isChanged = false;
+
+ ICfgScannerConfigBuilderInfo2Set info2set = getCfgScannerConfigBuildInfo(cfg);
+ Map infoMap = info2set.getInfoMap();
+ Collection infos = infoMap.values();
+ for (IScannerConfigBuilderInfo2 info2 : infos) {
+ isChanged = isChanged || info2.isAutoDiscoveryEnabled();
+ info2.setAutoDiscoveryEnabled(false);
+ }
+ return isChanged;
+ }
+
+ public static boolean disableScannerDiscovery(ICProjectDescription prjDescription) {
+ boolean isChanged = false;
+
+ ICConfigurationDescription[] cfgDescs = prjDescription.getConfigurations();
+ if (cfgDescs!=null) {
+ for (ICConfigurationDescription cfgDesc : cfgDescs) {
+ IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(cfgDesc);
+ boolean changed=CfgScannerConfigProfileManager.disableScannerDiscovery(cfg);
+ if (changed) {
+ isChanged = true;
+ }
+
+ }
+ }
+ return isChanged;
+ }
}
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 42940a74288..171046d3e2c 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
@@ -25,15 +25,23 @@ import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set
import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
import org.eclipse.cdt.core.CCorePlugin;
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.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.model.ICModelMarker;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.core.resources.RefreshScopeManager;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.internal.core.ConsoleOutputSniffer;
+import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
+import org.eclipse.cdt.make.core.scannerconfig.ILanguageSettingsBuiltinSpecsDetector;
import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2;
import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
@@ -114,6 +122,23 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
break;
}
+ URI workingDirectoryURI = ManagedBuildManager.getBuildLocationURI(configuration, builder);
+ final String pathFromURI = EFSExtensionManager.getDefault().getPathFromURI(workingDirectoryURI);
+ if(pathFromURI == null) {
+ throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, ManagedMakeMessages.getString("ManagedMakeBuilder.message.error"), null)); //$NON-NLS-1$
+ }
+
+ IPath workingDirectory = new Path(pathFromURI);
+
+ // Set the environment
+ 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);
@@ -135,14 +160,6 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
if (markers != null)
workspace.deleteMarkers(markers);
- URI workingDirectoryURI = ManagedBuildManager.getBuildLocationURI(configuration, builder);
- final String pathFromURI = EFSExtensionManager.getDefault().getPathFromURI(workingDirectoryURI);
- if(pathFromURI == null) {
- throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, ManagedMakeMessages.getString("ManagedMakeBuilder.message.error"), null)); //$NON-NLS-1$
- }
-
- IPath workingDirectory = new Path(pathFromURI);
-
String[] targets = getTargets(kind, builder);
if (targets.length != 0 && targets[targets.length - 1].equals(builder.getCleanBuildTarget()))
isClean = true;
@@ -153,9 +170,6 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
// Print the command for visual interaction.
launcher.showCommand(true);
- // Set the environment
- Map envMap = getEnvironment(builder);
- String[] env = getEnvStrings(envMap);
String[] buildArguments = targets;
String[] newArgs = CommandLineUtil.argumentsToArray(builder.getBuildArguments());
@@ -175,9 +189,15 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
OutputStream stderr = streamMon;
// Sniff console output for scanner info
- ConsoleOutputSniffer sniffer = createBuildOutputSniffer(stdout, stderr, project, configuration, workingDirectory, markerGenerator, null);
- OutputStream consoleOut = (sniffer == null ? stdout : sniffer.getOutputStream());
- OutputStream consoleErr = (sniffer == null ? stderr : sniffer.getErrorStream());
+ OutputStream consoleOut = stdout;
+ OutputStream consoleErr = stderr;
+ if (kind!=IncrementalProjectBuilder.CLEAN_BUILD) {
+ ConsoleOutputSniffer sniffer = createBuildOutputSniffer(stdout, stderr, project, configuration, workingDirectory, markerGenerator, null, epm);
+ if (sniffer!=null) {
+ consoleOut = sniffer.getOutputStream();
+ consoleErr = sniffer.getErrorStream();
+ }
+ }
Process p = launcher.execute(buildCommand, buildArguments, env, workingDirectory, monitor);
if (p != null) {
try {
@@ -193,6 +213,14 @@ 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.
@@ -245,6 +273,11 @@ 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);
@@ -337,10 +370,11 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
IConfiguration cfg,
IPath workingDirectory,
IMarkerGenerator markerGenerator,
- IScannerInfoCollector collector){
+ IScannerInfoCollector collector,
+ ErrorParserManager epm){
ICfgScannerConfigBuilderInfo2Set container = CfgScannerConfigProfileManager.getCfgScannerConfigBuildInfo(cfg);
Map map = container.getInfoMap();
- List clParserList = new ArrayList();
+ List clParserList = new ArrayList();
if(container.isPerRcTypeDiscovery()){
for (IResourceInfo rcInfo : cfg.getResourceInfos()) {
@@ -370,9 +404,25 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
contributeToConsoleParserList(project, map, new CfgInfoContext(cfg), workingDirectory, markerGenerator, collector, clParserList);
}
+ ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(cfg);
+ List lsProviders = cfgDescription.getLanguageSettingProviders();
+ for (ILanguageSettingsProvider lsProvider : lsProviders) {
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(lsProvider);
+ if (rawProvider instanceof ICConsoleParser && !(rawProvider instanceof ILanguageSettingsBuiltinSpecsDetector)) {
+ ICConsoleParser consoleParser = (ICConsoleParser) rawProvider;
+ try {
+ consoleParser.startup(cfgDescription);
+ clParserList.add(consoleParser);
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
if(clParserList.size() != 0){
- return new ConsoleOutputSniffer(outputStream, errorStream,
- clParserList.toArray(new IScannerInfoConsoleParser[clParserList.size()]));
+ IConsoleParser[] parsers = clParserList.toArray(new IConsoleParser[clParserList.size()]);
+ return new ConsoleOutputSniffer(outputStream, errorStream, parsers, epm);
}
return null;
@@ -385,7 +435,7 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
IPath workingDirectory,
IMarkerGenerator markerGenerator,
IScannerInfoCollector collector,
- List parserList){
+ List parserList){
IScannerConfigBuilderInfo2 info = map.get(context);
InfoContext ic = context.toInfoContext();
boolean added = false;
@@ -416,5 +466,4 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
return added;
}
-
}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
index 8b7f0499dce..3ab54cf1ec7 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java
@@ -46,6 +46,7 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont
// Schema element names
public static final String CONFIGURATION_ELEMENT_NAME = "configuration"; //$NON-NLS-1$
public static final String ERROR_PARSERS = "errorParsers"; //$NON-NLS-1$
+ public static final String LANGUAGE_SETTINGS_PROVIDERS = "languageSettingsProviders";
public static final String EXTENSION = "artifactExtension"; //$NON-NLS-1$
public static final String PARENT = "parent"; //$NON-NLS-1$
@@ -170,6 +171,8 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont
*/
public String[] getErrorParserList();
+ public String getDefaultLanguageSettingsProvidersIds();
+
/**
* Projects have C or CC natures. Tools can specify a filter so they are not
* misapplied to a project. This method allows the caller to retrieve a list
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java
index 57cba447fca..34a1a4331b7 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java
@@ -53,6 +53,8 @@ public interface IToolChain extends IBuildObject, IHoldsOptions {
// The attribute name for the scanner info collector
public static final String SCANNER_CONFIG_PROFILE_ID = "scannerConfigDiscoveryProfileId"; //$NON-NLS-1$
+ public static final String LANGUAGE_SETTINGS_PROVIDERS = "languageSettingsProviders";
+
/**
* Returns the configuration that is the parent of this tool-chain.
*
@@ -261,6 +263,13 @@ public interface IToolChain extends IBuildObject, IHoldsOptions {
*/
public void setErrorParserIds(String ids);
+ /**
+ * Returns the default language settings providers IDs.
+ *
+ * @return the default language settings providers IDs separated by semicolon or {@code null} if none.
+ */
+ public String getDefaultLanguageSettingsProvidersIds();
+
/**
* Returns the scanner config discovery profile id or null
if none.
*
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 b8f525e1a1b..933d9750483 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
@@ -13,14 +13,26 @@ package org.eclipse.cdt.managedbuilder.core;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.eclipse.cdt.core.CCorePlugin;
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;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
+import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
+import org.eclipse.cdt.make.core.scannerconfig.ILanguageSettingsBuildOutputScanner;
import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription;
+import org.eclipse.cdt.managedbuilder.internal.buildmodel.BuildDescription;
import org.eclipse.cdt.managedbuilder.internal.buildmodel.BuildStateManager;
import org.eclipse.cdt.managedbuilder.internal.buildmodel.DescriptionBuilder;
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IBuildModelBuilder;
@@ -35,6 +47,7 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
@@ -61,6 +74,21 @@ public class InternalBuildRunner extends AbstractBuildRunner {
private static final String NOTHING_BUILT = "ManagedMakeBuilder.message.no.build"; //$NON-NLS-1$
private static final String BUILD_ERROR = "ManagedMakeBuilder.message.error"; //$NON-NLS-1$
+
+ // TODO: same function is present in CommandBuilder and BuildProcessManager
+ private String[] mapToStringArray(Map map){
+ if(map == null)
+ return null;
+
+ List list = new ArrayList();
+
+ for (Entry entry : map.entrySet()) {
+ list.add(entry.getKey() + '=' + entry.getValue());
+ }
+
+ return list.toArray(new String[list.size()]);
+ }
+
@Override
public boolean invokeBuild(int kind, IProject project, IConfiguration configuration,
IBuilder builder, IConsole console, IMarkerGenerator markerGenerator,
@@ -96,6 +124,16 @@ public class InternalBuildRunner extends AbstractBuildRunner {
// Get a build console for the project
StringBuffer buf = new StringBuffer();
+
+ IBuildDescription des = BuildDescriptionManager.createBuildDescription(configuration, cBS, delta, flags);
+
+ IPath workingDirectory = des.getDefaultBuildDirLocation();
+ String[] env = null;
+ if (des instanceof BuildDescription) {
+ Map envMap = ((BuildDescription)des).getEnvironment();
+ env = mapToStringArray(envMap);
+ }
+
consoleOutStream = console.getOutputStream();
String[] consoleHeader = new String[3];
if(buildIncrementaly)
@@ -119,11 +157,28 @@ public class InternalBuildRunner extends AbstractBuildRunner {
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
}
+
+ if (kind!=IncrementalProjectBuilder.CLEAN_BUILD) {
+ ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(configuration);
+ ManagedBuildManager.runBuiltinSpecsDetectors(cfgDescription, workingDirectory, env, monitor);
+
+ List providers = cfgDescription.getLanguageSettingProviders();
+ for (ILanguageSettingsProvider provider : providers) {
+ if (provider instanceof ILanguageSettingsBuildOutputScanner) {
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ String msg = ManagedMakeMessages.getFormattedString("BOP Language Settings Provider [{0}] is not supported by Internal Builder.", provider.getName());
+ buf.append("**** "+msg+" ****");
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+
+ ManagedBuilderCorePlugin.error(msg);
+ }
+ }
+ }
+
consoleOutStream.write(buf.toString().getBytes());
consoleOutStream.flush();
- IBuildDescription des = BuildDescriptionManager.createBuildDescription(configuration, cBS, delta, flags);
-
DescriptionBuilder dBuilder = null;
if (!isParallel)
dBuilder = new DescriptionBuilder(des, buildIncrementaly, resumeOnErr, cBS);
@@ -193,6 +248,12 @@ 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
.getResourceString(MARKERS));
@@ -240,5 +301,4 @@ public class InternalBuildRunner extends AbstractBuildRunner {
}
return false;
}
-
}
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 6d8981d5bcc..296753806cd 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,17 +49,27 @@ 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;
+import org.eclipse.cdt.core.settings.model.ICFolderDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSetting;
import org.eclipse.cdt.core.settings.model.ICMultiConfigDescription;
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.settings.model.XmlStorageUtil;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.ILanguageSettingsBuiltinSpecsDetector;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyManager;
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentBuildPathsChangeListener;
@@ -149,6 +159,7 @@ import org.w3c.dom.ProcessingInstruction;
*/
public class ManagedBuildManager extends AbstractCExtension {
+ public static final String MBS_LANGUAGE_SETTINGS_PROVIDER = "org.eclipse.cdt.managedbuilder.core.LanguageSettingsProvider";
// private static final QualifiedName buildInfoProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "managedBuildInfo"); //$NON-NLS-1$
private static final String ROOT_NODE_NAME = "ManagedProjectBuildInfo"; //$NON-NLS-1$
public static final String SETTINGS_FILE_NAME = ".cdtbuild"; //$NON-NLS-1$
@@ -4714,4 +4725,138 @@ public class ManagedBuildManager extends AbstractCExtension {
return true; // no target platform - nothing to check.
}
+ private static String getLanguageSettingsProvidersStr(IToolChain toolchain) {
+ for (;toolchain!=null;toolchain=toolchain.getSuperClass()) {
+ String providersIdsStr = toolchain.getDefaultLanguageSettingsProvidersIds();
+ if (providersIdsStr!=null) {
+ return providersIdsStr;
+ }
+ }
+ return "";
+ }
+
+ private static String getLanguageSettingsProvidersStr(IConfiguration cfg) {
+ for (;cfg!=null;cfg=cfg.getParent()) {
+ String providersIdsStr = cfg.getDefaultLanguageSettingsProvidersIds();
+ if (providersIdsStr!=null) {
+ return providersIdsStr;
+ }
+ }
+ return "";
+ }
+
+ public static List getLanguageSettingsProviders(IConfiguration cfg) {
+ List providers = new ArrayList();
+
+ String providersIdsStr = getLanguageSettingsProvidersStr(cfg);
+ if (providersIdsStr!=null) {
+ if (providersIdsStr.contains("${Toolchain}")) {
+ IToolChain toolchain = cfg.getToolChain();
+ String toolchainProvidersIds = getLanguageSettingsProvidersStr(toolchain);
+ if (toolchainProvidersIds==null) {
+ toolchainProvidersIds="";
+ }
+ providersIdsStr = providersIdsStr.replaceAll("\\$\\{Toolchain\\}", toolchainProvidersIds);
+ }
+ List providersIds = Arrays.asList(providersIdsStr.split(String.valueOf(LanguageSettingsManager_TBD.PROVIDER_DELIMITER)));
+ for (String id : providersIds) {
+ id = id.trim();
+ ILanguageSettingsProvider provider = null;
+ if (id.startsWith("*")) {
+ id = id.substring(1);
+ provider = LanguageSettingsManager.getWorkspaceProvider(id);
+ } else if (id.startsWith("-")) {
+ id = id.substring(1);
+ for (ILanguageSettingsProvider pr : providers) {
+ if (pr.getId().equals(id)) {
+ providers.remove(pr);
+ // Has to break as the collection is invalidated
+ // TODO: remove all elements or better use unique list
+ break;
+ }
+ }
+ } else if (id.length()>0){
+ provider = LanguageSettingsManager.getExtensionProviderCopy(id);
+ }
+ if (provider!=null) {
+ providers.add(provider);
+ }
+ }
+ }
+
+ if (providers.isEmpty()) {
+ // Add MBS provider for unsuspecting toolchains (backward compatibility)
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getWorkspaceProvider(MBS_LANGUAGE_SETTINGS_PROVIDER);
+ providers.add(provider);
+ }
+
+ if (!isProviderThere(providers, LanguageSettingsManager_TBD.PROVIDER_UI_USER)) {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getExtensionProviderCopy(LanguageSettingsManager_TBD.PROVIDER_UI_USER);
+ providers.add(0, provider);
+ }
+
+ return providers;
+ }
+
+ private static boolean isProviderThere(List providers, String id) {
+ for (ILanguageSettingsProvider provider : providers) {
+ if (provider.getId().equals(id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * TODO - better home?
+ */
+ static public void runBuiltinSpecsDetectors(ICConfigurationDescription cfgDescription, IPath workingDirectory,
+ String[] env, IProgressMonitor monitor) {
+ IProject project = cfgDescription.getProjectDescription().getProject();
+ ICFolderDescription rootFolderDescription = cfgDescription.getRootFolderDescription();
+ List languageIds = new ArrayList();
+ for (ICLanguageSetting languageSetting : rootFolderDescription.getLanguageSettings()) {
+ String id = languageSetting.getLanguageId();
+ if (id!=null) {
+ languageIds.add(id);
+ }
+ }
+
+ 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(project, 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/core/CommonBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
index 3167b768e3e..06bf6f49a73 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
@@ -26,6 +26,8 @@ import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ProblemMarkerInfo;
+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.CoreModel;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.core.resources.IConsole;
@@ -145,6 +147,7 @@ public class CommonBuilder extends ACBuilder {
private final IConfiguration fCfg;
private final IBuilder fBuilder;
private IConsole fConsole;
+
CfgBuildInfo(IBuilder builder, boolean isForegound){
this.fBuilder = builder;
this.fCfg = builder.getParent().getParent();
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
index ef84a29dc1e..a2093855a1c 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java
@@ -105,6 +105,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
private String cleanCommand;
private String artifactExtension;
private String errorParserIds;
+ private String defaultLanguageSettingsProvidersIds;
private String prebuildStep;
private String postbuildStep;
private String preannouncebuildStep;
@@ -784,6 +785,9 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
// Get the semicolon separated list of IDs of the error parsers
errorParserIds = SafeStringInterner.safeIntern(element.getAttribute(ERROR_PARSERS));
+ // Get the initial/default language setttings providers IDs
+ defaultLanguageSettingsProvidersIds = SafeStringInterner.safeIntern(element.getAttribute(LANGUAGE_SETTINGS_PROVIDERS));
+
// Get the artifact extension
artifactExtension = SafeStringInterner.safeIntern(element.getAttribute(EXTENSION));
@@ -1425,6 +1429,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
return set;
}
+ public String getDefaultLanguageSettingsProvidersIds() {
+ return defaultLanguageSettingsProvidersIds;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IConfiguration#setArtifactExtension(java.lang.String)
*/
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java
index d9834448cad..a2bfbc22137 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MultiConfiguration.java
@@ -403,6 +403,11 @@ public class MultiConfiguration extends MultiItemsHolder implements
return s;
}
+ public String getDefaultLanguageSettingsProvidersIds() {
+ ManagedBuilderCorePlugin.error("Default Language Settings Providers are not supported in multiconfiguration mode");
+ return null;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IConfiguration#getFilteredTools()
*/
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java
index 6dd49708b6f..fb0bca68433 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java
@@ -85,6 +85,7 @@ public class ToolChain extends HoldsOptions implements IToolChain, IMatchKeyProv
private String targetToolIds;
private String secondaryOutputIds;
private Boolean isAbstract;
+ private String defaultLanguageSettingsProvidersIds;
private String scannerConfigDiscoveryProfileId;
private String versionsSupported;
private String convertToId;
@@ -554,6 +555,9 @@ public class ToolChain extends HoldsOptions implements IToolChain, IMatchKeyProv
// Get the target tool id
targetToolIds = SafeStringInterner.safeIntern(element.getAttribute(TARGET_TOOL));
+ // Get the initial/default language setttings providers IDs
+ defaultLanguageSettingsProvidersIds = element.getAttribute(LANGUAGE_SETTINGS_PROVIDERS);
+
// Get the scanner config discovery profile id
scannerConfigDiscoveryProfileId = SafeStringInterner.safeIntern(element.getAttribute(SCANNER_CONFIG_PROFILE_ID));
String tmp = element.getAttribute(RESOURCE_TYPE_BASED_DISCOVERY);
@@ -1501,6 +1505,10 @@ public class ToolChain extends HoldsOptions implements IToolChain, IMatchKeyProv
setDirty(true);
}
+ public String getDefaultLanguageSettingsProvidersIds() {
+ return defaultLanguageSettingsProvidersIds;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.managedbuilder.core.IToolChain#getScannerConfigDiscoveryProfileId()
*/
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/AbstractBuiltinSpecsDetector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/AbstractBuiltinSpecsDetector.java
new file mode 100644
index 00000000000..4b0a3ac816e
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/AbstractBuiltinSpecsDetector.java
@@ -0,0 +1,508 @@
+/*******************************************************************************
+ * 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.internal.scannerconfig;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.ICommandLauncher;
+import org.eclipse.cdt.core.IConsoleParser;
+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.internal.core.ConsoleOutputSniffer;
+import org.eclipse.cdt.internal.core.XmlUtil;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.AbstractLanguageSettingsOutputScanner;
+import org.eclipse.cdt.make.core.scannerconfig.ILanguageSettingsBuiltinSpecsDetector;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.StreamMonitor;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.SCMarkerGenerator;
+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.IProject;
+import org.eclipse.core.resources.IResource;
+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.NullProgressMonitor;
+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.w3c.dom.Element;
+
+public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSettingsOutputScanner implements ILanguageSettingsBuiltinSpecsDetector {
+ 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$
+
+ private String currentCommandResolved = null;
+ protected List detectedSettingEntries = null;
+
+ private boolean runOnce = true;
+ private boolean isConsoleEnabled = false;
+ protected java.io.File specFile = null;
+ protected boolean preserveSpecFile = false;
+
+ /**
+ * TODO
+ */
+ 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;
+ }
+
+ public void setRunOnce(boolean once) {
+ runOnce = once;
+ }
+
+ public boolean isRunOnce() {
+ return runOnce;
+ }
+
+ public void setConsoleEnabled(boolean enable) {
+ isConsoleEnabled = enable;
+ }
+
+ public boolean isConsoleEnabled() {
+ return isConsoleEnabled;
+ }
+
+ 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);
+ }
+ if (cmd.contains(SPEC_FILE_MACRO)) {
+ String specFileName = getSpecFile(languageId, tool);
+ 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);
+ }
+ }
+ return cmd;
+ }
+
+ /**
+ * TODO
+ */
+ @Override
+ protected String parseForResourceName(String line) {
+ // This works as if workspace-wide
+ return null;
+ }
+
+ @Override
+ protected String determineLanguage(String parsedResourceName) {
+ // language id is supposed to be set by run(), just return it
+ return currentLanguageId;
+ }
+
+ @Override
+ public void startup(ICConfigurationDescription cfgDescription) throws CoreException {
+ // for workspace provider cfgDescription is used to figure out the current project for build console
+ currentCfgDescription = cfgDescription;
+ if (cfgDescription!=null) {
+ currentProject = cfgDescription.getProjectDescription().getProject();
+ }
+
+ detectedSettingEntries = new ArrayList();
+ currentCommandResolved = customParameter;
+
+ specFile = null;
+
+ currentCommandResolved = resolveCommand(currentLanguageId);
+ }
+
+ @Override
+ public void shutdown() {
+ if (detectedSettingEntries!=null && detectedSettingEntries.size()>0) {
+ groupEntries(detectedSettingEntries);
+ setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, detectedSettingEntries);
+
+ IStatus status = new Status(IStatus.INFO, MakeCorePlugin.PLUGIN_ID, getClass().getSimpleName()
+ + " collected " + detectedSettingEntries.size() + " entries" + " for language " + currentLanguageId);
+ ManagedBuilderCorePlugin.log(status);
+ }
+ detectedSettingEntries = null;
+
+ if (specFile!=null && !preserveSpecFile) {
+ specFile.delete();
+ specFile = null;
+ }
+
+ currentCommandResolved = null;
+ }
+
+ protected void groupEntries(List inputEntries) {
+ Map> groupedEntries = new HashMap>();
+ int kindMax = 0;
+ for (ICLanguageSettingEntry entry : inputEntries) {
+ int kind = entry.getKind();
+ if (kind>kindMax) {
+ kindMax = kind;
+ }
+
+ List entries = groupedEntries.get(kind);
+ if (entries==null) {
+ entries = new ArrayList();
+ groupedEntries.put(kind, entries);
+ }
+ entries.add(entry);
+ }
+
+ inputEntries.clear();
+
+ for (int kind=1;kind<=kindMax;kind++) {
+ List entries = groupedEntries.get(kind);
+ if (entries!=null) {
+ inputEntries.addAll(entries);
+ }
+ }
+ }
+
+ 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);
+ }
+
+
+ /**
+ * TODO: test case for this function
+ */
+ private void run(IPath workingDirectory, String[] env, IProgressMonitor monitor)
+ throws CoreException, IOException {
+
+ IConsole console;
+ if (isConsoleEnabled) {
+ console = startProviderConsole();
+ } else {
+ // that looks in extension points registry and won't find the id
+ console = CCorePlugin.getDefault().getConsole(MakeCorePlugin.PLUGIN_ID + ".console.hidden"); //$NON-NLS-1$
+ }
+ console.start(currentProject);
+ OutputStream cos = console.getOutputStream();
+
+ ErrorParserManager epm = null;
+ if (currentProject!=null) {
+ epm = new ErrorParserManager(currentProject, new SCMarkerGenerator(), new String[] {GMAKE_ERROR_PARSER_ID});
+ epm.setOutputStream(cos);
+ }
+
+ 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) {
+ try {
+ consoleOut.close();
+ } catch (IOException e) {
+ ManagedBuilderCorePlugin.log(e);
+ }
+ try {
+ consoleErr.close();
+ } catch (IOException e) {
+ ManagedBuilderCorePlugin.log(e);
+ }
+ }
+ }
+
+ protected boolean runProgram(String command, String[] env, IPath workingDirectory, IProgressMonitor monitor,
+ OutputStream consoleOut, OutputStream consoleErr) throws CoreException, IOException {
+
+ if (command==null || command.trim().length()==0) {
+ return false;
+ }
+
+ String errMsg = null;
+ ICommandLauncher launcher = new CommandLauncher();
+
+ launcher.setProject(currentProject);
+
+ // Print the command for visual interaction.
+ launcher.showCommand(true);
+
+ String[] cmdArray = CommandLineUtil.argumentsToArray(command);
+ IPath program = new Path(cmdArray[0]);
+ String[] args = new String[0];
+ if (cmdArray.length>1) {
+ args = new String[cmdArray.length-1];
+ System.arraycopy(cmdArray, 1, args, 0, args.length);
+ }
+
+ 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) {
+ errMsg = launcher.getErrorMessage();
+ }
+ } else {
+ errMsg = launcher.getErrorMessage();
+ }
+ if (errMsg!=null) {
+ String errorPrefix = MakeMessages.getString("ExternalScannerInfoProvider.Error_Prefix"); //$NON-NLS-1$
+
+ String msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Provider_Error", command);
+ printLine(consoleErr, errorPrefix + msg + NEWLINE);
+
+ // Launching failed, trying to figure out possible cause
+ String envPath = getEnvVar(env, PATH_ENV);
+ if (!program.isAbsolute() && PathUtil.findProgramLocation(program.toString(), envPath) == null) {
+ printLine(consoleErr, errMsg);
+ msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Working_Directory", workingDirectory); //$NON-NLS-1$
+ msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Program_Not_In_Path", program); //$NON-NLS-1$
+ printLine(consoleErr, errorPrefix + msg + NEWLINE);
+ printLine(consoleErr, PATH_ENV + "=[" + envPath + "]" + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ printLine(consoleErr, errorPrefix + errMsg);
+ msg = MakeMessages.getFormattedString("ExternalScannerInfoProvider.Working_Directory", workingDirectory); //$NON-NLS-1$
+ printLine(consoleErr, PATH_ENV + "=[" + envPath + "]" + NEWLINE); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * TODO
+ */
+ @Override
+ protected void setSettingEntries(List entries) {
+ // Builtin specs detectors collect entries not per line but for the whole output
+ if (entries!=null)
+ detectedSettingEntries.addAll(entries);
+ }
+
+ private IConsole startProviderConsole() {
+ ILanguageDescriptor ld = LanguageManager.getInstance().getLanguageDescriptor(currentLanguageId);
+
+ String consoleId = MakeCorePlugin.PLUGIN_ID + '.' + getId() + '.' + currentLanguageId;
+ String consoleName = getName() + ", " + ld.getName();
+ URL defaultIcon = Platform.getBundle(PLUGIN_CDT_MAKE_UI_ID).getEntry("icons/obj16/inspect_system.gif");
+
+ IConsole console = CCorePlugin.getDefault().getConsole("org.eclipse.cdt.make.internal.ui.scannerconfig.ScannerDiscoveryConsole", consoleId, consoleName, defaultIcon);
+ return console;
+ }
+
+ private String getEnvVar(String[] envStrings, String envVar) {
+ String envPath = null;
+ if (envStrings!=null) {
+ String varPrefix = envVar+'=';
+ for (String envStr : envStrings) {
+ if (envStr.startsWith(varPrefix)) {
+ envPath = envStr.substring(varPrefix.length());
+ break;
+ }
+ }
+ } else {
+ envPath = System.getenv(envVar);
+ }
+ 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);
+ 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);
+ }
+ return compiler;
+ }
+
+ private String getSpecFile(String languageId, ITool tool) {
+ String ext = getSpecExt(languageId, tool);
+
+ String specFileName = SPEC_FILE_BASE + ext;
+ IPath workingLocation = MakeCorePlugin.getWorkingDirectory();
+ IPath fileLocation = workingLocation.append(specFileName);
+
+ specFile = new java.io.File(fileLocation.toOSString());
+ // will preserve spec file if it was already there otherwise will delete upon finishing
+ preserveSpecFile = specFile.exists();
+ if (!preserveSpecFile) {
+ try {
+ specFile.createNewFile();
+ } catch (IOException e) {
+ ManagedBuilderCorePlugin.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];
+ }
+ if (ext.length()==0) {
+ ManagedBuilderCorePlugin.error("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();
+ }
+
+ @Override
+ public Element serialize(Element parentElement) {
+ Element elementProvider = super.serialize(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);
+
+ String consoleValue = XmlUtil.determineAttributeValue(providerNode, ATTR_CONSOLE);
+ if (consoleValue!=null)
+ isConsoleEnabled = Boolean.parseBoolean(consoleValue);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + (runOnce ? 1231 : 1237);
+ result = prime * result + (isConsoleEnabled ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (!(obj instanceof AbstractBuiltinSpecsDetector))
+ return false;
+ AbstractBuiltinSpecsDetector other = (AbstractBuiltinSpecsDetector) obj;
+ if (runOnce != other.runOnce)
+ return false;
+ if (isConsoleEnabled != other.isConsoleEnabled)
+ return false;
+ return true;
+ }
+}
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
new file mode 100644
index 00000000000..d5fee24780e
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/GCCBuiltinSpecsDetector.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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.internal.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Class to detect built-in compiler settings. Note that currently this class is hardwired
+ * 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
+ 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}
+ State state = State.NONE;
+
+ @SuppressWarnings("nls")
+ static final AbstractOptionParser[] optionParsers = {
+ 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),
+ };
+
+ @Override
+ protected String getToolchainId() {
+ return GCC_TOOLCHAIN_ID;
+ }
+
+ @Override
+ protected AbstractOptionParser[] getOptionParsers() {
+ return optionParsers;
+ }
+
+ private List makeList(final String line) {
+ return new ArrayList() {{ add(line); }};
+ }
+
+ @Override
+ protected List parseForOptions(String line) {
+ line = line.trim();
+
+ // contribution of -dD option
+ if (line.startsWith("#define")) {
+ return makeList(line);
+ }
+
+ /**
+
+Framework search starts here:
+ /System/Library/Frameworks
+ /Library/Frameworks
+End of framework search list.
+
+ */
+
+ // contribution of includes
+ if (line.equals("#include \"...\" search starts here:")) {
+ state = State.EXPECTING_LOCAL_INCLUDE;
+ } else if (line.equals("#include <...> search starts here:")) {
+ state = State.EXPECTING_SYSTEM_INCLUDE;
+ } else if (line.startsWith("End of search list.")) {
+ state = State.NONE;
+ } else if (line.equals("Framework search starts here:")) {
+ state = State.EXPECTING_FRAMEWORKS;
+ } else if (line.startsWith("End of framework search list.")) {
+ state = State.NONE;
+ } else if (state==State.EXPECTING_LOCAL_INCLUDE) {
+ // making that up for the parser to figure out
+ line = "#include \""+line+"\"";
+ return makeList(line);
+ } else {
+ String frameworkIndicator = "(framework directory)";
+ if (state==State.EXPECTING_SYSTEM_INCLUDE) {
+ // making that up for the parser to figure out
+ if (line.contains(frameworkIndicator)) {
+ line = "#framework <"+line.replace(frameworkIndicator, "").trim()+">";
+ } else {
+ line = "#include <"+line+">";
+ }
+ return makeList(line);
+ } else if (state==State.EXPECTING_FRAMEWORKS) {
+ // making that up for the parser to figure out
+ line = "#framework <"+line.replace(frameworkIndicator, "").trim()+">";
+ return makeList(line);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void startup(ICConfigurationDescription cfgDescription) throws CoreException {
+ super.startup(cfgDescription);
+
+ state = State.NONE;
+ }
+
+ @Override
+ public void shutdown() {
+ state = State.NONE;
+
+ super.shutdown();
+ }
+
+ @Override
+ public GCCBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException {
+ return (GCCBuiltinSpecsDetector) super.cloneShallow();
+ }
+
+ @Override
+ public GCCBuiltinSpecsDetector clone() throws CloneNotSupportedException {
+ return (GCCBuiltinSpecsDetector) super.clone();
+ }
+
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/MBSLanguageSettingsProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/MBSLanguageSettingsProvider.java
new file mode 100644
index 00000000000..ebddb38e568
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/scannerconfig/MBSLanguageSettingsProvider.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2009 Andrew Gvozdev (Quoin Inc.) 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 (Quoin Inc.) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.managedbuilder.internal.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.cdt.core.AbstractExecutableExtensionBase;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICFileDescription;
+import org.eclipse.cdt.core.settings.model.ICFolderDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSetting;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.core.settings.model.ICSettingBase;
+import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+
+//public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase implements ILanguageSettingsEditableProvider {
+public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase implements ILanguageSettingsProvider {
+
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+
+ IPath projectPath = rc.getProjectRelativePath();
+ ICResourceDescription rcDescription = cfgDescription.getResourceDescription(projectPath, false);
+
+ List list = new ArrayList();
+ for (ICLanguageSetting languageSetting : getLanguageSettings(rcDescription)) {
+ if (languageSetting!=null) {
+ String id = languageSetting.getLanguageId();
+ if (id!=null && id.equals(languageId)) {
+ int kindsBits = languageSetting.getSupportedEntryKinds();
+ for (int kind=1;kind<=kindsBits;kind<<=1) {
+ if ((kindsBits & kind) != 0) {
+ list.addAll(languageSetting.getSettingEntriesList(kind));
+ }
+ }
+ } else {
+// System.err.println("languageSetting id=null: name=" + languageSetting.getName());
+ }
+ } else {
+ System.err.println("languageSetting=null: rcDescription=" + rcDescription.getName());
+ }
+ }
+ return list;
+ }
+
+ private ICLanguageSetting[] getLanguageSettings(ICResourceDescription rcDescription) {
+ ICLanguageSetting[] array = null;
+ switch (rcDescription.getType()) {
+ case ICSettingBase.SETTING_PROJECT:
+ case ICSettingBase.SETTING_CONFIGURATION:
+ case ICSettingBase.SETTING_FOLDER:
+ ICFolderDescription foDes = (ICFolderDescription)rcDescription;
+ array = foDes.getLanguageSettings();
+ break;
+ case ICSettingBase.SETTING_FILE:
+ ICFileDescription fiDes = (ICFileDescription)rcDescription;
+ ICLanguageSetting ls = fiDes.getLanguageSetting();
+ if (ls!=null) {
+ array = new ICLanguageSetting[] { ls };
+ }
+ }
+ if (array==null) {
+ array = new ICLanguageSetting[0];
+ }
+ return array;
+ }
+
+ public void setSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId,
+ List entries) {
+
+// lang.setSettingEntries(kind, entries);
+ IPath projectPath = rc.getProjectRelativePath();
+ ICResourceDescription rcDescription = cfgDescription.getResourceDescription(projectPath, false);
+
+ for (ICLanguageSetting languageSetting : getLanguageSettings(rcDescription)) {
+ if (languageSetting!=null) {
+ String id = languageSetting.getLanguageId();
+ if (id!=null && id.equals(languageId)) {
+ int kindsBits = languageSetting.getSupportedEntryKinds();
+ for (int kind=1;kind<=kindsBits;kind<<=1) {
+ if ((kindsBits & kind) != 0) {
+ List list = new ArrayList(entries.size());
+ for (ICLanguageSettingEntry entry : entries) {
+ if (entry.getKind()==kind) {
+ list.add(entry);
+ }
+ }
+ languageSetting.setSettingEntries(kind, list);
+ }
+ }
+ } else {
+// System.err.println("languageSetting id=null: name=" + languageSetting.getName());
+ }
+ } else {
+ System.err.println("languageSetting=null: rcDescription=" + rcDescription.getName());
+ }
+ }
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml
index f26ee076aae..77ada67aea3 100644
--- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml
+++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml
@@ -1665,10 +1665,11 @@
+ osList="linux,hpux,aix,qnx"
+ targetTool="cdt.managedbuild.tool.gnu.c.linker;cdt.managedbuild.tool.gnu.cpp.linker;cdt.managedbuild.tool.gnu.archiver">
@@ -1802,6 +1804,7 @@
configurationEnvironmentSupplier="org.eclipse.cdt.managedbuilder.gnu.mingw.MingwEnvironmentVariableSupplier"
id="cdt.managedbuild.toolchain.gnu.mingw.base"
isToolChainSupported="org.eclipse.cdt.managedbuilder.gnu.mingw.MingwIsToolChainSupported"
+ languageSettingsProviders="org.eclipse.cdt.make.core.build.command.parser.gcc;*org.eclipse.cdt.managedbuilder.core.gcc.specs.detector"
name="%ToolChainName.MinGW"
osList="win32"
targetTool="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base;cdt.managedbuild.tool.gnu.c.linker.mingw.base;cdt.managedbuild.tool.gnu.archiver">
@@ -2043,9 +2046,9 @@
+ id="cdt.managedbuild.config.gnu.base"
+ languageSettingsProviders="org.eclipse.cdt.ui.user.LanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.LanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.make.core.build.command.parser.gcc">
+ cleanCommand="rm -rf"
+ id="cdt.managedbuild.config.gnu.cygwin.base"
+ languageSettingsProviders="org.eclipse.cdt.ui.user.LanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.LanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.make.core.build.command.parser.gcc">
+ cleanCommand="rm -rf"
+ id="cdt.managedbuild.config.gnu.mingw.base"
+ languageSettingsProviders="org.eclipse.cdt.ui.user.LanguageSettingsProvider;org.eclipse.cdt.managedbuilder.core.LanguageSettingsProvider;${Toolchain};-org.eclipse.cdt.make.core.build.command.parser.gcc">
+
+
+
+
+
+
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java
index 7d4180d427f..e445ffb8dc3 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.java
@@ -210,6 +210,8 @@ public class Messages extends NLS {
public static String PropertyPageDefsTab_8;
public static String PropertyPageDefsTab_9;
public static String PropertyPageDefsTab_showIncludeFileTab;
+ public static String PropertyPageDefsTab_showProvidersTab;
+ public static String RefreshPolicyExceptionDialog_addButtonLabel;
public static String RefreshPolicyExceptionDialog_addDialogLabel;
public static String RefreshPolicyExceptionDialog_AddExceptionInfoDialog_message;
public static String RefreshPolicyExceptionDialog_AddExceptionInfoDialog_title;
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties
index 9b176b659e6..5185ed82802 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/Messages.properties
@@ -272,6 +272,7 @@ PropertyPageDefsTab_7=Show disc. page names if they are unique. Else show profil
PropertyPageDefsTab_8=Always show names + profile IDs
PropertyPageDefsTab_9=Always show profile IDs only
PropertyPageDefsTab_showIncludeFileTab=Display "Include Files" tab
+PropertyPageDefsTab_showProvidersTab=Display new experimental Scanner Discovery Providers tabs
ProjectConvert_convertersList=Converters List
AbstractPrefPage_0=\ Preference settings will be applied to new projects \n only when there were no toolchains selected.
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/BuiltinSpecsDetectorOptionPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/BuiltinSpecsDetectorOptionPage.java
new file mode 100644
index 00000000000..12885afab20
--- /dev/null
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/BuiltinSpecsDetectorOptionPage.java
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.ui.preferences;
+
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
+import org.eclipse.cdt.internal.ui.language.settings.providers.AbstractLanguageSettingProviderOptionPage;
+import org.eclipse.cdt.internal.ui.newui.StatusMessageLine;
+import org.eclipse.cdt.managedbuilder.internal.scannerconfig.AbstractBuiltinSpecsDetector;
+import org.eclipse.cdt.utils.ui.controls.ControlFactory;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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;
+
+/**
+ * Options page for TODO
+ *
+ */
+public final class BuiltinSpecsDetectorOptionPage extends AbstractLanguageSettingProviderOptionPage {
+ private boolean fEditable;
+
+ private Text inputCommand;
+
+ private StatusMessageLine fStatusLine;
+ private Button runOnceRadioButton;
+ private Button runEveryBuildRadioButton;
+ private Button allocateConsoleCheckBox;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+// Composite optionsPageComposite = new Composite(composite, SWT.NULL);
+ fEditable = parent.isEnabled();
+
+ final Composite composite = new Composite(parent, 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);
+
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ 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
+ {
+ Label label = ControlFactory.createLabel(composite, "Command to get compiler specs:");
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData(gd);
+ label.setEnabled(fEditable);
+ }
+
+ {
+ inputCommand = ControlFactory.createTextField(composite, SWT.SINGLE | SWT.BORDER);
+ String customParameter = provider.getCustomParameter();
+ inputCommand.setText(customParameter!=null ? customParameter : "");
+ inputCommand.setEnabled(fEditable);
+ inputCommand.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String text = inputCommand.getText();
+ AbstractBuiltinSpecsDetector provider = getRawProvider();
+ if (!text.equals(provider.getCustomParameter())) {
+ AbstractBuiltinSpecsDetector selectedProvider = getWorkingCopy(providerId);
+ selectedProvider.setCustomParameter(text);
+ providerTab.refreshItem(selectedProvider);
+ }
+ }
+ });
+ }
+
+ {
+ Button button = ControlFactory.createPushButton(composite, "Browse...");
+ button.setEnabled(fEditable);
+ button.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+// handleAddr2LineButtonSelected();
+ //updateLaunchConfigurationDialog();
+ }
+
+ });
+
+ }
+
+// {
+// 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);
+// }
+
+ {
+ allocateConsoleCheckBox = new Button(composite, SWT.CHECK);
+ allocateConsoleCheckBox.setText("Allocate console in the Console View");
+ allocateConsoleCheckBox.setSelection(provider.isConsoleEnabled());
+ allocateConsoleCheckBox.setEnabled(fEditable);
+ allocateConsoleCheckBox.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ boolean enabled = allocateConsoleCheckBox.getSelection();
+ AbstractBuiltinSpecsDetector provider = getRawProvider();
+ if (enabled != provider.isConsoleEnabled()) {
+ AbstractBuiltinSpecsDetector selectedProvider = getWorkingCopy(providerId);
+ selectedProvider.setConsoleEnabled(enabled);
+ providerTab.refreshItem(selectedProvider);
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ });
+
+ }
+
+// // Status line
+// if (fEditable) {
+// fStatusLine = new StatusMessageLine(composite, SWT.LEFT, 2);
+// IStatus status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID, "Note that currently not all options are persisted (FIXME)");
+// fStatusLine.setErrorStatus(status);
+// }
+
+ setControl(composite);
+ }
+
+ private AbstractBuiltinSpecsDetector getRawProvider() {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getRawProvider(providerTab.getProvider(providerId));
+ Assert.isTrue(provider instanceof AbstractBuiltinSpecsDetector);
+ return (AbstractBuiltinSpecsDetector) provider;
+ }
+
+ private AbstractBuiltinSpecsDetector getWorkingCopy(String providerId) {
+ ILanguageSettingsProvider provider = providerTab.getWorkingCopy(providerId);
+ Assert.isTrue(provider instanceof AbstractBuiltinSpecsDetector);
+ return (AbstractBuiltinSpecsDetector) provider;
+ }
+
+ @Override
+ public void performApply(IProgressMonitor monitor) throws CoreException {
+ // handled by LanguageSettingsProviderTab
+ }
+
+ @Override
+ public void performDefaults() {
+ // handled by LanguageSettingsProviderTab
+ }
+
+}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java
index 458f7e517a1..245dde59395 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/PropertyPageDefsTab.java
@@ -12,9 +12,9 @@
package org.eclipse.cdt.managedbuilder.ui.preferences;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
+import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
import org.eclipse.cdt.ui.newui.AbstractCPropertyTab;
import org.eclipse.cdt.ui.newui.CDTPrefUtil;
-import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
@@ -38,6 +38,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
private Button show_mng;
private Button show_tool;
private Button show_exp;
+ private Button show_providers_tab; // temporary checkbox for scanner discovery Providers tab
private Button show_tipbox;
private Button b_0;
@@ -74,6 +75,11 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
show_exp.setText(Messages.PropertyPageDefsTab_10);
show_exp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ show_providers_tab = new Button(usercomp, SWT.CHECK);
+ show_providers_tab.setText(Messages.PropertyPageDefsTab_showProvidersTab + ", " //$NON-NLS-1$
+ + org.eclipse.cdt.internal.ui.newui.Messages.CDTMainWizardPage_TrySD90);
+ show_providers_tab.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
show_tipbox = new Button(usercomp, SWT.CHECK);
show_tipbox.setText(Messages.PropertyPageDefsTab_16);
show_tipbox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
@@ -117,6 +123,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
show_mng.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOMNG));
show_tool.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOTOOLM));
show_exp.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_EXPORT));
+ show_providers_tab.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NO_SHOW_PROVIDERS));
show_tipbox.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_TIPBOX));
switch (CDTPrefUtil.getInt(CDTPrefUtil.KEY_DISC_NAMES)) {
@@ -140,6 +147,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
CDTPrefUtil.setBool(CDTPrefUtil.KEY_NOMNG, !show_mng.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_NOTOOLM, !show_tool.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_EXPORT, show_exp.getSelection());
+ CDTPrefUtil.setBool(CDTPrefUtil.KEY_NO_SHOW_PROVIDERS, !show_providers_tab.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_TIPBOX, show_tipbox.getSelection());
int x = 0;
if (b_1.getSelection()) x = 1;
@@ -160,6 +168,7 @@ public class PropertyPageDefsTab extends AbstractCPropertyTab {
show_mng.setSelection(true);
show_tool.setSelection(true);
show_exp.setSelection(false);
+ show_providers_tab.setSelection(false);
show_tipbox.setSelection(false);
b_0.setSelection(true);
b_1.setSelection(false);
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java
index 636382cc660..03b4f0a8f1f 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/preferences/WizardDefaultsTab.java
@@ -30,6 +30,7 @@ public class WizardDefaultsTab extends AbstractCPropertyTab {
private Button show_sup;
private Button show_oth;
+ private Button checkBoxTryNewSD;
@Override
public void createControls(Composite parent) {
@@ -44,20 +45,27 @@ public class WizardDefaultsTab extends AbstractCPropertyTab {
show_oth.setText(Messages.WizardDefaultsTab_1);
show_oth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ checkBoxTryNewSD = new Button(usercomp, SWT.CHECK);
+ checkBoxTryNewSD.setText(org.eclipse.cdt.internal.ui.newui.Messages.CDTMainWizardPage_TrySD90);
+ checkBoxTryNewSD.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
show_sup.setSelection(!CDTPrefUtil.getBool(CDTPrefUtil.KEY_NOSUPP));
show_oth.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_OTHERS));
+ checkBoxTryNewSD.setSelection(CDTPrefUtil.getBool(CDTPrefUtil.KEY_NEWSD));
}
@Override
protected void performOK() {
CDTPrefUtil.setBool(CDTPrefUtil.KEY_NOSUPP, !show_sup.getSelection());
CDTPrefUtil.setBool(CDTPrefUtil.KEY_OTHERS, show_oth.getSelection());
+ CDTPrefUtil.setBool(CDTPrefUtil.KEY_NEWSD, checkBoxTryNewSD.getSelection());
}
@Override
protected void performDefaults() {
show_sup.setSelection(true);
show_oth.setSelection(false);
+ checkBoxTryNewSD.setSelection(true);
}
@Override
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java
index 14fa0ce258b..ef874834d15 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/MBSWizardHandler.java
@@ -23,6 +23,9 @@ import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
+import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
@@ -41,8 +44,8 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.core.Configuration;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
-import org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin;
import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
+import org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin;
import org.eclipse.cdt.ui.newui.CDTPrefUtil;
import org.eclipse.cdt.ui.templateengine.IWizardDataPage;
import org.eclipse.cdt.ui.templateengine.Template;
@@ -549,6 +552,13 @@ public class MBSWizardHandler extends CWizardHandler {
}
private void setProjectDescription(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor) throws CoreException {
+ boolean isTryingNewSD = false;
+ IWizardPage page = getStartingPage();
+ if (page instanceof CDTMainWizardPage) {
+ CDTMainWizardPage mainWizardPage = (CDTMainWizardPage)page;
+ isTryingNewSD = mainWizardPage.isTryingNewSD();
+ }
+
ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager();
ICProjectDescription des = mngr.createProjectDescription(project, false, !onFinish);
ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project);
@@ -594,9 +604,32 @@ public class MBSWizardHandler extends CWizardHandler {
cfgDebug = cfgDes;
if (cfgFirst == null) // select at least first configuration
cfgFirst = cfgDes;
+
+ if (isTryingNewSD) {
+ CfgScannerConfigProfileManager.disableScannerDiscovery(config);
+
+ List providers = ManagedBuildManager.getLanguageSettingsProviders(config);
+ cfgDes.setLanguageSettingProviders(providers);
+ } else {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getWorkspaceProvider(ManagedBuildManager.MBS_LANGUAGE_SETTINGS_PROVIDER);
+ List providers = new ArrayList();
+ providers.add(provider);
+ cfgDes.setLanguageSettingProviders(providers);
+ }
+
monitor.worked(work);
}
mngr.setProjectDescription(project, des);
+
+ // FIXME if scanner discovery is empty it is "fixed" deeply inside setProjectDescription(), taking the easy road here for the moment
+ if (isTryingNewSD) {
+ des = mngr.getProjectDescription(project);
+ boolean isChanged = CfgScannerConfigProfileManager.disableScannerDiscovery(des);
+
+ if (isChanged) {
+ mngr.setProjectDescription(project, des);
+ }
+ }
}
@Override
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExisting.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExisting.java
index 3e5767ffabb..666a8dce04f 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExisting.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExisting.java
@@ -11,10 +11,16 @@
package org.eclipse.cdt.managedbuilder.ui.wizards;
import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
@@ -68,6 +74,7 @@ public class NewMakeProjFromExisting extends Wizard implements IImportWizard, IN
final String locationStr = page.getLocation();
final boolean isCPP = page.isCPP();
final IToolChain toolChain = page.getToolChain();
+ final boolean isTryingNewSD = page.isTryingNewSD();
IRunnableWithProgress op = new WorkspaceModifyOperation() {
@Override
@@ -109,13 +116,39 @@ public class NewMakeProjFromExisting extends Wizard implements IImportWizard, IN
IBuilder builder = config.getEditableBuilder();
builder.setManagedBuildOn(false);
CConfigurationData data = config.getConfigurationData();
- projDesc.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
+ ICConfigurationDescription cfgDes = projDesc.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
+
+ if (isTryingNewSD) {
+ CfgScannerConfigProfileManager.disableScannerDiscovery(config);
+
+ List providers = ManagedBuildManager.getLanguageSettingsProviders(config);
+ cfgDes.setLanguageSettingProviders(providers);
+ } else {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getWorkspaceProvider(ManagedBuildManager.MBS_LANGUAGE_SETTINGS_PROVIDER);
+ List providers = new ArrayList();
+ providers.add(provider);
+ cfgDes.setLanguageSettingProviders(providers);
+ }
+
+
monitor.worked(1);
pdMgr.setProjectDescription(project, projDesc);
+
+ // FIXME if scanner discovery is empty it is "fixed" deeply inside setProjectDescription(), taking the easy road here for the moment
+ if (isTryingNewSD) {
+ ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager();
+ ICProjectDescription des = mngr.getProjectDescription(project);
+ boolean isChanged = CfgScannerConfigProfileManager.disableScannerDiscovery(des);
+
+ if (isChanged) {
+ mngr.setProjectDescription(project, des);
+ }
+ }
} catch (Throwable e) {
ManagedBuilderUIPlugin.log(e);
}
+
monitor.done();
}
};
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExistingPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExistingPage.java
index 31e61531fff..0b584fe8aa4 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExistingPage.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/NewMakeProjFromExistingPage.java
@@ -19,6 +19,8 @@ import java.util.Map;
import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.newui.CDTPrefUtil;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
@@ -52,6 +54,9 @@ public class NewMakeProjFromExistingPage extends WizardPage {
List tcList;
Map tcMap = new HashMap();
+ private Button checkBoxTryNewSD;
+
+
protected NewMakeProjFromExistingPage() {
super(Messages.NewMakeProjFromExistingPage_0);
setTitle(Messages.NewMakeProjFromExistingPage_1);
@@ -71,6 +76,21 @@ public class NewMakeProjFromExistingPage extends WizardPage {
addLanguageSelector(comp);
addToolchainSelector(comp);
+ checkBoxTryNewSD = new Button(comp, SWT.CHECK);
+ checkBoxTryNewSD.setText(org.eclipse.cdt.internal.ui.newui.Messages.CDTMainWizardPage_TrySD90);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ checkBoxTryNewSD.setLayoutData(gd);
+
+
+ // restore settings from preferences
+ boolean isTryNewSD = true;
+ boolean contains = CUIPlugin.getDefault().getPreferenceStore().contains(CDTPrefUtil.KEY_NEWSD);
+ if (contains) {
+ isTryNewSD = CDTPrefUtil.getBool(CDTPrefUtil.KEY_NEWSD);
+ }
+ checkBoxTryNewSD.setSelection(isTryNewSD);
+
setControl(comp);
}
@@ -208,4 +228,7 @@ public class NewMakeProjFromExistingPage extends WizardPage {
return selection.length != 0 ? tcMap.get(selection[0]) : null;
}
+ public boolean isTryingNewSD() {
+ return checkBoxTryNewSD.getSelection();
+ }
}
diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java
index b5128f0ef2e..83951ab46c9 100644
--- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java
+++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/wizards/STDWizardHandler.java
@@ -11,7 +11,14 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.ui.wizards;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
+import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
+import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
@@ -24,10 +31,12 @@ import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
import org.eclipse.cdt.managedbuilder.internal.core.ToolChain;
import org.eclipse.cdt.managedbuilder.internal.ui.Messages;
+import org.eclipse.cdt.ui.wizards.CDTMainWizardPage;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.widgets.Composite;
/**
@@ -71,6 +80,14 @@ public class STDWizardHandler extends MBSWizardHandler {
private void setProjectDescription(IProject project, boolean defaults, boolean onFinish, IProgressMonitor monitor)
throws CoreException {
+
+ boolean isTryingNewSD = false;
+ IWizardPage page = getStartingPage();
+ if (page instanceof CDTMainWizardPage) {
+ CDTMainWizardPage mainWizardPage = (CDTMainWizardPage)page;
+ isTryingNewSD = mainWizardPage.isTryingNewSD();
+ }
+
ICProjectDescriptionManager mngr = CoreModel.getDefault().getProjectDescriptionManager();
ICProjectDescription des = mngr.createProjectDescription(project, false, !onFinish);
ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project);
@@ -99,10 +116,33 @@ public class STDWizardHandler extends MBSWizardHandler {
}
cfg.setArtifactName(mProj.getDefaultArtifactName());
CConfigurationData data = cfg.getConfigurationData();
- des.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
+ ICConfigurationDescription cfgDes = des.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
+
+ if (isTryingNewSD) {
+ CfgScannerConfigProfileManager.disableScannerDiscovery(cfg);
+
+ List providers = ManagedBuildManager.getLanguageSettingsProviders(cfg);
+ cfgDes.setLanguageSettingProviders(providers);
+ } else {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getWorkspaceProvider(ManagedBuildManager.MBS_LANGUAGE_SETTINGS_PROVIDER);
+ List providers = new ArrayList();
+ providers.add(provider);
+ cfgDes.setLanguageSettingProviders(providers);
+ }
+
monitor.worked(work);
}
mngr.setProjectDescription(project, des);
+
+ // FIXME if scanner discovery is empty it is "fixed" deeply inside setProjectDescription(), taking the easy road here for the moment
+ if (isTryingNewSD) {
+ des = mngr.getProjectDescription(project);
+ boolean isChanged = CfgScannerConfigProfileManager.disableScannerDiscovery(des);
+
+ if (isChanged) {
+ mngr.setProjectDescription(project, des);
+ }
+ }
}
public boolean canCreateWithoutToolchain() { return true; }
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/filesystem/ram/MemoryEFSExtensionProvider.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/filesystem/ram/MemoryEFSExtensionProvider.java
new file mode 100644
index 00000000000..279f507aae8
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/filesystem/ram/MemoryEFSExtensionProvider.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.core.internal.tests.filesystem.ram;
+
+import java.net.URI;
+
+import org.eclipse.cdt.core.EFSExtensionProvider;
+
+/**
+ * Test stub to test EFSExtensionProvider mappings.
+ *
+ */
+public class MemoryEFSExtensionProvider extends EFSExtensionProvider {
+
+ public String getMappedPath(URI locationURI) {
+
+ String path = locationURI.getPath();
+ if (path.contains("/BeingMappedFrom/Folder")) {
+ return path.replaceFirst("/BeingMappedFrom/Folder", "/LocallyMappedTo/Folder");
+ }
+
+ return super.getMappedPath(locationURI);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java
new file mode 100644
index 00000000000..fb9b5be8379
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/AllLanguageSettingsProvidersTests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.core.language.settings.providers;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+public class AllLanguageSettingsProvidersTests {
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(AllLanguageSettingsProvidersTests.class.getName());
+
+ suite.addTest(LanguageSettingsExtensionsTests.suite());
+ suite.addTest(LanguageSettingsManagerTests.suite());
+ suite.addTest(LanguageSettingsSerializableTests.suite());
+ suite.addTest(LanguageSettingsPersistenceProjectTests.suite());
+ suite.addTest(LanguageSettingsScannerInfoProviderTests.suite());
+ return suite;
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java
new file mode 100644
index 00000000000..3a95102a247
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsExtensionsTests.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.core.language.settings.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+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.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.core.settings.model.ILanguageSettingsEditableProvider;
+import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Test cases testing LanguageSettingsProvider functionality
+ */
+public class LanguageSettingsExtensionsTests extends TestCase {
+ // These should match corresponding entries defined in plugin.xml
+ private static final String EXTENSION_BASE_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider";
+ private static final String EXTENSION_BASE_PROVIDER_NAME = "Test Plugin Language Settings Base Provider";
+ private static final String EXTENSION_BASE_PROVIDER_LANG_ID = "org.eclipse.cdt.core.tests.language.id";
+ private static final String EXTENSION_BASE_PROVIDER_PARAMETER = "custom parameter";
+ private static final String EXTENSION_CUSTOM_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.language.settings.provider";
+ private static final String EXTENSION_CUSTOM_PROVIDER_NAME = "Test Plugin Language Settings Provider";
+ private static final String EXTENSION_BASE_SUBCLASS_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider.subclass";
+ private static final String EXTENSION_BASE_SUBCLASS_PROVIDER_PARAMETER = "custom parameter subclass";
+ private static final String EXTENSION_SERIALIZABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.serializable.language.settings.provider";
+ private static final String EXTENSION_EDITABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.editable.language.settings.provider";
+
+ // These are made up
+ private static final String PROVIDER_0 = "test.provider.0.id";
+ private static final String PROVIDER_NAME_0 = "test.provider.0.name";
+ private static final String LANG_ID = "test.lang.id";
+ private static final IFile FILE_0 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/project/path0"));
+
+ /**
+ * Constructor.
+ * @param name - name of the test.
+ */
+ public LanguageSettingsExtensionsTests(String name) {
+ super(name);
+
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ }
+
+ /**
+ * @return - new TestSuite.
+ */
+ public static TestSuite suite() {
+ return new TestSuite(LanguageSettingsExtensionsTests.class);
+ }
+
+ /**
+ * main function of the class.
+ *
+ * @param args - arguments
+ */
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ /**
+ * Check that regular ICLanguageSettingsProvider extension defined in plugin.xml is accessible.
+ */
+ public void testExtension() throws Exception {
+ {
+ List providers = LanguageSettingsManager.getWorkspaceProviders();
+ List ids = new ArrayList();
+ for (ILanguageSettingsProvider provider : providers) {
+ ids.add(provider.getId());
+ }
+ assertTrue("extension " + EXTENSION_BASE_PROVIDER_ID + " not found", ids.contains(EXTENSION_BASE_PROVIDER_ID));
+ }
+
+ {
+ // test provider not in the list
+ ILanguageSettingsProvider providerExt = LanguageSettingsManager.getExtensionProviderCopy("missing.povider");
+ assertTrue(LanguageSettingsManager.isWorkspaceProvider(providerExt));
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(providerExt);
+ assertNull(rawProvider);
+ }
+
+ // get test plugin extension provider
+ ILanguageSettingsProvider providerExt = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_BASE_PROVIDER_ID);
+ assertTrue(LanguageSettingsManager.isWorkspaceProvider(providerExt));
+
+ // get raw extension provider
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(providerExt);
+ assertTrue(rawProvider instanceof LanguageSettingsBaseProvider);
+ LanguageSettingsBaseProvider provider = (LanguageSettingsBaseProvider)rawProvider;
+ assertEquals(EXTENSION_BASE_PROVIDER_ID, provider.getId());
+ assertEquals(EXTENSION_BASE_PROVIDER_NAME, provider.getName());
+ assertEquals(EXTENSION_BASE_PROVIDER_PARAMETER, provider.getCustomParameter());
+
+ // attempt to get entries for wrong language
+ assertNull(provider.getSettingEntries(null, FILE_0, LANG_ID));
+
+ // benchmarks matching extension point definition
+ List entriesExt = new ArrayList();
+ entriesExt.add(new CIncludePathEntry("/usr/include/",
+ ICSettingEntry.BUILTIN
+ | ICSettingEntry.LOCAL
+ | ICSettingEntry.RESOLVED
+ | ICSettingEntry.VALUE_WORKSPACE_PATH
+ | ICSettingEntry.UNDEFINED
+ ));
+ entriesExt.add(new CMacroEntry("TEST_DEFINE", "100", 0));
+ entriesExt.add(new CIncludeFileEntry("/include/file.inc", 0));
+ entriesExt.add(new CLibraryPathEntry("/usr/lib/", 0));
+ entriesExt.add(new CLibraryFileEntry("libdomain.a", 0));
+ entriesExt.add(new CMacroFileEntry("/macro/file.mac", 0));
+
+ // retrieve entries from extension point
+ List actual = provider.getSettingEntries(null, FILE_0, EXTENSION_BASE_PROVIDER_LANG_ID);
+ for (int i=0;i entriesExt = new ArrayList();
+ entriesExt.add(new CIncludePathEntry("/usr/include/", ICSettingEntry.BUILTIN));
+
+ // retrieve entries from extension point
+ List actual = provider.getSettingEntries(null, FILE_0, LANG_ID);
+ for (int i=0;i entries = new ArrayList();
+ entries.add(new CIncludePathEntry("path0", 0));
+ List languages = new ArrayList(2);
+ languages.add("bogus.language.id");
+ languages.add(LANG_ID);
+
+ // add default provider
+ LanguageSettingsBaseProvider provider = new LanguageSettingsBaseProvider(
+ PROVIDER_0, PROVIDER_NAME_0, languages, entries);
+
+ {
+ // attempt to get entries for wrong language
+ List actual = provider.getSettingEntries(null, FILE_0, "wrong.lang.id");
+ assertNull(actual);
+ }
+
+ {
+ // retrieve the entries
+ List actual = provider.getSettingEntries(null, FILE_0, LANG_ID);
+ assertEquals(entries.get(0), actual.get(0));
+ assertNotSame(entries, actual);
+ // retrieve languages
+ List actualLanguageIds = provider.getLanguageScope();
+ for (String languageId: languages) {
+ assertTrue(actualLanguageIds.contains(languageId));
+ }
+ assertEquals(languages.size(), actualLanguageIds.size());
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public void testSerializableProvider() throws Exception {
+ // get test plugin extension for serializable provider
+ ILanguageSettingsProvider providerExt = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_SERIALIZABLE_PROVIDER_ID);
+ assertTrue(LanguageSettingsManager.isWorkspaceProvider(providerExt));
+
+ // get raw extension provider
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(providerExt);
+ assertTrue(rawProvider instanceof LanguageSettingsSerializable);
+ LanguageSettingsSerializable provider = (LanguageSettingsSerializable) rawProvider;
+
+ assertEquals(null, provider.getLanguageScope());
+ assertEquals("", provider.getCustomParameter());
+
+ List expected = new ArrayList();
+ expected.add(new CMacroEntry("MACRO", "value", 0));
+ assertEquals(expected, provider.getSettingEntries(null, null, null));
+ }
+
+ /**
+ * TODO
+ */
+ public void testEditableProvider() throws Exception {
+ // Non-editable providers cannot be copied so they are singletons
+ {
+ // get test plugin extension for serializable provider
+ ILanguageSettingsProvider providerExt = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_SERIALIZABLE_PROVIDER_ID);
+ assertTrue(LanguageSettingsManager.isWorkspaceProvider(providerExt));
+
+ // get raw extension provider
+ ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(providerExt);
+ assertTrue(rawProvider instanceof LanguageSettingsSerializable);
+ assertTrue(LanguageSettingsExtensionManager.equalsExtensionProvider(rawProvider));
+
+ // compare with workspace provider
+ ILanguageSettingsProvider providerWsp = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_SERIALIZABLE_PROVIDER_ID);
+ ILanguageSettingsProvider providerWspRaw = LanguageSettingsManager.getRawProvider(providerWsp);
+ assertSame(rawProvider, providerWspRaw);
+ }
+
+ // Editable providers are retrieved by copy
+ {
+ ILanguageSettingsProvider providerExt = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_EDITABLE_PROVIDER_ID);
+ assertFalse(LanguageSettingsManager.isWorkspaceProvider(providerExt));
+ assertTrue(providerExt instanceof ILanguageSettingsEditableProvider);
+ assertTrue(LanguageSettingsExtensionManager.equalsExtensionProvider(providerExt));
+
+ ILanguageSettingsProvider providerExt2 = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_EDITABLE_PROVIDER_ID);
+ assertNotSame(providerExt, providerExt2);
+ assertEquals(providerExt, providerExt2);
+
+ ILanguageSettingsProvider providerWsp = LanguageSettingsManager.getWorkspaceProvider(EXTENSION_EDITABLE_PROVIDER_ID);
+ ILanguageSettingsProvider providerWspRaw = LanguageSettingsManager.getRawProvider(providerWsp);
+ assertNotSame(providerExt, providerWspRaw);
+ assertEquals(providerExt, providerWspRaw);
+ assertTrue(LanguageSettingsExtensionManager.equalsExtensionProvider(providerWspRaw));
+ }
+
+ // Test shallow copy
+ {
+ ILanguageSettingsProvider provider = LanguageSettingsManager.getExtensionProviderCopy(EXTENSION_EDITABLE_PROVIDER_ID);
+ assertNotNull(provider);
+ assertTrue(provider instanceof ILanguageSettingsEditableProvider);
+
+ ILanguageSettingsProvider providerShallow = LanguageSettingsExtensionManager.getExtensionProviderShallow(EXTENSION_EDITABLE_PROVIDER_ID);
+ assertNotNull(providerShallow);
+ assertTrue(providerShallow instanceof ILanguageSettingsEditableProvider);
+ assertFalse(provider.equals(providerShallow));
+
+ assertFalse(LanguageSettingsExtensionManager.equalsExtensionProvider(providerShallow));
+ assertTrue(LanguageSettingsExtensionManager.equalsExtensionProviderShallow((ILanguageSettingsEditableProvider) providerShallow));
+
+ }
+ }
+
+// /**
+// * LanguageSettingsBaseProvider is not allowed to be configured twice.
+// */
+// public void testBaseProviderConfigure() throws Exception {
+// // create LanguageSettingsBaseProvider
+// LanguageSettingsBaseProvider provider = new LanguageSettingsBaseProvider();
+// List entries = new ArrayList();
+// entries.add(new CIncludePathEntry("/usr/include/", 0));
+// // configure it
+// provider.configureProvider("id", "name", null, entries, null);
+//
+// try {
+// // attempt to configure it twice should fail
+// provider.configureProvider("id", "name", null, entries, null);
+// fail("LanguageSettingsBaseProvider is not allowed to be configured twice");
+// } catch (UnsupportedOperationException e) {
+// }
+// }
+
+}
diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java
new file mode 100644
index 00000000000..066ac866a66
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManagerTests.java
@@ -0,0 +1,781 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.core.language.settings.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.cdt.core.AbstractExecutableExtensionBase;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
+import org.eclipse.cdt.core.settings.model.CMacroEntry;
+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.ICSettingEntry;
+import org.eclipse.cdt.core.testplugin.CModelMock;
+import org.eclipse.cdt.core.testplugin.ResourceHelper;
+import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager;
+import org.eclipse.cdt.internal.core.settings.model.CConfigurationDescription;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Test cases testing LanguageSettingsProvider functionality
+ */
+public class LanguageSettingsManagerTests extends TestCase {
+ // Should match id of extension point defined in plugin.xml
+ private static final String EXTENSION_BASE_PROVIDER_ID = "org.eclipse.cdt.core.tests.language.settings.base.provider";
+ private static final String EXTENSION_EDITABLE_PROVIDER_ID = "org.eclipse.cdt.core.tests.custom.editable.language.settings.provider";
+ private static final String EXTENSION_EDITABLE_PROVIDER_NAME = "Test Plugin Editable Language Settings Provider";
+
+ private static final IFile FILE_0 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/project/path0"));
+ private static final String CFG_ID = "test.configuration.id";
+ private static final String LANG_ID = "test.lang.id";
+ private static final String PROVIDER_0 = "test.provider.0.id";
+ private static final String PROVIDER_1 = "test.provider.1.id";
+ private static final String PROVIDER_2 = "test.provider.2.id";
+ private static final String PROVIDER_NAME_0 = "test.provider.0.name";
+ private static final String PROVIDER_NAME_1 = "test.provider.1.name";
+ private static final String PROVIDER_NAME_2 = "test.provider.2.name";
+
+ class MockConfigurationDescription extends CModelMock.DummyCConfigurationDescription {
+ List providers = new ArrayList();
+ public MockConfigurationDescription(String id) {
+ super(id);
+ }
+
+ @Override
+ public void setLanguageSettingProviders(List providers) {
+ this.providers = new ArrayList(providers);
+ }
+
+ @Override
+ public List getLanguageSettingProviders() {
+ return providers;
+ }
+ }
+
+ private class MockProvider extends AbstractExecutableExtensionBase implements ILanguageSettingsProvider {
+ private List entries;
+
+ public MockProvider(String id, String name, List entries) {
+ super(id, name);
+ this.entries = entries;
+ }
+
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+ return entries;
+ }
+ }
+
+
+ /**
+ * Constructor.
+ * @param name - name of the test.
+ */
+ public LanguageSettingsManagerTests(String name) {
+ super(name);
+
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ LanguageSettingsManager.setWorkspaceProviders(null);
+ ResourceHelper.cleanUp();
+ }
+
+ /**
+ * @return - new TestSuite.
+ */
+ public static TestSuite suite() {
+ return new TestSuite(LanguageSettingsManagerTests.class);
+ }
+
+ /**
+ * main function of the class.
+ *
+ * @param args - arguments
+ */
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ /**
+ * Test ICConfigurationDescription API (getters and setters).
+ */
+ public void testConfigurationDescription_Providers() throws Exception {
+ ICConfigurationDescription cfgDescription = new MockConfigurationDescription(CFG_ID);
+
+ // set providers
+ ILanguageSettingsProvider provider1 = new MockProvider(PROVIDER_1, PROVIDER_NAME_1, null);
+ ILanguageSettingsProvider provider2 = new MockProvider(PROVIDER_2, PROVIDER_NAME_2, null);
+ List providers = new ArrayList();
+ providers.add(provider1);
+ providers.add(provider2);
+ cfgDescription.setLanguageSettingProviders(providers);
+
+ // get providers
+ List actual = cfgDescription.getLanguageSettingProviders();
+ assertEquals(provider1, actual.get(0));
+ assertEquals(provider2, actual.get(1));
+ assertEquals(providers.size(), actual.size());
+ assertNotSame(actual, providers);
+ }
+
+ /**
+ * Test to ensure uniqueness of ids for providers kept in configuration description.
+ */
+ public void testConfigurationDescription_ProvidersUniqueId() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICProjectDescription writableProjDescription = CoreModel.getDefault().getProjectDescription(project, true);
+
+ ICConfigurationDescription[] cfgDescriptions = writableProjDescription.getConfigurations();
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+ assertTrue(cfgDescription instanceof CConfigurationDescription);
+
+ // attempt to add duplicate providers
+ MockProvider dupe1 = new MockProvider(PROVIDER_0, PROVIDER_NAME_1, null);
+ MockProvider dupe2 = new MockProvider(PROVIDER_0, PROVIDER_NAME_2, null);
+
+ List providers = new ArrayList();
+ providers.add(dupe1);
+ providers.add(dupe2);
+
+ try {
+ cfgDescription.setLanguageSettingProviders(providers);
+ fail("cfgDescription.setLanguageSettingProviders() should not accept duplicate providers");
+ } catch (Exception e) {
+ // Exception is welcome here
+ }
+ }
+
+ /**
+ * Test various cases of ill-defined providers.
+ */
+ public void testRudeProviders() throws Exception {
+ ICConfigurationDescription cfgDescription = new MockConfigurationDescription(CFG_ID);
+ // set impolite provider returning null by getSettingEntries()
+ ILanguageSettingsProvider providerNull = new MockProvider(PROVIDER_1, PROVIDER_NAME_1, null);
+ {
+ List providers = new ArrayList();
+ providers.add(providerNull);
+ cfgDescription.setLanguageSettingProviders(providers);
+ }
+
+ // use provider returning null, no exception should be recorded
+ {
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(providerNull, cfgDescription, FILE_0, LANG_ID);
+ assertNotNull(actual);
+ assertEquals(0, actual.size());
+ }
+ {
+ List actual = LanguageSettingsManager
+ .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, 0);
+ assertNotNull(actual);
+ assertEquals(0, actual.size());
+ }
+
+ // set impolite provider returning null in getSettingEntries() array
+ ILanguageSettingsProvider providerNull_2 = new MockProvider(PROVIDER_2, PROVIDER_NAME_2,
+ new ArrayList() {
+ { // init via static initializer
+ add(null);
+ }
+ });
+
+ {
+ List providers = new ArrayList();
+ providers.add(providerNull);
+ cfgDescription.setLanguageSettingProviders(providers);
+ }
+
+ // use provider returning null as item in array
+ {
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(providerNull_2, cfgDescription, FILE_0, LANG_ID);
+ assertNotNull(actual);
+ assertEquals(1, actual.size());
+ }
+ {
+ List actual = LanguageSettingsManager
+ .getSettingEntriesByKind(cfgDescription, FILE_0, LANG_ID, 0);
+ assertNotNull(actual);
+ assertEquals(0, actual.size());
+ }
+
+ // use careless provider causing an exception
+ {
+ ILanguageSettingsProvider providerNPE = new MockProvider(PROVIDER_1, PROVIDER_NAME_1, null) {
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+ throw new NullPointerException("Can you handle me?");
+ }
+ };
+ try {
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(providerNPE, null, null, LANG_ID);
+ assertNotNull(actual);
+ assertEquals(0, actual.size());
+ } catch (Throwable e) {
+ fail("Exceptions are expected to be swallowed (after logging) but got " + e);
+ }
+ }
+ }
+
+ /**
+ * Test simple use case.
+ */
+ public void testProvider_Basic() throws Exception {
+ final ICConfigurationDescription modelCfgDescription = new MockConfigurationDescription(CFG_ID);
+
+ final List entries = new ArrayList();
+ entries.add(new CIncludePathEntry("path0", 0));
+
+ List providers = new ArrayList();
+ // define provider returning entries when configuration id matches and null otherwise
+ ILanguageSettingsProvider providerYes = new MockProvider(PROVIDER_0, PROVIDER_NAME_0, null) {
+ @Override
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+ if (cfgDescription.getId().equals(modelCfgDescription.getId())) {
+ return entries;
+ }
+ return null;
+ }
+
+ };
+ providers.add(providerYes);
+ // define provider returning null when configuration id matches and some entries otherwise
+ ILanguageSettingsProvider providerNo = new MockProvider(PROVIDER_1, PROVIDER_NAME_1, null) {
+ @Override
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+ if (cfgDescription.getId().equals(modelCfgDescription.getId())) {
+ return null;
+ }
+ return entries;
+ }
+
+ };
+ providers.add(providerNo);
+ modelCfgDescription.setLanguageSettingProviders(providers);
+
+ {
+ // retrieve the entries with provider returning the given list
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(providerYes, modelCfgDescription, FILE_0, LANG_ID);
+ assertEquals(entries.get(0), actual.get(0));
+ assertEquals(entries.size(), actual.size());
+ }
+
+ {
+ // retrieve the entries with provider returning empty list
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(providerNo, modelCfgDescription, FILE_0, LANG_ID);
+ assertEquals(0, actual.size());
+ }
+ }
+
+ /**
+ * Test regular functionality with a few providers.
+ */
+ public void testProvider_Regular() throws Exception {
+ ICConfigurationDescription cfgDescription = new MockConfigurationDescription(CFG_ID);
+
+ // create couple of providers
+ List entries1 = new ArrayList();
+ entries1.add(new CIncludePathEntry("value1", 1));
+ entries1.add(new CIncludePathEntry("value2", 2));
+
+ List entries2 = new ArrayList();
+ entries2.add(new CIncludePathEntry("value1", 1));
+ entries2.add(new CIncludePathEntry("value2", 2));
+ entries2.add(new CIncludePathEntry("value3", 2));
+
+ ILanguageSettingsProvider provider1 = new MockProvider(PROVIDER_1, PROVIDER_NAME_1, entries1);
+ ILanguageSettingsProvider provider2 = new MockProvider(PROVIDER_2, PROVIDER_NAME_2, entries2);
+ List providers = new ArrayList();
+ providers.add(provider1);
+ providers.add(provider2);
+ cfgDescription.setLanguageSettingProviders(providers);
+
+ {
+ // retrieve the entries for provider-1
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(provider1, cfgDescription, FILE_0, LANG_ID);
+ assertNotSame(entries1, actual);
+
+ ICLanguageSettingEntry[] entriesArray = entries1.toArray(new ICLanguageSettingEntry[0]);
+ ICLanguageSettingEntry[] actualArray = actual.toArray(new ICLanguageSettingEntry[0]);
+ for (int i=0;i actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(provider2, cfgDescription, FILE_0, LANG_ID);
+ assertNotSame(entries2, actual);
+
+ ICLanguageSettingEntry[] entriesArray = entries2.toArray(new ICLanguageSettingEntry[0]);
+ ICLanguageSettingEntry[] actualArray = actual.toArray(new ICLanguageSettingEntry[0]);
+ for (int i=0;i entries = new ArrayList();
+ entries.add(new CIncludePathEntry("path0", 0));
+ List providers = new ArrayList();
+ ILanguageSettingsProvider provider = new MockProvider(PROVIDER_0, PROVIDER_NAME_0, null) {
+ @Override
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+ if (rc.equals(parentFolder)) {
+ return entries;
+ }
+ if (rc.equals(emptySettingsPath)) {
+ return new ArrayList(0);
+ }
+ return null;
+ }
+
+ };
+ providers.add(provider);
+ cfgDescription.setLanguageSettingProviders(providers);
+
+ {
+ // retrieve entries for a derived resource (in a subfolder)
+ IFile derived = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/resource");
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(provider, cfgDescription, derived, LANG_ID);
+ // taken from parent folder
+ assertEquals(entries.get(0),actual.get(0));
+ assertEquals(entries.size(), actual.size());
+ }
+
+ {
+ // retrieve entries for not related resource
+ IFile notRelated = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("/AnotherFolder/Subfolder/resource"));
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(provider, cfgDescription, notRelated, LANG_ID);
+ assertEquals(0, actual.size());
+ }
+
+ {
+ // test distinction between no settings and empty settings
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(provider, cfgDescription, emptySettingsPath, LANG_ID);
+ // NOT taken from parent folder
+ assertEquals(0, actual.size());
+ }
+ }
+
+ /**
+ */
+ public void testProvider_DefaultEntries() throws Exception {
+ // Create model project and accompanied descriptions
+ String projectName = getName();
+ IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
+ ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project);
+ ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations();
+
+ ICConfigurationDescription cfgDescription = cfgDescriptions[0];
+ assertTrue(cfgDescription instanceof CConfigurationDescription);
+
+ final IFolder parentFolder = ResourceHelper.createFolder(project, "/ParentFolder/");
+ assertNotNull(parentFolder);
+ final IFile emptySettingsPath = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/empty");
+ assertNotNull(emptySettingsPath);
+
+ // store the entries as default entries
+ final List entries = new ArrayList();
+ entries.add(new CIncludePathEntry("path0", 0));
+ List providers = new ArrayList();
+ ILanguageSettingsProvider provider = new MockProvider(PROVIDER_0, PROVIDER_NAME_0, null) {
+ @Override
+ public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
+ if (cfgDescription==null && rc==null) {
+ return entries;
+ }
+ return null;
+ }
+
+ };
+ providers.add(provider);
+ cfgDescription.setLanguageSettingProviders(providers);
+
+ {
+ // retrieve entries for a resource
+ IFile derived = ResourceHelper.createFile(project, "/ParentFolder/Subfolder/resource");
+ List actual = LanguageSettingsManager
+ .getSettingEntriesUpResourceTree(provider, cfgDescription, derived, LANG_ID);
+ // default entries given
+ assertEquals(entries.get(0),actual.get(0));
+ assertEquals(entries.size(), actual.size());
+ }
+ }
+
+ /**
+ * Test ability to get entries by kind.
+ */
+ public void testEntriesByKind_Regular() throws Exception {
+ ICConfigurationDescription cfgDescription = new MockConfigurationDescription(CFG_ID);
+
+ // contribute the entries
+ List