mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12:10 +02:00
bug 371797: [sd90] Implement language settings providers in build
plugins
This commit is contained in:
parent
1a0bdf2d5d
commit
b1b320f94e
42 changed files with 6403 additions and 129 deletions
|
@ -26,8 +26,17 @@ 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.language.settings.providers.ICBuildOutputParser;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper;
|
||||
import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.resources.ACBuilder;
|
||||
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.BuildRunnerHelper;
|
||||
import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
|
||||
import org.eclipse.cdt.make.internal.core.MakeMessages;
|
||||
|
@ -175,6 +184,7 @@ public class MakeBuilder extends ACBuilder {
|
|||
String[] targets = getTargets(kind, info);
|
||||
if (targets.length != 0 && targets[targets.length - 1].equals(info.getCleanBuildTarget()))
|
||||
isClean = true;
|
||||
boolean isOnlyClean = isClean && (targets.length == 1);
|
||||
|
||||
String[] args = getCommandArguments(info, targets);
|
||||
|
||||
|
@ -187,8 +197,17 @@ public class MakeBuilder extends ACBuilder {
|
|||
ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectoryURI, this, errorParsers);
|
||||
|
||||
List<IConsoleParser> parsers = new ArrayList<IConsoleParser>();
|
||||
if (!isOnlyClean) {
|
||||
ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
if (prjDescription != null) {
|
||||
ICConfigurationDescription cfgDescription = prjDescription.getActiveConfiguration();
|
||||
collectLanguageSettingsConsoleParsers(cfgDescription, epm, parsers);
|
||||
}
|
||||
if (ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(project)) {
|
||||
IScannerInfoConsoleParser parserSD = ScannerInfoConsoleParserFactory.getScannerInfoConsoleParser(project, workingDirectoryURI, this);
|
||||
parsers.add(parserSD);
|
||||
}
|
||||
}
|
||||
|
||||
buildRunnerHelper.setLaunchParameters(launcher, buildCommand, args, workingDirectoryURI, envp);
|
||||
buildRunnerHelper.prepareStreams(epm, parsers, console, new SubProgressMonitor(monitor, TICKS_STREAM_PROGRESS_MONITOR, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
|
||||
|
@ -307,4 +326,26 @@ public class MakeBuilder extends ACBuilder {
|
|||
private String[] makeArray(String string) {
|
||||
return CommandLineUtil.argumentsToArray(string);
|
||||
}
|
||||
|
||||
private static void collectLanguageSettingsConsoleParsers(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker, List<IConsoleParser> parsers) {
|
||||
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
|
||||
List<ILanguageSettingsProvider> lsProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
||||
for (ILanguageSettingsProvider lsProvider : lsProviders) {
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(lsProvider);
|
||||
if (rawProvider instanceof ICBuildOutputParser) {
|
||||
ICBuildOutputParser consoleParser = (ICBuildOutputParser) rawProvider;
|
||||
try {
|
||||
consoleParser.startup(cfgDescription, cwdTracker);
|
||||
parsers.add(consoleParser);
|
||||
} catch (CoreException e) {
|
||||
MakeCorePlugin.log(new Status(IStatus.ERROR, MakeCorePlugin.PLUGIN_ID,
|
||||
"Language Settings Provider failed to start up", e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ package org.eclipse.cdt.make.core.scannerconfig;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.resources.ACBuilder;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
|
@ -60,6 +62,11 @@ public class ScannerConfigBuilder extends ACBuilder {
|
|||
// boolean autodiscoveryEnabled;
|
||||
if(buildNewStyle(getProject(), monitor))
|
||||
return getProject().getReferencedProjects();
|
||||
|
||||
if (!ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(getProject())) {
|
||||
return getProject().getReferencedProjects();
|
||||
}
|
||||
|
||||
boolean autodiscoveryEnabled2;
|
||||
IScannerConfigBuilderInfo2 buildInfo2 = null;
|
||||
try {
|
||||
|
@ -128,8 +135,8 @@ public class ScannerConfigBuilder extends ACBuilder {
|
|||
}
|
||||
|
||||
protected boolean build(IProject project, InfoContext context, IScannerConfigBuilderInfo2 buildInfo2, IProgressMonitor monitor){
|
||||
if (ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(getProject())) {
|
||||
boolean autodiscoveryEnabled2 = buildInfo2.isAutoDiscoveryEnabled();
|
||||
|
||||
if (autodiscoveryEnabled2) {
|
||||
monitor.beginTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder"), 100); //$NON-NLS-1$
|
||||
monitor.subTask(MakeMessages.getString("ScannerConfigBuilder.Invoking_Builder") + //$NON-NLS-1$
|
||||
|
@ -142,6 +149,7 @@ public class ScannerConfigBuilder extends ACBuilder {
|
|||
SCJobsUtil.updateScannerConfiguration(getProject(), context, buildInfo2, new SubProgressMonitor(monitor, 30));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ Bundle-Activator: org.eclipse.cdt.managedbuilder.testplugin.CTestPlugin
|
|||
Bundle-Vendor: Eclipse CDT
|
||||
Bundle-Localization: plugin
|
||||
Export-Package: org.eclipse.cdt.managedbuilder.core.tests,
|
||||
org.eclipse.cdt.managedbuilder.language.settings.providers.tests,
|
||||
org.eclipse.cdt.managedbuilder.templateengine.tests,
|
||||
org.eclipse.cdt.managedbuilder.testplugin,
|
||||
org.eclipse.cdt.managedbuilder.tests.suite,
|
||||
|
|
|
@ -9301,4 +9301,14 @@
|
|||
</matchObject>
|
||||
</conflictDefinition>
|
||||
</extension>
|
||||
<extension
|
||||
id="org.eclipse.cdt.managedbuilder.core.tests.ErrorParsers"
|
||||
name="org.eclipse.cdt.managedbuilder.core.tests ErrorParsers"
|
||||
point="org.eclipse.cdt.core.ErrorParser">
|
||||
<errorparser
|
||||
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser$GCCBuildCommandPatternHighlighter"
|
||||
id="org.eclipse.cdt.core.tests.managedbuilder.core.GCCBuildCommandPatternHighlighter"
|
||||
name="Test Plugin GCC BOP Patterns Highlighter">
|
||||
</errorparser>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.eclipse.cdt.managedbuilder.core.tests.OptionCategoryEnablementTests;
|
|||
import org.eclipse.cdt.managedbuilder.core.tests.OptionEnablementTests;
|
||||
import org.eclipse.cdt.managedbuilder.core.tests.PathConverterTest;
|
||||
import org.eclipse.cdt.managedbuilder.core.tests.ResourceBuildCoreTests;
|
||||
import org.eclipse.cdt.managedbuilder.language.settings.providers.tests.AllLanguageSettingsProvidersMBSTests;
|
||||
import org.eclipse.cdt.managedbuilder.templateengine.tests.AllTemplateEngineTests;
|
||||
import org.eclipse.cdt.projectmodel.tests.BackwardCompatiblityTests;
|
||||
import org.eclipse.cdt.projectmodel.tests.CProjectDescriptionSerializationTests;
|
||||
|
@ -61,6 +62,9 @@ public class AllManagedBuildTests {
|
|||
suite.addTest(CfgScannerConfigProfileManagerTests.suite());
|
||||
suite.addTestSuite(GCCSpecsConsoleParserTest.class);
|
||||
|
||||
// language settings providers tests
|
||||
suite.addTest(AllLanguageSettingsProvidersMBSTests.suite());
|
||||
|
||||
// managedbuilder.core.tests
|
||||
suite.addTest(ManagedBuildDependencyLibsTests.suite());
|
||||
suite.addTest(ManagedBuildCoreTests20.suite());
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2012 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.language.settings.providers.tests;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Test suite to test language settings providers defined in cdt.managedbuilder.core.
|
||||
*/
|
||||
public class AllLanguageSettingsProvidersMBSTests extends TestSuite {
|
||||
|
||||
public static TestSuite suite() {
|
||||
return new AllLanguageSettingsProvidersMBSTests();
|
||||
}
|
||||
|
||||
public AllLanguageSettingsProvidersMBSTests() {
|
||||
super(AllLanguageSettingsProvidersMBSTests.class.getName());
|
||||
|
||||
addTestSuite(GCCBuildCommandParserTest.class);
|
||||
addTestSuite(BuiltinSpecsDetectorTest.class);
|
||||
addTestSuite(GCCBuiltinSpecsDetectorTest.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,569 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2012 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.language.settings.providers.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
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.core.testplugin.util.BaseTestCase;
|
||||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.managedbuilder.language.settings.providers.AbstractBuiltinSpecsDetector;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Test cases to test built-in specs detectors.
|
||||
*/
|
||||
public class BuiltinSpecsDetectorTest extends BaseTestCase {
|
||||
private static final String PROVIDER_ID = "provider.id";
|
||||
private static final String PROVIDER_NAME = "provider name";
|
||||
private static final String LANGUAGE_ID = "language.test.id";
|
||||
private static final String CUSTOM_PARAMETER = "customParameter";
|
||||
private static final String CUSTOM_PARAMETER_2 = "customParameter2";
|
||||
private static final String ELEM_TEST = "test";
|
||||
|
||||
// those attributes must match that in AbstractBuiltinSpecsDetector
|
||||
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
|
||||
private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Mock built-in specs detector to test basic functionality of {@link AbstractBuiltinSpecsDetector}.
|
||||
*/
|
||||
private class MockBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector {
|
||||
@Override
|
||||
protected List<String> parseOptions(String line) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected AbstractOptionParser[] getOptionParsers() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected String getCompilerCommand(String languageId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startupForLanguage(String languageId) throws CoreException {
|
||||
super.startupForLanguage(languageId);
|
||||
}
|
||||
@Override
|
||||
protected void shutdownForLanguage() {
|
||||
super.shutdownForLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock built-in specs detector to test execute() functionality.
|
||||
*/
|
||||
private class MockBuiltinSpecsDetectorExecutedFlag extends AbstractBuiltinSpecsDetector {
|
||||
@Override
|
||||
protected List<String> parseOptions(String line) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected AbstractOptionParser[] getOptionParsers() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected String getCompilerCommand(String languageId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute() {
|
||||
super.execute();
|
||||
}
|
||||
protected boolean isExecuted() {
|
||||
return isExecuted;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock built-in specs detector to test parsing functionality.
|
||||
*/
|
||||
private class MockConsoleBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector {
|
||||
@SuppressWarnings("nls")
|
||||
private final AbstractOptionParser[] optionParsers = {
|
||||
new MacroOptionParser("#define (\\S*) *(\\S*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
};
|
||||
@Override
|
||||
protected int runProgramForLanguage(String languageId, String command, String[] envp, URI workingDirectoryURI, OutputStream consoleOut, OutputStream consoleErr, IProgressMonitor monitor) throws CoreException, IOException {
|
||||
String line = "#define MACRO VALUE";
|
||||
consoleOut.write((line + '\n').getBytes());
|
||||
consoleOut.flush();
|
||||
return ICommandLauncher.OK;
|
||||
}
|
||||
@Override
|
||||
protected IStatus runForEachLanguage(IProgressMonitor monitor) {
|
||||
return super.runForEachLanguage(monitor);
|
||||
}
|
||||
@Override
|
||||
protected List<String> parseOptions(final String line) {
|
||||
return new ArrayList<String>() {{ add(line); }};
|
||||
}
|
||||
@Override
|
||||
protected AbstractOptionParser[] getOptionParsers() {
|
||||
return optionParsers;
|
||||
}
|
||||
@Override
|
||||
protected String getCompilerCommand(String languageId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
Job.getJobManager().join(AbstractBuiltinSpecsDetector.JOB_FAMILY_BUILTIN_SPECS_DETECTOR, null);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to fetch configuration descriptions.
|
||||
*/
|
||||
private ICConfigurationDescription[] getConfigurationDescriptions(IProject project) {
|
||||
CoreModel coreModel = CoreModel.getDefault();
|
||||
ICProjectDescriptionManager mngr = coreModel.getProjectDescriptionManager();
|
||||
// project description
|
||||
ICProjectDescription projectDescription = mngr.getProjectDescription(project, false);
|
||||
assertNotNull(projectDescription);
|
||||
assertEquals(1, projectDescription.getConfigurations().length);
|
||||
// configuration description
|
||||
ICConfigurationDescription[] cfgDescriptions = projectDescription.getConfigurations();
|
||||
return cfgDescriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test configure, getters and setters.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_GettersSetters() throws Exception {
|
||||
{
|
||||
// provider configured with null parameters
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
provider.configureProvider(PROVIDER_ID, PROVIDER_NAME, null, null, null);
|
||||
|
||||
assertEquals(PROVIDER_ID, provider.getId());
|
||||
assertEquals(PROVIDER_NAME, provider.getName());
|
||||
assertEquals(null, provider.getLanguageScope());
|
||||
assertEquals(null, provider.getSettingEntries(null, null, null));
|
||||
assertEquals("", provider.getCommand());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
assertEquals(false, provider.isConsoleEnabled());
|
||||
}
|
||||
|
||||
{
|
||||
// provider configured with non-null parameters
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
List<String> languages = new ArrayList<String>();
|
||||
languages.add(LANGUAGE_ID);
|
||||
Map<String, String> properties = new HashMap<String, String>();
|
||||
properties.put(ATTR_PARAMETER, CUSTOM_PARAMETER);
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
entries.add(entry);
|
||||
|
||||
provider.configureProvider(PROVIDER_ID, PROVIDER_NAME, languages, entries, properties);
|
||||
assertEquals(PROVIDER_ID, provider.getId());
|
||||
assertEquals(PROVIDER_NAME, provider.getName());
|
||||
assertEquals(languages, provider.getLanguageScope());
|
||||
assertEquals(entries, provider.getSettingEntries(null, null, null));
|
||||
assertEquals(CUSTOM_PARAMETER, provider.getCommand());
|
||||
assertEquals(false, provider.isConsoleEnabled());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
|
||||
// setters
|
||||
provider.setCommand(CUSTOM_PARAMETER_2);
|
||||
assertEquals(CUSTOM_PARAMETER_2, provider.getCommand());
|
||||
provider.setConsoleEnabled(true);
|
||||
assertEquals(true, provider.isConsoleEnabled());
|
||||
|
||||
provider.execute();
|
||||
assertEquals(true, provider.isExecuted());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test clone() and equals().
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_CloneAndEquals() throws Exception {
|
||||
// define mock detector
|
||||
class MockDetectorCloneable extends MockBuiltinSpecsDetectorExecutedFlag implements Cloneable {
|
||||
@Override
|
||||
public MockDetectorCloneable clone() throws CloneNotSupportedException {
|
||||
return (MockDetectorCloneable) super.clone();
|
||||
}
|
||||
@Override
|
||||
public MockDetectorCloneable cloneShallow() throws CloneNotSupportedException {
|
||||
return (MockDetectorCloneable) super.cloneShallow();
|
||||
}
|
||||
}
|
||||
|
||||
// create instance to compare to
|
||||
MockDetectorCloneable provider = new MockDetectorCloneable();
|
||||
|
||||
List<String> languages = new ArrayList<String>();
|
||||
languages.add(LANGUAGE_ID);
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
ICLanguageSettingEntry entry = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
entries.add(entry);
|
||||
|
||||
// check clone after initialization
|
||||
MockDetectorCloneable clone0 = provider.clone();
|
||||
assertTrue(provider.equals(clone0));
|
||||
|
||||
// configure provider
|
||||
Map<String, String> properties = new HashMap<String, String>();
|
||||
properties.put(ATTR_PARAMETER, CUSTOM_PARAMETER);
|
||||
provider.configureProvider(PROVIDER_ID, PROVIDER_NAME, languages, entries, properties);
|
||||
assertEquals(false, provider.isConsoleEnabled());
|
||||
provider.setConsoleEnabled(true);
|
||||
provider.execute();
|
||||
assertEquals(true, provider.isExecuted());
|
||||
assertFalse(provider.equals(clone0));
|
||||
|
||||
// check another clone after configuring
|
||||
{
|
||||
MockDetectorCloneable clone = provider.clone();
|
||||
assertTrue(provider.equals(clone));
|
||||
}
|
||||
|
||||
// check custom parameter
|
||||
{
|
||||
MockDetectorCloneable clone = provider.clone();
|
||||
clone.setCommand("changed");
|
||||
assertFalse(provider.equals(clone));
|
||||
}
|
||||
|
||||
// check language scope
|
||||
{
|
||||
MockDetectorCloneable clone = provider.clone();
|
||||
clone.setLanguageScope(null);
|
||||
assertFalse(provider.equals(clone));
|
||||
}
|
||||
|
||||
// check console flag
|
||||
{
|
||||
MockDetectorCloneable clone = provider.clone();
|
||||
boolean isConsoleEnabled = clone.isConsoleEnabled();
|
||||
clone.setConsoleEnabled( ! isConsoleEnabled );
|
||||
assertFalse(provider.equals(clone));
|
||||
}
|
||||
|
||||
// check isExecuted flag
|
||||
{
|
||||
MockDetectorCloneable clone = provider.clone();
|
||||
assertEquals(true, clone.isExecuted());
|
||||
clone.clear();
|
||||
assertEquals(false, clone.isExecuted());
|
||||
assertFalse(provider.equals(clone));
|
||||
}
|
||||
|
||||
// check entries
|
||||
{
|
||||
MockDetectorCloneable clone = provider.clone();
|
||||
clone.setSettingEntries(null, null, null, null);
|
||||
assertFalse(provider.equals(clone));
|
||||
}
|
||||
|
||||
// check cloneShallow()
|
||||
{
|
||||
MockDetectorCloneable provider2 = provider.clone();
|
||||
MockDetectorCloneable clone = provider2.cloneShallow();
|
||||
assertEquals(false, clone.isExecuted());
|
||||
assertFalse(provider2.equals(clone));
|
||||
|
||||
provider2.setSettingEntries(null, null, null, null);
|
||||
assertFalse(provider2.equals(clone));
|
||||
|
||||
clone.execute();
|
||||
assertTrue(provider2.equals(clone));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic serialization functionality.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_SerializeDOM() throws Exception {
|
||||
{
|
||||
// create empty XML
|
||||
Document doc = XmlUtil.newDocument();
|
||||
Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
|
||||
// initialize provider
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
assertEquals(false, provider.isExecuted());
|
||||
// load the XML to new provider
|
||||
provider.load(rootElement);
|
||||
assertEquals(false, provider.isConsoleEnabled());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
}
|
||||
|
||||
Element elementProvider;
|
||||
{
|
||||
// define mock detector
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
assertEquals(false, provider.isConsoleEnabled());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
|
||||
// redefine the settings
|
||||
provider.setConsoleEnabled(true);
|
||||
assertEquals(true, provider.isConsoleEnabled());
|
||||
|
||||
// serialize in XML
|
||||
Document doc = XmlUtil.newDocument();
|
||||
Element rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
elementProvider = provider.serialize(rootElement);
|
||||
String xmlString = XmlUtil.toString(doc);
|
||||
|
||||
assertTrue(xmlString.contains(ATTR_CONSOLE));
|
||||
}
|
||||
{
|
||||
// create another instance of the provider
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
assertEquals(false, provider.isConsoleEnabled());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
|
||||
// load element
|
||||
provider.load(elementProvider);
|
||||
assertEquals(true, provider.isConsoleEnabled());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test serialization of entries and "isExecuted" flag handling.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_SerializeEntriesDOM() throws Exception {
|
||||
Element rootElement;
|
||||
{
|
||||
// create provider
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
|
||||
entries.add(new CIncludePathEntry("path0", 1));
|
||||
provider.setSettingEntries(null, null, null, entries);
|
||||
// serialize entries
|
||||
Document doc = XmlUtil.newDocument();
|
||||
rootElement = XmlUtil.appendElement(doc, ELEM_TEST);
|
||||
provider.serializeEntries(rootElement);
|
||||
// check XML
|
||||
String xmlString = XmlUtil.toString(doc);
|
||||
assertTrue(xmlString.contains("path0"));
|
||||
}
|
||||
|
||||
{
|
||||
// create new provider
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
assertEquals(true, provider.isEmpty());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
|
||||
// load the XML to the new provider
|
||||
provider.load(rootElement);
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, null, null);
|
||||
assertNotNull(entries);
|
||||
assertTrue(entries.size() > 0);
|
||||
assertEquals(new CIncludePathEntry("path0", 1), entries.get(0));
|
||||
assertEquals(false, provider.isEmpty());
|
||||
assertEquals(true, provider.isExecuted());
|
||||
|
||||
// clear the new provider
|
||||
provider.clear();
|
||||
assertEquals(true, provider.isEmpty());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
}
|
||||
|
||||
{
|
||||
// create new provider
|
||||
MockBuiltinSpecsDetectorExecutedFlag provider = new MockBuiltinSpecsDetectorExecutedFlag();
|
||||
assertEquals(true, provider.isEmpty());
|
||||
assertEquals(false, provider.isExecuted());
|
||||
|
||||
// execute provider
|
||||
provider.execute();
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, null, null);
|
||||
assertEquals(null, entries);
|
||||
// executed provider should NOT appear as empty even with no entries set
|
||||
assertEquals(false, provider.isEmpty());
|
||||
assertEquals(true, provider.isExecuted());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smoke test exercising passing {@code null} to the functions.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_Nulls() throws Exception {
|
||||
{
|
||||
// test AbstractBuiltinSpecsDetector.processLine(...) flow
|
||||
MockBuiltinSpecsDetector provider = new MockBuiltinSpecsDetector();
|
||||
provider.startup(null, null);
|
||||
provider.startupForLanguage(null);
|
||||
provider.processLine(null);
|
||||
provider.shutdownForLanguage();
|
||||
provider.shutdown();
|
||||
}
|
||||
{
|
||||
// test AbstractBuiltinSpecsDetector.processLine(...) flow
|
||||
MockConsoleBuiltinSpecsDetector provider = new MockConsoleBuiltinSpecsDetector();
|
||||
provider.startup(null, null);
|
||||
provider.runForEachLanguage(null);
|
||||
provider.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic parsing functionality.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_RunConfiguration() throws Exception {
|
||||
// Create model project and accompanied descriptions
|
||||
String projectName = getName();
|
||||
IProject project = ResourceHelper.createCDTProjectWithConfig(projectName);
|
||||
ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project);
|
||||
ICConfigurationDescription cfgDescription = cfgDescriptions[0];
|
||||
|
||||
MockConsoleBuiltinSpecsDetector provider = new MockConsoleBuiltinSpecsDetector();
|
||||
provider.setLanguageScope(new ArrayList<String>() {{add(LANGUAGE_ID);}});
|
||||
|
||||
// Run provider
|
||||
provider.startup(cfgDescription, null);
|
||||
provider.runForEachLanguage(null);
|
||||
provider.shutdown();
|
||||
|
||||
assertFalse(provider.isEmpty());
|
||||
|
||||
List<ICLanguageSettingEntry> noentries = provider.getSettingEntries(null, null, null);
|
||||
assertNull(noentries);
|
||||
|
||||
// Check parsed entries
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(cfgDescription, null, LANGUAGE_ID);
|
||||
ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
assertEquals(expected, entries.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Smoke test running as global provider on workspace level.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_RunGlobal() throws Exception {
|
||||
// Create provider
|
||||
MockConsoleBuiltinSpecsDetector provider = new MockConsoleBuiltinSpecsDetector();
|
||||
provider.setLanguageScope(new ArrayList<String>() {{add(LANGUAGE_ID);}});
|
||||
|
||||
// Run provider
|
||||
provider.startup(null, null);
|
||||
provider.runForEachLanguage(null);
|
||||
provider.shutdown();
|
||||
|
||||
assertFalse(provider.isEmpty());
|
||||
|
||||
// Check parsed entries
|
||||
List<ICLanguageSettingEntry> entries = provider.getSettingEntries(null, null, LANGUAGE_ID);
|
||||
ICLanguageSettingEntry expected = new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
assertEquals(expected, entries.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that entries get grouped by kinds by stock built-in specs detector.
|
||||
*/
|
||||
public void testAbstractBuiltinSpecsDetector_GroupSettings() throws Exception {
|
||||
// define benchmarks
|
||||
final CIncludePathEntry includePath_1 = new CIncludePathEntry("/include/path_1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CIncludePathEntry includePath_2 = new CIncludePathEntry("/include/path_2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CIncludeFileEntry includeFile_1 = new CIncludeFileEntry(new Path("/include.file1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CIncludeFileEntry includeFile_2 = new CIncludeFileEntry(new Path("/include.file2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CMacroEntry macro_1 = new CMacroEntry("MACRO_1", "", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CMacroEntry macro_2 = new CMacroEntry("MACRO_2", "", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY |ICSettingEntry.UNDEFINED);
|
||||
final CMacroFileEntry macroFile_1 = new CMacroFileEntry(new Path("/macro.file1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CMacroFileEntry macroFile_2 = new CMacroFileEntry(new Path("/macro.file2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CLibraryPathEntry libraryPath_1 = new CLibraryPathEntry(new Path("/lib/path_1"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CLibraryPathEntry libraryPath_2 = new CLibraryPathEntry(new Path("/lib/path_2"), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CLibraryFileEntry libraryFile_1 = new CLibraryFileEntry("lib_1.a", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
final CLibraryFileEntry libraryFile_2 = new CLibraryFileEntry("lib_2.a", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY);
|
||||
|
||||
// Define mock detector adding unorganized entries
|
||||
MockBuiltinSpecsDetector provider = 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
|
||||
provider.startup(null, null);
|
||||
provider.startupForLanguage(null);
|
||||
provider.processLine("");
|
||||
provider.shutdownForLanguage();
|
||||
provider.shutdown();
|
||||
|
||||
// compare benchmarks, expected well-sorted
|
||||
List<ICLanguageSettingEntry> entries = provider.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());
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,366 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2012 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.language.settings.providers.tests;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
|
||||
import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
|
||||
import org.eclipse.cdt.core.settings.model.CMacroEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
||||
import org.eclipse.cdt.core.testplugin.ResourceHelper;
|
||||
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||
import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* Test cases to test GCC built-in specs detector.
|
||||
*/
|
||||
public class GCCBuiltinSpecsDetectorTest extends BaseTestCase {
|
||||
private static final String LANGUAGE_ID_C = GCCLanguage.ID;
|
||||
|
||||
/**
|
||||
* Mock GCCBuiltinSpecsDetector to gain access to protected methods.
|
||||
*/
|
||||
class MockGCCBuiltinSpecsDetector extends GCCBuiltinSpecsDetector {
|
||||
@Override
|
||||
public void startupForLanguage(String languageId) throws CoreException {
|
||||
super.startupForLanguage(languageId);
|
||||
}
|
||||
@Override
|
||||
public void shutdownForLanguage() {
|
||||
super.shutdownForLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test expansion of variables in build command.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_ResolvedCommand() throws Exception {
|
||||
class MockGCCBuiltinSpecsDetectorLocal extends GCCBuiltinSpecsDetector {
|
||||
@Override
|
||||
public String resolveCommand(String languageId) throws CoreException {
|
||||
return super.resolveCommand(languageId);
|
||||
}
|
||||
}
|
||||
{
|
||||
MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal();
|
||||
detector.setLanguageScope(new ArrayList<String>() {{add(LANGUAGE_ID_C);}});
|
||||
detector.setCommand("${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"));
|
||||
}
|
||||
{
|
||||
MockGCCBuiltinSpecsDetectorLocal detector = new MockGCCBuiltinSpecsDetectorLocal();
|
||||
detector.setLanguageScope(new ArrayList<String>() {{add(LANGUAGE_ID_C);}});
|
||||
detector.setCommand("${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"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro without value.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_NoValue() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO", null, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro with ordinary value.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_Simple() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO VALUE");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro with value in round brackets.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_Const() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO (3)");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO", "(3)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition with tabs.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_WhiteSpaces() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define \t MACRO_1 VALUE");
|
||||
detector.processLine("#define MACRO_2 \t VALUE");
|
||||
detector.processLine("#define MACRO_3 VALUE \t");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
int index = 0;
|
||||
assertEquals(new CMacroEntry("MACRO_1", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CMacroEntry("MACRO_2", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CMacroEntry("MACRO_3", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(index, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition with empty argument list.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_EmptyArgList() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO() VALUE");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO()", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition with unused parameter.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_ParamUnused() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO(X) VALUE");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO(X)", "VALUE", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition with multiple parameters.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_ParamSpace() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO(P1, P2) VALUE(P1, P2)");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition with multiple parameters and no value.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_ArgsNoValue() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define MACRO(P1, P2) ");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CMacroEntry("MACRO(P1, P2)", null, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition having white spaces in various places.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Macro_Args_WhiteSpaces() throws Exception {
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#define \t MACRO_1(P1, P2) VALUE(P1, P2)");
|
||||
detector.processLine("#define MACRO_2(P1, P2) \t VALUE(P1, P2)");
|
||||
detector.processLine("#define MACRO_3(P1, P2) VALUE(P1, P2) \t");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
int index = 0;
|
||||
assertEquals(new CMacroEntry("MACRO_1(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CMacroEntry("MACRO_2(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CMacroEntry("MACRO_3(P1, P2)", "VALUE(P1, P2)", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(index, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of include directives.
|
||||
*/
|
||||
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();
|
||||
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
|
||||
detector.processLine(" "+loc+"/misplaced/include1");
|
||||
detector.processLine("#include \"...\" search starts here:");
|
||||
detector.processLine(" "+loc+"/local/include");
|
||||
detector.processLine("#include <...> search starts here:");
|
||||
detector.processLine(" "+loc+"/usr/include");
|
||||
detector.processLine(" "+loc+"/usr/include/../include2");
|
||||
detector.processLine(" "+loc+"/missing/folder");
|
||||
detector.processLine(" "+loc+"/Library/Frameworks (framework directory)");
|
||||
detector.processLine("End of search list.");
|
||||
detector.processLine(" "+loc+"/misplaced/include2");
|
||||
detector.processLine("Framework search starts here:");
|
||||
detector.processLine(" "+loc+"/System/Library/Frameworks");
|
||||
detector.processLine("End of framework search list.");
|
||||
detector.processLine(" "+loc+"/misplaced/include3");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
int index = 0;
|
||||
assertEquals(new CIncludePathEntry(loc+"/local/include", ICSettingEntry.LOCAL | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/usr/include", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/usr/include2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/missing/folder", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/System/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(index, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of macro definition of include directives having white spaces.
|
||||
*/
|
||||
public void testGCCBuiltinSpecsDetector_Includes_WhiteSpaces() throws Exception {
|
||||
String loc = ResourceHelper.createTemporaryFolder().toString();
|
||||
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
|
||||
detector.processLine("#include \"...\" search starts here:");
|
||||
detector.processLine(" \t "+loc+"/local/include");
|
||||
detector.processLine("#include <...> search starts here:");
|
||||
detector.processLine(loc+"/usr/include");
|
||||
detector.processLine(" "+loc+"/Library/Frameworks \t (framework directory)");
|
||||
detector.processLine("End of search list.");
|
||||
detector.processLine("Framework search starts here:");
|
||||
detector.processLine(" "+loc+"/System/Library/Frameworks \t ");
|
||||
detector.processLine("End of framework search list.");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
int index = 0;
|
||||
assertEquals(new CIncludePathEntry(loc+"/local/include", ICSettingEntry.LOCAL | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/usr/include", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(new CIncludePathEntry(loc+"/System/Library/Frameworks", ICSettingEntry.FRAMEWORKS_MAC | ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(index++));
|
||||
assertEquals(index, entries.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing of include directives incorporating symbolic links.
|
||||
*/
|
||||
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);
|
||||
|
||||
MockGCCBuiltinSpecsDetector detector = new MockGCCBuiltinSpecsDetector();
|
||||
|
||||
detector.startup(null, null);
|
||||
detector.startupForLanguage(null);
|
||||
detector.processLine("#include <...> search starts here:");
|
||||
detector.processLine(" "+linkPath.toString()+"/..");
|
||||
detector.processLine("End of search list.");
|
||||
detector.shutdownForLanguage();
|
||||
detector.shutdown();
|
||||
|
||||
// check populated entries
|
||||
List<ICLanguageSettingEntry> entries = detector.getSettingEntries(null, null, null);
|
||||
assertEquals(new CIncludePathEntry(dir2.removeLastSegments(1), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY), entries.get(0));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
|
||||
}
|
|
@ -15,9 +15,12 @@ Export-Package: org.eclipse.cdt.build.core.scannerconfig,
|
|||
org.eclipse.cdt.managedbuilder.envvar,
|
||||
org.eclipse.cdt.managedbuilder.internal.buildmodel;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
||||
org.eclipse.cdt.managedbuilder.internal.core;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
||||
org.eclipse.cdt.managedbuilder.internal.dataprovider;x-internal:=true,
|
||||
org.eclipse.cdt.managedbuilder.internal.envvar;x-internal:=true,
|
||||
org.eclipse.cdt.managedbuilder.internal.language.settings.providers;x-internal:=true,
|
||||
org.eclipse.cdt.managedbuilder.internal.macros;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
||||
org.eclipse.cdt.managedbuilder.internal.scannerconfig;x-internal:=true,
|
||||
org.eclipse.cdt.managedbuilder.language.settings.providers,
|
||||
org.eclipse.cdt.managedbuilder.macros,
|
||||
org.eclipse.cdt.managedbuilder.makegen,
|
||||
org.eclipse.cdt.managedbuilder.makegen.gnu,
|
||||
|
|
|
@ -597,6 +597,40 @@
|
|||
</run>
|
||||
</application>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider
|
||||
class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.MBSLanguageSettingsProvider"
|
||||
id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
|
||||
name="CDT Managed Build Setting Entries">
|
||||
</provider>
|
||||
<provider
|
||||
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector"
|
||||
id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector"
|
||||
name="CDT GCC Builtin Compiler Settings"
|
||||
parameter="${COMMAND} -E -P -v -dD ${INPUTS}">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
<provider
|
||||
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser"
|
||||
id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"
|
||||
name="CDT GCC Build Output Parser"
|
||||
parameter="(gcc)|([gc]\+\+)"
|
||||
prefer-non-shared="true">
|
||||
</provider>
|
||||
</extension>
|
||||
<extension
|
||||
id="scanner.discovery.problem"
|
||||
name="C/C++ Scanner Discovery Problem"
|
||||
point="org.eclipse.core.resources.markers">
|
||||
<super
|
||||
type="org.eclipse.core.resources.problemmarker">
|
||||
</super>
|
||||
<persistent
|
||||
value="true">
|
||||
</persistent>
|
||||
</extension>
|
||||
<extension
|
||||
id="headlessSettings"
|
||||
name="HeadlessBuilder Additional Settings"
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfil
|
|||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.resources.ACBuilder;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
|
@ -179,6 +180,7 @@ public class ScannerConfigBuilder extends ACBuilder {
|
|||
|
||||
public static SCProfileInstance build(CfgInfoContext context, IScannerConfigBuilderInfo2 buildInfo2, int flags, Properties env, IProgressMonitor monitor) throws CoreException{
|
||||
IConfiguration cfg = context.getConfiguration();
|
||||
if (ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(ManagedBuildManager.getDescriptionForConfiguration(cfg))) {
|
||||
IProject project = cfg.getOwner().getProject();
|
||||
boolean autodiscoveryEnabled2 = buildInfo2.isAutoDiscoveryEnabled();
|
||||
|
||||
|
@ -211,6 +213,7 @@ public class ScannerConfigBuilder extends ACBuilder {
|
|||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Map.Entry;
|
|||
import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
|
||||
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
|
||||
import org.eclipse.cdt.build.internal.core.scannerconfig.CfgScannerConfigUtil;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.make.core.MakeCorePlugin;
|
||||
|
@ -36,6 +37,7 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
|||
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
|
||||
import org.eclipse.cdt.managedbuilder.internal.core.Configuration;
|
||||
import org.eclipse.cdt.managedbuilder.internal.dataprovider.BuildConfigurationData;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.Preferences;
|
||||
import org.eclipse.core.runtime.QualifiedName;
|
||||
|
@ -213,8 +215,13 @@ public class CfgScannerConfigInfoFactory2 {
|
|||
}
|
||||
}
|
||||
if (id == null) {
|
||||
// Language Settings Providers are meant to replace legacy scanner discovery
|
||||
// so do not try to find default profile
|
||||
ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(cfg);
|
||||
if (ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(cfgDescription)) {
|
||||
id = CfgScannerConfigUtil.getDefaultProfileId(context, true);
|
||||
}
|
||||
}
|
||||
|
||||
InfoContext baseContext = context.toInfoContext();
|
||||
if(info == null){
|
||||
|
|
|
@ -30,6 +30,7 @@ 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.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.internal.core.BuildRunnerHelper;
|
||||
|
@ -96,6 +97,7 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
|
|||
String[] targets = getTargets(kind, builder);
|
||||
if (targets.length != 0 && targets[targets.length - 1].equals(builder.getCleanBuildTarget()))
|
||||
isClean = true;
|
||||
boolean isOnlyClean = isClean && (targets.length == 1);
|
||||
|
||||
String[] args = getCommandArguments(builder, targets);
|
||||
|
||||
|
@ -108,7 +110,13 @@ public class ExternalBuildRunner extends AbstractBuildRunner {
|
|||
ErrorParserManager epm = new ErrorParserManager(project, workingDirectoryURI, markerGenerator, errorParsers);
|
||||
|
||||
List<IConsoleParser> parsers = new ArrayList<IConsoleParser>();
|
||||
if (!isOnlyClean) {
|
||||
ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(configuration);
|
||||
ManagedBuildManager.collectLanguageSettingsConsoleParsers(cfgDescription, epm, parsers);
|
||||
if (ScannerDiscoveryLegacySupport.isLegacyScannerDiscoveryOn(cfgDescription)) {
|
||||
collectScannerInfoConsoleParsers(project, configuration, workingDirectoryURI, markerGenerator, parsers);
|
||||
}
|
||||
}
|
||||
|
||||
buildRunnerHelper.setLaunchParameters(launcher, buildCommand, args, workingDirectoryURI, envp);
|
||||
buildRunnerHelper.prepareStreams(epm, parsers, console, new SubProgressMonitor(monitor, TICKS_STREAM_PROGRESS_MONITOR));
|
||||
|
|
|
@ -14,11 +14,15 @@ package org.eclipse.cdt.managedbuilder.core;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
import org.eclipse.cdt.core.IMarkerGenerator;
|
||||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.internal.core.BuildRunnerHelper;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription;
|
||||
|
@ -77,9 +81,10 @@ public class InternalBuildRunner extends AbstractBuildRunner {
|
|||
flags = BuildDescriptionManager.REBUILD | BuildDescriptionManager.REMOVED | BuildDescriptionManager.DEPS;
|
||||
// delta = getDelta(currentProject);
|
||||
// }
|
||||
|
||||
boolean buildIncrementaly = delta != null;
|
||||
|
||||
ICConfigurationDescription cfgDescription = ManagedBuildManager.getDescriptionForConfiguration(configuration);
|
||||
|
||||
// Prepare launch parameters for BuildRunnerHelper
|
||||
String cfgName = configuration.getName();
|
||||
String toolchainName = configuration.getToolChain().getName();
|
||||
|
@ -90,7 +95,10 @@ public class InternalBuildRunner extends AbstractBuildRunner {
|
|||
String[] errorParsers = builder.getErrorParsers();
|
||||
ErrorParserManager epm = new ErrorParserManager(project, workingDirectoryURI, markerGenerator, errorParsers);
|
||||
|
||||
buildRunnerHelper.prepareStreams(epm, null, console, new SubProgressMonitor(monitor, TICKS_STREAM_PROGRESS_MONITOR));
|
||||
List<IConsoleParser> parsers = new ArrayList<IConsoleParser>();
|
||||
ManagedBuildManager.collectLanguageSettingsConsoleParsers(cfgDescription, epm, parsers);
|
||||
|
||||
buildRunnerHelper.prepareStreams(epm, parsers, console, new SubProgressMonitor(monitor, TICKS_STREAM_PROGRESS_MONITOR));
|
||||
|
||||
IBuildDescription des = BuildDescriptionManager.createBuildDescription(configuration, cBS, delta, flags);
|
||||
DescriptionBuilder dBuilder = null;
|
||||
|
|
|
@ -49,6 +49,12 @@ import javax.xml.transform.stream.StreamResult;
|
|||
|
||||
import org.eclipse.cdt.core.AbstractCExtension;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ICBuildOutputParser;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper;
|
||||
import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.CoreModelUtil;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
|
@ -148,7 +154,6 @@ import org.w3c.dom.ProcessingInstruction;
|
|||
* @noinstantiate This class is not intended to be instantiated by clients.
|
||||
*/
|
||||
public class ManagedBuildManager extends AbstractCExtension {
|
||||
|
||||
// private static final QualifiedName buildInfoProperty = new QualifiedName(ManagedBuilderCorePlugin.PLUGIN_ID, "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$
|
||||
|
@ -4721,4 +4726,24 @@ public class ManagedBuildManager extends AbstractCExtension {
|
|||
return true; // no target platform - nothing to check.
|
||||
}
|
||||
|
||||
/*package*/ static void collectLanguageSettingsConsoleParsers(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker, List<IConsoleParser> parsers) {
|
||||
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
|
||||
List<ILanguageSettingsProvider> lsProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
||||
for (ILanguageSettingsProvider lsProvider : lsProviders) {
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(lsProvider);
|
||||
if (rawProvider instanceof ICBuildOutputParser) {
|
||||
ICBuildOutputParser consoleParser = (ICBuildOutputParser) rawProvider;
|
||||
try {
|
||||
consoleParser.startup(cfgDescription, cwdTracker);
|
||||
parsers.add(consoleParser);
|
||||
} catch (CoreException e) {
|
||||
ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID,
|
||||
"Language Settings Provider failed to start up", e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -283,12 +283,4 @@ public class ManagedBuilderCorePlugin extends Plugin {
|
|||
ProjectConverter.convertOldStdMakeToNewStyle(project, monitor);
|
||||
}
|
||||
|
||||
|
||||
// public IDiscoveredPathManager getDiscoveryManager() {
|
||||
// if ( fDiscoveryPathManager == null) {
|
||||
// fDiscoveryPathManager = new DiscoveredPathManager();
|
||||
// fDiscoveryPathManager.startup();
|
||||
// }
|
||||
// return fDiscoveryPathManager;
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -169,3 +169,14 @@ MultiResourceInfo.MultiResourceInfo.UnhandledIHoldsOptionsType=Unhandled parent
|
|||
ResourceChangeHandler2.0=project build settings update job
|
||||
ToolInfo.0=conversion failure
|
||||
ToolInfo.1=the tool is removed
|
||||
|
||||
#Language settings providers messages
|
||||
AbstractBuiltinSpecsDetector.AddScannerDiscoveryMarkers=Adding Scanner Discovery markers
|
||||
AbstractBuiltinSpecsDetector.ClearingMarkers=Clearing markers for {0}
|
||||
AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobName=Discover compiler built-in language settings
|
||||
AbstractBuiltinSpecsDetector.RunningScannerDiscovery=Running scanner discovery: {0}
|
||||
AbstractBuiltinSpecsDetector.ScannerDiscoveryMarkerLocationPreferences=Preferences, C++/Build/Settings/Discovery, [{0}] options
|
||||
AbstractBuiltinSpecsDetector.ScannerDiscoveryMarkerLocationProperties=Project Properties, C++ Preprocessor Include.../Providers, [{0}] options
|
||||
AbstractBuiltinSpecsDetector.ScannerDiscoveryTaskTitle=CDT Scanner Discovery
|
||||
AbstractBuiltinSpecsDetector.SerializingResults=Serializing results
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*******************************************************************************
|
||||
* 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.language.settings.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.AbstractExecutableExtensionBase;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsBroadcastingProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsStorage;
|
||||
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.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
/**
|
||||
* Implementation of language settings provider for CDT Managed Build System.
|
||||
*/
|
||||
public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase implements ILanguageSettingsBroadcastingProvider {
|
||||
@Override
|
||||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
|
||||
IPath projectPath = rc.getProjectRelativePath();
|
||||
ICLanguageSetting[] languageSettings = null;
|
||||
|
||||
if (rc instanceof IFile) {
|
||||
ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(projectPath, true);
|
||||
if (ls != null) {
|
||||
languageSettings = new ICLanguageSetting[] { ls };
|
||||
} else {
|
||||
return getSettingEntries(cfgDescription, rc.getParent(), languageId);
|
||||
}
|
||||
} else {
|
||||
ICResourceDescription rcDescription = cfgDescription.getResourceDescription(projectPath, false);
|
||||
languageSettings = getLanguageSettings(rcDescription);
|
||||
}
|
||||
|
||||
List<ICLanguageSettingEntry> list = new ArrayList<ICLanguageSettingEntry>();
|
||||
|
||||
if (languageSettings != null) {
|
||||
for (ICLanguageSetting langSetting : languageSettings) {
|
||||
if (langSetting != null) {
|
||||
String id = langSetting.getLanguageId();
|
||||
if (id != null && id.equals(languageId)) {
|
||||
int kindsBits = langSetting.getSupportedEntryKinds();
|
||||
for (int kind=1; kind <= kindsBits; kind <<= 1) {
|
||||
if ((kindsBits & kind) != 0) {
|
||||
list.addAll(langSetting.getSettingEntriesList(kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return LanguageSettingsStorage.getPooledList(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get language settings for resource description.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LanguageSettingsStorage copyStorage() {
|
||||
class PretendStorage extends LanguageSettingsStorage {
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public LanguageSettingsStorage clone() throws CloneNotSupportedException {
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Note that this always triggers change event even if nothing changed in MBS
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return new PretendStorage();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
/*******************************************************************************
|
||||
* 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.language.settings.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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.ILanguageSettingsProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
||||
/**
|
||||
* Abstract class for providers parsing compiler option from build command when present in build output.
|
||||
*
|
||||
* @since 8.1
|
||||
*/
|
||||
public abstract class AbstractBuildCommandParser extends AbstractLanguageSettingsOutputScanner {
|
||||
public static final Object JOB_FAMILY_BUILD_COMMAND_PARSER = "org.eclipse.cdt.managedbuilder.AbstractBuildCommandParser"; //$NON-NLS-1$
|
||||
|
||||
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
|
||||
private static final String ATTR_RESOURCE_SCOPE = "resource-scope"; //$NON-NLS-1$
|
||||
private static final String VALUE_FILE_SCOPE = "per-file"; //$NON-NLS-1$
|
||||
private static final String VALUE_FOLDER_SCOPE = "per-folder"; //$NON-NLS-1$
|
||||
private static final String VALUE_PROJECT_SCOPE = "per-project"; //$NON-NLS-1$
|
||||
|
||||
|
||||
private static final String LEADING_PATH_PATTERN = "\\S+[/\\\\]"; //$NON-NLS-1$
|
||||
private static final Pattern OPTIONS_PATTERN = Pattern.compile("-[^\\s\"']*(\\s*((\".*?\")|('.*?')|([^-\\s][^\\s]+)))?"); //$NON-NLS-1$
|
||||
private static final int OPTION_GROUP = 0;
|
||||
|
||||
public enum ResourceScope {
|
||||
FILE,
|
||||
FOLDER,
|
||||
PROJECT,
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: design patterns to keep file group the same and matching {@link #FILE_GROUP}
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
private static final String[] COMPILER_COMMAND_PATTERN_TEMPLATES = {
|
||||
"${COMPILER_PATTERN}.*\\s" + "()([^'\"\\s]*\\.${EXTENSIONS_PATTERN})(\\s.*)?[\r\n]*", // compiling unquoted file
|
||||
"${COMPILER_PATTERN}.*\\s" + "(['\"])(.*\\.${EXTENSIONS_PATTERN})\\${COMPILER_GROUPS+1}(\\s.*)?[\r\n]*" // compiling quoted file
|
||||
};
|
||||
private static final int FILE_GROUP = 2;
|
||||
|
||||
// cached value from properties, do not need to use in equals() and hashCode()
|
||||
private ResourceScope resourceScope = null;
|
||||
|
||||
/**
|
||||
* The compiler command pattern without specifying compiler options.
|
||||
* The options are intended to be handled with option parsers,
|
||||
* see {@link #getOptionParsers()}.
|
||||
* This is regular expression pattern.
|
||||
*
|
||||
* @return the compiler command pattern.
|
||||
*/
|
||||
public String getCompilerPattern() {
|
||||
return getProperty(ATTR_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set compiler command pattern for the provider. See {@link #getCompilerPattern()}.
|
||||
* @param commandPattern - value of the command pattern to set.
|
||||
* This is regular expression pattern.
|
||||
*/
|
||||
public void setCompilerPattern(String commandPattern) {
|
||||
setProperty(ATTR_PARAMETER, commandPattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub-expression for compiler command pattern accounting for spaces, quotes etc.
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
private String getCompilerPatternExtended() {
|
||||
String compilerPattern = getCompilerPattern();
|
||||
return "\\s*\"?("+LEADING_PATH_PATTERN+")?(" + compilerPattern + ")\"?";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource scope of the entries, i.e. level in resource hierarchy where language settings entries
|
||||
* will be applied by the provider. Resource scope can be one of the following:
|
||||
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FILE} - apply entries to the file being parsed.
|
||||
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FOLDER} - apply entries to the enclosing folder.
|
||||
* <br>- {@code AbstractBuildCommandParser.ResourceScope.PROJECT} - apply entries to the project level.
|
||||
*/
|
||||
public ResourceScope getResourceScope() {
|
||||
if (resourceScope == null) {
|
||||
String scopeStr = getProperty(ATTR_RESOURCE_SCOPE);
|
||||
if (scopeStr.equals(VALUE_FILE_SCOPE)) {
|
||||
resourceScope = ResourceScope.FILE;
|
||||
} else if (scopeStr.equals(VALUE_FOLDER_SCOPE)) {
|
||||
resourceScope = ResourceScope.FOLDER;
|
||||
} else if (scopeStr.equals(VALUE_PROJECT_SCOPE)) {
|
||||
resourceScope = ResourceScope.PROJECT;
|
||||
} else {
|
||||
resourceScope = ResourceScope.FILE;
|
||||
}
|
||||
}
|
||||
return resourceScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set resource scope of the entries, i.e. level in resource hierarchy where language settings entries
|
||||
* will be applied by the provider.
|
||||
*
|
||||
* @param rcScope - resource scope can be one of the following:
|
||||
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FILE} - apply entries to the file being parsed.
|
||||
* <br>- {@code AbstractBuildCommandParser.ResourceScope.FOLDER} - apply entries to the enclosing folder.
|
||||
* <br>- {@code AbstractBuildCommandParser.ResourceScope.PROJECT} - apply entries to the project level.
|
||||
*/
|
||||
public void setResourceScope(ResourceScope rcScope) {
|
||||
resourceScope = rcScope;
|
||||
switch (rcScope) {
|
||||
case FILE:
|
||||
setProperty(ATTR_RESOURCE_SCOPE, VALUE_FILE_SCOPE);
|
||||
break;
|
||||
case FOLDER:
|
||||
setProperty(ATTR_RESOURCE_SCOPE, VALUE_FOLDER_SCOPE);
|
||||
break;
|
||||
case PROJECT:
|
||||
setProperty(ATTR_RESOURCE_SCOPE, VALUE_PROJECT_SCOPE);
|
||||
break;
|
||||
default:
|
||||
setProperty(ATTR_RESOURCE_SCOPE, VALUE_FILE_SCOPE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSettingEntries(List<ICLanguageSettingEntry> entries) {
|
||||
IResource rc = null;
|
||||
switch (getResourceScope()) {
|
||||
case FILE:
|
||||
rc = currentResource;
|
||||
break;
|
||||
case FOLDER:
|
||||
if (currentResource instanceof IFile) {
|
||||
rc = currentResource.getParent();
|
||||
}
|
||||
break;
|
||||
case PROJECT:
|
||||
if (currentResource != null) {
|
||||
rc = currentResource.getProject();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
setSettingEntries(currentCfgDescription, rc, currentLanguageId, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust count for file group taking into consideration extra groups added by {@link #getCompilerPatternExtended()}.
|
||||
*/
|
||||
private int adjustFileGroup() {
|
||||
return countGroups(getCompilerPatternExtended()) + FILE_GROUP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make search pattern for compiler command based on template.
|
||||
*/
|
||||
private String makePattern(String template) {
|
||||
@SuppressWarnings("nls")
|
||||
String pattern = template
|
||||
.replace("${COMPILER_PATTERN}", getCompilerPatternExtended())
|
||||
.replace("${EXTENSIONS_PATTERN}", getPatternFileExtensions())
|
||||
.replace("${COMPILER_GROUPS+1}", new Integer(countGroups(getCompilerPatternExtended()) + 1).toString());
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parseResourceName(String line) {
|
||||
if (line == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (String template : COMPILER_COMMAND_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<String> parseOptions(String line) {
|
||||
if (line == null || currentResource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> options = new ArrayList<String>();
|
||||
Matcher optionMatcher = OPTIONS_PATTERN.matcher(line);
|
||||
while (optionMatcher.find()) {
|
||||
String option = optionMatcher.group(OPTION_GROUP);
|
||||
if (option!=null) {
|
||||
options.add(option);
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
private void serializeLanguageSettingsInBackground() {
|
||||
ILanguageSettingsProvider wspProvider = LanguageSettingsManager.getWorkspaceProvider(getId());
|
||||
ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(wspProvider);
|
||||
if (rawProvider == this) {
|
||||
// this is workspace provider
|
||||
serializeLanguageSettingsInBackground(null);
|
||||
} else {
|
||||
serializeLanguageSettingsInBackground(currentCfgDescription);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
serializeLanguageSettingsInBackground();
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 via extension point {@code org.eclipse.cdt.core.ErrorParser}.
|
||||
*/
|
||||
protected static abstract class AbstractBuildCommandPatternHighlighter extends RegexErrorParser implements IErrorParser2 {
|
||||
/**
|
||||
* Constructor.
|
||||
* @param parserId - build command parser ID specified in the extension {@code org.eclipse.cdt.core.LanguageSettingsProvider}.
|
||||
*/
|
||||
public AbstractBuildCommandPatternHighlighter(String parserId) {
|
||||
init(parserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the error parser.
|
||||
* @param parserId - language settings provider (the build command parser) ID.
|
||||
*/
|
||||
protected void init(String parserId) {
|
||||
AbstractBuildCommandParser buildCommandParser = (AbstractBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(parserId, false);
|
||||
if (buildCommandParser != null) {
|
||||
for (String template : COMPILER_COMMAND_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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProcessLineBehaviour() {
|
||||
return KEEP_LONGLINES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,745 @@
|
|||
/*******************************************************************************
|
||||
* 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.language.settings.providers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
import org.eclipse.cdt.core.IMarkerGenerator;
|
||||
import org.eclipse.cdt.core.ProblemMarkerInfo;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ICBuildOutputParser;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ICListenerAgent;
|
||||
import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ILanguageDescriptor;
|
||||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
import org.eclipse.cdt.internal.core.BuildRunnerHelper;
|
||||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
|
||||
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
|
||||
import org.eclipse.cdt.utils.CommandLineUtil;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
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.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.MultiStatus;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||
import org.eclipse.core.runtime.content.IContentType;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Abstract parser capable to execute compiler command printing built-in compiler
|
||||
* specs and parse built-in language settings out of it.
|
||||
*
|
||||
* @since 8.1
|
||||
*/
|
||||
public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSettingsOutputScanner implements ICListenerAgent {
|
||||
public static final String JOB_FAMILY_BUILTIN_SPECS_DETECTOR = "org.eclipse.cdt.managedbuilder.AbstractBuiltinSpecsDetector"; //$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 static final String CDT_MANAGEDBUILDER_UI_PLUGIN_ID = "org.eclipse.cdt.managedbuilder.ui"; //$NON-NLS-1$
|
||||
private static final String SCANNER_DISCOVERY_CONSOLE = "org.eclipse.cdt.managedbuilder.ScannerDiscoveryConsole"; //$NON-NLS-1$
|
||||
private static final String SCANNER_DISCOVERY_GLOBAL_CONSOLE = "org.eclipse.cdt.managedbuilder.ScannerDiscoveryGlobalConsole"; //$NON-NLS-1$
|
||||
private static final String DEFAULT_CONSOLE_ICON = "icons/obj16/inspect_system.gif"; //$NON-NLS-1$
|
||||
private static final String GMAKE_ERROR_PARSER_ID = "org.eclipse.cdt.core.GmakeErrorParser"; //$NON-NLS-1$
|
||||
|
||||
private static final String ATTR_PARAMETER = "parameter"; //$NON-NLS-1$
|
||||
private static final String ATTR_CONSOLE = "console"; //$NON-NLS-1$
|
||||
|
||||
private static final int MONITOR_SCALE = 100;
|
||||
private static final int TICKS_REMOVE_MARKERS = 1 * MONITOR_SCALE;
|
||||
private static final int TICKS_RUN_FOR_ONE_LANGUAGE = 10 * MONITOR_SCALE;
|
||||
private static final int TICKS_SERIALIZATION = 1 * MONITOR_SCALE;
|
||||
private static final int TICKS_OUTPUT_PARSING = 1 * MONITOR_SCALE;
|
||||
private static final int TICKS_EXECUTE_COMMAND = 1 * MONITOR_SCALE;
|
||||
|
||||
protected URI mappedRootURI = null;
|
||||
protected URI buildDirURI = null;
|
||||
protected java.io.File specFile = null;
|
||||
protected boolean preserveSpecFile = false;
|
||||
protected List<ICLanguageSettingEntry> detectedSettingEntries = null;
|
||||
protected int collected = 0;
|
||||
protected boolean isExecuted = false;
|
||||
|
||||
private BuildRunnerHelper buildRunnerHelper;
|
||||
private SDMarkerGenerator markerGenerator = new SDMarkerGenerator();
|
||||
private boolean isConsoleEnabled = false;
|
||||
private String currentCommandResolved = null;
|
||||
|
||||
private class SDMarkerGenerator implements IMarkerGenerator {
|
||||
// Reuse scanner discovery markers defined in org.eclipse.cdt.managedbuilder.core plugin.xml
|
||||
protected static final String SCANNER_DISCOVERY_PROBLEM_MARKER = "org.eclipse.cdt.managedbuilder.core.scanner.discovery.problem"; //$NON-NLS-1$
|
||||
protected static final String ATTR_PROVIDER = "provider"; //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
public void addMarker(IResource rc, int lineNumber, String errorDesc, int severity, String errorVar) {
|
||||
ProblemMarkerInfo info = new ProblemMarkerInfo(rc, lineNumber, errorDesc, severity, errorVar);
|
||||
addMarker(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMarker(final ProblemMarkerInfo problemMarkerInfo) {
|
||||
final String providerName = getName();
|
||||
final String providerId = getId();
|
||||
// Add markers in a job to avoid deadlocks
|
||||
Job markerJob = new Job(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.AddScannerDiscoveryMarkers")) { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
// Avoid duplicates as different languages can generate identical errors
|
||||
try {
|
||||
IMarker[] markers = problemMarkerInfo.file.findMarkers(SDMarkerGenerator.SCANNER_DISCOVERY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
|
||||
for (IMarker marker : markers) {
|
||||
int sev = ((Integer) marker.getAttribute(IMarker.SEVERITY)).intValue();
|
||||
if (sev == problemMarkerInfo.severity) {
|
||||
String msg = (String) marker.getAttribute(IMarker.MESSAGE);
|
||||
if (msg != null && msg.equals(problemMarkerInfo.description)) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
return new Status(Status.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Error checking markers.", e); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
try {
|
||||
IMarker marker = problemMarkerInfo.file.createMarker(SDMarkerGenerator.SCANNER_DISCOVERY_PROBLEM_MARKER);
|
||||
marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description);
|
||||
marker.setAttribute(IMarker.SEVERITY, problemMarkerInfo.severity);
|
||||
marker.setAttribute(SDMarkerGenerator.ATTR_PROVIDER, providerId);
|
||||
|
||||
if (problemMarkerInfo.file instanceof IWorkspaceRoot) {
|
||||
String msgPreferences = ManagedMakeMessages.getFormattedString("AbstractBuiltinSpecsDetector.ScannerDiscoveryMarkerLocationPreferences", providerName); //$NON-NLS-1$
|
||||
marker.setAttribute(IMarker.LOCATION, msgPreferences);
|
||||
} else {
|
||||
String msgProperties = ManagedMakeMessages.getFormattedString("AbstractBuiltinSpecsDetector.ScannerDiscoveryMarkerLocationProperties", providerName); //$NON-NLS-1$
|
||||
marker.setAttribute(IMarker.LOCATION, msgProperties);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
return new Status(Status.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Error adding markers.", e); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
|
||||
markerJob.setRule(problemMarkerInfo.file);
|
||||
markerJob.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete markers previously set by this provider for the resource.
|
||||
*
|
||||
* @param rc - resource to check markers.
|
||||
*/
|
||||
public void deleteMarkers(IResource rc) {
|
||||
String providerId = getId();
|
||||
try {
|
||||
IMarker[] markers = rc.findMarkers(SCANNER_DISCOVERY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
|
||||
for (IMarker marker : markers) {
|
||||
if (providerId.equals(marker.getAttribute(ATTR_PROVIDER))) {
|
||||
marker.delete();
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
ManagedBuilderCorePlugin.log(new Status(Status.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Error deleting markers.", e)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal ICConsoleParser to handle individual run for one language.
|
||||
*/
|
||||
private class ConsoleParserAdapter implements ICBuildOutputParser {
|
||||
@Override
|
||||
public void startup(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker) throws CoreException {
|
||||
AbstractBuiltinSpecsDetector.this.cwdTracker = cwdTracker;
|
||||
}
|
||||
@Override
|
||||
public boolean processLine(String line) {
|
||||
return AbstractBuiltinSpecsDetector.this.processLine(line);
|
||||
}
|
||||
@Override
|
||||
public void shutdown() {
|
||||
AbstractBuiltinSpecsDetector.this.cwdTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiler command without arguments. This value is used to replace macro ${COMMAND}.
|
||||
* In particular, this method is implemented in {@link ToolchainBuiltinSpecsDetector}
|
||||
* which retrieves the command from tool-chain.
|
||||
*
|
||||
* @param languageId - language ID.
|
||||
* @return compiler command without arguments, i.e. compiler program.
|
||||
*/
|
||||
protected abstract String getCompilerCommand(String languageId);
|
||||
|
||||
/**
|
||||
* The command to run. Some macros could be specified in there:
|
||||
* <ul>
|
||||
* <b>${COMMAND}</b> - compiler command without arguments (compiler program).
|
||||
* Normally would come from the tool-chain.<br>
|
||||
* <b>${INPUTS}</b> - path to spec file which will be placed in workspace area.<br>
|
||||
* <b>${EXT}</b> - file extension calculated from language ID.
|
||||
* </ul>
|
||||
* The parameter could be taken from the extension
|
||||
* in {@code plugin.xml} or from property file.
|
||||
*
|
||||
* @return the command to run or empty string if command is not defined.
|
||||
*/
|
||||
public String getCommand() {
|
||||
return getProperty(ATTR_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom command for the provider. See {@link #getCommand()}.
|
||||
* @param command - value of custom command to set.
|
||||
*/
|
||||
public void setCommand(String command) {
|
||||
setProperty(ATTR_PARAMETER, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if console output is enabled for this provider, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isConsoleEnabled() {
|
||||
return isConsoleEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable console output for this provider.
|
||||
*
|
||||
* @param enable - {@code true} to enable console output or {@code false} to disable.
|
||||
*/
|
||||
public void setConsoleEnabled(boolean enable) {
|
||||
isConsoleEnabled = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand macros specified in the compiler command. See {@link #getCommand()} for
|
||||
* the recognized list of macros.
|
||||
*
|
||||
* @param languageId - language ID.
|
||||
* @return - resolved command to run.
|
||||
* @throws CoreException if something goes wrong.
|
||||
*/
|
||||
protected String resolveCommand(String languageId) throws CoreException {
|
||||
String cmd = getCommand();
|
||||
if (cmd != null) {
|
||||
if (cmd.contains(COMPILER_MACRO)) {
|
||||
String compiler = getCompilerCommand(languageId);
|
||||
if (compiler != null)
|
||||
cmd = cmd.replace(COMPILER_MACRO, compiler);
|
||||
}
|
||||
if (cmd.contains(SPEC_FILE_MACRO)) {
|
||||
String specFileName = getSpecFile(languageId);
|
||||
if (specFileName != null)
|
||||
cmd = cmd.replace(SPEC_FILE_MACRO, specFileName);
|
||||
}
|
||||
if (cmd.contains(SPEC_EXT_MACRO)) {
|
||||
String specFileExt = getSpecFileExtension(languageId);
|
||||
if (specFileExt != null)
|
||||
cmd = cmd.replace(SPEC_EXT_MACRO, specFileExt);
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String parseResourceName(String line) {
|
||||
// Normally built-in specs detectors are per-language and the result applies for the whole workspace.
|
||||
// Returning null works workspace-wide here.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String determineLanguage() {
|
||||
// language id is supposed to be set by run(), just return it
|
||||
return currentLanguageId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URI getMappedRootURI(IResource sourceFile, String parsedResourceName) {
|
||||
// Do not calculate mappedRootURI for each line
|
||||
if (mappedRootURI == null) {
|
||||
mappedRootURI = super.getMappedRootURI(sourceFile, parsedResourceName);
|
||||
}
|
||||
return mappedRootURI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URI getBuildDirURI(URI mappedRootURI) {
|
||||
// Do not calculate buildDirURI for each line
|
||||
if (buildDirURI == null) {
|
||||
buildDirURI = super.getBuildDirURI(mappedRootURI);
|
||||
}
|
||||
return buildDirURI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListener(ICConfigurationDescription cfgDescription) {
|
||||
currentCfgDescription = cfgDescription;
|
||||
execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startup(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker) throws CoreException {
|
||||
super.startup(cfgDescription, cwdTracker);
|
||||
|
||||
mappedRootURI = null;
|
||||
buildDirURI = super.getBuildDirURI(mappedRootURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
mappedRootURI = null;
|
||||
buildDirURI = null;
|
||||
|
||||
super.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute provider's command which is expected to print built-in compiler options (specs) to build output.
|
||||
* The parser will parse output and generate language settings for corresponding resources.
|
||||
*/
|
||||
protected void execute() {
|
||||
if (isExecuted) {
|
||||
return;
|
||||
}
|
||||
isExecuted = true;
|
||||
|
||||
Job job = new Job(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobNam")) { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
IStatus status;
|
||||
try {
|
||||
startup(currentCfgDescription, null);
|
||||
status = runForEachLanguage(monitor);
|
||||
} catch (CoreException e) {
|
||||
ManagedBuilderCorePlugin.log(e);
|
||||
status = new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error running Builtin Specs Detector", e); //$NON-NLS-1$
|
||||
} finally {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
@Override
|
||||
public boolean belongsTo(Object family) {
|
||||
return family == JOB_FAMILY_BUILTIN_SPECS_DETECTOR;
|
||||
}
|
||||
};
|
||||
|
||||
IProject project = null;
|
||||
if (currentCfgDescription != null) {
|
||||
ICProjectDescription prjDescription = currentCfgDescription.getProjectDescription();
|
||||
if (prjDescription != null) {
|
||||
project = prjDescription.getProject();
|
||||
}
|
||||
}
|
||||
job.setRule(project);
|
||||
job.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run built-in specs command for each language.
|
||||
*
|
||||
* @param monitor - progress monitor in the initial state where {@link IProgressMonitor#beginTask(String, int)}
|
||||
* has not been called yet.
|
||||
* @return status of operation.
|
||||
*/
|
||||
protected IStatus runForEachLanguage(IProgressMonitor monitor) {
|
||||
MultiStatus status = new MultiStatus(ManagedBuilderCorePlugin.PLUGIN_ID, IStatus.OK, "Problem running CDT Scanner Discovery provider " + getId(), null); //$NON-NLS-1$
|
||||
|
||||
if (monitor == null) {
|
||||
monitor = new NullProgressMonitor();
|
||||
}
|
||||
|
||||
try {
|
||||
boolean isChanged = false;
|
||||
|
||||
List<String> languageIds = getLanguageScope();
|
||||
if (languageIds != null) {
|
||||
monitor.beginTask(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.ScannerDiscoveryTaskTitle"), //$NON-NLS-1$
|
||||
TICKS_REMOVE_MARKERS + languageIds.size()*TICKS_RUN_FOR_ONE_LANGUAGE + TICKS_SERIALIZATION);
|
||||
|
||||
IResource markersResource = currentProject != null ? currentProject : ResourcesPlugin.getWorkspace().getRoot();
|
||||
|
||||
monitor.subTask(ManagedMakeMessages.getFormattedString("AbstractBuiltinSpecsDetector.ClearingMarkers", markersResource.getFullPath().toString())); //$NON-NLS-1$
|
||||
markerGenerator.deleteMarkers(markersResource);
|
||||
if (monitor.isCanceled())
|
||||
throw new OperationCanceledException();
|
||||
|
||||
monitor.worked(TICKS_REMOVE_MARKERS);
|
||||
|
||||
for (String languageId : languageIds) {
|
||||
List<ICLanguageSettingEntry> oldEntries = getSettingEntries(currentCfgDescription, null, languageId);
|
||||
try {
|
||||
startupForLanguage(languageId);
|
||||
runForLanguage(new SubProgressMonitor(monitor, TICKS_RUN_FOR_ONE_LANGUAGE));
|
||||
} catch (Exception e) {
|
||||
IStatus s = new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error running Builtin Specs Detector", e); //$NON-NLS-1$
|
||||
ManagedBuilderCorePlugin.log(s);
|
||||
status.merge(s);
|
||||
} finally {
|
||||
shutdownForLanguage();
|
||||
}
|
||||
if (!isChanged) {
|
||||
List<ICLanguageSettingEntry> newEntries = getSettingEntries(currentCfgDescription, null, languageId);
|
||||
isChanged = newEntries != oldEntries;
|
||||
}
|
||||
|
||||
if (monitor.isCanceled())
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
}
|
||||
|
||||
monitor.subTask(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.SerializingResults")); //$NON-NLS-1$
|
||||
if (isChanged) { // avoids resource and settings change notifications
|
||||
IStatus s = serializeLanguageSettings(currentCfgDescription);
|
||||
status.merge(s);
|
||||
}
|
||||
monitor.worked(TICKS_SERIALIZATION);
|
||||
|
||||
} catch (OperationCanceledException e) {
|
||||
// user chose to cancel operation, do not threaten them with red error signs
|
||||
} catch (Exception e) {
|
||||
status.merge(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, IStatus.ERROR, "Error running Builtin Specs Detector", e)); //$NON-NLS-1$
|
||||
ManagedBuilderCorePlugin.log(status);
|
||||
} finally {
|
||||
monitor.done();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize provider before running for a language.
|
||||
*
|
||||
* @param languageId - language ID.
|
||||
* @throws CoreException if something goes wrong.
|
||||
*/
|
||||
protected void startupForLanguage(String languageId) throws CoreException {
|
||||
currentLanguageId = languageId;
|
||||
|
||||
specFile = null; // init specFile *before* calling resolveCommand(), can be changed in there
|
||||
currentCommandResolved = resolveCommand(currentLanguageId);
|
||||
|
||||
detectedSettingEntries = new ArrayList<ICLanguageSettingEntry>();
|
||||
collected = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save collected entries and dispose temporary data used during run for the language.
|
||||
*/
|
||||
protected void shutdownForLanguage() {
|
||||
if (detectedSettingEntries != null && detectedSettingEntries.size() > 0) {
|
||||
collected = detectedSettingEntries.size();
|
||||
setSettingEntries(currentCfgDescription, currentResource, currentLanguageId, detectedSettingEntries);
|
||||
}
|
||||
detectedSettingEntries = null;
|
||||
|
||||
currentCommandResolved = null;
|
||||
if (specFile!=null && !preserveSpecFile) {
|
||||
specFile.delete();
|
||||
specFile = null;
|
||||
}
|
||||
|
||||
currentLanguageId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run built-in specs command for one language.
|
||||
*
|
||||
* @param monitor - progress monitor in the initial state where {@link IProgressMonitor#beginTask(String, int)}
|
||||
* has not been called yet.
|
||||
*/
|
||||
private void runForLanguage(IProgressMonitor monitor) throws CoreException {
|
||||
buildRunnerHelper = new BuildRunnerHelper(currentProject);
|
||||
|
||||
if (monitor == null) {
|
||||
monitor = new NullProgressMonitor();
|
||||
}
|
||||
try {
|
||||
monitor.beginTask(ManagedMakeMessages.getFormattedString("AbstractBuiltinSpecsDetector.RunningScannerDiscovery", getName()), //$NON-NLS-1$
|
||||
TICKS_EXECUTE_COMMAND + TICKS_OUTPUT_PARSING);
|
||||
|
||||
IConsole console;
|
||||
if (isConsoleEnabled) {
|
||||
console = startProviderConsole();
|
||||
} else {
|
||||
// that looks in extension points registry and won't find the id, this console is not shown
|
||||
console = CCorePlugin.getDefault().getConsole(ManagedBuilderCorePlugin.PLUGIN_ID + ".console.hidden"); //$NON-NLS-1$
|
||||
}
|
||||
console.start(currentProject);
|
||||
|
||||
ICommandLauncher launcher = new CommandLauncher();
|
||||
launcher.setProject(currentProject);
|
||||
|
||||
IPath program = new Path(""); //$NON-NLS-1$
|
||||
String[] args = new String[0];
|
||||
String[] cmdArray = CommandLineUtil.argumentsToArray(currentCommandResolved);
|
||||
if (cmdArray != null && cmdArray.length > 0) {
|
||||
program = new Path(cmdArray[0]);
|
||||
if (cmdArray.length > 1) {
|
||||
args = new String[cmdArray.length-1];
|
||||
System.arraycopy(cmdArray, 1, args, 0, args.length);
|
||||
}
|
||||
}
|
||||
|
||||
String[] envp = BuildRunnerHelper.getEnvp(currentCfgDescription);
|
||||
|
||||
// Using GMAKE_ERROR_PARSER_ID as it can handle generated error messages
|
||||
ErrorParserManager epm = new ErrorParserManager(currentProject, buildDirURI, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID});
|
||||
ConsoleParserAdapter consoleParser = new ConsoleParserAdapter();
|
||||
consoleParser.startup(currentCfgDescription, epm);
|
||||
List<IConsoleParser> parsers = new ArrayList<IConsoleParser>();
|
||||
parsers.add(consoleParser);
|
||||
|
||||
buildRunnerHelper.setLaunchParameters(launcher, program, args, buildDirURI, envp);
|
||||
buildRunnerHelper.prepareStreams(epm, parsers, console, new SubProgressMonitor(monitor, TICKS_OUTPUT_PARSING));
|
||||
|
||||
buildRunnerHelper.greeting(ManagedMakeMessages.getFormattedString("AbstractBuiltinSpecsDetector.RunningScannerDiscovery", getName())); //$NON-NLS-1$
|
||||
|
||||
OutputStream outStream = buildRunnerHelper.getOutputStream();
|
||||
OutputStream errStream = buildRunnerHelper.getErrorStream();
|
||||
runProgramForLanguage(currentLanguageId, currentCommandResolved, envp, buildDirURI, outStream, errStream,
|
||||
new SubProgressMonitor(monitor, TICKS_EXECUTE_COMMAND, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
|
||||
|
||||
buildRunnerHelper.close();
|
||||
buildRunnerHelper.goodbye();
|
||||
|
||||
} catch (Exception e) {
|
||||
ManagedBuilderCorePlugin.log(new CoreException(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Error running Builtin Specs Detector" , e))); //$NON-NLS-1$
|
||||
} finally {
|
||||
try {
|
||||
buildRunnerHelper.close();
|
||||
} catch (IOException e) {
|
||||
ManagedBuilderCorePlugin.log(e);
|
||||
}
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
protected int runProgramForLanguage(String languageId, String command, String[] envp, URI workingDirectoryURI, OutputStream consoleOut, OutputStream consoleErr, IProgressMonitor monitor) throws CoreException, IOException {
|
||||
return buildRunnerHelper.build(monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSettingEntries(List<ICLanguageSettingEntry> entries) {
|
||||
// Built-in specs detectors collect entries not per line but for the whole output
|
||||
// so collect them to save later when output finishes
|
||||
if (entries != null) {
|
||||
detectedSettingEntries.addAll(entries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and start the provider console.
|
||||
* @return CDT console.
|
||||
*/
|
||||
private IConsole startProviderConsole() {
|
||||
IConsole console = null;
|
||||
|
||||
if (isConsoleEnabled && currentLanguageId != null) {
|
||||
String extConsoleId;
|
||||
if (currentProject != null) {
|
||||
extConsoleId = SCANNER_DISCOVERY_CONSOLE;
|
||||
} else {
|
||||
extConsoleId = SCANNER_DISCOVERY_GLOBAL_CONSOLE;
|
||||
}
|
||||
ILanguage ld = LanguageManager.getInstance().getLanguage(currentLanguageId);
|
||||
if (ld != null) {
|
||||
String consoleId = ManagedBuilderCorePlugin.PLUGIN_ID + '.' + getId() + '.' + currentLanguageId;
|
||||
String consoleName = getName() + ", " + ld.getName(); //$NON-NLS-1$
|
||||
URL defaultIcon = Platform.getBundle(CDT_MANAGEDBUILDER_UI_PLUGIN_ID).getEntry(DEFAULT_CONSOLE_ICON);
|
||||
if (defaultIcon == null) {
|
||||
@SuppressWarnings("nls")
|
||||
String msg = "Unable to find icon " + DEFAULT_CONSOLE_ICON + " in plugin " + CDT_MANAGEDBUILDER_UI_PLUGIN_ID;
|
||||
ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, msg));
|
||||
}
|
||||
|
||||
console = CCorePlugin.getDefault().getConsole(extConsoleId, consoleId, consoleName, defaultIcon);
|
||||
}
|
||||
}
|
||||
|
||||
if (console == null) {
|
||||
// that looks in extension points registry and won't find the id, this console is not shown
|
||||
console = CCorePlugin.getDefault().getConsole(ManagedBuilderCorePlugin.PLUGIN_ID + ".console.hidden"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return console;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to spec file which normally would be placed in workspace area.
|
||||
* This value is used to replace macro ${INPUTS}.
|
||||
*
|
||||
* @param languageId - language ID.
|
||||
* @return full path to the specs file.
|
||||
*/
|
||||
protected String getSpecFile(String languageId) {
|
||||
String specExt = getSpecFileExtension(languageId);
|
||||
String ext = ""; //$NON-NLS-1$
|
||||
if (specExt != null) {
|
||||
ext = '.' + specExt;
|
||||
}
|
||||
|
||||
String specFileName = SPEC_FILE_BASE + ext;
|
||||
IPath workingLocation = ManagedBuilderCorePlugin.getDefault().getStateLocation();
|
||||
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 {
|
||||
// In the typical case it is sufficient to have an empty file.
|
||||
specFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
ManagedBuilderCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
return fileLocation.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine file extension by language id. This implementation retrieves first extension
|
||||
* from the list as there could be multiple extensions associated with the given language.
|
||||
* This value is used to replace macro ${EXT}.
|
||||
*
|
||||
* @param languageId - given language ID.
|
||||
* @return file extension associated with the language or {@code null} if not found.
|
||||
*/
|
||||
protected String getSpecFileExtension(String languageId) {
|
||||
String ext = null;
|
||||
ILanguageDescriptor langDescriptor = LanguageManager.getInstance().getLanguageDescriptor(languageId);
|
||||
if (langDescriptor != null) {
|
||||
IContentType[] contentTypes = langDescriptor.getContentTypes();
|
||||
if (contentTypes != null && contentTypes.length > 0) {
|
||||
String[] fileExtensions = contentTypes[0].getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
|
||||
if (fileExtensions != null && fileExtensions.length > 0) {
|
||||
ext = fileExtensions[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ext == null) {
|
||||
ManagedBuilderCorePlugin.log(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.PLUGIN_ID, "Unable to find file extension for language " + languageId)); //$NON-NLS-1$
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element serializeAttributes(Element parentElement) {
|
||||
Element elementProvider = super.serializeAttributes(parentElement);
|
||||
elementProvider.setAttribute(ATTR_CONSOLE, Boolean.toString(isConsoleEnabled));
|
||||
return elementProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAttributes(Element providerNode) {
|
||||
super.loadAttributes(providerNode);
|
||||
|
||||
String consoleValue = XmlUtil.determineAttributeValue(providerNode, ATTR_CONSOLE);
|
||||
if (consoleValue != null) {
|
||||
isConsoleEnabled = Boolean.parseBoolean(consoleValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEntries(Element providerNode) {
|
||||
super.loadEntries(providerNode);
|
||||
if (!isEmpty()) {
|
||||
isExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
// treat provider that has been executed as not empty
|
||||
// to let "Clear" button to restart the provider
|
||||
return !isExecuted && super.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
isExecuted = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException {
|
||||
AbstractBuiltinSpecsDetector clone = (AbstractBuiltinSpecsDetector) super.cloneShallow();
|
||||
clone.isExecuted = false;
|
||||
return clone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + (isConsoleEnabled ? 1231 : 1237);
|
||||
result = prime * result + (isExecuted ? 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 (isConsoleEnabled != other.isConsoleEnabled)
|
||||
return false;
|
||||
if (isExecuted != other.isExecuted)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,84 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2012 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.language.settings.providers;
|
||||
|
||||
|
||||
import org.eclipse.cdt.core.errorparsers.RegexErrorPattern;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
||||
|
||||
/**
|
||||
* Build command parser capable to parse gcc command in build output and generate
|
||||
* language settings per file being compiled.
|
||||
*
|
||||
* @since 8.1
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Parser which allows highlighting of output lines matching the patterns of this parser.
|
||||
* Intended for better troubleshooting experience.
|
||||
*/
|
||||
public static class GCCBuildCommandPatternHighlighter extends AbstractBuildCommandParser.AbstractBuildCommandPatternHighlighter {
|
||||
// ID of the parser taken from the existing extension point
|
||||
private static final String GCC_BUILD_COMMAND_PARSER_EXT = "org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2012 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.language.settings.providers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Language settings provider to detect built-in compiler settings for GCC compiler.
|
||||
*
|
||||
* @since 8.1
|
||||
*/
|
||||
public class GCCBuiltinSpecsDetector extends ToolchainBuiltinSpecsDetector implements ILanguageSettingsEditableProvider {
|
||||
// ID must match the tool-chain 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}
|
||||
private State state = State.NONE;
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
private 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+(\\S*\\(.*?\\))\\s*(.*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
new MacroOptionParser("#define\\s+(\\S*)\\s*(\\S*)", "$1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
};
|
||||
|
||||
@Override
|
||||
protected String getToolchainId() {
|
||||
return GCC_TOOLCHAIN_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractOptionParser[] getOptionParsers() {
|
||||
return optionParsers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list from one item.
|
||||
*/
|
||||
private List<String> makeList(String line) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add(line);
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
@Override
|
||||
protected List<String> parseOptions(String line) {
|
||||
line = line.trim();
|
||||
|
||||
// contribution of -dD option
|
||||
if (line.startsWith("#define")) {
|
||||
return makeList(line);
|
||||
}
|
||||
|
||||
// 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, IWorkingDirectoryTracker cwdTracker) throws CoreException {
|
||||
super.startup(cfgDescription, cwdTracker);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2012 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.language.settings.providers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Abstract parser capable to execute compiler command printing built-in compiler
|
||||
* specs and parse built-in language settings out of it. The compiler to be used
|
||||
* is taken from MBS tool-chain definition.
|
||||
*
|
||||
* @since 8.1
|
||||
*/
|
||||
public abstract class ToolchainBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector {
|
||||
private Map<String, ITool> toolMap = new HashMap<String, ITool>();
|
||||
|
||||
/**
|
||||
* Concrete compiler specs detectors need to supply tool-chain ID.
|
||||
*
|
||||
* Tool-chain id must be supplied for global providers where we don't
|
||||
* have configuration description to figure that out programmatically.
|
||||
*/
|
||||
protected abstract String getToolchainId();
|
||||
|
||||
/**
|
||||
* Finds a tool handling given language in the tool-chain of the provider.
|
||||
* This returns the first tool found.
|
||||
*/
|
||||
private ITool getTool(String languageId) {
|
||||
ITool langTool = toolMap.get(languageId);
|
||||
if (langTool != null) {
|
||||
return langTool;
|
||||
}
|
||||
|
||||
String toolchainId = getToolchainId();
|
||||
for (IToolChain toolchain = ManagedBuildManager.getExtensionToolChain(toolchainId);toolchain != null;toolchain = toolchain.getSuperClass()) {
|
||||
ITool tool = getTool(languageId, toolchain);
|
||||
if (tool != null) {
|
||||
return tool;
|
||||
}
|
||||
}
|
||||
ManagedBuilderCorePlugin.error("Unable to find tool in toolchain=" + toolchainId + " for language=" + languageId); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a tool handling given language in the tool-chain.
|
||||
* This returns the first tool found.
|
||||
*/
|
||||
private ITool getTool(String languageId, IToolChain toolchain) {
|
||||
ITool[] tools = toolchain.getTools();
|
||||
for (ITool tool : tools) {
|
||||
IInputType[] inputTypes = tool.getInputTypes();
|
||||
for (IInputType inType : inputTypes) {
|
||||
String lang = inType.getLanguageId(tool);
|
||||
if (languageId.equals(lang)) {
|
||||
toolMap.put(languageId, tool);
|
||||
return tool;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCompilerCommand(String languageId) {
|
||||
ITool tool = getTool(languageId);
|
||||
String compilerCommand = tool.getToolCommand();
|
||||
if (compilerCommand.isEmpty()) {
|
||||
ManagedBuilderCorePlugin.error("Unable to find compiler command in toolchain=" + getToolchainId()); //$NON-NLS-1$
|
||||
}
|
||||
return compilerCommand;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSpecFileExtension(String languageId) {
|
||||
String ext = null;
|
||||
ITool tool = getTool(languageId);
|
||||
String[] srcFileExtensions = tool.getAllInputExtensions();
|
||||
if (srcFileExtensions != null && srcFileExtensions.length > 0) {
|
||||
ext = srcFileExtensions[0];
|
||||
}
|
||||
if (ext == null || ext.isEmpty()) {
|
||||
ManagedBuilderCorePlugin.error("Unable to find file extension for language " + languageId); //$NON-NLS-1$
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -240,6 +240,13 @@
|
|||
</run>
|
||||
</filesystem>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.EFSExtensionProvider">
|
||||
<EFSExtensionProvider
|
||||
class="org.eclipse.cdt.core.internal.tests.filesystem.ram.MemoryEFSExtensionProvider"
|
||||
scheme="mem">
|
||||
</EFSExtensionProvider>
|
||||
</extension>
|
||||
<extension
|
||||
id="RegexErrorParserId"
|
||||
name="Test Plugin RegexErrorParser"
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012, 2012 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 org.eclipse.cdt.core.IConsoleParser;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Console parser interface extended to support language settings providers.
|
||||
*
|
||||
* @since 5.4
|
||||
*/
|
||||
public interface ICBuildOutputParser extends IConsoleParser {
|
||||
/**
|
||||
* Initialize console parser.
|
||||
*
|
||||
* @param cfgDescription - configuration description for the parser.
|
||||
* @param cwdTracker - tracker to keep track of current working directory.
|
||||
* @throws CoreException if anything goes wrong.
|
||||
*/
|
||||
public void startup(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker) throws CoreException;
|
||||
|
||||
@Override
|
||||
public boolean processLine(String line);
|
||||
@Override
|
||||
public void shutdown();
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012, 2012 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.net.URI;
|
||||
|
||||
/**
|
||||
* Interface for console parsers able to track current working directory for build.
|
||||
*
|
||||
* @since 5.4
|
||||
*/
|
||||
public interface IWorkingDirectoryTracker {
|
||||
/**
|
||||
* Returns current working directory for the current build command as determined from
|
||||
* build output.
|
||||
*
|
||||
* @return URI of current working directory or {@code null}.
|
||||
*/
|
||||
public URI getWorkingDirectoryURI();
|
||||
}
|
|
@ -330,9 +330,26 @@ public class LanguageSettingsManager {
|
|||
/**
|
||||
* Save language settings providers of the workspace (global providers) to persistent storage.
|
||||
*
|
||||
* @throws CoreException
|
||||
* @throws CoreException if something goes wrong.
|
||||
*/
|
||||
public static void serializeLanguageSettingsWorkspace() throws CoreException {
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language settings providers of a project to persistent storage in a background job.
|
||||
*
|
||||
* @param prjDescription - project description of the project.
|
||||
*/
|
||||
public static void serializeLanguageSettingsInBackground(ICProjectDescription prjDescription) {
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsInBackground(prjDescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language settings providers of the workspace (global providers) to persistent storage
|
||||
* in a background job.
|
||||
*/
|
||||
public static void serializeLanguageSettingsWorkspaceInBackground() {
|
||||
LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspaceInBackground();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,6 +258,24 @@ public class LanguageSettingsSerializableProvider extends LanguageSettingsBasePr
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to persist language settings entries in background for the project or
|
||||
* workspace as often-used operation.
|
||||
* Note that configuration description is passed as an argument but the
|
||||
* current implementation saves all configurations.
|
||||
*
|
||||
* @param cfgDescription - configuration description.
|
||||
* If not {@code null}, all providers of the project are serialized.
|
||||
* If {@code null}, global workspace providers are serialized.
|
||||
*/
|
||||
public void serializeLanguageSettingsInBackground(ICConfigurationDescription cfgDescription) {
|
||||
if (cfgDescription != null) {
|
||||
LanguageSettingsManager.serializeLanguageSettingsInBackground(cfgDescription.getProjectDescription());
|
||||
} else {
|
||||
LanguageSettingsManager.serializeLanguageSettingsWorkspaceInBackground();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load provider from XML provider element.
|
||||
* This is convenience method not intended to be overridden on purpose.
|
||||
|
|
|
@ -15,6 +15,9 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
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.internal.core.LocalProjectScope;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager;
|
||||
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
|
||||
|
@ -82,6 +85,49 @@ public class ScannerDiscoveryLegacySupport {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if legacy Scanner Discovery in MBS should be active.
|
||||
*/
|
||||
private static boolean isMbsLanguageSettingsProviderOn(ICConfigurationDescription cfgDescription) {
|
||||
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
|
||||
List<ILanguageSettingsProvider> lsProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
||||
for (ILanguageSettingsProvider lsp : lsProviders) {
|
||||
if (MBS_LANGUAGE_SETTINGS_PROVIDER_ID.equals(lsp.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noreference This is internal helper method to support compatibility with previous versions
|
||||
* which is not intended to be referenced by clients.
|
||||
*/
|
||||
public static boolean isLegacyScannerDiscoveryOn(ICConfigurationDescription cfgDescription) {
|
||||
IProject project = null;
|
||||
if (cfgDescription != null) {
|
||||
ICProjectDescription prjDescription = cfgDescription.getProjectDescription();
|
||||
if (prjDescription != null) {
|
||||
project = prjDescription.getProject();
|
||||
}
|
||||
}
|
||||
return isLanguageSettingsProvidersFunctionalityEnabled(project) || isMbsLanguageSettingsProviderOn(cfgDescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noreference This is internal helper method to support compatibility with previous versions
|
||||
* which is not intended to be referenced by clients.
|
||||
*/
|
||||
public static boolean isLegacyScannerDiscoveryOn(IProject project) {
|
||||
ICConfigurationDescription cfgDescription = null;
|
||||
ICProjectDescription prjDescription = CoreModel.getDefault().getProjectDescription(project);
|
||||
if (prjDescription != null) {
|
||||
cfgDescription = prjDescription.getActiveConfiguration();
|
||||
}
|
||||
return isLanguageSettingsProvidersFunctionalityEnabled(project) || isMbsLanguageSettingsProviderOn(cfgDescription);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list containing MBS and User provider. Used to initialize for unaware tool-chains (backward compatibility).
|
||||
*/
|
||||
|
|
|
@ -334,10 +334,8 @@ public class CDataUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convenience method to create {@link ICLanguageSettingEntry} depending on kind.
|
||||
* Convenience method to create {@link ICSettingEntry} depending on kind.
|
||||
* Note that this method keeps the entries in the pool to avoid proliferation of duplicates.
|
||||
*
|
||||
* Note that the method always returns {@link ICLanguageSettingEntry}.
|
||||
*/
|
||||
public static ICSettingEntry createEntry(int kind, String name, String value, IPath[] exclusionPatterns, int flags) {
|
||||
return createEntry(kind, name, value, exclusionPatterns, flags, null, null, null);
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
|||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
import org.eclipse.cdt.internal.core.settings.model.CConfigurationSpecSettings;
|
||||
import org.eclipse.cdt.internal.core.settings.model.IInternalCCfgInfo;
|
||||
import org.eclipse.cdt.internal.core.settings.model.SettingsModelMessages;
|
||||
import org.eclipse.core.filesystem.URIUtil;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
|
@ -47,13 +48,16 @@ import org.eclipse.core.resources.ResourcesPlugin;
|
|||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.ILock;
|
||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -70,11 +74,16 @@ public class LanguageSettingsProvidersSerializer {
|
|||
public static final String ELEM_PROVIDER = LanguageSettingsExtensionManager.ELEM_PROVIDER;
|
||||
public static final String ELEM_LANGUAGE_SCOPE = LanguageSettingsExtensionManager.ELEM_LANGUAGE_SCOPE;
|
||||
|
||||
private static final String JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_PROJECT = "CDT_JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_PROJECT"; //$NON-NLS-1$
|
||||
private static final String JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE = "CDT_JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE"; //$NON-NLS-1$
|
||||
private static final String PREFERENCE_WORSPACE_PROVIDERS_SET = "language.settings.providers.workspace.prefs.toggle"; //$NON-NLS-1$
|
||||
private static final String CPROJECT_STORAGE_MODULE = "org.eclipse.cdt.core.LanguageSettingsProviders"; //$NON-NLS-1$
|
||||
private static final String STORAGE_WORKSPACE_LANGUAGE_SETTINGS = "language.settings.xml"; //$NON-NLS-1$
|
||||
private static final String STORAGE_PROJECT_PATH = ".settings/language.settings.xml"; //$NON-NLS-1$
|
||||
|
||||
private static final int PROGRESS_MONITOR_SCALE = 100;
|
||||
private static final int TICKS_SERIALIZING = 1 * PROGRESS_MONITOR_SCALE;
|
||||
|
||||
private static final String ELEM_PLUGIN = "plugin"; //$NON-NLS-1$
|
||||
private static final String ELEM_EXTENSION = "extension"; //$NON-NLS-1$
|
||||
private static final String ATTR_EXTENSION_POINT = "point"; //$NON-NLS-1$
|
||||
|
@ -537,6 +546,46 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language settings providers of the workspace (global providers) to persistent storage
|
||||
* in background.
|
||||
*/
|
||||
public static void serializeLanguageSettingsWorkspaceInBackground() {
|
||||
Job[] jobs = Job.getJobManager().find(JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE);
|
||||
for (Job job : jobs) {
|
||||
if (job.getState() == Job.WAITING) {
|
||||
// do not schedule if there is serializing job in queue already
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Job job = new Job(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializeJobName")) { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
monitor.beginTask(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializingForWorkspace"), //$NON-NLS-1$
|
||||
TICKS_SERIALIZING);
|
||||
serializeLanguageSettingsWorkspace();
|
||||
monitor.worked(TICKS_SERIALIZING);
|
||||
return Status.OK_STATUS;
|
||||
} catch (Throwable e) {
|
||||
String msg = "Internal error running job of serializing language settings in workspace"; //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, msg, e);
|
||||
} finally {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean belongsTo(Object family) {
|
||||
return family == JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE;
|
||||
}
|
||||
};
|
||||
|
||||
job.setRule(null);
|
||||
job.schedule();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load language settings for workspace.
|
||||
*/
|
||||
|
@ -811,6 +860,57 @@ public class LanguageSettingsProvidersSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save language settings providers of a project to persistent storage in background.
|
||||
*
|
||||
* @param prjDescription - project description of the project.
|
||||
*/
|
||||
public static void serializeLanguageSettingsInBackground(final ICProjectDescription prjDescription) {
|
||||
Job job = new Job(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializeJobName")) { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
monitor.beginTask(NLS.bind(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializingForProject"), //$NON-NLS-1$
|
||||
prjDescription.getName()), TICKS_SERIALIZING);
|
||||
serializeLanguageSettings(prjDescription);
|
||||
monitor.worked(TICKS_SERIALIZING);
|
||||
return Status.OK_STATUS;
|
||||
} catch (Throwable e) {
|
||||
String msg = "Internal error running job of serializing language settings for project " + prjDescription.getName(); //$NON-NLS-1$
|
||||
return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, msg, e);
|
||||
} finally {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean belongsTo(Object family) {
|
||||
return family == JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_PROJECT;
|
||||
}
|
||||
};
|
||||
|
||||
ISchedulingRule rule = null;
|
||||
IProject project = prjDescription.getProject();
|
||||
if (project != null) {
|
||||
IFile fileStorePrj = getStoreInProjectArea(project);
|
||||
IContainer folder = fileStorePrj.getParent();
|
||||
if (folder instanceof IFolder && !folder.exists()) {
|
||||
try {
|
||||
((IFolder) folder).create(true, true, null);
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
if (folder.isAccessible()) {
|
||||
rule = fileStorePrj;
|
||||
}
|
||||
}
|
||||
if (rule == null) {
|
||||
rule = ResourcesPlugin.getWorkspace().getRoot();
|
||||
}
|
||||
job.setRule(rule);
|
||||
job.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load language settings to the project description from XML.
|
||||
*
|
||||
|
|
|
@ -51,6 +51,9 @@ ExtensionContainerFactory.4=invalid setting provider class specified
|
|||
ExtensionContainerFactory.5=provider element not specified
|
||||
LanguageSettingsBaseProvider.CanBeConfiguredOnlyOnce=LanguageSettingsBaseProvider can be configured only once
|
||||
LanguageSettingsScannerInfoProvider.UnableToDetermineLanguage=Error getting ScannerInfo: Unable to determine language for resource {0}
|
||||
LanguageSettingsProvidersSerializer.SerializeJobName=Serialize CDT language settings entries
|
||||
LanguageSettingsProvidersSerializer.SerializingForProject="Serializing language settings for project {0}
|
||||
LanguageSettingsProvidersSerializer.SerializingForWorkspace="Serializing language settings for global providers
|
||||
SettingsContext.0=no project associated with the context
|
||||
SettingsContext.1=can not accept the not-context project description
|
||||
|
||||
|
|
|
@ -531,8 +531,10 @@ public class CCorePlugin extends Plugin {
|
|||
* </code>
|
||||
*
|
||||
* @return CDT console adapter.
|
||||
*
|
||||
* @since 5.4
|
||||
*/
|
||||
private IConsole getConsole(String extConsoleId, String contextId, String name, URL iconUrl) {
|
||||
public IConsole getConsole(String extConsoleId, String contextId, String name, URL iconUrl) {
|
||||
try {
|
||||
IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, "CBuildConsole"); //$NON-NLS-1$
|
||||
if (extensionPoint != null) {
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Map;
|
|||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.core.errorparsers.ErrorParserNamedWrapper;
|
||||
import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker;
|
||||
import org.eclipse.cdt.core.resources.ACBuilder;
|
||||
import org.eclipse.cdt.internal.core.Cygwin;
|
||||
import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
|
||||
|
@ -50,7 +51,7 @@ import org.osgi.service.prefs.BackingStoreException;
|
|||
*
|
||||
* @noextend This class is not intended to be subclassed by clients.
|
||||
*/
|
||||
public class ErrorParserManager extends OutputStream implements IConsoleParser {
|
||||
public class ErrorParserManager extends OutputStream implements IConsoleParser, IWorkingDirectoryTracker {
|
||||
/**
|
||||
* The list of error parsers stored in .project for 3.X projects
|
||||
* as key/value pair with key="org.eclipse.cdt.core.errorOutputParser"
|
||||
|
@ -193,6 +194,7 @@ public class ErrorParserManager extends OutputStream implements IConsoleParser {
|
|||
* @return the current URI location where the build is being performed
|
||||
* @since 5.1
|
||||
*/
|
||||
@Override
|
||||
public URI getWorkingDirectoryURI() {
|
||||
if (!fDirectoryStack.isEmpty())
|
||||
return fDirectoryStack.lastElement();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2009 IBM Corporation and others.
|
||||
* Copyright (c) 2004, 2012 IBM Corporation 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
|
||||
|
@ -12,10 +12,6 @@ package org.eclipse.cdt.core;
|
|||
|
||||
/**
|
||||
* A basic interface for console parsers
|
||||
*
|
||||
* @author vhirsl
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IConsoleParser {
|
||||
/**
|
||||
|
|
|
@ -31,13 +31,23 @@ public class Cygwin {
|
|||
* Check if cygwin path conversion utilities are available in the path.
|
||||
*
|
||||
* @param envPath - list of directories to search for cygwin utilities separated
|
||||
* by path separator (format of environment variable $PATH).
|
||||
* by path separator (format of environment variable $PATH)
|
||||
* or {@code null} to use current $PATH.
|
||||
* @return {@code true} if cygwin is available, {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isAvailable(String envPath) {
|
||||
return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(envPath) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if cygwin path conversion utilities are available in $PATH.
|
||||
*
|
||||
* @return {@code true} if cygwin is available, {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isAvailable() {
|
||||
return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(null) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion from Cygwin path to Windows path.
|
||||
*
|
||||
|
|
|
@ -17,3 +17,6 @@ objectFileName=Object File
|
|||
|
||||
profileName=XL C managed make per project scanner discovery profile
|
||||
profileNameCPP=XL C++ managed make per project scanner discovery profile
|
||||
|
||||
XlcBuiltinSpecsDetectorName=CDT XLC Builtin Compiler Settings
|
||||
XlcBuildCommandParserName=CDT XLC Build Output Parser
|
||||
|
|
|
@ -74,6 +74,25 @@
|
|||
class="org.eclipse.cdt.make.xlc.core.scannerconfig.XlCSpecsConsoleParser">
|
||||
</scannerInfoConsoleParser>
|
||||
</scannerInfoProvider>
|
||||
|
||||
</extension>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<provider
|
||||
class="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuiltinSpecsDetector"
|
||||
id="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuiltinSpecsDetector"
|
||||
name="%XlcBuiltinSpecsDetectorName"
|
||||
parameter="${COMMAND} -E -V -P -w ${INPUTS}">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
<provider
|
||||
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser"
|
||||
id="org.eclipse.cdt.managedbuilder.xlc.core.XlcBuildCommandParser"
|
||||
name="%XlcBuildCommandParserName"
|
||||
parameter="xl[cC]"
|
||||
prefer-non-shared="true">
|
||||
</provider>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*******************************************************************************
|
||||
* 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.xlc.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsEditableProvider;
|
||||
import org.eclipse.cdt.core.settings.model.ICSettingEntry;
|
||||
import org.eclipse.cdt.managedbuilder.language.settings.providers.ToolchainBuiltinSpecsDetector;
|
||||
|
||||
/**
|
||||
* Language settings provider to detect built-in compiler settings for IBM XLC compiler.
|
||||
*/
|
||||
public class XlcBuiltinSpecsDetector extends ToolchainBuiltinSpecsDetector implements ILanguageSettingsEditableProvider {
|
||||
// must match the toolchain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point
|
||||
private static final String XLC_TOOLCHAIN_ID = "cdt.managedbuild.toolchain.xlc.exe.debug"; //$NON-NLS-1$
|
||||
|
||||
private static final Pattern OPTIONS_PATTERN = Pattern.compile("-[^\\s\"']*(\\s*((\".*?\")|('.*?')|([^-\\s][^\\s]+)))?"); //$NON-NLS-1$
|
||||
private static final int OPTION_GROUP = 0;
|
||||
|
||||
/* Sample output:
|
||||
|
||||
> xlC -E -V -P -w ~/tmp/spec.C
|
||||
export XL_CONFIG=/etc/vac.cfg:xlC
|
||||
/usr/vac/exe/xlCcpp /home/me/tmp/spec.C - -qc++=/usr/vacpp/include -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 -D_AIX50 -D_AIX51 -D_AIX52 -D_IBMR2 -D_POWER -E -P -w -qlanglvl=ansi -qansialias
|
||||
rm /tmp/xlcW0lt4Jia
|
||||
rm /tmp/xlcW1lt4Jib
|
||||
rm /tmp/xlcW2lt4Jic
|
||||
*/
|
||||
@SuppressWarnings("nls")
|
||||
private static final AbstractOptionParser[] optionParsers = {
|
||||
new IncludePathOptionParser("-I\\s*([\"'])(.*)\\1", "$2", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.LOCAL),
|
||||
new IncludePathOptionParser("-I\\s*([^\\s\"']*)", "$1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
new IncludePathOptionParser("-qc\\+\\+=\\s*([^\\s\"']*)", "$1", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
new MacroOptionParser("-D\\s*([\"'])([^=]*)(=(.*))?\\1", "$2", "$4", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
new MacroOptionParser("-D\\s*([^\\s=\"']*)=(\\\\([\"']))(.*?)\\2", "$1", "$3$4$3", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
new MacroOptionParser("-D\\s*([^\\s=\"']*)=([\"'])(.*?)\\2", "$1", "$3", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
new MacroOptionParser("-D\\s*([^\\s=\"']*)(=([^\\s\"']*))?", "$1", "$3", ICSettingEntry.BUILTIN | ICSettingEntry.READONLY),
|
||||
};
|
||||
|
||||
@Override
|
||||
protected String getToolchainId() {
|
||||
return XLC_TOOLCHAIN_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractOptionParser[] getOptionParsers() {
|
||||
return optionParsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> parseOptions(String line) {
|
||||
List<String> options = new ArrayList<String>();
|
||||
Matcher optionMatcher = OPTIONS_PATTERN.matcher(line);
|
||||
while (optionMatcher.find()) {
|
||||
String option = optionMatcher.group(OPTION_GROUP);
|
||||
if (option!=null) {
|
||||
options.add(option);
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XlcBuiltinSpecsDetector cloneShallow() throws CloneNotSupportedException {
|
||||
return (XlcBuiltinSpecsDetector) super.cloneShallow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XlcBuiltinSpecsDetector clone() throws CloneNotSupportedException {
|
||||
return (XlcBuiltinSpecsDetector) super.clone();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue