[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Reresubmitted: CDT2.0 Scanner Configuration discovery - initial work
|
Valid comments.
Resubmitting with corrections. My comments are below.
Thanks,
Vladimir Hirsl
Rational Software - IBM Software Group
Ottawa, Ontario, Canada
> Sorry, but firstly I would like to see us stick to eclipse convention
> with package naming and move the non-public classes to a internal
package.
Done.
> Secondly there is still the question of gcc/g++ specifics being placed
> in this plugin and its not clear to me how this is extensible for other
> compilers, (It looks like there might be some interface to do this put
> its not clear when presented as just a patch).
My intention is to separate all GNU specific stuff into extensions. I have
already done some work in this direction. For parsing make build and
'specs' build output I extended ErrorParser extension point. New extension
point is defined to encapsulate generation of compiler's internal scanner
info - SpecsBuilder. Extension to this extension point was used for GNU
implementation (parses the output of 'generate specs' command). There are
still some 'GNUizms' left in but I am working on separating them into
generic and .gnu packages.
Design spec for this feature is now available on CDT web site (under PR
47465)
http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/cdt-home/plans/CDT_R2.0_plan.html?cvsroot=Tools_Project#Plan_Items
I hope it can answer some of your question.
I agree with the idea in Doug's and your follow up emails that all
compiler (for now GNU) specific stuff should be moved to a separate
plugin(s). But until the plugin is created, I guess the GNU specifics can
reside in packages with .gnu in their name.
>Thirdly I have noticed some strange naming in the schema and in some
> javadoc..."org.vmir.cdt....."
Done. The work started as a separate plugin :).
>
> Please revise.
>
> Thanks
> Dave.
>
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 19 Feb 2004 16:17:50 -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
+
+natureScannerConfig.name=Scanner Configuration Nature
+builderScannerConfig.name=Scanner Configuration Builder
+extensionSpecsBuilder.name=C/C++ Compiler Specs Builder Extension
+specsBuilder.name=Specs Builder
+
+epGnuCommandLine.name=CDT GNU C/C++ Scanner Info Parser
+epGnuCompilerSpecs.name=CDT GNU C/C++ Specs Parser
+spGnuSpecsBuilder.name=CDT GNU C/C++ Specs Builder
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 19 Feb 2004 16:17:50 -0000
@@ -21,6 +21,7 @@
<extension-point id="MakeTargetBuilder" name="%extensionTargetBuilder.name" schema="schema/MakeTargetBuilder.exsd"/>
+ <extension-point id="SpecsBuilder" name="%extensionSpecsBuilder.name" schema="schema/SpecsBuilder.exsd"/>
<extension
id="MakeScannerProvider"
@@ -76,6 +77,74 @@
builderID="org.eclipse.cdt.make.core.makeBuilder"
id="org.eclipse.cdt.make.MakeTargetBuilder">
</builder>
+ </extension>
+ <extension
+ id="GCCCommandLineParser"
+ name="%epGnuCommandLine.name"
+ point="org.eclipse.cdt.core.ErrorParser">
+ <errorparser
+ class="org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCScannerInfoParser">
+ </errorparser>
+ </extension>
+ <extension
+ id="GCCSpecsParser"
+ name="%epGnuCompilerSpecs.name"
+ point="org.eclipse.cdt.core.ErrorParser">
+ <errorparser
+ class="org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCCompilerSpecsParser">
+ </errorparser>
+ </extension>
+ <extension
+ id="ScannerConfigNature"
+ name="%natureScannerConfig.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="%builderScannerConfig.name"
+ point="org.eclipse.core.resources.builders">
+ <builder
+ hasNature="true">
+ <run
+ class="org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder">
+ </run>
+ </builder>
+ </extension>
+ <extension
+ point="org.eclipse.cdt.make.core.MakeTargetBuilder">
+ <builder
+ builderID="org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder"
+ id="org.eclipse.cdt.make.core.scannerconfig.ScannerConfigTargetBuilder">
+ </builder>
+ </extension>
+ <extension
+ id="GCCSpecsBuilder"
+ name="%spGnuSpecsBuilder.name"
+ point="org.eclipse.cdt.make.core.SpecsBuilder">
+ <specsbuilder>
+ <run
+ class="org.eclipse.cdt.make.internal.core.scannerconfig.gnu.GCCSpecsBuilder">
+ <parameter
+ name="defaultCommand"
+ value="gcc">
+ </parameter>
+ <parameter
+ name="defaultAttributes"
+ value="-c -v">
+ </parameter>
+ </run>
+ </specsbuilder>
</extension>
</plugin>
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 19 Feb 2004 16:17:50 -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
@@ -10,6 +10,8 @@
***********************************************************************/
package org.eclipse.cdt.make.core;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
@@ -19,13 +21,21 @@
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.ISpecsBuilder;
+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 +50,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 SPECS_BUILDER_SIMPLE_ID = "SpecsBuilder"; //$NON-NLS-1$
+ public static final String GCC_SPECS_BUILDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCSpecsBuilder"; //$NON-NLS-1$
+
+ public static final String CPP_SPECS_FILE = "specs.cpp"; //$NON-NLS-1$
+ public static final String C_SPECS_FILE = "specs.c"; //$NON-NLS-1$
+
//The shared instance.
private static MakeCorePlugin plugin;
//Resource bundle.
@@ -56,6 +73,7 @@
} catch (MissingResourceException x) {
resourceBundle = null;
}
+ createSpecs();
}
/**
@@ -131,6 +149,16 @@
} 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.setUseDefaultSpecsCmd(true);
+ scInfo.setSpecsCommand(new Path("gcc")); //$NON-NLS-1$
+ scInfo.setSpecsArguments("-c -v"); //$NON-NLS-1$
+ } catch (CoreException e) {
+ }
}
public static IMakeBuilderInfo createBuildInfo(Preferences prefs, String builderID, boolean useDefaults) {
@@ -177,6 +205,85 @@
fTargetManager.shutdown();
fTargetManager = null;
}
+ }
+
+ /*
+ * 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();
+ }
+
+ private void createSpecs() {
+ IPath path = getWorkingDirectory();
+ try {
+ createSpecsFile(path, CPP_SPECS_FILE);
+ createSpecsFile(path, C_SPECS_FILE);
+ } catch (CoreException e) {
+ log(e);
+ }
+ }
+
+ private 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, "Error writing specs file", e));
+ }
+ }
+ }
+
+ /**
+ * @param toolset - id specifying compiler toolset i.e. GCC
+ * @return builder - new instance of a 'specs' builder
+ */
+ public ISpecsBuilder loadSpecsBuilder(String id) {
+ ISpecsBuilder[] empty = new ISpecsBuilder[0];
+ try {
+ IExtensionPoint extension = getDescriptor().getExtensionPoint(SPECS_BUILDER_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) {
+ ISpecsBuilder builder = (ISpecsBuilder) runElement[0].createExecutableExtension("class");
+ return builder;
+ }
+ }
+ }
+ }
+ }
+ } catch (CoreException e) {
+ log(e);
+ }
+ return null;
}
}
Index: src/org/eclipse/cdt/make/core/PluginResources.properties
===================================================================
retrieving revision 1.5
diff -u -r1.5 PluginResources.properties
--- src/org/eclipse/cdt/make/core/PluginResources.properties 19 Feb 2004 13:38:36 -0000 1.5
+++ src/org/eclipse/cdt/make/core/PluginResources.properties 19 Feb 2004 16:17:51 -0000
@@ -7,8 +7,28 @@
BuildInfoFactory.Missing_Builder=Missing Builder:
+<<<<<<< PluginResources.properties
+MakeTargetProvider.add_to_workspace_root=Cannot add build targets to workspace root
+MakeTargetProvider.add_temporary_target=Cannot add temporart Target to manager.
+MakeTargetProvider.target_exists=Target exists
+MakeTargetProvider.failed_initializing_targets=Failed initializing build targets
+
+ScannerConfigBuilder.Invoking_Builder=Scanner Configuration update ...
+
+SpecsBuilder.Build_Error=Error launching builder ({0})
+SpecsBuilder.Reading_Specs=Reading specs ...
+SpecsBuilder.Parsing_Output=Parsing output...
+SpecsBuidler.Creating_Markers=Generating markers...
+
+ScannerInfoCollector.Processing=Processing discovered scanner configuration ...
+ScannerInfoCollector.Updating=Updating Scanner Configuration for project
+
+=======
MakeTargetManager.add_to_workspace_root=Cannot add build targets to workspace root
MakeTargetManager.add_temporary_target=Cannot add temporart Target to manager.
MakeTargetManager.target_exists=Target exists
MakeTargetManager.failed_initializing_targets=Failed initializing build targets
MakeTargetManager.error_writing_file=Error writing target file
+>>>>>>> 1.5
Index: schema/SpecsBuilder.exsd
===================================================================
RCS file: schema/SpecsBuilder.exsd
diff -N schema/SpecsBuilder.exsd
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ schema/SpecsBuilder.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="SpecsBuilders" name="C/C++ Compiler Specs Builder"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to plug in particular compiler specs builder.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="specsbuilder" 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="specsbuilder">
+ <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.ISpecsBuilder</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 specs builder.
+ </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.ISpecsBuilder</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 builder.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
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,34 @@
+/**********************************************************************
+ * 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 isDefaultSpecsCmd();
+ void setUseDefaultSpecsCmd(boolean on) throws CoreException;
+
+ IPath getSpecsCommand();
+ void setSpecsCommand(IPath command) throws CoreException;
+
+ String getSpecsArguments();
+ void setSpecsArguments(String args) throws CoreException;
+}
Index: src/org/eclipse/cdt/make/core/scannerconfig/ISpecsBuilder.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/ISpecsBuilder.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/ISpecsBuilder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/ISpecsBuilder.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.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Interface for C/++ specs builders
+ *
+ * @author vhirsl
+ */
+public interface ISpecsBuilder {
+ /**
+ * Initializes specs builder
+ *
+ * @param workingDirectory - where the compiler will be invoked
+ * @param current project - current project being built
+ * @return boolean - successful initialization
+ */
+ public boolean initialize(IPath workingDirectory, IScannerConfigBuilderInfo buildInfo, IProject currentProject);
+ /**
+ * Invokes a C/C++ compiler with target specific options to generate
+ * compiler specs.
+ *
+ * @param monitor
+ * @param buildInfo - settings for ScannerConfigBuilder
+ * @param targetSpecificOptions - array of options affecting compiler specs
+ */
+ public boolean invokeCompiler(IProgressMonitor monitor, String[] targetSpecificOptions);
+}
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$
+ // TODO: correct the monitor's text
+ monitor.subTask(MakeCorePlugin.getResourceString("ScannerConfigBuilder.Invoking_Builder") + 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,131 @@
+/**********************************************************************
+ * 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;
+ }
+
+ static public 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);
+ }
+
+ static public 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/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,259 @@
+/**********************************************************************
+ * 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_SPECS_CMD = PREFIX + ".useDefaultSpecsCmd"; //$NON-NLS-1$
+ static final String SPECS_COMMAND = PREFIX + ".specsCommand"; //$NON-NLS-1$
+ static final String SPECS_ARGUMENTS = PREFIX + ".specsArguments"; //$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#isDefaultSpecsCmd()
+ */
+ public boolean isDefaultSpecsCmd() {
+ if (getString(USE_DEFAULT_SPECS_CMD) == null ||
+ getString(USE_DEFAULT_SPECS_CMD).length() == 0) { // if no property then default to true
+ return true;
+ }
+ return getBoolean(USE_DEFAULT_SPECS_CMD);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setUseDefaultSpecsCmd(boolean)
+ */
+ public void setUseDefaultSpecsCmd(boolean on) throws CoreException {
+ putString(USE_DEFAULT_SPECS_CMD, Boolean.toString(on));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getSpecsCommand()
+ */
+ public IPath getSpecsCommand() {
+ if (isDefaultSpecsCmd()) {
+ String command = getSpecsParameter("defaultCommand"); //$NON-NLS-1$
+ if (command == null) {
+ return new Path("gcc"); //$NON-NLS-1$
+ }
+ return new Path(command);
+ }
+ return new Path(getString(SPECS_COMMAND));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setSpecsCommand(org.eclipse.core.runtime.IPath)
+ */
+ public void setSpecsCommand(IPath command) throws CoreException {
+ putString(SPECS_COMMAND, command.toString());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#getSpecsArguments()
+ */
+ public String getSpecsArguments() {
+ if (isDefaultSpecsCmd()) {
+ String command = getSpecsParameter("defaultAttributes"); //$NON-NLS-1$
+ if (command == null) {
+ command = "-c -v"; //$NON-NLS-1$
+ }
+ return command;
+ }
+ return getString(SPECS_ARGUMENTS);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo#setSpecsArguments(java.lang.String)
+ */
+ public void setSpecsArguments(String args) throws CoreException {
+ putString(SPECS_ARGUMENTS, args);
+ }
+
+ 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 getSpecsParameter(String name) {
+ IExtension extension =
+ Platform.getPluginRegistry().getExtension(
+ MakeCorePlugin.getUniqueIdentifier(),
+ MakeCorePlugin.SPECS_BUILDER_SIMPLE_ID,
+// TODO VMIR account for possible multiple available specs builders
+ MakeCorePlugin.GCC_SPECS_BUILDER_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;
+ }
+ }
+
+ /**
+ *
+ * @author vhirsl
+ */
+ 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,330 @@
+/**********************************************************************
+ * 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.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.ISpecsBuilder;
+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 project
+ * @param includes
+ * @param symbols
+ * @param targetSpecificOptions
+ */
+ public synchronized void contributeToScannerConfig(IProject project, List includes, List symbols, List targetSpecificOptions) {
+ 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();
+ }
+ }
+
+ /**
+ * Published method to receive compiler specified contributions to ScannerInfo
+ *
+ * @param includes
+ * @param symbols
+ */
+ public void contributeToScannerConfig(List includes, List symbols) {
+ contributeToScannerConfig(currentProject, includes, symbols, null);
+ }
+
+ /**
+ * @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);
+ Set symbols = new HashSet((List) discoveredSymbols.get(projectName));
+ if (includes == null && symbols == null)
+ return false;
+
+ // 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
+ }
+ }
+ }
+ }
+ return translatedIncludePaths;
+ }
+
+ private void getCompilerScannerInfo(final IProject project,
+ final List tso,
+ final IProgressMonitor monitor) {
+ // Call specs builder to get compiler's scanner info
+ final ISpecsBuilder specsBuilder = MakeCorePlugin.getDefault().
+ loadSpecsBuilder(MakeCorePlugin.GCC_SPECS_BUILDER_ID);
+ if (specsBuilder != null) {
+ // 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);
+ }
+ final IScannerConfigBuilderInfo buildInfo = info;
+
+ ISafeRunnable runnable = new ISafeRunnable() {
+ public void run() {
+ if (specsBuilder.initialize(MakeCorePlugin.getWorkingDirectory(), buildInfo, project)) {
+ if (tso == null) {
+ specsBuilder.invokeCompiler(monitor, new String[0]);
+ }
+ else {
+ specsBuilder.invokeCompiler(monitor, (String[])tso.toArray(new String[tso.size()]));
+ }
+ }
+ }
+
+ 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$
+ getCompilerScannerInfo(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/gnu/GCCCompilerSpecsParser.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCCompilerSpecsParser.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCCompilerSpecsParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCCompilerSpecsParser.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,90 @@
+/**********************************************************************
+ * 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.core.ErrorParserManager;
+import org.eclipse.cdt.core.IErrorParser;
+
+import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector;
+
+/**
+ * Parses output of gcc -c -v specs.c or
+ * g++ -c -v specs.cpp
+ * command
+ *
+ * @author vhirsl
+ */
+public class GCCCompilerSpecsParser implements IErrorParser {
+ private final int STATE_BEGIN = 0;
+ private final int STATE_SPECS_STARTED = 1;
+ private final int STATE_INCLUDES_STARTED = 2;
+
+ private int state = STATE_BEGIN;
+ private List symbols = new ArrayList();
+ private List includes = new ArrayList();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IErrorParser#processLine(java.lang.String, org.eclipse.cdt.core.ErrorParserManager)
+ */
+ public boolean processLine(String line, ErrorParserManager eoParser) {
+ 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(includes, symbols);
+
+ return rc;
+ }
+
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoParser.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoParser.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoParser.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,123 @@
+/**********************************************************************
+ * 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.ErrorParserManager;
+import org.eclipse.cdt.core.IErrorParser;
+import org.eclipse.cdt.core.IMarkerGenerator;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+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 GCCScannerInfoParser implements IErrorParser {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.IErrorParser#processLine(java.lang.String, org.eclipse.cdt.core.ErrorParserManager)
+ */
+ public boolean processLine(String line, ErrorParserManager eoParser) {
+ boolean rc = false;
+ // 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$
+ if (!targetSpecificOptions.contains(token))
+ targetSpecificOptions.add(token);
+ }
+ else {
+ String possibleFileName = token.toLowerCase();
+ if (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;
+ if (fileName != null) {
+ file = eoParser.findFilePath(fileName);
+
+ if (file == null) {
+ // Parse the entire project.
+ file = eoParser.findFileName(fileName);
+ if (file != null) {
+ // If there is a conflict set the error on the project.
+ if (eoParser.isConflictingName(fileName)) {
+ desc = "*" + desc;
+ file = null;
+ }
+ }
+ }
+
+ // Contribute discovered includes and symbols to the ScannerInfoCollector
+ if (file != null) {
+ IProject project = file.getProject();
+ 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();
+ eoParser.generateMarker(file, -1, "Found an include path: "+iPath, severity, iPath);
+ }
+ for (Iterator i = symbols.iterator(); i.hasNext(); ) {
+ String symbol = (String)i.next();
+ eoParser.generateMarker(file, -1, "Found a symbol definition: "+symbol, severity, symbol);
+ }
+
+ }
+ return false;
+ }
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsBuilder.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsBuilder.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsBuilder.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsBuilder.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,271 @@
+/**********************************************************************
+ * 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.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.CCProjectNature;
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.CProjectNature;
+import org.eclipse.cdt.core.CommandLauncher;
+import org.eclipse.cdt.core.ErrorParserManager;
+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.ISpecsBuilder;
+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;
+
+/**
+ * New type
+ *
+ * @author vhirsl
+ */
+public class GCCSpecsBuilder implements ISpecsBuilder, IMarkerGenerator {
+
+ private static final String BUILD_ERROR = "SpecsBuilder.Build_Error"; //$NON-NLS-1$
+ private static final String SPECS_ERROR_PARSER = MakeCorePlugin.getUniqueIdentifier() + ".GCCSpecsParser"; //$NON-NLS-1$
+ private static final String SPECS_BUILDER_CONSOLE_ID = MakeCorePlugin.getUniqueIdentifier() + ".SpecsBuilderConsole"; //$NON-NLS-1$
+
+ private IPath workingDirectory;
+ private IProject currentProject;
+ private IPath fCompileCommand;
+ private String fCompileArguments = null;
+ private String targetFile;
+ private IScannerConfigBuilderInfo fBuildInfo;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.ISpecsBuilder#initialize(org.eclipse.core.runtime.IPath, org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo, org.eclipse.core.resources.IProject)
+ */
+ public boolean initialize(IPath workingDirectory, IScannerConfigBuilderInfo buildInfo, IProject currentProject) {
+ boolean rc = false;
+ this.workingDirectory = workingDirectory;
+ this.currentProject = currentProject;
+ this.fBuildInfo = buildInfo;
+ try {
+ fCompileCommand = fBuildInfo.getSpecsCommand();
+ if (fCompileCommand != null) {
+ fCompileArguments = fBuildInfo.getSpecsArguments();
+ if (currentProject.hasNature(CCProjectNature.CC_NATURE_ID)) {
+ targetFile = MakeCorePlugin.CPP_SPECS_FILE;
+ }
+ else if (currentProject.hasNature(CProjectNature.C_NATURE_ID)) {
+ targetFile = MakeCorePlugin.C_SPECS_FILE;
+ }
+ rc = true;
+ }
+ } catch (CoreException e) {
+ fCompileCommand = null;
+ CCorePlugin.log(e);
+ }
+ return rc;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.ISpecsBuilder#invokeCompiler(org.eclipse.core.runtime.IProgressMonitor, java.lang.String[])
+ */
+ public boolean invokeCompiler(IProgressMonitor monitor, String[] targetSpecificOptions) {
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+ monitor.beginTask(MakeCorePlugin.getResourceString("SpecsBuilder.Reading_Specs"), 100); //$NON-NLS-1$
+
+ try {
+ if (fCompileCommand != null) {
+ IConsole console = CCorePlugin.getDefault().getConsole("SPECS_BUILDER_CONSOLE_ID");
+ console.start(currentProject);
+ OutputStream cos = console.getOutputStream();
+
+ // Before launching give visual cues via the monitor
+ monitor.subTask(MakeCorePlugin.getResourceString("SpecsBuilder.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("SpecsBuilder.Invoking_Command")
+ + fCompileCommand.toString() + ca); //$NON-NLS-1$
+ cos = new StreamMonitor(new SubProgressMonitor(monitor, 70), cos, 100);
+ ErrorParserManager epm = new ErrorParserManager(currentProject, this, new String[] {SPECS_ERROR_PARSER});
+ epm.setOutputStream(cos);
+ OutputStream stdout = epm.getOutputStream();
+ OutputStream stderr = epm.getOutputStream();
+ Process p = launcher.execute(fCompileCommand, compileArguments, setEnvironment(launcher), workingDirectory);
+ 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(stdout, stderr, new SubProgressMonitor(monitor, 0))
+ != CommandLauncher.OK)
+ errMsg = launcher.getErrorMessage();
+ monitor.subTask(MakeCorePlugin.getResourceString("SpecsBuilder.Parsing_Output")); //$NON-NLS-1$
+ }
+ else {
+ errMsg = launcher.getErrorMessage();
+ }
+
+ if (errMsg != null) {
+ String errorDesc = MakeCorePlugin.getFormattedString(BUILD_ERROR,
+ fCompileCommand.toString() + ca);
+ epm.generateMarker(currentProject, -1, errorDesc, IMarkerGenerator.SEVERITY_ERROR_BUILD, null);
+ }
+
+ stdout.close();
+ stderr.close();
+
+ monitor.subTask(MakeCorePlugin.getResourceString("SpecsBuidler.Creating_Markers")); //$NON-NLS-1$
+ epm.reportProblems();
+ cos.close();
+ }
+ } catch (Exception e) {
+ CCorePlugin.log(e);
+ } finally {
+ monitor.done();
+ }
+ return true;
+ }
+
+ /**
+ * @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 + 1 + tso.length];
+ for (int i = 0; tokenizer.hasMoreTokens(); ++i) {
+ rv[i] = tokenizer.nextToken();
+ }
+ }
+ }
+ if (rv == null) {
+ rv = new String[1 + tso.length];
+ }
+ rv[nTokens] = targetFile;
+ for (int i = 0; i < tso.length; ++i) {
+ rv[nTokens + 1 + 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", 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;
+ }
+
+ /* (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/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;
+
+/**
+ * TODO Provide description
+ *
+ * @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$
+ new Path(".")); //$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,96 @@
+/**********************************************************************
+ * 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/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.7
diff -u -r1.7 plugin.properties
--- plugin.properties 17 Oct 2003 02:34:10 -0000 1.7
+++ plugin.properties 19 Feb 2004 16:18:28 -0000
@@ -46,3 +46,5 @@
MakefileEditor.name=Makefile Editor
+PropertyScannerConfig.name=Scanner Configuration Discovery
+PreferenceScannerConfig.name=Scanner Configuration Discovery
Index: plugin.xml
===================================================================
retrieving revision 1.26
diff -u -r1.26 plugin.xml
--- plugin.xml 2 Feb 2004 20:04:46 -0000 1.26
+++ plugin.xml 19 Feb 2004 16:18:28 -0000
@@ -399,5 +399,28 @@
</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.9
diff -u -r1.9 MakeResources.properties
--- src/org/eclipse/cdt/make/internal/ui/MakeResources.properties 13 Jan 2004 18:54:39 -0000 1.9
+++ src/org/eclipse/cdt/make/internal/ui/MakeResources.properties 19 Feb 2004 16:18:30 -0000
@@ -102,3 +102,11 @@
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.specsCmd.group_label=Generate specs command
+ScannerConfigPage.specsCmd.use_default=Use default
+ScannerConfigPage.specsCmd.label=Generate specs command:
Index: src/org/eclipse/cdt/make/ui/dialogs/SettingsBlock.java
===================================================================
retrieving revision 1.4
diff -u -r1.4 SettingsBlock.java
--- src/org/eclipse/cdt/make/ui/dialogs/SettingsBlock.java 13 Jan 2004 18:54:39 -0000 1.4
+++ src/org/eclipse/cdt/make/ui/dialogs/SettingsBlock.java 19 Feb 2004 16:18:30 -0000
@@ -91,6 +91,7 @@
if (fBuildInfo.isStopOnError()) {
stopOnErrorButton.setSelection(true);
}
+ stopOnErrorButton.setEnabled(fBuildInfo.isDefaultBuildCmd());
}
protected void createBuildCmdControls(Composite parent) {
@@ -142,8 +143,6 @@
}
if (fBuildInfo.isDefaultBuildCmd()) {
buildCommand.setEnabled(false);
- } else {
- stopOnErrorButton.setEnabled(false);
}
defButton.setSelection(fBuildInfo.isDefaultBuildCmd());
}
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 19 Feb 2004 16:18:30 -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,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.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;
+
+/**
+ * TODO: Provide description for "ScannerConfigPreferencePage".
+ * @see PreferencePage
+ */
+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() {
+ 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();
+ }
+}
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,79 @@
+/**********************************************************************
+ * 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;
+
+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() {
+ 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();
+ }
+
+}
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,277 @@
+/**********************************************************************
+ * 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 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.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.widgets.Button;
+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;
+
+/**
+ *
+ * @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 SPECS_CMD_GROUP = PREFIX + ".specsCmd.group_label"; //$NON-NLS-1$
+ private static final String SPECS_CMD_USE_DEFAULT = PREFIX + ".specsCmd.use_default"; //$NON-NLS-1$
+ private static final String SPECS_CMD_LABEL = PREFIX + ".specsCmd.label"; //$NON-NLS-1$
+
+
+ private boolean addTitle = false;
+
+ private Button autoDiscovery;
+
+ Button defButton;
+ Text specsCommand;
+
+ IScannerConfigBuilderInfo fBuildInfo;
+
+ /**
+ * 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#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);
+ }
+ }
+
+ /* (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.setUseDefaultSpecsCmd(useDefaultSpecsCmd());
+ if (!useDefaultSpecsCmd()) {
+ String specsLine = getSpecsCommandLine();
+ int start = 0;
+ int end = -1;
+ if (specsLine.startsWith("\"")) { //$NON-NLS-1$
+ start = 1;
+ end = specsLine.indexOf('"', 1);
+ }
+ else {
+ end = specsLine.indexOf(' ');
+ }
+ IPath path;
+ if (end == -1) {
+ path = new Path(specsLine);
+ } else {
+ path = new Path(specsLine.substring(start, end));
+ }
+ buildInfo.setSpecsCommand(path);
+ String args = ""; //$NON-NLS-1$
+ if (end != -1) {
+ args = specsLine.substring(end + 1);
+ }
+ buildInfo.setSpecsArguments(args);
+ }
+ }
+
+ /* (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.getSpecsCommand();
+ if (sCommand != null) {
+ StringBuffer cmd = new StringBuffer(sCommand.toOSString());
+ String args = buildInfo.getSpecsArguments();
+ if (args != null && !args.equals("")) { //$NON-NLS-1$
+ cmd.append(' ');
+ cmd.append(args);
+ }
+ specsCommand.setText(cmd.toString());
+ }
+ if (buildInfo.isDefaultSpecsCmd()) {
+ specsCommand.setEnabled(false);
+ } else {
+ specsCommand.setEnabled(true);
+ }
+ defButton.setSelection(buildInfo.isDefaultSpecsCmd());
+ }
+
+ /* (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);
+ createSpecsCmdControls(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 createSpecsCmdControls(Composite parent) {
+ Group group = ControlFactory.createGroup(parent, MakeUIPlugin.getResourceString(SPECS_CMD_GROUP), 2);
+ defButton = ControlFactory.createCheckBox(group, MakeUIPlugin.getResourceString(SPECS_CMD_USE_DEFAULT));
+ defButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (useDefaultSpecsCmd() == true) {
+ specsCommand.setEnabled(false);
+ } else {
+ specsCommand.setEnabled(true);
+ }
+ getContainer().updateContainer();
+ }
+ });
+ ((GridData) (defButton.getLayoutData())).horizontalAlignment = GridData.FILL_HORIZONTAL;
+ ((GridData) (defButton.getLayoutData())).horizontalSpan = 2;
+ Label label = ControlFactory.createLabel(group, MakeUIPlugin.getResourceString(SPECS_CMD_LABEL));
+ ((GridData) (label.getLayoutData())).horizontalAlignment = GridData.BEGINNING;
+ ((GridData) (label.getLayoutData())).grabExcessHorizontalSpace = false;
+ specsCommand = ControlFactory.createTextField(group, SWT.SINGLE | SWT.BORDER);
+ ((GridData) (specsCommand.getLayoutData())).horizontalAlignment = GridData.FILL;
+ ((GridData) (specsCommand.getLayoutData())).grabExcessHorizontalSpace = true;
+ specsCommand.addListener(SWT.Modify, new Listener() {
+ public void handleEvent(Event e) {
+ getContainer().updateContainer();
+ }
+ });
+ IPath sCommand = fBuildInfo.getSpecsCommand();
+ if (sCommand != null) {
+ StringBuffer cmd = new StringBuffer(sCommand.toOSString());
+ String args = fBuildInfo.getSpecsArguments();
+ if (args != null && !args.equals("")) { //$NON-NLS-1$
+ cmd.append(' ');
+ cmd.append(args);
+ }
+ specsCommand.setText(cmd.toString());
+ }
+ if (fBuildInfo.isDefaultSpecsCmd()) {
+ specsCommand.setEnabled(false);
+ }
+ defButton.setSelection(fBuildInfo.isDefaultSpecsCmd());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#getErrorMessage()
+ */
+ public String getErrorMessage() {
+ if (!useDefaultSpecsCmd()) {
+ String cmd = getSpecsCommandLine();
+ if (cmd == null || cmd.length() == 0) {
+ return "Must enter a 'specs' command"; //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+
+ private boolean useDefaultSpecsCmd() {
+ return defButton.getSelection();
+ }
+
+ private String getSpecsCommandLine() {
+ return specsCommand.getText().trim();
+ }
+}