From 7d48a4fcc6e86f1dba208ace6229b798ac21053d Mon Sep 17 00:00:00 2001 From: David Inglis Date: Tue, 16 Mar 2004 20:35:25 +0000 Subject: [PATCH] applied patch from vhirsl@ca.ibm.com implementing new auto scanner configuration detection mechanism --- .../plugin.properties | 11 +- build/org.eclipse.cdt.make.core/plugin.xml | 65 +++ .../schema/ExternalScannerInfoProvider.exsd | 137 +++++ .../schema/ScannerInfoConsoleParser.exsd | 119 +++++ .../eclipse/cdt/make/core/MakeBuilder.java | 7 +- .../eclipse/cdt/make/core/MakeCorePlugin.java | 139 ++++- .../cdt/make/core/PluginResources.properties | 15 +- .../IExternalScannerInfoProvider.java | 35 ++ .../IScannerConfigBuilderInfo.java | 46 ++ .../IScannerInfoConsoleParser.java | 40 ++ .../scannerconfig/ScannerConfigBuilder.java | 45 ++ .../scannerconfig/ScannerConfigNature.java | 128 +++++ .../ConsoleOutputStreamSniffer.java | 117 +++++ .../DefaultExternalScannerInfoProvider.java | 257 ++++++++++ .../IScannerInfoConsoleParserUtility.java | 31 ++ .../ScannerConfigInfoFactory.java | 337 ++++++++++++ .../scannerconfig/ScannerInfoCollector.java | 343 +++++++++++++ .../ScannerInfoConsoleParserFactory.java | 95 ++++ .../gnu/GCCScannerConfigUtil.java | 57 +++ .../gnu/GCCScannerInfoConsoleParser.java | 203 ++++++++ .../gnu/GCCSpecsConsoleParser.java | 109 ++++ .../scannerconfig/util/CygpathTranslator.java | 111 ++++ .../scannerconfig/util/ScannerConfigUtil.java | 95 ++++ .../util/ScannerInfoConsoleParserUtility.java | 342 +++++++++++++ .../core/scannerconfig/util/SymbolEntry.java | 127 +++++ .../org.eclipse.cdt.make.ui/plugin.properties | 2 + build/org.eclipse.cdt.make.ui/plugin.xml | 24 +- .../make/internal/ui/MakeResources.properties | 15 + .../ScannerConfigPreferencePage.java | 100 ++++ .../properties/ScannerConfigPropertyPage.java | 91 ++++ .../make/ui/dialogs/ScannerConfigPage.java | 482 ++++++++++++++++++ .../wizards/MakeProjectWizardOptionPage.java | 6 +- 32 files changed, 3724 insertions(+), 7 deletions(-) create mode 100644 build/org.eclipse.cdt.make.core/schema/ExternalScannerInfoProvider.exsd create mode 100644 build/org.eclipse.cdt.make.core/schema/ScannerInfoConsoleParser.exsd create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java create mode 100644 build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java create mode 100644 build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java create mode 100644 build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java diff --git a/build/org.eclipse.cdt.make.core/plugin.properties b/build/org.eclipse.cdt.make.core/plugin.properties index 0c13be60b2c..8ac4da23c08 100644 --- a/build/org.eclipse.cdt.make.core/plugin.properties +++ b/build/org.eclipse.cdt.make.core/plugin.properties @@ -3,4 +3,13 @@ providerName=Eclipse.org extensionTargetBuilder.name=Target Builder Extension natureMake.name=CDT Make Nature -builderMake.name=CDT Makefile Builder \ No newline at end of file +builderMake.name=CDT Makefile Builder + +epScannerConfigNature.name=Scanner Configuration Nature +epScannerConfigBuilder.name=Scanner Configuration Builder +extensionExternalScannerInfoProvider.name=C/C++ External Scanner Info Provider Extension +epDefaultExternalScannerInfoProvider.name=Default External Scanner Info Provider + +extensionScannerInfoConsoleParser.name=C/C++ Scanner Info Console Parser Extension +epGCCCommandLineParser.name=GNU C/C++ Scanner Info Parser +epGCCSpecsParser.name=GNU C/C++ Compiler Specs Parser diff --git a/build/org.eclipse.cdt.make.core/plugin.xml b/build/org.eclipse.cdt.make.core/plugin.xml index 6903624159b..e087239130d 100644 --- a/build/org.eclipse.cdt.make.core/plugin.xml +++ b/build/org.eclipse.cdt.make.core/plugin.xml @@ -21,6 +21,8 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/org.eclipse.cdt.make.core/schema/ExternalScannerInfoProvider.exsd b/build/org.eclipse.cdt.make.core/schema/ExternalScannerInfoProvider.exsd new file mode 100644 index 00000000000..ba67a98e776 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/schema/ExternalScannerInfoProvider.exsd @@ -0,0 +1,137 @@ + + + + + + + + + This extension point is used to plug in particular compiler scanner info provider. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A fully qualified name of the Java class that implements <samp>org.eclipse.cdt.make.core.scannerconfig.ICompilerScannerInfoProvider</samp> interface. + + + + + + + + + + + + + Parameters passed to the compiler scanner info provider. + + + + + + + Name of a parameter. + + + + + + + Value of a parameter. + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + Plug-ins that want to extend this extension point must implement <samp>org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider</samp> interface. + + + + + + + + + org.eclipse.cdt.make.core plugin provides default implementation of the GNU C/C++ compiler specs scanner info provider. + + + + + + + + + + + + + diff --git a/build/org.eclipse.cdt.make.core/schema/ScannerInfoConsoleParser.exsd b/build/org.eclipse.cdt.make.core/schema/ScannerInfoConsoleParser.exsd new file mode 100644 index 00000000000..a84b6183dd5 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/schema/ScannerInfoConsoleParser.exsd @@ -0,0 +1,119 @@ + + + + + + + + + [Enter description of this extension point.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Id of the command the console parser is associated with. Can be 'all', 'makeBuilder' or 'externalScannerInfoProvider'. + + + + + + + + + + + + + + + + + Java class that implements IScannerInfoConsoleParser interface. + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + + diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java index 7494b1ff102..dc3e60c34c4 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java @@ -24,6 +24,7 @@ import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.resources.ACBuilder; import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.make.internal.core.StreamMonitor; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoConsoleParserFactory; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -179,6 +180,9 @@ public class MakeBuilder extends ACBuilder { epm.setOutputStream(streamMon); OutputStream stdout = epm.getOutputStream(); OutputStream stderr = epm.getOutputStream(); + // Sniff console output for scanner info + OutputStream sniffer = ScannerInfoConsoleParserFactory.getMakeBuilderOutputSniffer( + epm.getOutputStream(), getProject(), workingDirectory, this); Process p = launcher.execute(buildCommand, buildArguments, env, workingDirectory); if (p != null) { try { @@ -189,7 +193,7 @@ public class MakeBuilder extends ACBuilder { } // Before launching give visual cues via the monitor monitor.subTask(MakeCorePlugin.getResourceString("MakeBuilder.Invoking_Command") + launcher.getCommandLine()); //$NON-NLS-1$ - if (launcher.waitAndRead(stdout, stderr, new SubProgressMonitor(monitor, 0)) + if (launcher.waitAndRead(sniffer, sniffer, new SubProgressMonitor(monitor, 0)) != CommandLauncher.OK) errMsg = launcher.getErrorMessage(); monitor.subTask(MakeCorePlugin.getResourceString("MakeBuilder.Updating_project")); //$NON-NLS-1$ @@ -225,6 +229,7 @@ public class MakeBuilder extends ACBuilder { stderr.close(); monitor.subTask(MakeCorePlugin.getResourceString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$ + sniffer.close(); epm.reportProblems(); cos.close(); } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java index 9eb8547be95..5ce26e2997b 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2002,2003 QNX Software Systems and others. + * Copyright (c) 2002,2004 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at @@ -13,19 +13,30 @@ package org.eclipse.cdt.make.core; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.make.core.makefile.IMakefile; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder; import org.eclipse.cdt.make.internal.core.BuildInfoFactory; import org.eclipse.cdt.make.internal.core.MakeTargetManager; import org.eclipse.cdt.make.internal.core.makefile.gnu.GNUMakefile; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigInfoFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPluginDescriptor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; @@ -40,6 +51,13 @@ public class MakeCorePlugin extends Plugin { public static final String MAKE_PROJECT_ID = MakeCorePlugin.getUniqueIdentifier() + ".make"; //$NON-NLS-1$ private MakeTargetManager fTargetManager; public static final String OLD_BUILDER_ID = "org.eclipse.cdt.core.cbuilder"; //$NON-NLS-1$ + + public static final String EXTERNAL_SI_PROVIDER_SIMPLE_ID = "ExternalScannerInfoProvider"; //$NON-NLS-1$ + public static final String SI_CONSOLE_PARSER_SIMPLE_ID = "ScannerInfoConsoleParser"; //$NON-NLS-1$ + public static final String DEFAULT_EXTERNAL_SI_PROVIDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".DefaultExternalScannerInfoProvider"; //$NON-NLS-1$ + public static final String GCC_SPECS_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCSpecsConsoleParser"; //$NON-NLS-1$ + public static final String GCC_SCANNER_INFO_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCScannerInfoConsoleParser"; //$NON-NLS-1$ + //The shared instance. private static MakeCorePlugin plugin; //Resource bundle. @@ -131,6 +149,20 @@ public class MakeCorePlugin extends Plugin { } catch (CoreException e) { } getPluginPreferences().setDefault(CCorePlugin.PREF_BINARY_PARSER, CCorePlugin.PLUGIN_ID + ".ELF"); //$NON-NLS-1$ + + // default plugin preferences for scanner configuration discovery + IScannerConfigBuilderInfo scInfo = createScannerConfigBuildInfo(getPluginPreferences(), ScannerConfigBuilder.BUILDER_ID, true); + try { + scInfo.setAutoDiscoveryEnabled(false); + scInfo.setMakeBuilderConsoleParserEnabled(true); + scInfo.setESIProviderCommandEnabled(true); + scInfo.setUseDefaultESIProviderCmd(true); + scInfo.setESIProviderCommand(new Path("gcc")); //$NON-NLS-1$ + scInfo.setESIProviderArguments("-c -v"); //$NON-NLS-1$ + scInfo.setESIProviderConsoleParserId(GCC_SPECS_CONSOLE_PARSER_ID); + scInfo.setMakeBuilderConsoleParserId(GCC_SCANNER_INFO_CONSOLE_PARSER_ID); + } catch (CoreException e) { + } } public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) { @@ -179,4 +211,109 @@ public class MakeCorePlugin extends Plugin { } } + /* + * Following methods create IScannerConfigBuilderInfo + * Delegating requests to ScannerConfigInfoFactory + */ + public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( + Preferences prefs, String builderID, boolean useDefaults) { + return ScannerConfigInfoFactory.create(prefs, builderID, useDefaults); + } + + public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( + IProject project, String builderID) throws CoreException { + return ScannerConfigInfoFactory.create(project, builderID); + } + + public static IScannerConfigBuilderInfo createScannerConfigBuildInfo( + Map args, String builderID) { + return ScannerConfigInfoFactory.create(args, builderID); + } + + public static IPath getWorkingDirectory() { + return MakeCorePlugin.getDefault().getStateLocation(); + } + + /** + * @param id - id specifying external scanner info provider + * @return provider - new instance of an external scanner info provider + */ + public IExternalScannerInfoProvider getExternalScannerInfoProvider(String id) { + try { + IExtensionPoint extension = getDescriptor().getExtensionPoint(EXTERNAL_SI_PROVIDER_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + String tool = extensions[i].getUniqueIdentifier(); + if (tool != null && tool.equals(id)) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + for (int j = 0; j < configElements.length; j++) { + IConfigurationElement[] runElement = configElements[j].getChildren("run"); //$NON-NLS-1$ + if (runElement.length > 0) { + IExternalScannerInfoProvider builder = (IExternalScannerInfoProvider) runElement[0].createExecutableExtension("class"); + return builder; + } + } + } + } + } + } + catch (CoreException e) { + log(e); + } + return null; + } + + /** + * @param commandId + * @return String[] - array of parserIds associated with the commandId or 'all' + */ + public String[] getScannerInfoConsoleParserIds(String commandId) { + String[] empty = new String[0]; + if (commandId == null || commandId.length() == 0) { + commandId = "all"; //$NON-NLS-1$ + } + IExtensionPoint extension = getDescriptor().getExtensionPoint(SI_CONSOLE_PARSER_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + List parserIds = new ArrayList(extensions.length); + for (int i = 0; i < extensions.length; i++) { + String parserId = extensions[i].getUniqueIdentifier(); + if (parserId != null) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + String id = configElements[0].getAttribute("commandId");//$NON-NLS-1$ + if (id != null && (id.equals(commandId) || id.equals("all"))) { //$NON-NLS-1$ + parserIds.add(parserId); + } + } + } + return (String[])parserIds.toArray(empty); + } + return empty; + } + + /** + * @param parserId + * @return parser - parser object identified by the parserId + */ + public IScannerInfoConsoleParser getScannerInfoConsoleParser(String parserId) { + try { + IExtensionPoint extension = getDescriptor().getExtensionPoint(SI_CONSOLE_PARSER_SIMPLE_ID); + if (extension != null) { + IExtension[] extensions = extension.getExtensions(); + for (int i = 0; i < extensions.length; i++) { + String id = extensions[i].getUniqueIdentifier(); + if (id != null && id.equals(parserId)) { + IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); + IScannerInfoConsoleParser parser = (IScannerInfoConsoleParser)configElements[0].createExecutableExtension("class");//$NON-NLS-1$ + return parser; + } + } + } + } + catch (CoreException e) { + log(e); + } + return null; + } } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/PluginResources.properties b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/PluginResources.properties index d527c887cf8..e17efd09391 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/PluginResources.properties +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/PluginResources.properties @@ -13,4 +13,17 @@ MakeTargetManager.target_exists=Target exists MakeTargetManager.failed_initializing_targets=Failed initializing build targets MakeTargetManager.error_writing_file=Error writing target file -ProjectTargets.error_reading_project_targets=Error reading project targets. \ No newline at end of file +ProjectTargets.error_reading_project_targets=Error reading project targets. + +ScannerConfigBuilder.Invoking_Builder=Invoking scanner config builder on project + +ExternalScannerInfoProvider.Provider_Error=Error launching compiler scanner info generator ({0}) +ExternalScannerInfoProvider.Reading_Specs=Reading specs ... +ExternalScannerInfoProvider.Invoking_Command=Invoking Command: +ExternalScannerInfoProvider.Parsing_Output=Parsing output ... +ExternalScannerInfoProvider.Creating_Markers=Generating markers ... + +ScannerInfoCollector.Processing=Processing discovered scanner configuration ... +ScannerInfoCollector.Updating=Updating Scanner Configuration for project + +GCCScannerConfigUtil.Error_Message=Error creating specs file diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java new file mode 100644 index 00000000000..16a20afc35b --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * Interface for providers of C/C++ scanner info + * + * @author vhirsl + */ +public interface IExternalScannerInfoProvider { + /** + * Invokes a C/C++ compiler with target specific options to generate + * compiler scanner info. + * + * @param monitor + * @param current project - current project being built + * @param buildInfo - settings for ScannerConfigBuilder + * @param targetSpecificOptions - array of options affecting compiler specs + */ + public boolean invokeProvider(IProgressMonitor monitor, + IProject currentProject, + IScannerConfigBuilderInfo buildInfo, + String[] targetSpecificOptions); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java new file mode 100644 index 00000000000..808d1897549 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java @@ -0,0 +1,46 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.make.core.scannerconfig; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * Settings for ScannerConfigBuilder + * + * @author vhirsl + */ +public interface IScannerConfigBuilderInfo { + boolean isAutoDiscoveryEnabled(); + void setAutoDiscoveryEnabled(boolean enabled) throws CoreException; + + String getMakeBuilderConsoleParserId(); + void setMakeBuilderConsoleParserId(String parserId) throws CoreException; + + boolean isESIProviderCommandEnabled(); + void setESIProviderCommandEnabled(boolean enabled) throws CoreException; + + boolean isDefaultESIProviderCmd(); + void setUseDefaultESIProviderCmd(boolean on) throws CoreException; + + IPath getESIProviderCommand(); + void setESIProviderCommand(IPath command) throws CoreException; + + String getESIProviderArguments(); + void setESIProviderArguments(String args) throws CoreException; + + String getESIProviderConsoleParserId(); + void setESIProviderConsoleParserId(String parserId) throws CoreException; + + boolean isMakeBuilderConsoleParserEnabled(); + void setMakeBuilderConsoleParserEnabled(boolean enabled) throws CoreException; +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java new file mode 100644 index 00000000000..c794e21899b --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java @@ -0,0 +1,40 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +import org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility; +import org.eclipse.core.resources.IProject; + +/** + * Parses a line of command output looking for scanner info entries. + * + * @author vhirsl + */ +public interface IScannerInfoConsoleParser { + /** + * Optional one time initialization of a console parser. + * + * @param project + */ + public void startup(IProject project, IScannerInfoConsoleParserUtility util); + + /** + * Parse one line of output. + * @param line + * @return true if scanner info entry was found in the line + */ + public boolean processLine(String line); + + /** + * Optional finalization of a console parser. + */ + public void shutdown(); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java new file mode 100644 index 00000000000..f4ae72758d6 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java @@ -0,0 +1,45 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +import org.eclipse.cdt.core.resources.ACBuilder; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.internal.core.scannerconfig.*; +import org.eclipse.core.resources.IProject; +import java.util.Map; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * Runs after standard make builder. + * Consolidates discovered scanner configuration and updates project's scanner configuration. + * + * @see IncrementalProjectBuilder + */ +public class ScannerConfigBuilder extends ACBuilder { + public final static String BUILDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".ScannerConfigBuilder"; //$NON-NLS-1$ + + public ScannerConfigBuilder() { + super(); + } + + /** + * @see IncrementalProjectBuilder#build + */ + protected IProject [] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { + monitor.beginTask("", 100); //$NON-NLS-1$ + monitor.subTask(MakeCorePlugin.getResourceString("ScannerConfigBuilder.Invoking_Builder") + //$NON-NLS-1$ + getProject().getName()); + ScannerInfoCollector.getInstance().updateScannerConfiguration(getProject(), new SubProgressMonitor(monitor, 100)); + return getProject().getReferencedProjects(); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java new file mode 100644 index 00000000000..aab6fa15c30 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java @@ -0,0 +1,128 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.core.scannerconfig; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IProjectNature; + +/** + * @see IProjectNature + */ +public class ScannerConfigNature implements IProjectNature { + + public final static String NATURE_ID = MakeCorePlugin.getUniqueIdentifier() + ".ScannerConfigNature"; //$NON-NLS-1$ + private IProject fProject; + + public ScannerConfigNature() { + } + + /** + * @see IProjectNature#configure + */ + public void configure() throws CoreException { + IProjectDescription description = getProject().getDescription(); + ICommand[] commands = description.getBuildSpec(); + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(ScannerConfigBuilder.BUILDER_ID)) { + return; + } + } + ICommand command = description.newCommand(); + command.setBuilderName(ScannerConfigBuilder.BUILDER_ID); + ICommand[] newCommands = new ICommand[commands.length + 1]; + System.arraycopy(commands, 0, newCommands, 0, commands.length); + newCommands[commands.length] = command; + description.setBuildSpec(newCommands); + getProject().setDescription(description, null); + } + + /** + * @see IProjectNature#deconfigure + */ + public void deconfigure() throws CoreException { + IProjectDescription description = getProject().getDescription(); + ICommand[] commands = description.getBuildSpec(); + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(ScannerConfigBuilder.BUILDER_ID)) { + ICommand[] newCommands = new ICommand[commands.length - 1]; + System.arraycopy(commands, 0, newCommands, 0, i); + System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1); + description.setBuildSpec(newCommands); + break; + } + } + getProject().setDescription(description, null); + } + + /** + * @see IProjectNature#getProject + */ + public IProject getProject() { + return fProject; + } + + /** + * @see IProjectNature#setProject + */ + public void setProject(IProject project) { + fProject = project; + } + + public static void addScannerConfigNature(IProject project) throws CoreException { + if (project.hasNature(NATURE_ID)) + return; + + IProjectDescription description = project.getDescription(); + String[] ids = description.getNatureIds(); + String[] newIds = new String[ids.length + 1]; + System.arraycopy(ids, 0, newIds, 0, ids.length); + newIds[ids.length] = NATURE_ID; + description.setNatureIds(newIds); + project.setDescription(description, null); + } + + public static void removeScannerConfigNature(IProject project) throws CoreException { + IProjectDescription description = project.getDescription(); + String[] ids = description.getNatureIds(); + for (int i = 0; i < ids.length; ++i) { + if (ids[i].equals(NATURE_ID)) { + String[] newIds = new String[ids.length - 1]; + System.arraycopy(ids, 0, newIds, 0, i); + System.arraycopy(ids, i + 1, newIds, i, ids.length - i - 1); + description.setNatureIds(newIds); + project.setDescription(description, null); + } + } + } + + /** + * Returns build command as stored in .project file + * + * @param project + * @param builderID + * @return ICommand + * @throws CoreException + */ + public static ICommand getBuildSpec(IProject project, String builderID) throws CoreException { + IProjectDescription description = project.getDescription(); + ICommand[] commands = description.getBuildSpec(); + for (int i = 0; i < commands.length; ++i) { + if (commands[i].getBuilderName().equals(builderID)) { + return commands[i]; + } + } + return null; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java new file mode 100644 index 00000000000..de3f506d4fb --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java @@ -0,0 +1,117 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.cdt.make.core.scannerconfig.*; + +/** + * Intercepts an output to console and forwards it to line parsers for processing + * + * @author vhirsl + */ +public class ConsoleOutputStreamSniffer extends OutputStream { + + private StringBuffer currentLine = new StringBuffer(); + private OutputStream outputStream; + private int nOpens = 0; + private IScannerInfoConsoleParser[] parsers; + + public ConsoleOutputStreamSniffer(IScannerInfoConsoleParser[] parsers) { + this.parsers = parsers; + } + + public ConsoleOutputStreamSniffer(OutputStream outputStream, IScannerInfoConsoleParser[] parsers) { + this(parsers); + nOpens = 1; + this.outputStream = outputStream; + } + + /* (non-Javadoc) + * @see java.io.OutputStream#write(int) + */ + public void write(int b) throws IOException { + currentLine.append((char) b); + checkLine(false); + if (outputStream != null) { + outputStream.write(b); + } + } + /** + * @param flush + */ + private void checkLine(boolean flush) { + String buffer = currentLine.toString(); + int i = 0; + while ((i = buffer.indexOf('\n')) != -1) { + String line = buffer.substring(0, i).trim(); // get rid of any trailing \r + processLine(line); + buffer = buffer.substring(i + 1); // skip the \n and advance + } + currentLine.setLength(0); + if (flush) { + if (buffer.length() > 0) { + processLine(buffer); + } + } else { + currentLine.append(buffer); + } + } + + /** + * @param line + */ + private void processLine(String line) { + for (int i = 0; i < parsers.length; ++i) { + parsers[i].processLine(line); + } + } + + /* (non-Javadoc) + * @see java.io.OutputStream#close() + */ + public void close() throws IOException { + if (nOpens > 0 && --nOpens == 0) { + checkLine(true); + if (outputStream != null) + outputStream.close(); + } + for (int i = 0; i < parsers.length; ++i) { + parsers[i].shutdown(); + } + } + /* (non-Javadoc) + * @see java.io.OutputStream#flush() + */ + public void flush() throws IOException { + if (outputStream != null) { + outputStream.flush(); + } + } + /* (non-Javadoc) + * @see java.io.OutputStream#write(byte[], int, int) + */ + public void write(byte[] b, int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off != 0 || (len < 0) || (len > b.length)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + currentLine.append(new String(b, 0, len)); + checkLine(false); + if (outputStream != null) + outputStream.write(b, off, len); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java new file mode 100644 index 00000000000..ff771636208 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java @@ -0,0 +1,257 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CommandLauncher; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; +import org.eclipse.cdt.make.internal.core.StreamMonitor; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; + +/** + * Default external scanner info provider. + * Runs an external command (i.e. gcc -c -v) and parses an output for scanner info. + * + * @author vhirsl + */ +public class DefaultExternalScannerInfoProvider implements IExternalScannerInfoProvider, IMarkerGenerator { + + private static final String EXTERNAL_SI_PROVIDER_ERROR = "DefaultExternalScannerInfoProvider.Provider_Error"; //$NON-NLS-1$ + private static final String EXTERNAL_SI_PROVIDER_CONSOLE_ID = MakeCorePlugin.getUniqueIdentifier() + ".ExternalScannerInfoProviderConsole"; //$NON-NLS-1$ + + private IPath fWorkingDirectory; + private IPath fCompileCommand; + private String fCompileArguments; + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider#invokeProvider(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.resources.IProject, org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo, java.lang.String[]) + */ + public boolean invokeProvider(IProgressMonitor monitor, IProject currentProject, IScannerConfigBuilderInfo buildInfo, String[] targetSpecificOptions) { + if (!initialize(currentProject, buildInfo)) { + return false; + } + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask(MakeCorePlugin.getResourceString("ExternalScannerInfoProvider.Reading_Specs"), 100); //$NON-NLS-1$ + + try { + IConsole console = CCorePlugin.getDefault().getConsole(EXTERNAL_SI_PROVIDER_CONSOLE_ID); + console.start(currentProject); + OutputStream cos = console.getOutputStream(); + + // Before launching give visual cues via the monitor + monitor.subTask(MakeCorePlugin.getResourceString("ExternalScannerInfoProvider.Reading_Specs")); //$NON-NLS-1$ + + String errMsg = null; + CommandLauncher launcher = new CommandLauncher(); + // Print the command for visual interaction. + launcher.showCommand(true); + + // add file and TSO + String[] compileArguments = prepareArguments(targetSpecificOptions); + + String ca = coligate(compileArguments); + + monitor.subTask(MakeCorePlugin.getResourceString("ExternalScannerInfoProvider.Invoking_Command") + + fCompileCommand.toString() + ca); //$NON-NLS-1$ + cos = new StreamMonitor(new SubProgressMonitor(monitor, 70), cos, 100); + + OutputStream sniffer = ScannerInfoConsoleParserFactory.getESIProviderOutputSniffer( + cos, currentProject, buildInfo); + Process p = launcher.execute(fCompileCommand, compileArguments, setEnvironment(launcher), fWorkingDirectory); + if (p != null) { + try { + // Close the input of the Process explicitely. + // We will never write to it. + p.getOutputStream().close(); + } catch (IOException e) { + } + if (launcher.waitAndRead(sniffer, sniffer, new SubProgressMonitor(monitor, 0)) != CommandLauncher.OK) { + errMsg = launcher.getErrorMessage(); + } + monitor.subTask(MakeCorePlugin.getResourceString("ExternalScannerInfoProvider.Parsing_Output")); //$NON-NLS-1$ + } + else { + errMsg = launcher.getErrorMessage(); + } + + if (errMsg != null) { + String errorDesc = MakeCorePlugin.getFormattedString(EXTERNAL_SI_PROVIDER_ERROR, + fCompileCommand.toString() + ca); + addMarker(currentProject, -1, errorDesc, IMarkerGenerator.SEVERITY_ERROR_BUILD, null); + } + + monitor.subTask(MakeCorePlugin.getResourceString("ExternalScannerInfoProvider.Creating_Markers")); //$NON-NLS-1$ + sniffer.close(); + cos.close(); + } + catch (Exception e) { + CCorePlugin.log(e); + } + finally { + monitor.done(); + } + return true; + } + + /** + * @param currentProject + * @param buildInfo + * @return boolean + */ + private boolean initialize(IProject currentProject, IScannerConfigBuilderInfo buildInfo) { + boolean rc = false; + if (buildInfo.isDefaultESIProviderCmd()) { + fWorkingDirectory = MakeCorePlugin.getWorkingDirectory(); + } + else { + fWorkingDirectory = currentProject.getLocation(); + } + fCompileCommand = buildInfo.getESIProviderCommand(); + if (fCompileCommand != null) { + fCompileArguments = buildInfo.getESIProviderArguments(); + rc = true; + } + return rc; + } + + /** + * @param tso + * @return + */ + private String[] prepareArguments(String[] tso) { + String[] rv = null; + // commandArguments may have multiple arguments; tokenizing + int nTokens = 0; + if (fCompileArguments != null && fCompileArguments.length() > 0) { + StringTokenizer tokenizer = new StringTokenizer(fCompileArguments, " ");//$NON-NLS-1$ + nTokens = tokenizer.countTokens(); + if (nTokens > 0) { + rv = new String[nTokens + tso.length]; + for (int i = 0; tokenizer.hasMoreTokens(); ++i) { + rv[i] = tokenizer.nextToken(); + } + } + } + if (rv == null) { + rv = new String[tso.length]; + } + for (int i = 0; i < tso.length; ++i) { + rv[nTokens + i] = tso[i]; + } + return rv; + } + + /** + * @param array + * @return + */ + private String coligate(String[] array) { + StringBuffer sb = new StringBuffer(128); + for (int i = 0; i < array.length; ++i) { + sb.append(' '); + sb.append(array[i]); + } + String ca = sb.toString(); + return ca; + } + + /** + * @param launcher + * @return + */ + private String[] setEnvironment(CommandLauncher launcher) { + // Set the environmennt, some scripts may need the CWD var to be set. + Properties props = launcher.getEnvironment(); + props.put("CWD", fWorkingDirectory.toOSString()); //$NON-NLS-1$ + props.put("PWD", fWorkingDirectory.toOSString()); //$NON-NLS-1$ + String[] env = null; + ArrayList envList = new ArrayList(); + Enumeration names = props.propertyNames(); + if (names != null) { + while (names.hasMoreElements()) { + String key = (String) names.nextElement(); + envList.add(key + "=" + props.getProperty(key)); //$NON-NLS-1$ + } + env = (String[]) envList.toArray(new String[envList.size()]); + } + return env; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IMarkerGenerator#addMarker(org.eclipse.core.resources.IResource, int, java.lang.String, int, java.lang.String) + */ + public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) { + try { + IMarker[] cur = file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE); + /* + * Try to find matching markers and don't put in duplicates + */ + if ((cur != null) && (cur.length > 0)) { + for (int i = 0; i < cur.length; i++) { + int line = ((Integer) cur[i].getAttribute(IMarker.LOCATION)).intValue(); + int sev = ((Integer) cur[i].getAttribute(IMarker.SEVERITY)).intValue(); + String mesg = (String) cur[i].getAttribute(IMarker.MESSAGE); + if (line == lineNumber && sev == mapMarkerSeverity(severity) && mesg.equals(errorDesc)) { + return; + } + } + } + + IMarker marker = file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER); + marker.setAttribute(IMarker.LOCATION, lineNumber); + marker.setAttribute(IMarker.MESSAGE, errorDesc); + marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(severity)); + marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); + marker.setAttribute(IMarker.CHAR_START, -1); + marker.setAttribute(IMarker.CHAR_END, -1); + if (errorVar != null) { + marker.setAttribute(ICModelMarker.C_MODEL_MARKER_VARIABLE, errorVar); + } + } + catch (CoreException e) { + CCorePlugin.log(e.getStatus()); + } + } + + int mapMarkerSeverity(int severity) { + switch (severity) { + case SEVERITY_ERROR_BUILD : + case SEVERITY_ERROR_RESOURCE : + return IMarker.SEVERITY_ERROR; + case SEVERITY_INFO : + return IMarker.SEVERITY_INFO; + case SEVERITY_WARNING : + return IMarker.SEVERITY_WARNING; + } + return IMarker.SEVERITY_ERROR; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java new file mode 100644 index 00000000000..c4355b99572 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java @@ -0,0 +1,31 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig; + +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; + +/** + * Common work required by the scanner info console parsers + * + * @author vhirsl + */ +public interface IScannerInfoConsoleParserUtility { + // Problem marker related + public void generateMarker(IResource file, int lineNumber, String desc, int severity, String varName); + public boolean reportProblems(); + // File path management + public void changeMakeDirectory(String dir, int dirLevel, boolean enterDir); + public IFile findFile(String fileName); + public List translateRelativePaths(IFile file, String fileName, List includes); +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java new file mode 100644 index 00000000000..b4a3ee9fb46 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java @@ -0,0 +1,337 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.make.internal.core.scannerconfig; + +import java.util.Map; + +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.core.runtime.Status; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature; + +/** + * Creates a ScannerConfigBuilderInfo variant + * @author vhirsl + */ +public class ScannerConfigInfoFactory { + private static final String PREFIX = MakeCorePlugin.getUniqueIdentifier(); + + static final String BUILD_SCANNER_CONFIG_ENABLED = PREFIX + ".ScannerConfigDiscoveryEnabled"; //$NON-NLS-1$ + static final String MAKE_BUILDER_PARSER_ENABLED = PREFIX + ".makeBuilderParserEnabled"; //$NON-NLS-1$ + static final String MAKE_BUILDER_PARSER_ID = PREFIX + ".makeBuilderParserId"; //$NON-NLS-1$ + static final String ESI_PROVIDER_COMMAND_ENABLED = PREFIX + ".esiProviderCommandEnabled"; //$NON-NLS-1$ + static final String USE_DEFAULT_ESI_PROVIDER_CMD = PREFIX + ".useDefaultESIProviderCmd"; //$NON-NLS-1$ + static final String ESI_PROVIDER_COMMAND = PREFIX + ".esiProviderCommand"; //$NON-NLS-1$ + static final String ESI_PROVIDER_ARGUMENTS = PREFIX + ".esiProviderArguments"; //$NON-NLS-1$ + static final String ESI_PROVIDER_PARSER_ID = PREFIX + ".esiProviderParserId"; //$NON-NLS-1$ + + /** + * + * @author vhirsl + */ + private abstract static class Store implements IScannerConfigBuilderInfo { + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isAutoDiscoveryEnabled() + */ + public boolean isAutoDiscoveryEnabled() { + return getBoolean(BUILD_SCANNER_CONFIG_ENABLED); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setAutoDiscoveryEnabled(boolean) + */ + public void setAutoDiscoveryEnabled(boolean enabled) throws CoreException { + putString(BUILD_SCANNER_CONFIG_ENABLED, Boolean.toString(enabled)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isMakeBuilderConsoleParserEnabled() + */ + public boolean isMakeBuilderConsoleParserEnabled() { + if (getString(MAKE_BUILDER_PARSER_ENABLED) == null || + getString(MAKE_BUILDER_PARSER_ENABLED).length() == 0) { // if no property then default to true + return true; + } + return getBoolean(MAKE_BUILDER_PARSER_ENABLED); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setMakeBuilderConsoleParserEnabled(boolean) + */ + public void setMakeBuilderConsoleParserEnabled(boolean enabled) throws CoreException { + putString(MAKE_BUILDER_PARSER_ENABLED, Boolean.toString(enabled)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getMakeBuilderConsoleParserId() + */ + public String getMakeBuilderConsoleParserId() { + String parserId = getString(MAKE_BUILDER_PARSER_ID); + if (parserId == null || parserId.length() == 0) { + String[] parserIds = MakeCorePlugin.getDefault(). + getScannerInfoConsoleParserIds("makeBuilder"); //$NON-NLS-1$ + // the default is the first one in the registry + parserId = parserIds[0]; + } + return parserId; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setMakeBuilderConsoleParserId(java.lang.String) + */ + public void setMakeBuilderConsoleParserId(String parserId) throws CoreException { + putString(MAKE_BUILDER_PARSER_ID, parserId); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isESIProviderCommandEnabled() + */ + public boolean isESIProviderCommandEnabled() { + if (getString(ESI_PROVIDER_COMMAND_ENABLED) == null || + getString(ESI_PROVIDER_COMMAND_ENABLED).length() == 0) { // if no property then default to true + return true; + } + return getBoolean(ESI_PROVIDER_COMMAND_ENABLED); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderCommandEnabled(boolean) + */ + public void setESIProviderCommandEnabled(boolean enabled) throws CoreException { + putString(ESI_PROVIDER_COMMAND_ENABLED, Boolean.toString(enabled)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#isDefaultESIProviderCmd() + */ + public boolean isDefaultESIProviderCmd() { + if (getString(USE_DEFAULT_ESI_PROVIDER_CMD) == null || + getString(USE_DEFAULT_ESI_PROVIDER_CMD).length() == 0) { // if no property then default to true + return true; + } + return getBoolean(USE_DEFAULT_ESI_PROVIDER_CMD); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setUseDefaultESIProviderCmd(boolean) + */ + public void setUseDefaultESIProviderCmd(boolean on) throws CoreException { + putString(USE_DEFAULT_ESI_PROVIDER_CMD, Boolean.toString(on)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getESIProviderCommand() + */ + public IPath getESIProviderCommand() { + if (isDefaultESIProviderCmd()) { + String command = getESIProviderParameter("defaultCommand"); //$NON-NLS-1$ + if (command == null) { + return new Path("gcc"); //$NON-NLS-1$ + } + return new Path(command); + } + return new Path(getString(ESI_PROVIDER_COMMAND)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderCommand(org.eclipse.core.runtime.IPath) + */ + public void setESIProviderCommand(IPath command) throws CoreException { + putString(ESI_PROVIDER_COMMAND, command.toString()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getESIProviderArguments() + */ + public String getESIProviderArguments() { + if (isDefaultESIProviderCmd()) { + String attributes = getESIProviderParameter("defaultAttributes"); //$NON-NLS-1$ + if (attributes == null) { + attributes = "-c -v"; //$NON-NLS-1$ + } + return attributes; + } + return getString(ESI_PROVIDER_ARGUMENTS); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderArguments(java.lang.String) + */ + public void setESIProviderArguments(String args) throws CoreException { + putString(ESI_PROVIDER_ARGUMENTS, args); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getESIProviderConsoleParserId() + */ + public String getESIProviderConsoleParserId() { + String parserId = getString(ESI_PROVIDER_PARSER_ID); + if (parserId == null || parserId.length() == 0) { + String[] parserIds = MakeCorePlugin.getDefault(). + getScannerInfoConsoleParserIds("externalScannerInfoProvider"); //$NON-NLS-1$ + // the default is the first one in the registry + parserId = parserIds[0]; + } + return parserId; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderConsoleParserId(java.lang.String) + */ + public void setESIProviderConsoleParserId(String parserId) throws CoreException { + putString(ESI_PROVIDER_PARSER_ID, parserId); + } + + protected boolean getBoolean(String property) { + return Boolean.valueOf(getString(property)).booleanValue(); + } + + protected abstract String getBuilderID(); + protected abstract String getString(String property); + protected abstract void putString(String name, String value) throws CoreException; + + protected String getESIProviderParameter(String name) { + IExtension extension = + Platform.getPluginRegistry().getExtension( + MakeCorePlugin.getUniqueIdentifier(), + MakeCorePlugin.EXTERNAL_SI_PROVIDER_SIMPLE_ID, + // TODO VMIR make this configurable + MakeCorePlugin.DEFAULT_EXTERNAL_SI_PROVIDER_ID); + if (extension == null) + return null; + IConfigurationElement[] configs = extension.getConfigurationElements(); + if (configs.length == 0) + return null; + IConfigurationElement[] runElement = configs[0].getChildren("run"); //$NON-NLS-1$ + IConfigurationElement[] paramElement = runElement[0].getChildren("parameter"); //$NON-NLS-1$ + for (int i = 0; i < paramElement.length; i++) { + if (paramElement[i].getAttribute("name").equals(name)) { //$NON-NLS-1$ + return paramElement[i].getAttribute("value"); //$NON-NLS-1$ + } + } + return null; + } + } + + private static class Preference extends Store { + private Preferences prefs; + private String builderID; + private boolean useDefaults; + + Preference(Preferences prefs, String builderID, boolean useDefaults) { + this.prefs = prefs; + this.builderID = builderID; + this.useDefaults = useDefaults; + } + + protected void putString(String name, String value) { + if (useDefaults) { + prefs.setDefault(name, value); + } else { + prefs.setValue(name, value); + } + } + + protected String getString(String property) { + if (useDefaults) { + return prefs.getDefaultString(property); + } + return prefs.getString(property); + } + + protected String getBuilderID() { + return builderID; + } + } + + private static class BuildProperty extends Store { + private IProject project; + private String builderID; + private Map args; + + BuildProperty(IProject project, String builderID) throws CoreException { + this.project = project; + this.builderID = builderID; + ICommand builder = ScannerConfigNature.getBuildSpec(project, builderID); + if (builder == null) { + throw new CoreException(new Status(IStatus.ERROR, + MakeCorePlugin.getUniqueIdentifier(), -1, + MakeCorePlugin.getResourceString("ScannerConfigInfoFactory.Missing_Builder")//$NON-NLS-1$ + + builderID, null)); + } + args = builder.getArguments(); + } + + protected void putString(String name, String value) throws CoreException { + String curValue = (String) args.get(name); + if (curValue != null && curValue.equals(value)) { + return; + } + ICommand builder = ScannerConfigNature.getBuildSpec(project, builderID); + args.put(name, value); + builder.setArguments(args); + project.setDescription(project.getDescription(), null); + } + + protected String getString(String name) { + String value = (String) args.get(name); + return value == null ? "" : value; //$NON-NLS-1$ + } + + protected String getBuilderID() { + return builderID; + } + } + + private static class BuildArguments extends Store { + private Map args; + private String builderID; + + BuildArguments(Map args, String builderID) { + this.args = args; + this.builderID = builderID; + } + + protected void putString(String name, String value) { + args.put(name, value); + } + + protected String getString(String name) { + return (String) args.get(name); + } + + protected String getBuilderID() { + return builderID; + } + } + + public static IScannerConfigBuilderInfo create(Preferences prefs, String builderID, boolean useDefaults) { + return new ScannerConfigInfoFactory.Preference(prefs, builderID, useDefaults); + } + + public static IScannerConfigBuilderInfo create(IProject project, String builderID) throws CoreException { + return new ScannerConfigInfoFactory.BuildProperty(project, builderID); + } + + public static IScannerConfigBuilderInfo create(Map args, String builderID) { + return new ScannerConfigInfoFactory.BuildArguments(args, builderID); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java new file mode 100644 index 00000000000..1845b4a1633 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java @@ -0,0 +1,343 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.cdt.make.core.MakeScannerInfo; +import org.eclipse.cdt.make.core.MakeProjectNature; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil; + + +/** + * Singleton object that collects scanner config updates from ScannerInfoParser + * and updates scanner config when the project's build is done. + * + * @author vhirsl + */ +public class ScannerInfoCollector { + + // Singleton + private static ScannerInfoCollector instance = new ScannerInfoCollector(); + private Map discoveredIncludes; + private Map discoveredSymbols; + private Map discoveredTSO; // target specific options + // cumulative values + private Map sumDiscoveredIncludes; + private Map sumDiscoveredSymbols; + private Map sumDiscoveredTSO; // target specific options + + private IProject currentProject; // project being built + + private ScannerInfoCollector() { + discoveredIncludes = new HashMap(); + discoveredSymbols = new HashMap(); + discoveredTSO = new HashMap(); + + sumDiscoveredIncludes = new HashMap(); + sumDiscoveredSymbols = new HashMap(); + sumDiscoveredTSO = new HashMap(); + } + + public static ScannerInfoCollector getInstance() { + return instance; + } + + /** + * Published method to receive per file contributions to ScannerInfo + * + * @param resource + * @param includes + * @param symbols + * @param targetSpecificOptions + */ + public synchronized void contributeToScannerConfig(IResource resource, List includes, List symbols, List targetSpecificOptions) { + IProject project; + if (resource == null || (project = resource.getProject()) == null) { + // TODO VMIR create a log + return; + } + try { + if (project.hasNature(MakeProjectNature.NATURE_ID) && // limits to StandardMake projects + (project.hasNature(CProjectNature.C_NATURE_ID) || + project.hasNature(CCProjectNature.CC_NATURE_ID))) { + + String projectName = project.getName(); + contribute(projectName, discoveredIncludes, includes); + contribute(projectName, discoveredSymbols, symbols); + contribute(projectName, discoveredTSO, targetSpecificOptions); + } + } + catch (CoreException e) { + e.printStackTrace(); + } + } + + /** + * @param project + * @param discovered symbols | includes | targetSpecificOptions + * @param delta symbols | includes | targetSpecificOptions + * @return true if there is a change in discovered symbols | includes | targetSpecificOptions + */ + private boolean contribute(String projectName, Map discovered, List delta) { + if (delta == null || delta.isEmpty()) + return false; + List projectDiscovered = (List) discovered.get(projectName); + if (projectDiscovered == null) { + projectDiscovered = new ArrayList(delta); + discovered.put(projectName, projectDiscovered); + return true; + } + boolean added = false; + for (Iterator i = delta.iterator(); i.hasNext(); ) { + String item = (String) i.next(); + if (!projectDiscovered.contains(item)) { + added |= projectDiscovered.add(item); + } + } + return added; + } + + /** + * @param project + * @param monitor + */ + private void updateScannerConfig(IProject project, IProgressMonitor monitor) { + IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project); + monitor.beginTask(MakeCorePlugin.getResourceString("ScannerInfoCollector.Processing"), 100); + if (provider != null) { + IScannerInfo scanInfo = provider.getScannerInformation(project); + if (scanInfo != null) { + if (scanInfo instanceof MakeScannerInfo) { + MakeScannerInfo makeScanInfo = (MakeScannerInfo)scanInfo; + String projectName = project.getName(); + + monitor.subTask(MakeCorePlugin.getResourceString("ScannerInfoCollector.Processing")); + if (scannerConfigNeedsUpdate(makeScanInfo, projectName)) { + monitor.worked(50); + monitor.subTask(MakeCorePlugin.getResourceString("ScannerInfoCollector.Updating") + projectName); + + try { + // update scanner configuration + makeScanInfo.update(); + monitor.worked(50); + } catch (CoreException e) { + // TODO : VMIR create a marker? + MakeCorePlugin.log(e); + } + } + } + } + } + monitor.done(); + } + + /** + * Compare discovered include paths and symbol definitions with the ones from scanInfo. + * @param scanInfo + * @param projectName + * @return + */ + private boolean scannerConfigNeedsUpdate(MakeScannerInfo makeScanInfo, String projectName) { + // TODO : VMIR to implement other variants + List includes = (List) discoveredIncludes.get(projectName); + List dSymbols = (List) discoveredSymbols.get(projectName); + if (includes == null && dSymbols == null) + return false; + Set symbols = new HashSet(dSymbols); + + // Step 1. Add discovered scanner config to the existing discovered scanner config + // add the includes from the latest discovery + boolean addedIncludes = false; + List sumIncludes = (List) sumDiscoveredIncludes.get(projectName); + if (sumIncludes == null) { + sumIncludes = new ArrayList(includes); + sumDiscoveredIncludes.put(projectName, sumIncludes); + addedIncludes = true; + } + else { + for (Iterator i = includes.iterator(); i.hasNext(); ) { + String include = (String) i.next(); + if (!sumIncludes.contains(include)) { + addedIncludes |= sumIncludes.add(include); + } + } + } + // try to translate cygpaths to absolute paths + List finalSumIncludes = translateIncludePaths(sumIncludes); + + // add the symbols from the latest discovery + boolean addedSymbols = false; + Map sumSymbols = (Map) sumDiscoveredSymbols.get(projectName); + if (sumSymbols == null) { + sumSymbols = new HashMap(); + sumDiscoveredSymbols.put(projectName, sumSymbols); + } + addedSymbols = ScannerConfigUtil.scAddSymbolsSet2SymbolEntryMap(sumSymbols, symbols, false); + + // Step 2. Get project's scanner config + String[] persistedIncludes = makeScanInfo.getIncludePaths(); + Map persistedSymbols = makeScanInfo.getDefinedSymbols(); + + // TODO VMIR this is likely to change when new UI is introduced + // Step 3. Merge scanner config from steps 1 and 2 + List candidateIncludes = new ArrayList(Arrays.asList(persistedIncludes)); + for (Iterator i = finalSumIncludes.iterator(); i.hasNext(); ) { + String include = (String) i.next(); + if (!candidateIncludes.contains(include)) { + addedIncludes |= candidateIncludes.add(include); + } + } + Map candidateSymbols = new HashMap(sumSymbols); + Set persistedSymbolsSet = ScannerConfigUtil.scSymbolsMap2Set(persistedSymbols); + addedSymbols |= ScannerConfigUtil.scAddSymbolsSet2SymbolEntryMap(candidateSymbols, persistedSymbolsSet, true); + + // Step 4. Set resulting scanner config + makeScanInfo.setIncludePaths((String[])candidateIncludes.toArray(new String[candidateIncludes.size()])); + makeScanInfo.setPreprocessorSymbols((String[])ScannerConfigUtil. + scSymbolsSymbolEntryMap2Set(candidateSymbols).toArray(new String[candidateSymbols.size()])); + + // invalidate discovered include paths and symbol definitions + discoveredIncludes.put(projectName, null); + discoveredSymbols.put(projectName, null); + + return (addedIncludes | addedSymbols); + } + + /** + * @param sumIncludes + * @return + */ + private List translateIncludePaths(List sumIncludes) { + List translatedIncludePaths = new ArrayList(); + for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) { + String includePath = (String) i.next(); + IPath realPath = new Path(includePath); + if (!realPath.toFile().exists()) { + String translatedPath = new CygpathTranslator(currentProject, includePath).run(); + if (!translatedPath.equals(includePath)) { + // Check if the translated path exists + IPath transPath = new Path(translatedPath); + if (transPath.toFile().exists()) { + translatedIncludePaths.add(translatedPath); + } + else { + // TODO VMIR create problem marker + // TODO VMIR for now add even if it does not exist + translatedIncludePaths.add(translatedPath); + } + } + else { + // TODO VMIR for now add even if it does not exist + translatedIncludePaths.add(translatedPath); + } + } + else { + translatedIncludePaths.add(includePath); + } + } + return translatedIncludePaths; + } + + /** + * Call ESI provider to get scanner info + * + * @param project + * @param tso + * @param monitor + */ + private void getProviderScannerInfo(final IProject project, + final List tso, + final IProgressMonitor monitor) { + // get IScannerConfigBuilderInfo + IScannerConfigBuilderInfo info; + try { + info = MakeCorePlugin.createScannerConfigBuildInfo( + project, ScannerConfigBuilder.BUILDER_ID); + } + catch (CoreException e) { + MakeCorePlugin.log(e); + info = MakeCorePlugin.createScannerConfigBuildInfo( + MakeCorePlugin.getDefault().getPluginPreferences(), + ScannerConfigBuilder.BUILDER_ID, false); + } + if (info.isESIProviderCommandEnabled()) { + final IScannerConfigBuilderInfo buildInfo = info; + final IExternalScannerInfoProvider esiProvider = MakeCorePlugin.getDefault(). + getExternalScannerInfoProvider(MakeCorePlugin.DEFAULT_EXTERNAL_SI_PROVIDER_ID); + if (esiProvider != null) { + ISafeRunnable runnable = new ISafeRunnable() { + public void run() { + String[] tsoArray; + if (tso == null) { + tsoArray = new String[0]; + } + else { + tsoArray = (String[])tso.toArray(new String[tso.size()]); + } + esiProvider.invokeProvider(monitor, project, buildInfo, tsoArray); + } + + public void handleException(Throwable exception) { + MakeCorePlugin.log(exception); + } + }; + Platform.run(runnable); + } + } + } + + /** + * @param project + * @param monitor + */ + public synchronized void updateScannerConfiguration(IProject project, IProgressMonitor monitor) { + currentProject = project; + String projectName = project.getName(); + // check TSO for the project + monitor.beginTask("", 100); //$NON-NLS-1$ + getProviderScannerInfo(project, (List) discoveredTSO.get(projectName), new SubProgressMonitor(monitor, 60)); + updateScannerConfig(project, new SubProgressMonitor(monitor, 40)); + + // delete discovered scanner config + discoveredIncludes.put(projectName, null); + discoveredSymbols.put(projectName, null); + discoveredTSO.put(projectName, null); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java new file mode 100644 index 00000000000..eb04a0499af --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java @@ -0,0 +1,95 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig; + +import java.io.OutputStream; + +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerInfoConsoleParserUtility; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; + +/** + * A factory that creates a ConsoleOutputStreamSniffer, + * ScannerInfoConsoleParser and optionally a ScannerInfoConsoleParserUtility. + * + * @author vhirsl + */ +public class ScannerInfoConsoleParserFactory { + + /** + * Creates a ConsoleOutputStreamSniffer, make builder scanner info console parser + * and a utility. + * + * @param outputStream + * @param currentProject + * @param markerGenerator + * @param scBuildInfo + * @return OutputStream + */ + public static OutputStream getESIProviderOutputSniffer(OutputStream outputStream, + IProject currentProject, + IScannerConfigBuilderInfo scBuildInfo) { + if (scBuildInfo.isESIProviderCommandEnabled()) { + // get the ESIProvider console parser + IScannerInfoConsoleParser clParser = MakeCorePlugin.getDefault(). + getScannerInfoConsoleParser(scBuildInfo.getESIProviderConsoleParserId()); + // initialize it with the utility + clParser.startup(currentProject, null /*new ScannerInfoConsoleParserUtility( + currentProject, null, markerGenerator)*/); + // create an output stream sniffer + return new ConsoleOutputStreamSniffer(outputStream, new + IScannerInfoConsoleParser[] {clParser}); + } + return outputStream; + } + + /** + * Creates a ConsoleOutputStreamSniffer, ESI provider scanner info console parser + * and a utility. + * + * @param outputStream + * @param currentProject + * @param workingDirectory + * @param markerGenerator + * @return OutputStream + */ + public static OutputStream getMakeBuilderOutputSniffer(OutputStream outputStream, + IProject currentProject, + IPath workingDirectory, + IMarkerGenerator markerGenerator) { + try { + // get the SC builder settings + IScannerConfigBuilderInfo scBuildInfo = MakeCorePlugin. + createScannerConfigBuildInfo(currentProject, ScannerConfigBuilder.BUILDER_ID); + if (scBuildInfo.isMakeBuilderConsoleParserEnabled()) { + // get the make builder console parser + IScannerInfoConsoleParser clParser = MakeCorePlugin.getDefault(). + getScannerInfoConsoleParser(scBuildInfo.getMakeBuilderConsoleParserId()); + // initialize it with the utility + clParser.startup(currentProject, new ScannerInfoConsoleParserUtility( + currentProject, workingDirectory, markerGenerator)); + // create an output stream sniffer + return new ConsoleOutputStreamSniffer(outputStream, new + IScannerInfoConsoleParser[] {clParser}); + } + } + catch (CoreException e) { + MakeCorePlugin.log(e.getStatus()); + } + return outputStream; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java new file mode 100644 index 00000000000..e207339b595 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java @@ -0,0 +1,57 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * GCC related utility class + * + * @author vhirsl + */ +public class GCCScannerConfigUtil { + public static final String CPP_SPECS_FILE = "specs.cpp"; //$NON-NLS-1$ + public static final String C_SPECS_FILE = "specs.c"; //$NON-NLS-1$ + + public static void createSpecs() { + IPath path = MakeCorePlugin.getWorkingDirectory(); + try { + createSpecsFile(path, CPP_SPECS_FILE); + createSpecsFile(path, C_SPECS_FILE); + } catch (CoreException e) { + MakeCorePlugin.log(e); + } + } + + private static void createSpecsFile(IPath path, String fileName) throws CoreException { + IPath specs = path.append(fileName); + File specsFile = specs.toFile(); + if (!specsFile.exists()) { + try { + FileOutputStream file = new FileOutputStream(specsFile); + file.write('\n'); + file.close(); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, + MakeCorePlugin.getDefault().getDescriptor().getUniqueIdentifier(), -1, + MakeCorePlugin.getResourceString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$ + } + } + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java new file mode 100644 index 00000000000..571603feb90 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java @@ -0,0 +1,203 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import java.util.StringTokenizer; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; +import org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Parses gcc and g++ output for -I and -D parameters. + * + * @author vhirsl + */ +public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { + + private IProject fProject = null; + private IScannerInfoConsoleParserUtility fUtil = null; + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject) + */ + public void startup(IProject project, IScannerInfoConsoleParserUtility util) { + fProject = project; + fUtil = util; + + IPath workingDirectory = MakeCorePlugin.getWorkingDirectory(); + String targetFile = "dummy"; //$NON-NLS-1$ + try { + if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { + targetFile = GCCScannerConfigUtil.CPP_SPECS_FILE; + } + else if (project.hasNature(CProjectNature.C_NATURE_ID)) { + targetFile = GCCScannerConfigUtil.C_SPECS_FILE; + } + } catch (CoreException e) { + //TODO VMIR better error handling + MakeCorePlugin.log(e.getStatus()); + } + IPath path2File = workingDirectory.append(targetFile); + if (!path2File.toFile().exists()) { + GCCScannerConfigUtil.createSpecs(); + } + List targetSpecificOptions = new ArrayList(); + targetSpecificOptions.add(targetFile); + + ScannerInfoCollector.getInstance(). + contributeToScannerConfig(project, null, null, targetSpecificOptions); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.ScannerInfoConsoleParserUtility#processLine(java.lang.String) + */ + public boolean processLine(String line) { + boolean rc = false; + // make\[[0-9]*\]: error_desc + int firstColon= line.indexOf(':'); + if (firstColon != -1 && line.startsWith("make")) { //$NON-NLS-1$ + boolean enter = false; + String msg = line.substring(firstColon + 1).trim(); + if ((enter = msg.startsWith("Entering directory")) || //$NON-NLS-1$ + (msg.startsWith("Leaving directory"))) { //$NON-NLS-1$ + int s = msg.indexOf('`'); + int e = msg.indexOf('\''); + if (s != -1 && e != -1) { + String dir = msg.substring(s+1, e); + fUtil.changeMakeDirectory(dir, getDirectoryLevel(line), enter); + return rc; + } + } + } + // Known patterns: + // (a) gcc|g++ ... -Dxxx -Iyyy ... + StringTokenizer scanner = new StringTokenizer(line); + if (scanner.countTokens() <= 1) + return false; + String token = scanner.nextToken(); + if (token.equalsIgnoreCase("gcc") || token.equalsIgnoreCase("g++")) {//$NON-NLS-1$ //$NON-NLS-2$ + // Recognized gcc or g++ compiler invocation + List includes = new ArrayList(); + List symbols = new ArrayList(); + List targetSpecificOptions = new ArrayList(); + + rc = true; + String fileName = null; + String desc = "Found"; + while (scanner.hasMoreTokens()) { + token = scanner.nextToken(); + if (token.startsWith("-D")) {//$NON-NLS-1$ + String symbol = token.substring(2); + if (!symbols.contains(symbol)) + symbols.add(symbol); + } + else if (token.startsWith("-I")) {//$NON-NLS-1$ + String iPath = token.substring(2); + if (!includes.contains(iPath)) + includes.add(iPath); + } + else if (token.equals("-mwin32") || //$NON-NLS-1$ + token.equals("-mno-win32") || //$NON-NLS-1$ + token.equals("-mno-cygwin") || //$NON-NLS-1$ + token.equals("-ansi") || //$NON-NLS-1$ + token.equals("-nostdinc") || //$NON-NLS-1$ + token.equals("-posix") || //$NON-NLS-1$ + token.equals("-pthread")) { //$NON-NLS-1$ + if (!targetSpecificOptions.contains(token)) + targetSpecificOptions.add(token); + } + else { + String possibleFileName = token.toLowerCase(); + if (possibleFileName.startsWith("..") || //$NON-NLS-1$ + possibleFileName.startsWith(".") || //$NON-NLS-1$ + possibleFileName.startsWith("/") || //$NON-NLS-1$ + possibleFileName.startsWith("$(") || //$NON-NLS-1$ + possibleFileName.endsWith(".c") || //$NON-NLS-1$ + possibleFileName.endsWith(".cpp") || //$NON-NLS-1$ + possibleFileName.endsWith(".cc") || //$NON-NLS-1$ + possibleFileName.endsWith(".cxx")) { //$NON-NLS-1$ + + fileName = token; + } + } + } + + IProject project = fProject; + IFile file = null; + if (includes.size() > 0) { + if (fileName != null) { + file = fUtil.findFile(fileName); + if (file != null) { + project = file.getProject(); + includes = fUtil.translateRelativePaths(file, fileName, includes); + } + } + else { + fUtil.generateMarker(fProject, -1, "Unable to find file name: " + line, + IMarkerGenerator.SEVERITY_ERROR_RESOURCE, null); + } + } + // Contribute discovered includes and symbols to the ScannerInfoCollector + ScannerInfoCollector.getInstance(). + contributeToScannerConfig(project, includes, symbols, targetSpecificOptions); + + // TODO : VMIR remove when debugging is done + int severity = IMarkerGenerator.SEVERITY_INFO; + + for (Iterator i = includes.iterator(); i.hasNext(); ) { + String iPath = (String)i.next(); + fUtil.generateMarker(file, -1, "Found an include path: "+iPath, severity, iPath); + } + for (Iterator i = symbols.iterator(); i.hasNext(); ) { + String symbol = (String)i.next(); + fUtil.generateMarker(file, -1, "Found a symbol definition: "+symbol, severity, symbol); + } + + } + return rc; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#shutdown() + */ + public void shutdown() { + if (fUtil != null) { + fUtil.reportProblems(); + } + } + + private int getDirectoryLevel(String line) { + int s = line.indexOf('['); + int num = 0; + if (s != -1) { + int e = line.indexOf(']'); + String number = line.substring(s + 1, e).trim(); + try { + num = Integer.parseInt(number); + } catch (NumberFormatException exc) { + } + } + return num; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java new file mode 100644 index 00000000000..96a9a929fd7 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java @@ -0,0 +1,109 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; +import org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility; +import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector; +import org.eclipse.core.resources.IProject; + +/** + * Parses output of gcc -c -v specs.c or + * g++ -c -v specs.cpp + * command + * + * @author vhirsl + */ +public class GCCSpecsConsoleParser implements IScannerInfoConsoleParser { + private final int STATE_BEGIN = 0; + private final int STATE_SPECS_STARTED = 1; + private final int STATE_INCLUDES_STARTED = 2; + + private IProject project = null; + private IScannerInfoConsoleParserUtility util = null; + + private int state = STATE_BEGIN; + private List symbols = new ArrayList(); + private List includes = new ArrayList(); + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#initialize(org.eclipse.core.resources.IProject, org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility) + */ + public void startup(IProject project, IScannerInfoConsoleParserUtility util) { + this.project = project; + this.util = util; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParser#processLine(java.lang.String) + */ + public boolean processLine(String line) { + boolean rc = false; + // Known patterns: + // (a) gcc|g++ ... -Dxxx -Iyyy ... + switch (state) { + case STATE_BEGIN: + if (line.startsWith("Reading specs from")) { //$NON-NLS-1$ + state = STATE_SPECS_STARTED; + } + return rc; + case STATE_SPECS_STARTED: + if (line.indexOf("-D") != -1) { //$NON-NLS-1$ + // line contains -Ds, extract them + StringTokenizer scanner = new StringTokenizer(line); + if (scanner.countTokens() <= 1) + return rc; + for (String token = scanner.nextToken(); scanner.hasMoreTokens(); token = scanner.nextToken()) { + if (token.startsWith("-D")) { //$NON-NLS-1$ + String symbol = token.substring(2); + if (!symbols.contains(symbol)) + symbols.add(symbol); + } + } + } + // now get all the includes + if (line.startsWith("#include") && line.endsWith("search starts here:")) { //$NON-NLS-1$ //$NON-NLS-2$ + state = STATE_INCLUDES_STARTED; + } + return rc; + case STATE_INCLUDES_STARTED: + if (line.startsWith("#include") && line.endsWith("search starts here:")) { //$NON-NLS-1$ //$NON-NLS-2$ + state = STATE_INCLUDES_STARTED; + } + else if (line.startsWith("End of search list.")) { //$NON-NLS-1$ + state = STATE_BEGIN; + break; + } + else { + if (!includes.contains(line)) + includes.add(line); + } + return rc; + } + + ScannerInfoCollector.getInstance().contributeToScannerConfig(project, includes, symbols, null); + + return rc; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParser#shutdown() + */ + public void shutdown() { + if (util != null) { + util.reportProblems(); + } + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java new file mode 100644 index 00000000000..8720435c018 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java @@ -0,0 +1,111 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Properties; + +import org.eclipse.cdt.core.CommandLauncher; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; + +/** + * Executes external command 'cygpath' to translate cygpaths to absolute paths. + * + * @author vhirsl + */ +public class CygpathTranslator { + IProject project; + private String orgPath; + private String transPath; + + public CygpathTranslator(IProject project, String path) { + this.project = project; + orgPath = path; + } + + public String run() { + ISafeRunnable runnable = new ISafeRunnable() { + public void run() throws Exception { + transPath = platformRun(); + } + + public void handleException(Throwable exception) { + transPath = orgPath; + MakeCorePlugin.log(exception); + } + }; + Platform.run(runnable); + return transPath; + } + + /** + * @return + */ + private String platformRun() { + CommandLauncher launcher = new CommandLauncher(); + launcher.showCommand(false); + + OutputStream output = new ByteArrayOutputStream(); + + Process p = launcher.execute( + new Path("cygpath"), //$NON-NLS-1$ + new String[] {"-m", orgPath}, //$NON-NLS-1$ + new String[0],//setEnvironment(launcher, "c:/"),//$NON-NLS-1$ + project.getLocation()); //$NON-NLS-1$ + if (p != null) { + try { + // Close the input of the Process explicitely. + // We will never write to it. + p.getOutputStream().close(); + } + catch (IOException e) { + } + if (launcher.waitAndRead(output, output) != CommandLauncher.OK) { + String errMsg = launcher.getErrorMessage(); + } + else + return output.toString().trim(); + } + return orgPath; + } + + /** + * @param launcher + * @return + */ + private String[] setEnvironment(CommandLauncher launcher, String dir) { + // Set the environmennt, some scripts may need the CWD var to be set. + IPath workingDirectory = new Path(dir); + Properties props = launcher.getEnvironment(); + props.put("CWD", workingDirectory.toOSString()); //$NON-NLS-1$ + props.put("PWD", workingDirectory.toOSString()); //$NON-NLS-1$ + String[] env = null; + ArrayList envList = new ArrayList(); + Enumeration names = props.propertyNames(); + if (names != null) { + while (names.hasMoreElements()) { + String key = (String) names.nextElement(); + envList.add(key + "=" + props.getProperty(key)); //$NON-NLS-1$ + } + env = (String[]) envList.toArray(new String[envList.size()]); + } + return env; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java new file mode 100644 index 00000000000..8298ff8a560 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java @@ -0,0 +1,95 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * Utility class that handles some Scanner Config specifig collection conversions + * + * @author vhirsl + */ +public final class ScannerConfigUtil { + /** + * Converts a map of symbols to a set + * + * @param symbolsMap + * @return + */ + public static Set scSymbolsMap2Set(Map symbolsMap) { + Set retSymbols = new HashSet(); + Set keys = symbolsMap.keySet(); + for (Iterator i = keys.iterator(); i.hasNext(); ) { + String symbol; + String key = (String) i.next(); + String value = (String) symbolsMap.get(key); + if (value == null || value.length() == 0) { + symbol = key; + } + else { + symbol = key + "=" + value; //$NON-NLS-1 + } + retSymbols.add(symbol); + } + return retSymbols; + } + + /** + * Adds all new discovered symbols/values to the existing ones. + * + * @param sumSymbols - a map of [String, Set] where Set is a SymbolEntry + * @param symbols + * @return boolean + */ + public static boolean scAddSymbolsSet2SymbolEntryMap(Map sumSymbols, Set symbols, boolean preferred) { + boolean rc = false; + for (Iterator i = symbols.iterator(); i.hasNext(); ) { + String symbol = (String) i.next(); + String key; + String value = null; + int index = symbol.indexOf("="); //$NON-NLS-1$ + if (index != -1) { + key = symbol.substring(0, index).trim(); + value = symbol.substring(index + 1).trim(); + } else { + key = symbol.trim(); + } + SymbolEntry sEntry = (SymbolEntry) sumSymbols.get(key); + if (sEntry == null) { + sEntry = new SymbolEntry(key, value, true); + rc = true; + } + else { + rc |= sEntry.add(value, preferred); + } + sumSymbols.put(key, sEntry); + } + return rc; + } + + /** + * Gets all discovered symbols with preferred values + * @param sumSymbols + * @return + */ + public static Set scSymbolsSymbolEntryMap2Set(Map sumSymbols) { + Set symbols = (Set) sumSymbols.entrySet(); + Set rv = new HashSet(symbols.size()); + for (Iterator i = symbols.iterator(); i.hasNext(); ) { + SymbolEntry sEntry = (SymbolEntry) ((Map.Entry) i.next()).getValue(); + rv.add(sEntry.getPreferedRaw()); + } + return rv; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java new file mode 100644 index 00000000000..cfef7a4d07a --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java @@ -0,0 +1,342 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * Implements error reporting mechanism and file/path translation mechanism + * Taken from ErrorParserManager and modified. + * + * @author vhirsl + */ +public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParserUtility { + private IProject fProject; + private IPath fBaseDirectory; + private IMarkerGenerator fMarkerGenerator; + private ArrayList fErrors; + + /* + * For tracking the location of files being compiled + */ + private Map fFilesInProject; + private List fCollectedFiles; + private List fNameConflicts; + private Vector fDirectoryStack; + + public ScannerInfoConsoleParserUtility(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) { + fProject = project; + fMarkerGenerator = markerGenerator; + fBaseDirectory = fProject.getLocation(); + fErrors = new ArrayList(); + + fFilesInProject = new HashMap(); + fCollectedFiles = new ArrayList(); + fNameConflicts = new ArrayList(); + fDirectoryStack = new Vector(); + + collectFiles(fProject, fCollectedFiles); + + for (int i = 0; i < fCollectedFiles.size(); i++) { + IFile curr = (IFile) fCollectedFiles.get(i); + Object existing = fFilesInProject.put(curr.getName(), curr); + if (existing != null) { + fNameConflicts.add(curr.getName()); + } + } + if (workingDirectory != null) { + pushDirectory(workingDirectory); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility#reportProblems() + */ + public boolean reportProblems() { + boolean reset = false; + for (Iterator iter = fErrors.iterator(); iter.hasNext(); ) { + Problem problem = (Problem) iter.next(); + if (problem.severity == IMarkerGenerator.SEVERITY_ERROR_BUILD) { + reset = true; + } + if (problem.file == null) { + fMarkerGenerator.addMarker( + fProject, + problem.lineNumber, + problem.description, + problem.severity, + problem.variableName); + } else { + fMarkerGenerator.addMarker( + problem.file, + problem.lineNumber, + problem.description, + problem.severity, + problem.variableName); + } + } + fErrors.clear(); + return reset; + } + + protected class Problem { + protected IResource file; + protected int lineNumber; + protected String description; + protected int severity; + protected String variableName; + + public Problem(IResource file, int lineNumber, String desciption, int severity, String variableName) { + this.file = file; + this.lineNumber = lineNumber; + this.description = desciption; + this.severity = severity; + this.variableName = variableName; + } + } + + /** + * Called by the console line parsers to generate a problem marker. + */ + public void generateMarker(IResource file, int lineNumber, String desc, int severity, String varName) { + Problem problem = new Problem(file, lineNumber, desc, severity, varName); + fErrors.add(problem); + } + + /** + * Called by the console line parsers to find a file with a given name. + * @param fileName + * @return IFile or null + */ + public IFile findFile(String fileName) { + IFile file = findFilePath(fileName); + if (file == null) { + // Try the project's map. + file = findFileName(fileName); + if (file != null) { + // If there is a conflict then try all files in the project. + if (isConflictingName(fileName)) { + file = null; + // Create a problem marker + generateMarker(fProject, -1, "Ambiguous file path: "+fileName, //$NON-NLS-1$ + IMarkerGenerator.SEVERITY_ERROR_RESOURCE, null); + } + } + } + return file; + } + + /** + * @param filePath + * @return + */ + protected IFile findFilePath(String filePath) { + IPath path = null; + IPath fp = new Path(filePath); + if (fp.isAbsolute()) { + if (fBaseDirectory.isPrefixOf(fp)) { + int segments = fBaseDirectory.matchingFirstSegments(fp); + path = fp.removeFirstSegments(segments); + } else { + path = fp; + } + } else { + path = (IPath) getWorkingDirectory().append(filePath); + } + + IFile file = null; + // The workspace may throw an IllegalArgumentException + // Catch it and the parser should fallback to scan the entire project. + try { + file = findFileInWorkspace(path); + } catch (Exception e) { + } + + // We have to do another try, on Windows for cases like "TEST.C" vs "test.c" + // We use the java.io.File canonical path. + if (file == null || !file.exists()) { + File f = path.toFile(); + try { + String canon = f.getCanonicalPath(); + path = new Path(canon); + file = findFileInWorkspace(path); + } catch (IOException e1) { + } + } + return (file != null && file.exists()) ? file : null; + } + + /** + * @param fileName + * @return + */ + protected IFile findFileName(String fileName) { + IPath path = new Path(fileName); + return (IFile) fFilesInProject.get(path.lastSegment()); + } + + protected IFile findFileInWorkspace(IPath path) { + IFile file = null; + if (path.isAbsolute()) { + IWorkspaceRoot root = fProject.getWorkspace().getRoot(); + file = root.getFileForLocation(path); + // It may be a link resource so we must check it also. + if (file == null) { + IFile[] files = root.findFilesForLocation(path); + for (int i = 0; i < files.length; i++) { + if (files[i].getProject().equals(fProject)) { + file = files[i]; + break; + } + } + } + + } else { + file = fProject.getFile(path); + } + return file; + } + + protected void collectFiles(IContainer parent, List result) { + try { + IResource[] resources = parent.members(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (resource instanceof IFile) { + result.add(resource); + } else if (resource instanceof IContainer) { + collectFiles((IContainer) resource, result); + } + } + } catch (CoreException e) { + MakeCorePlugin.log(e.getStatus()); + } + } + + protected boolean isConflictingName(String fileName) { + IPath path = new Path(fileName); + return fNameConflicts.contains(path.lastSegment()); + } + + protected IPath getWorkingDirectory() { + if (fDirectoryStack.size() != 0) { + return (IPath) fDirectoryStack.lastElement(); + } + // Fallback to the Project Location + // FIXME: if the build did not start in the Project ? + return fBaseDirectory; + } + + protected void pushDirectory(IPath dir) { + if (dir != null) { + IPath pwd = null; + if (fBaseDirectory.isPrefixOf(dir)) { +// int segments = fBaseDirectory.matchingFirstSegments(dir); + pwd = dir.removeFirstSegments(fBaseDirectory.segmentCount()); + } else { + pwd = dir; + } + fDirectoryStack.addElement(pwd); + } + } + + protected IPath popDirectory() { + int i = getDirectoryLevel(); + if (i != 0) { + IPath dir = (IPath) fDirectoryStack.lastElement(); + fDirectoryStack.removeElementAt(i - 1); + return dir; + } + return new Path(""); //$NON-NLS-1$ + } + + protected int getDirectoryLevel() { + return fDirectoryStack.size(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility#changeMakeDirectory(java.lang.String, int, boolean) + */ + public void changeMakeDirectory(String dir, int dirLevel, boolean enterDir) { + if (enterDir) { + /* Sometimes make screws up the output, so + * "leave" events can't be seen. Double-check level + * here. + */ + for (int parseLevel = getDirectoryLevel(); dirLevel < parseLevel; parseLevel = getDirectoryLevel()) { + popDirectory(); + } + pushDirectory(new Path(dir)); + } else { + popDirectory(); + /* Could check to see if they match */ + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility#translateRelativePaths(org.eclipse.core.resources.IFile, java.lang.String, java.util.List) + */ + public List translateRelativePaths(IFile file, String fileName, List includes) { + List translatedIncludes = new ArrayList(includes.size()); + for (Iterator i = includes.iterator(); i.hasNext(); ) { + String include = (String) i.next(); + IPath includePath = new Path(include); + if (!includePath.isAbsolute()) { + // check if it is a relative path + if (include.startsWith("..") || include.startsWith(".")) { //$NON-NLS-1$ //$NON-NLS-2$ + // First try the current working directory + IPath pwd = getWorkingDirectory(); + if (!pwd.isAbsolute()) { + pwd = fProject.getLocation().append(pwd); + } + IPath candidatePath = pwd.append(includePath); + File dir = candidatePath.makeAbsolute().toFile(); + if (dir.exists()) { + translatedIncludes.add(candidatePath.toString()); + break; + } + else { + // try to deduce a current path from the fileName format + if (file != null && fileName != null) { + // TODO VMIR implement heuristics to translate relative path when the working directory is invalid + // For now create a marker to identify prospective cases + generateMarker(file.getProject(), -1, "Ambiguous include path: "+include, //$NON-NLS-1$ + IMarkerGenerator.SEVERITY_WARNING, fileName); + } + } + } + } + // TODO VMIR for now add unresolved paths as well + translatedIncludes.add(include); + } + return translatedIncludes; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java new file mode 100644 index 00000000000..116a541ebd3 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java @@ -0,0 +1,127 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Represents a symbol definition with possible multiple values + * example: + * LOG_LEVEL + * LOG_LEVEL = 2 + * LOG_LEVEL = LOG_BASE + 1 + * @author vhirsl + */ +public class SymbolEntry { + private static final String UNSPECIFIED_VALUE = "1"; //$NON-NLS-1$ + private String name; + private Set values; + private String preferredValue; // the first added value unless otherwise specified + + public SymbolEntry(String name) { + this.name = name; + } + public SymbolEntry(String name, String value) { + this(name); + if (values == null) { + values = new HashSet(); + } + values.add(value); + } + public SymbolEntry(String name, String value, boolean preferred) { + this(name, value); + if (preferred) { + preferredValue = value; + } + } + + public boolean add(String value) { + if (values == null) { + values = new HashSet(); + } + if (preferredValue == null) { + preferredValue = value; + } + return values.add(value); + } + public boolean add(String value, boolean preferred) { + boolean rc = add(value); + if (preferred) { + preferredValue = value; + } + return rc; + } + public boolean addAll(SymbolEntry se) { + return values.addAll(se.values); + } + + public void removeAll() { + values = null; + preferredValue = null; + } + + public String getPrefered() { + return name+ "=" + (preferredValue == null ? UNSPECIFIED_VALUE : preferredValue);//$NON-NLS-1$ + } + public String getPreferedRaw() { + return name + (preferredValue == null ? "" : "=" + preferredValue);//$NON-NLS-1$ //$NON-NLS-2$ + } + + public Set getAllButPreferred() { + if (values == null) + return null; + Set rv = new HashSet(values.size()); + for (Iterator i = values.iterator(); i.hasNext(); ) { + String val = (String) i.next(); + if (val.equals(preferredValue)) + continue; + rv.add(name + "=" + (val == null ? UNSPECIFIED_VALUE : val));//$NON-NLS-1$ + } + return rv; + } + public Set getAllButPreferredRaw() { + if (values == null) + return null; + Set rv = new HashSet(values.size()); + for (Iterator i = values.iterator(); i.hasNext(); ) { + String val = (String) i.next(); + if (val.equals(preferredValue)) + continue; + rv.add(name + (val == null ? "" : "=" + val));//$NON-NLS-1$ //$NON-NLS-2$ + } + return rv; + } + public Set getAll() { + if (values == null) + return null; + Set rv = new HashSet(values.size()); + for (Iterator i = values.iterator(); i.hasNext(); ) { + String val = (String) i.next(); + rv.add(name + "=" + (val == null ? UNSPECIFIED_VALUE : val));//$NON-NLS-1$ + } + return rv; + } + public Set getAllRaw() { + if (values == null) + return null; + Set rv = new HashSet(values.size()); + for (Iterator i = values.iterator(); i.hasNext(); ) { + String val = (String) i.next(); + rv.add(name + (val == null ? "" : "=" + val));//$NON-NLS-1$ //$NON-NLS-2$ + } + return rv; + } + +} \ No newline at end of file diff --git a/build/org.eclipse.cdt.make.ui/plugin.properties b/build/org.eclipse.cdt.make.ui/plugin.properties index 0ba1a5d717f..3eea17795ca 100644 --- a/build/org.eclipse.cdt.make.ui/plugin.properties +++ b/build/org.eclipse.cdt.make.ui/plugin.properties @@ -43,3 +43,5 @@ ActionDefinition.uncomment.description= Uncomment the selected # style comment l MakefileEditor.name=Makefile Editor +PropertyScannerConfig.name=Scanner Configuration Discovery +PreferenceScannerConfig.name=Scanner Configuration Discovery diff --git a/build/org.eclipse.cdt.make.ui/plugin.xml b/build/org.eclipse.cdt.make.ui/plugin.xml index b7394167c68..89ee47c5706 100644 --- a/build/org.eclipse.cdt.make.ui/plugin.xml +++ b/build/org.eclipse.cdt.make.ui/plugin.xml @@ -26,7 +26,6 @@ - + + + + + + + + + + diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties index 2ffbddbf71b..2fed915fa72 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties @@ -191,3 +191,18 @@ LexicalSortingAction.tooltip=Sort LexicalSortingAction.tooltip.on=Do Not Sort LexicalSortingAction.tooltip.off=Sort +# --- ScannerConfigPage --- +ScannerConfigPage.label=Scanner Config +ScannerConfigPage.desc=Scanner configuration discovery settings +ScannerConfigPage.activate=Automate scanner configuration discovery + +ScannerConfigPage.siBuilder.parser.group_label=Build output parser options +ScannerConfigPage.siBuilder.parser.enable.label=Enable build output parser +ScannerConfigPage.siBuilder.parser.label=Make build output parser: +ScannerConfigPage.siProvider.cmd.group_label=Generate scanner info command options +ScannerConfigPage.siProvider.cmd.enable.label=Enable generate scanner info command +ScannerConfigPage.siProvider.cmd.use_default=Use default +ScannerConfigPage.siProvider.cmd.label=Generate scanner info command: +ScannerConfigPage.siProvider.parser.label=Command output parser: + +ScannerConfigPage.siProvider.cmd.error_message=Must enter a 'generate scanner info' command diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java new file mode 100644 index 00000000000..d13cf2a83a5 --- /dev/null +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java @@ -0,0 +1,100 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.ui.preferences; + +import org.eclipse.ui.IWorkbench; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.ui.dialogs.ScannerConfigPage; + +/** + * Scanner config preference page + * @author vhirsl + */ +public class ScannerConfigPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, ICOptionContainer { + + private ScannerConfigPage fScannerConfigPage; + + public ScannerConfigPreferencePage() { + super(); + } + + /** + * @see PreferencePage#init + */ + public void init(IWorkbench workbench) { + } + + /** + * @see PreferencePage#createContents + */ + protected Control createContents(Composite parent) { + fScannerConfigPage = new ScannerConfigPage(true); // add title + // must set container before call to createControl + fScannerConfigPage.setContainer(this); + + fScannerConfigPage.createControl(parent); + return fScannerConfigPage.getControl(); + } + + protected void performDefaults() { + fScannerConfigPage.performDefaults(); + super.performDefaults(); + } + + public boolean performOk() { + try { + fScannerConfigPage.performApply(null); + MakeCorePlugin.getDefault().savePluginPreferences(); + return true; + } + catch (CoreException e) { + return false; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#updateContainer() + */ + public void updateContainer() { + setValid(fScannerConfigPage.isValid()); + setErrorMessage(fScannerConfigPage.getErrorMessage()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getProject() + */ + public IProject getProject() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getPreferences() + */ + public Preferences getPreferences() { + return MakeCorePlugin.getDefault().getPluginPreferences(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferencePage#isValid() + */ + public boolean isValid() { + updateContainer(); + return super.isValid(); + } +} diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java new file mode 100644 index 00000000000..7775ed0469c --- /dev/null +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java @@ -0,0 +1,91 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.internal.ui.properties; + +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.dialogs.PropertyPage; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.ui.dialogs.ScannerConfigPage; + +/** + * Scanner config property page + * @author vhirsl + */ +public class ScannerConfigPropertyPage extends PropertyPage implements ICOptionContainer { + + private ScannerConfigPage fScannerConfigPage; + + public ScannerConfigPropertyPage() { + super(); + } + + /** + * @see PreferencePage#createContents(Composite) + */ + protected Control createContents(Composite parent) { + fScannerConfigPage = new ScannerConfigPage(true); // add title + // must set container before call to createControl + fScannerConfigPage.setContainer(this); + + fScannerConfigPage.createControl(parent); + return fScannerConfigPage.getControl(); + } + + protected void performDefaults() { + fScannerConfigPage.performDefaults(); + super.performDefaults(); + } + + public boolean performOk() { + try { + fScannerConfigPage.performApply(null); + return true; + } + catch (CoreException e) { + return false; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#updateContainer() + */ + public void updateContainer() { + setValid(fScannerConfigPage.isValid()); + setErrorMessage(fScannerConfigPage.getErrorMessage()); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getProject() + */ + public IProject getProject() { + return (IProject) getElement(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getPreferences() + */ + public Preferences getPreferences() { + return MakeCorePlugin.getDefault().getPluginPreferences(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.IPreferencePage#isValid() + */ + public boolean isValid() { + updateContainer(); + return super.isValid(); + } +} diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java new file mode 100644 index 00000000000..b25c1f06f49 --- /dev/null +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java @@ -0,0 +1,482 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.make.ui.dialogs; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.cdt.utils.ui.controls.ControlFactory; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder; +import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature; +import org.eclipse.cdt.make.internal.ui.MakeUIPlugin; + +/** + * Scanner Config settings page + * + * @author vhirsl + */ +public class ScannerConfigPage extends AbstractCOptionPage { + private static final String PREFIX = "ScannerConfigPage"; //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ + private static final String DESC = PREFIX + ".desc"; //$NON-NLS-1$ + private static final String ACTIVATE_AUTO_DISCOVERY = PREFIX + ".activate"; //$NON-NLS-1$ + private static final String SI_BUILD_PARSER_GROUP = PREFIX + ".siBuilder.parser.group_label"; //$NON-NLS-1$ + private static final String ENABLE_SI_BUILD_PARSER = PREFIX + ".siBuilder.parser.enable.label"; //$NON-NLS-1$ + private static final String SI_BUILD_PARSER_LABEL = PREFIX + ".siBuilder.parser.label"; //$NON-NLS-1$ + private static final String SI_PROVIDER_CMD_GROUP = PREFIX + ".siProvider.cmd.group_label"; //$NON-NLS-1$ + private static final String ENABLE_SI_PROVIDER_COMMAND = PREFIX + ".siProvider.cmd.enable.label"; //$NON-NLS-1$ + private static final String SI_PROVIDER_CMD_USE_DEFAULT = PREFIX + ".siProvider.cmd.use_default"; //$NON-NLS-1$ + private static final String SI_PROVIDER_CMD_LABEL = PREFIX + ".siProvider.cmd.label"; //$NON-NLS-1$ + private static final String SI_PROVIDER_PARSER_LABEL = PREFIX + ".siProvider.parser.label"; //$NON-NLS-1$ + private static final String SI_PROVIDER_CMD_ERROR_MESSAGE = PREFIX + ".siProvider.cmd.error_message"; //$NON-NLS-1$ + + private boolean addTitle = false; + + private Button autoDiscovery; + + private Button defESIProviderCommandButton; + private Text esiProviderCommand; + + private Button enableBuilderParserButton; + private Combo makeBuilderSIParserComboBox; + private Button enableProviderCommandButton; + private Combo esiProviderParserComboBox; + + private IScannerConfigBuilderInfo fBuildInfo; + private Map builderParsers = new HashMap(); + private String initialBuilderParserId = null; + private Map providerParsers = new HashMap(); + private String initialProviderParserId = null; + + /** + * Default constructor + */ + public ScannerConfigPage() { + super(MakeUIPlugin.getResourceString(LABEL)); + setDescription(MakeUIPlugin.getResourceString(DESC)); + } + + /** + * @param addTitle + */ + public ScannerConfigPage(boolean addTitle) { + this(); + this.addTitle = addTitle; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#isValid() + */ + public boolean isValid() { + if (!useDefaultESIProviderCmd()) { + String cmd = getSIProviderCommandLine(); + if (cmd == null || cmd.length() == 0) { + return false; + } + } + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#setContainer(org.eclipse.cdt.ui.dialogs.ICOptionContainer) + */ + public void setContainer(ICOptionContainer container) { + super.setContainer(container); + IProject project = container.getProject(); + if (project != null) { + try { + fBuildInfo = MakeCorePlugin.createScannerConfigBuildInfo(project, ScannerConfigBuilder.BUILDER_ID); + } + catch (CoreException e) { + fBuildInfo = MakeCorePlugin.createScannerConfigBuildInfo(container.getPreferences(), ScannerConfigBuilder.BUILDER_ID, true); + } + } + else { + fBuildInfo = MakeCorePlugin.createScannerConfigBuildInfo(container.getPreferences(), ScannerConfigBuilder.BUILDER_ID, false); + } + retrieveSIConsoleParsers(); + initialBuilderParserId = fBuildInfo.getMakeBuilderConsoleParserId(); //$NON-NLS-1$ + initialProviderParserId = fBuildInfo.getESIProviderConsoleParserId(); //$NON-NLS-1$ + } + + /** + * Fills console parser maps + */ + private void retrieveSIConsoleParsers() { + IExtensionPoint ep = MakeCorePlugin.getDefault().getDescriptor(). + getExtensionPoint(MakeCorePlugin.SI_CONSOLE_PARSER_SIMPLE_ID); + if (ep != null) { + IExtension[] extensions = ep.getExtensions(); + for (int i = 0; i < extensions.length; ++i) { + String parserId = extensions[i].getUniqueIdentifier(); + String label = extensions[i].getLabel(); + IConfigurationElement[] elements = (IConfigurationElement[]) extensions[i].getConfigurationElements(); + String commandId = elements[0].getAttribute("commandId"); //$NON-NLS-1$ + if (commandId.equals("makeBuilder") || commandId.equals("all")) { //$NON-NLS-1$//$NON-NLS-2$ + builderParsers.put(label, parserId); + } + if (commandId.equals("externalScannerInfoProvider") || commandId.equals("all")) { //$NON-NLS-1$//$NON-NLS-2$ + providerParsers.put(label, parserId); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt..dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + public void performApply(IProgressMonitor monitor) throws CoreException { + // install/deinstall the scanner configuration builder + IProject project = getContainer().getProject(); + IScannerConfigBuilderInfo buildInfo; + if (project != null) { + if (autoDiscovery.getSelection()) { + ScannerConfigNature.addScannerConfigNature(project); + buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(project, ScannerConfigBuilder.BUILDER_ID); + buildInfo.setAutoDiscoveryEnabled(autoDiscovery.getSelection()); + } + else { + ScannerConfigNature.removeScannerConfigNature(project); + return; + } + } + else { + buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(getContainer().getPreferences(), ScannerConfigBuilder.BUILDER_ID, false); + buildInfo.setAutoDiscoveryEnabled(autoDiscovery.getSelection()); + } + + buildInfo.setMakeBuilderConsoleParserEnabled(enableBuilderParser()); + if (enableBuilderParser()) { + buildInfo.setMakeBuilderConsoleParserId( + (String)builderParsers.get(makeBuilderSIParserComboBox.getText())); + } + + buildInfo.setESIProviderCommandEnabled(enableProviderCommand()); + if (enableProviderCommand()) { + buildInfo.setUseDefaultESIProviderCmd(useDefaultESIProviderCmd()); + if (!useDefaultESIProviderCmd()) { + String esiProviderLine = getSIProviderCommandLine(); + int start = 0; + int end = -1; + if (esiProviderLine.startsWith("\"")) { //$NON-NLS-1$ + start = 1; + end = esiProviderLine.indexOf('"', 1); + } + else { + end = esiProviderLine.indexOf(' '); + } + IPath path; + if (end == -1) { + path = new Path(esiProviderLine); + } else { + path = new Path(esiProviderLine.substring(start, end)); + } + buildInfo.setESIProviderCommand(path); + String args = ""; //$NON-NLS-1$ + if (end != -1) { + args = esiProviderLine.substring(end + 1); + } + buildInfo.setESIProviderArguments(args); + } + buildInfo.setESIProviderConsoleParserId( + (String)providerParsers.get(esiProviderParserComboBox.getText())); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults() + */ + public void performDefaults() { + IScannerConfigBuilderInfo buildInfo; + // Populate with the default value + if (getContainer().getProject() != null) { + // get the preferences + buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(getContainer().getPreferences(), + ScannerConfigBuilder.BUILDER_ID, false); + } + else { + // get the defaults + buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(getContainer().getPreferences(), + ScannerConfigBuilder.BUILDER_ID, true); + } + + autoDiscovery.setSelection(buildInfo.isAutoDiscoveryEnabled()); + + enableBuilderParserButton.setSelection(buildInfo.isMakeBuilderConsoleParserEnabled()); + String builderParserId = buildInfo.getMakeBuilderConsoleParserId(); + for (Iterator i = builderParsers.keySet().iterator(); i.hasNext(); ) { + String builderParser = (String) i.next(); + if (builderParserId.equals((String) builderParsers.get(builderParser))) { + makeBuilderSIParserComboBox.setText(builderParser); + } + } + + enableProviderCommandButton.setSelection(buildInfo.isESIProviderCommandEnabled()); + defESIProviderCommandButton.setSelection(buildInfo.isDefaultESIProviderCmd()); + IPath sCommand = fBuildInfo.getESIProviderCommand(); + if (sCommand != null) { + StringBuffer cmd = new StringBuffer(sCommand.toOSString()); + String args = buildInfo.getESIProviderArguments(); + if (args != null && !args.equals("")) { //$NON-NLS-1$ + cmd.append(' '); + cmd.append(args); + } + esiProviderCommand.setText(cmd.toString()); + } + enableProviderCommandButton.setSelection(buildInfo.isESIProviderCommandEnabled()); + String providerParserId = buildInfo.getESIProviderConsoleParserId(); + for (Iterator i = providerParsers.keySet().iterator(); i.hasNext(); ) { + String providerParser = (String) i.next(); + if (providerParserId.equals((String) providerParsers.get(providerParser))) { + esiProviderParserComboBox.setText(providerParser); + } + } + // enable controls according to Auto Discovery button selection + enableAllControls(enableAutoDiscovery()); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite composite = ControlFactory.createComposite(parent, 1); + setControl(composite); + + if (addTitle) { + addTitle(composite); + } + addSCDiscoveryState(composite); + addSeparator(composite); + createBuildOutputParserControls(composite); + createAfterBuildCmdControls(composite); + // enable controls depending on the state of auto discovery + enableAllControls(enableAutoDiscovery()); + } + + private void addTitle(Composite composite) { + //Label for dialog title + Label pathLabel = ControlFactory.createLabel(composite, + MakeUIPlugin.getResourceString(DESC)); + } + + private void addSCDiscoveryState(Composite parent) { + //Checkbox for enabling the discovery + ControlFactory.insertSpace(parent, 1, 10); + autoDiscovery = ControlFactory.createCheckBox(parent, + MakeUIPlugin.getResourceString(ACTIVATE_AUTO_DISCOVERY)); + autoDiscovery.setSelection(fBuildInfo.isAutoDiscoveryEnabled()); + autoDiscovery.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + enableAllControls(enableAutoDiscovery()); + getContainer().updateContainer(); + } + }); + } + + /** + * @param enable + */ + private void enableAllControls(boolean enable) { + enableBuilderParserButton.setEnabled(enable); + makeBuilderSIParserComboBox.setEnabled(enable && enableBuilderParser()); + enableProviderCommandButton.setEnabled(enable); + defESIProviderCommandButton.setEnabled(enable && enableProviderCommand()); + esiProviderCommand.setEnabled(enable && enableProviderCommand() && !useDefaultESIProviderCmd()); + esiProviderParserComboBox.setEnabled(enable && enableProviderCommand()); + } + + private void addSeparator(Composite parent) { + Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData gridData = new GridData(); + gridData.horizontalAlignment = GridData.FILL; + gridData.grabExcessHorizontalSpace = true; + separator.setLayoutData(gridData); + } + + private void createBuildOutputParserControls(Composite parent) { +// ControlFactory.insertSpace(parent, 1, 10); + Group bopGroup = ControlFactory.createGroup(parent, + MakeUIPlugin.getResourceString(SI_BUILD_PARSER_GROUP), 2); + ((GridLayout)bopGroup.getLayout()).marginHeight = 5; + ((GridLayout)bopGroup.getLayout()).marginWidth = 5; + ((GridData)bopGroup.getLayoutData()).verticalAlignment = GridData.FILL; + + enableBuilderParserButton = ControlFactory.createCheckBox(bopGroup, + MakeUIPlugin.getResourceString(ENABLE_SI_BUILD_PARSER)); + ((GridData)enableBuilderParserButton.getLayoutData()).horizontalSpan = 2; + boolean enabledBuilderParser = fBuildInfo.isMakeBuilderConsoleParserEnabled(); + enableBuilderParserButton.setSelection(enabledBuilderParser); + enableBuilderParserButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + makeBuilderSIParserComboBox.setEnabled(enableBuilderParser()); + getContainer().updateContainer(); + } + }); + + Label label = ControlFactory.createLabel(bopGroup, + MakeUIPlugin.getResourceString(SI_BUILD_PARSER_LABEL)); + ((GridData)label.getLayoutData()).grabExcessHorizontalSpace = false; + + makeBuilderSIParserComboBox = new Combo(bopGroup, SWT.DROP_DOWN | SWT.READ_ONLY); + + // fill the combobox and set the initial value + Iterator items = builderParsers.keySet().iterator(); + while (items.hasNext()) { + String parser = (String) items.next(); + makeBuilderSIParserComboBox.add(parser); + if (initialBuilderParserId.equals(builderParsers.get(parser))) { + makeBuilderSIParserComboBox.setText(parser); + } + } + makeBuilderSIParserComboBox.setEnabled(enabledBuilderParser); + } + + private void createAfterBuildCmdControls(Composite parent) { + Group abcGroup = ControlFactory.createGroup(parent, + MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_GROUP), 2); + ((GridData)abcGroup.getLayoutData()).horizontalSpan = 2; + + enableProviderCommandButton = ControlFactory.createCheckBox(abcGroup, + MakeUIPlugin.getResourceString(ENABLE_SI_PROVIDER_COMMAND)); + ((GridData)enableProviderCommandButton.getLayoutData()).horizontalSpan = 2; + ((GridData)enableProviderCommandButton.getLayoutData()).horizontalAlignment = GridData.FILL_HORIZONTAL; + boolean enabledProviderCommand = fBuildInfo.isESIProviderCommandEnabled(); + enableProviderCommandButton.setSelection(enabledProviderCommand); + enableProviderCommandButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + defESIProviderCommandButton.setEnabled(enableProviderCommand()); + esiProviderCommand.setEnabled(enableProviderCommand() && !useDefaultESIProviderCmd()); + esiProviderParserComboBox.setEnabled(enableProviderCommand()); + getContainer().updateContainer(); + } + }); + + createESIProviderCmdControls(abcGroup); + + Label label = ControlFactory.createLabel(abcGroup, + MakeUIPlugin.getResourceString(SI_PROVIDER_PARSER_LABEL)); + ((GridData)label.getLayoutData()).grabExcessHorizontalSpace = false; + + esiProviderParserComboBox = new Combo(abcGroup, SWT.DROP_DOWN | SWT.READ_ONLY); + + // fill the combobox and set the initial value + Iterator items = providerParsers.keySet().iterator(); + while (items.hasNext()) { + String parser = (String) items.next(); + esiProviderParserComboBox.add(parser); + if (initialProviderParserId.equals(providerParsers.get(parser))) { + esiProviderParserComboBox.setText(parser); + } + } + defESIProviderCommandButton.setEnabled(enabledProviderCommand); + esiProviderCommand.setEnabled(enabledProviderCommand && !useDefaultESIProviderCmd()); + esiProviderParserComboBox.setEnabled(enabledProviderCommand); + } + + private void createESIProviderCmdControls(Composite parent) { + defESIProviderCommandButton = ControlFactory.createCheckBox(parent, + MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_USE_DEFAULT)); + defESIProviderCommandButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + esiProviderCommand.setEnabled(!useDefaultESIProviderCmd()); + getContainer().updateContainer(); + } + }); + ((GridData) (defESIProviderCommandButton.getLayoutData())).horizontalAlignment = GridData.FILL_HORIZONTAL; + ((GridData) (defESIProviderCommandButton.getLayoutData())).horizontalSpan = 2; + Label label = ControlFactory.createLabel(parent, + MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_LABEL)); + ((GridData) (label.getLayoutData())).horizontalAlignment = GridData.BEGINNING; + ((GridData) (label.getLayoutData())).grabExcessHorizontalSpace = false; + esiProviderCommand = ControlFactory.createTextField(parent, SWT.SINGLE | SWT.BORDER); + ((GridData) (esiProviderCommand.getLayoutData())).horizontalAlignment = GridData.FILL; + ((GridData) (esiProviderCommand.getLayoutData())).grabExcessHorizontalSpace = true; + esiProviderCommand.addListener(SWT.Modify, new Listener() { + public void handleEvent(Event e) { + getContainer().updateContainer(); + } + }); + IPath sCommand = fBuildInfo.getESIProviderCommand(); + if (sCommand != null) { + StringBuffer cmd = new StringBuffer(sCommand.toOSString()); + String args = fBuildInfo.getESIProviderArguments(); + if (args != null && args.length() > 0) { + cmd.append(' '); + cmd.append(args); + } + esiProviderCommand.setText(cmd.toString()); + } + if (fBuildInfo.isDefaultESIProviderCmd()) { + esiProviderCommand.setEnabled(false); + } + defESIProviderCommandButton.setSelection(fBuildInfo.isDefaultESIProviderCmd()); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#getErrorMessage() + */ + public String getErrorMessage() { + if (!useDefaultESIProviderCmd()) { + String cmd = getSIProviderCommandLine(); + if (cmd == null || cmd.length() == 0) { + return MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_ERROR_MESSAGE); +// return "Must enter a 'generate scanner info' command"; //$NON-NLS-1$ + } + } + return super.getErrorMessage(); + } + + private boolean enableAutoDiscovery() { + return autoDiscovery.getSelection(); + } + + private boolean useDefaultESIProviderCmd() { + return defESIProviderCommandButton.getSelection(); + } + + private String getSIProviderCommandLine() { + return esiProviderCommand.getText().trim(); + } + + private boolean enableBuilderParser() { + return enableBuilderParserButton.getSelection(); + } + + private boolean enableProviderCommand() { + return enableProviderCommandButton.getSelection(); + } +} \ No newline at end of file diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java index 3d14e8d9fd0..8a9fbcaec0a 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java @@ -5,8 +5,9 @@ package org.eclipse.cdt.make.ui.wizards; * All Rights Reserved. */ +import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.internal.ui.MakeProjectOptionBlock; -import org.eclipse.cdt.make.internal.ui.MakeUIPlugin; +import org.eclipse.cdt.make.ui.dialogs.ScannerConfigPage; import org.eclipse.cdt.ui.dialogs.ICOptionContainer; import org.eclipse.cdt.ui.dialogs.ReferenceBlock; import org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock; @@ -40,6 +41,7 @@ public class MakeProjectWizardOptionPage extends NewCProjectWizardOptionPage { protected void addTabs() { addTab(new ReferenceBlock()); super.addTabs(); + addTab(new ScannerConfigPage()); } } @@ -61,7 +63,7 @@ public class MakeProjectWizardOptionPage extends NewCProjectWizardOptionPage { * @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getPreference() */ public Preferences getPreferences() { - return MakeUIPlugin.getDefault().getPluginPreferences(); + return MakeCorePlugin.getDefault().getPluginPreferences(); } }