[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Fw: CDT2.0 Scanner configuration discovery
|
This patch contains redesigned implementation of Scanner config discovery.
After Doug's inspections following changes were made:
- ErrorParserManager, IErrorParser interface and ErrorParsers extension
point are not used anymore. Instead, ScannerInfoConsoleParser extension
point is defined with appropriate surrounding classes.
- GNU specifics are now minimized to two ScannerInfoConsoleParsers one for
make builder, the other for ExternalScannerInforProvider command
(implemented as extension point/extension) and a cygpath translator.
- The build/error parse performance is not affected in case console
parsing for scanner info is disabled.
- New Scanner config page for Preferences, project properties and New Make
Project wizard.
Limitations/future work:
- relative paths are not handled properly yet, currently being worked on,
- changes to Paths and Symbols page UI to follow.
Please let me know if the work can be further improved, I am eager to see
it in CVS.
Thanks,
Vmir
P.S. Huge thanks to Doug for many valuable comments.
Index: plugin.properties
===================================================================
retrieving revision 1.2
diff -u -r1.2 plugin.properties
--- plugin.properties 19 Aug 2003 20:17:28 -0000 1.2
+++ plugin.properties 4 Mar 2004 21:38:44 -0000
@@ -3,4 +3,13 @@
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
Index: plugin.xml
===================================================================
retrieving revision 1.11
diff -u -r1.11 plugin.xml
--- plugin.xml 5 Jan 2004 20:26:09 -0000 1.11
+++ plugin.xml 4 Mar 2004 21:38:44 -0000
@@ -21,6 +21,8 @@
<extension-point id="MakeTargetBuilder" name="%extensionTargetBuilder.name" schema="schema/MakeTargetBuilder.exsd"/>
+ <extension-point id="ExternalScannerInfoProvider" name="%extensionExternalScannerInfoProvider.name" schema="schema/ExternalScannerInfoProvider.exsd"/>
+ <extension-point id="ScannerInfoConsoleParser" name="%extensionScannerInfoConsoleParser.name" schema="schema/ScannerInfoConsoleParser.exsd"/>
<extension
id="MakeScannerProvider"
@@ -76,6 +78,69 @@
builderID="org.eclipse.cdt.make.core.makeBuilder"
id="org.eclipse.cdt.make.MakeTargetBuilder">
</builder>
+ </extension>
+ <extension
+ id="ScannerConfigNature"
+ name="%epScannerConfigNature.name"
+ point="org.eclipse.core.resources.natures">
+ <requires-nature
+ id="org.eclipse.cdt.make.core.makeNature">
+ </requires-nature>
+ <runtime>
+ <run
+ class="org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature">
+ </run>
+ </runtime>
+ <builder
+ id="org.eclipse.cdt.make.core.ScannerConfigBuilder">
+ </builder>
+ </extension>
+ <extension
+ id="ScannerConfigBuilder"
+ name="%epScannerConfigBuilder.name"
+ point="org.eclipse.core.resources.builders">
+ <builder
+ hasNature="true">
+ <run
+ class="org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder">
+ </run>
+ </builder>
+ </extension>
+ <extension
+ id="DefaultExternalScannerInfoProvider"
+ name="%epDefaultExternalScannerInfoProvider.name"
+ point="org.eclipse.cdt.make.core.ExternalScannerInfoProvider">
+ <externalScannerInfoProvider>
+ <run
+ class="org.eclipse.cdt.make.internal.core.scannerconfig.DefaultExternalScannerInfoProvider">
+ <parameter
+ name="defaultCommand"
+ value="gcc">
+ </parameter>
+ <parameter
+ name="defaultAttributes"
+ value="-c -v">
+ </parameter>
+ </run>
+ </externalScannerInfoProvider>
+ </extension>
+ <extension
+ id="GCCScannerInfoConsoleParser"
+ name="%epGCCCommandLineParser.name"
+ point="org.eclipse.cdt.make.core.ScannerInfoConsoleParser">
+ <scannerInfoConsoleParser
+ commandId="makeBuilder"
+ class="org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerInfoConsoleParser">
+ </scannerInfoConsoleParser>
+ </extension>
+ <extension
+ id="GCCSpecsConsoleParser"
+ name="%epGCCSpecsParser.name"
+ point="org.eclipse.cdt.make.core.ScannerInfoConsoleParser">
+ <scannerInfoConsoleParser
+ commandId="externalScannerInfoProvider"
+ class="org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCSpecsConsoleParser">
+ </scannerInfoConsoleParser>
</extension>
</plugin>
Index: src/org/eclipse/cdt/make/core/MakeBuilder.java
===================================================================
retrieving revision 1.18
diff -u -r1.18 MakeBuilder.java
--- src/org/eclipse/cdt/make/core/MakeBuilder.java 24 Feb 2004 02:03:08 -0000 1.18
+++ src/org/eclipse/cdt/make/core/MakeBuilder.java 4 Mar 2004 21:38:44 -0000
@@ -24,6 +24,7 @@
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 @@
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 @@
}
// 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 @@
stderr.close();
monitor.subTask(MakeCorePlugin.getResourceString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$
+ sniffer.close();
epm.reportProblems();
cos.close();
}
Index: src/org/eclipse/cdt/make/core/MakeCorePlugin.java
===================================================================
retrieving revision 1.12
diff -u -r1.12 MakeCorePlugin.java
--- src/org/eclipse/cdt/make/core/MakeCorePlugin.java 19 Feb 2004 13:38:36 -0000 1.12
+++ src/org/eclipse/cdt/make/core/MakeCorePlugin.java 4 Mar 2004 21:38:44 -0000
@@ -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 @@
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 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 @@
} 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.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);
+ scInfo.setMakeBuilderConsoleParserEnabled(true);
+ scInfo.setESIProviderConsoleParserEnabled(true);
+ } catch (CoreException e) {
+ }
}
public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) {
@@ -179,4 +211,109 @@
}
}
+ /*
+ * 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;
+ }
}
Index: src/org/eclipse/cdt/make/core/PluginResources.properties
===================================================================
retrieving revision 1.6
diff -u -r1.6 PluginResources.properties
--- src/org/eclipse/cdt/make/core/PluginResources.properties 2 Mar 2004 17:13:52 -0000 1.6
+++ src/org/eclipse/cdt/make/core/PluginResources.properties 4 Mar 2004 21:38:44 -0000
@@ -13,4 +13,17 @@
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
Index: schema/ExternalScannerInfoProvider.exsd
===================================================================
RCS file: schema/ExternalScannerInfoProvider.exsd
diff -N schema/ExternalScannerInfoProvider.exsd
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ schema/ExternalScannerInfoProvider.exsd 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,137 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.cdt.make.core">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.cdt.make.core" id="ExternalScannerInfoProvider" name="C/C++ Scanner Info Provider"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to plug in particular compiler scanner info provider.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="externalScannerInfoProvider" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="externalScannerInfoProvider">
+ <complexType>
+ <sequence>
+ <element ref="run"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="run">
+ <complexType>
+ <sequence>
+ <element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A fully qualified name of the Java class that implements <samp>org.eclipse.cdt.make.core.scannerconfig.ICompilerScannerInfoProvider</samp> interface.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.cdt.make.core.scannerconfig.ISpecsBuilder"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="parameter">
+ <annotation>
+ <documentation>
+ Parameters passed to the compiler scanner info provider.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ Name of a parameter.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="value" type="string" use="required">
+ <annotation>
+ <documentation>
+ Value of a parameter.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ Plug-ins that want to extend this extension point must implement <samp>org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider</samp> interface.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ org.eclipse.cdt.make.core plugin provides default implementation of the GNU C/C++ compiler specs scanner info provider.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
Index: schema/ScannerInfoConsoleParser.exsd
===================================================================
RCS file: schema/ScannerInfoConsoleParser.exsd
diff -N schema/ScannerInfoConsoleParser.exsd
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ schema/ScannerInfoConsoleParser.exsd 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,119 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.cdt.make.core">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.cdt.make.core" id="ScannerInfoConsoleParser" name="%extensionScannerInfoConsoleParser.name"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="scannerInfoConsoleParser"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="scannerInfoConsoleParser">
+ <complexType>
+ <attribute name="commandId" use="default" value="all">
+ <annotation>
+ <documentation>
+ Id of the command the console parser is associated with. Can be 'all', 'makeBuilder' or 'externalScannerInfoProvider'.
+ </documentation>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="all">
+ </enumeration>
+ <enumeration value="makeBuilder">
+ </enumeration>
+ <enumeration value="externalScannerInfoProvider">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Java class that implements IScannerInfoConsoleParser interface.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.cdt.make.core.IScannerInfoConsoleParser"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
Index: src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/IExternalScannerInfoProvider.java 1 Jan 1970 00:00:00 -0000
@@ -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);
+}
Index: src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/IScannerConfigBuilderInfo.java 1 Jan 1970 00:00:00 -0000
@@ -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;
+
+ 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;
+
+ String getMakeBuilderConsoleParserId();
+ void setMakeBuilderConsoleParserId(String parserId) throws CoreException;
+
+ boolean isMakeBuilderConsoleParserEnabled();
+ void setMakeBuilderConsoleParserEnabled(boolean enabled) throws CoreException;
+
+ boolean isESIProviderConsoleParserEnabled();
+ void setESIProviderConsoleParserEnabled(boolean enabled) throws CoreException;
+}
Index: src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java 1 Jan 1970 00:00:00 -0000
@@ -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();
+}
Index: src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigBuilder.java 1 Jan 1970 00:00:00 -0000
@@ -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();
+ }
+}
Index: src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java 1 Jan 1970 00:00:00 -0000
@@ -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;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/ConsoleOutputStreamSniffer.java 1 Jan 1970 00:00:00 -0000
@@ -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);
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/DefaultExternalScannerInfoProvider.java 1 Jan 1970 00:00:00 -0000
@@ -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;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/IScannerInfoConsoleParserUtility.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * 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 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);
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerConfigInfoFactory.java 1 Jan 1970 00:00:00 -0000
@@ -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 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$
+ static final String MAKE_BUILDER_PARSER_ID = PREFIX + ".makeBuilderParserId"; //$NON-NLS-1$
+ static final String MAKE_BUILDER_PARSER_ENABLED = PREFIX + ".makeBuilderParserEnabled"; //$NON-NLS-1$
+ static final String ESI_PROVIDER_PARSER_ENABLED = PREFIX + ".esiProviderParserEnabled"; //$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#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);
+ }
+
+ /* (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#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#isESIProviderConsoleParserEnabled()
+ */
+ public boolean isESIProviderConsoleParserEnabled() {
+ if (getString(ESI_PROVIDER_PARSER_ENABLED) == null ||
+ getString(ESI_PROVIDER_PARSER_ENABLED).length() == 0) { // if no property then default to true
+ return true;
+ }
+ return getBoolean(ESI_PROVIDER_PARSER_ENABLED);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setESIProviderConsoleParserEnabled(boolean)
+ */
+ public void setESIProviderConsoleParserEnabled(boolean enabled) throws CoreException {
+ putString(ESI_PROVIDER_PARSER_ENABLED, Boolean.toString(enabled));
+ }
+
+ 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);
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java 1 Jan 1970 00:00:00 -0000
@@ -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.isESIProviderConsoleParserEnabled()) {
+ 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);
+ }
+
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java 1 Jan 1970 00:00:00 -0000
@@ -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.isESIProviderConsoleParserEnabled()) {
+ // 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;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerConfigUtil.java 1 Jan 1970 00:00:00 -0000
@@ -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$
+ }
+ }
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,197 @@
+/**********************************************************************
+ * 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;
+ }
+ }
+ }
+
+ IFile file = null;
+ IProject project = fProject;
+ if (fileName != null) {
+ file = fUtil.findFile(fileName);
+ if (file != null) {
+ project = file.getProject();
+// fUtil.translateRelativePaths(file, fileName, includes);
+ }
+ }
+ // 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;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java 1 Jan 1970 00:00:00 -0000
@@ -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();
+ }
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java 1 Jan 1970 00:00:00 -0000
@@ -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;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java 1 Jan 1970 00:00:00 -0000
@@ -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;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,302 @@
+/**********************************************************************
+ * 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, 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(segments);
+ } 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 */
+ }
+ }
+
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SymbolEntry.java 1 Jan 1970 00:00:00 -0000
@@ -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;
+ }
+
+}
Index: plugin.properties
===================================================================
retrieving revision 1.8
diff -u -r1.8 plugin.properties
--- plugin.properties 2 Mar 2004 21:37:42 -0000 1.8
+++ plugin.properties 4 Mar 2004 21:39:15 -0000
@@ -43,3 +43,5 @@
MakefileEditor.name=Makefile Editor
+PropertyScannerConfig.name=Scanner Configuration Discovery
+PreferenceScannerConfig.name=Scanner Configuration Discovery
Index: plugin.xml
===================================================================
retrieving revision 1.27
diff -u -r1.27 plugin.xml
--- plugin.xml 2 Mar 2004 21:37:42 -0000 1.27
+++ plugin.xml 4 Mar 2004 21:39:15 -0000
@@ -26,7 +26,6 @@
<import plugin="org.eclipse.core.runtime.compatibility"/>
</requires>
-
<extension
point="org.eclipse.ui.newWizards">
<wizard
@@ -392,6 +391,29 @@
id="org.eclipse.cdt.make.ui.makeTargetActionSet">
</actionSet>
</perspectiveExtension>
+ </extension>
+ <extension
+ point="org.eclipse.ui.propertyPages">
+ <page
+ adaptable="true"
+ objectClass="org.eclipse.core.resources.IProject"
+ name="%PropertyScannerConfig.name"
+ class="org.eclipse.cdt.make.internal.ui.properties.ScannerConfigPropertyPage"
+ id="org.eclipse.cdt.make.ui.properties.ScannerConfigPropertyPage">
+ <filter
+ name="nature"
+ value="org.eclipse.cdt.make.core.makeNature">
+ </filter>
+ </page>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ name="%PreferenceScannerConfig.name"
+ category="org.eclipse.cdt.ui.preferences.CPluginPreferencePage"
+ class="org.eclipse.cdt.make.internal.ui.preferences.ScannerConfigPreferencePage"
+ id="org.eclipse.cdt.make.ui.preferences.ScannerConfigPreferencePage">
+ </page>
</extension>
</plugin>
Index: src/org/eclipse/cdt/make/internal/ui/MakeResources.properties
===================================================================
retrieving revision 1.12
diff -u -r1.12 MakeResources.properties
--- src/org/eclipse/cdt/make/internal/ui/MakeResources.properties 2 Mar 2004 21:37:42 -0000 1.12
+++ src/org/eclipse/cdt/make/internal/ui/MakeResources.properties 4 Mar 2004 21:39:16 -0000
@@ -183,3 +183,19 @@
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
+ScannerConfigPage.siProvider.cmd.use_default=Use default
+ScannerConfigPage.siProvider.cmd.label=Generate scanner info command:
+ScannerConfigPage.siProvider.parser.group_label=Command output parser options
+ScannerConfigPage.siProvider.parser.enable.label=Enable command output parser
+ScannerConfigPage.siProvider.parser.label=Command output parser:
+
+ScannerConfigPage.siProvider.cmd.error_message=Must enter a 'generate scanner info' command
Index: src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java
===================================================================
retrieving revision 1.7
diff -u -r1.7 MakeProjectWizardOptionPage.java
--- src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java 14 Oct 2003 20:59:08 -0000 1.7
+++ src/org/eclipse/cdt/make/ui/wizards/MakeProjectWizardOptionPage.java 4 Mar 2004 21:39:18 -0000
@@ -5,8 +5,9 @@
* 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 @@
protected void addTabs() {
addTab(new ReferenceBlock());
super.addTabs();
+ addTab(new ScannerConfigPage());
}
}
@@ -61,7 +63,7 @@
* @see org.eclipse.cdt.ui.dialogs.ICOptionContainer#getPreference()
*/
public Preferences getPreferences() {
- return MakeUIPlugin.getDefault().getPluginPreferences();
+ return MakeCorePlugin.getDefault().getPluginPreferences();
}
}
Index: src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java
diff -N src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/ui/preferences/ScannerConfigPreferencePage.java 1 Jan 1970 00:00:00 -0000
@@ -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();
+ }
+}
Index: src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java
diff -N src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/ui/properties/ScannerConfigPropertyPage.java 1 Jan 1970 00:00:00 -0000
@@ -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();
+ }
+}
Index: src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java
===================================================================
RCS file: src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java
diff -N src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/ui/dialogs/ScannerConfigPage.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,458 @@
+/**********************************************************************
+ * 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 SI_BUILD_PARSER_LABEL = PREFIX + ".siBuilder.parser.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_PROVIDER_CMD_GROUP = PREFIX + ".siProvider.cmd.group_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_GROUP = PREFIX + ".siProvider.parser.group_label"; //$NON-NLS-1$
+ private static final String ENABLE_SI_PROVIDER_PARSER = PREFIX + ".siProvider.parser.enable.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 defButton;
+ private Text esiProviderCommand;
+
+ private Button enableBuilderParserButton;
+ private Combo makeBuilderSIParserComboBox;
+ private Button enableProviderParserButton;
+ 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 (!useDefaultSpecsCmd()) {
+ 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.setUseDefaultESIProviderCmd(useDefaultSpecsCmd());
+ if (!useDefaultSpecsCmd()) {
+ 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.setMakeBuilderConsoleParserEnabled(enableBuilderParser());
+ if (enableBuilderParser()) {
+ buildInfo.setMakeBuilderConsoleParserId(
+ (String)builderParsers.get(makeBuilderSIParserComboBox.getText()));
+ }
+ buildInfo.setESIProviderConsoleParserEnabled(enableProviderParser());
+ if (enableProviderParser()) {
+ 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());
+ 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());
+ }
+ if (buildInfo.isDefaultESIProviderCmd()) {
+ esiProviderCommand.setEnabled(false);
+ } else {
+ esiProviderCommand.setEnabled(true);
+ }
+ defButton.setSelection(buildInfo.isDefaultESIProviderCmd());
+
+ 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);
+ }
+ }
+ enableBuilderParserButton.setSelection(buildInfo.isMakeBuilderConsoleParserEnabled());
+ makeBuilderSIParserComboBox.setEnabled(enableBuilderParser());
+
+ String providerParserId = buildInfo.getMakeBuilderConsoleParserId();
+ for (Iterator i = providerParsers.keySet().iterator(); i.hasNext(); ) {
+ String providerParser = (String) i.next();
+ if (providerParserId.equals((String) builderParsers.get(providerParser))) {
+ esiProviderParserComboBox.setText(providerParser);
+ }
+ }
+ enableProviderParserButton.setSelection(buildInfo.isESIProviderConsoleParserEnabled());
+ esiProviderParserComboBox.setEnabled(enableProviderParser());
+ }
+
+ /* (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);
+ }
+
+ 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());
+ }
+
+ 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) {
+ createESIProviderCmdControls(parent);
+
+ Group abcParserGroup = ControlFactory.createGroup(parent,
+ MakeUIPlugin.getResourceString(SI_PROVIDER_PARSER_GROUP), 2);
+ ((GridData)abcParserGroup.getLayoutData()).horizontalSpan = 2;
+
+ enableProviderParserButton = ControlFactory.createCheckBox(abcParserGroup,
+ MakeUIPlugin.getResourceString(ENABLE_SI_PROVIDER_PARSER));
+ ((GridData)enableProviderParserButton.getLayoutData()).horizontalSpan = 2;
+ boolean enabledProviderParser = fBuildInfo.isESIProviderConsoleParserEnabled();
+ enableProviderParserButton.setSelection(enabledProviderParser);
+ enableProviderParserButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ esiProviderParserComboBox.setEnabled(enableProviderParser());
+ getContainer().updateContainer();
+ }
+ });
+
+ Label label = ControlFactory.createLabel(abcParserGroup,
+ MakeUIPlugin.getResourceString(SI_PROVIDER_PARSER_LABEL));
+ ((GridData)label.getLayoutData()).grabExcessHorizontalSpace = false;
+
+ esiProviderParserComboBox = new Combo(abcParserGroup, 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);
+ }
+ }
+ esiProviderParserComboBox.setEnabled(enabledProviderParser);
+ }
+
+ private void createESIProviderCmdControls(Composite parent) {
+ Group group = ControlFactory.createGroup(parent,
+ MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_GROUP), 2);
+ ((GridData)group.getLayoutData()).horizontalSpan = 2;
+ defButton = ControlFactory.createCheckBox(group,
+ MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_USE_DEFAULT));
+ defButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ esiProviderCommand.setEnabled(!useDefaultSpecsCmd());
+ getContainer().updateContainer();
+ }
+ });
+ ((GridData) (defButton.getLayoutData())).horizontalAlignment = GridData.FILL_HORIZONTAL;
+ ((GridData) (defButton.getLayoutData())).horizontalSpan = 2;
+ Label label = ControlFactory.createLabel(group,
+ MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_LABEL));
+ ((GridData) (label.getLayoutData())).horizontalAlignment = GridData.BEGINNING;
+ ((GridData) (label.getLayoutData())).grabExcessHorizontalSpace = false;
+ esiProviderCommand = ControlFactory.createTextField(group, 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);
+ }
+ defButton.setSelection(fBuildInfo.isDefaultESIProviderCmd());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#getErrorMessage()
+ */
+ public String getErrorMessage() {
+ if (!useDefaultSpecsCmd()) {
+ 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 useDefaultSpecsCmd() {
+ return defButton.getSelection();
+ }
+
+ private String getSIProviderCommandLine() {
+ return esiProviderCommand.getText().trim();
+ }
+
+ private boolean enableBuilderParser() {
+ return enableBuilderParserButton.getSelection();
+ }
+
+ private boolean enableProviderParser() {
+ return enableProviderParserButton.getSelection();
+ }
+}