Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: Rejected: Re: [cdt-patch] Resubmitted: CDT2.0 Scanner Configuration discovery - initial work

I like this, as it more clearly defines areas in which various integration pieces (gnu) belong, and moves toward what I have always thought the core CDT should be, which is just a core C/C++ language framework we build on top of to integrate C/C++ development tools.

Douglas Schaefer wrote:

Thanks, Dave

+1 on Dave's comments.

That also get's me thinking. I wonder if it is time to create new plugins for the Gnu build integrations. We should be able to remove all such integrations as we have done for MI in Debug. This would include such things as the gcc error parsers, gcc managed build tool defs, the gcc extensions for standard make build output scanning (Vlad's work), etc. Thoughts?

Then maybe we can get our friends from Microsoft who we met at the EclipseCon BOF to do the integration for Visual C++ :-).

Doug Schaefer, Senior Software Developer
IBM Rational Software, Ottawa, Ontario, Canada



David Inglis <dinglis@xxxxxxx> Sent by: cdt-patch-admin@xxxxxxxxxxx
02/19/2004 08:30 AM
Please respond to
cdt-patch@xxxxxxxxxxx


To
cdt-patch@xxxxxxxxxxx
cc

Subject
Rejected: Re: [cdt-patch] Resubmitted: CDT2.0 Scanner Configuration discovery - initial work






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. 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). Thirdly I have noticed some strange naming in the schema and in some javadoc..."org.vmir.cdt....."
Please revise.

Thanks
Dave.


Vladimir Hirsl wrote:

This is the resubmission of the initial patch.

This patch contains initial work for Scanner Configuration discovery feature. Also there is a simple UI interface (preference, project
property
and New Standard Make project wizard pages). The feature is disabled by default so it does not affect existing projects inadvertently. If turned on, it will populate C/C++ Make Project's Paths and Symbols tab with discovered info (preserving user specified entries). The discovered cygpath include paths are now translated to the absolute paths. Relative include paths are still not handled properly. Further refinements are coming along.

Please, apply to the head branch.

Thanks,
Vladimir Hirsl
Rational Software - IBM Software Group
Ottawa, Ontario, Canada

[attachment "cdt.make.core.txt" deleted by Vladimir Hirsl/Ottawa/IBM] [attachment "cdt.make.ui.txt" deleted by Vladimir Hirsl/Ottawa/IBM]


------------------------------------------------------------------------

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           18 Feb 2004 21:46:42 -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          18 Feb 2004 21:46:42 -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.core.scannerconfig.gnu.GCCScannerInfoParser">
+      </errorparser>
+   </extension>
+   <extension
+         id="GCCSpecsParser"
+         name="%epGnuCompilerSpecs.name"
+         point="org.eclipse.cdt.core.ErrorParser">
+      <errorparser
+
class="org.eclipse.cdt.make.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.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.11
diff -u -r1.11 MakeCorePlugin.java
--- src/org/eclipse/cdt/make/core/MakeCorePlugin.java 24 Sep
2003 18:03:36 -0000              1.11
+++ src/org/eclipse/cdt/make/core/MakeCorePlugin.java 18 Feb
2004 21:46:42 -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";
              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.4
diff -u -r1.4 PluginResources.properties
--- src/org/eclipse/cdt/make/core/PluginResources.properties 24 Sep 2003
14:20:21 -0000           1.4
+++ src/org/eclipse/cdt/make/core/PluginResources.properties 18 Feb 2004
21:46:42 -0000
@@ -11,3 +11,16 @@
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

+
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.vmir.cdt.scannerconfig">
+<annotation>
+      <appInfo>
+ <meta.schema plugin="org.vmir.cdt.scannerconfig"
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 &lt;samp&gt;org.eclipse.cdt.make.core.scannerconfig.ISpecsBuilder&lt;/samp&gt; interface.
+               </documentation>
+               <appInfo>
+ <meta.attribute kind="java"
basedOn="org.vmir.cdt.scannerconfig.core.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 fo 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 &lt;samp&gt;org.vmir.cdt.scannerconfig.core.ISpecsBuilder&lt;/samp&gt; interface or extend &lt;samp&gt;org.vmir.cdt.scannerconfig.core.ASpecsBuilder&lt;/samp&gt; abstract base class.
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+ org.vmir.cdt.scannerconfig 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,44 @@
+/**********************************************************************
+ * 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.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/core/scannerconfig/ScannerInfoCollector.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/ScannerInfoCollector.java
diff -N
src/org/eclipse/cdt/make/core/scannerconfig/ScannerInfoCollector.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/ScannerInfoCollector.java
        1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,327 @@
+/**********************************************************************
+ * 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 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.util.CygpathTranslator;
+import org.eclipse.cdt.make.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/core/scannerconfig/gnu/GCCCompilerSpecsParser.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/gnu/GCCCompilerSpecsParser.java
diff -N
src/org/eclipse/cdt/make/core/scannerconfig/gnu/GCCCompilerSpecsParser.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++
src/org/eclipse/cdt/make/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.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.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/core/scannerconfig/gnu/GCCScannerInfoParser.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/gnu/GCCScannerInfoParser.java
diff -N
src/org/eclipse/cdt/make/core/scannerconfig/gnu/GCCScannerInfoParser.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++
src/org/eclipse/cdt/make/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.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.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/core/scannerconfig/gnu/GCCSpecsBuilder.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/gnu/GCCSpecsBuilder.java
diff -N
src/org/eclipse/cdt/make/core/scannerconfig/gnu/GCCSpecsBuilder.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/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.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/core/scannerconfig/util/CygpathTranslator.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/util/CygpathTranslator.java
diff -N
src/org/eclipse/cdt/make/core/scannerconfig/util/CygpathTranslator.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++
src/org/eclipse/cdt/make/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.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/core/scannerconfig/util/ScannerConfigUtil.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/util/ScannerConfigUtil.java
diff -N
src/org/eclipse/cdt/make/core/scannerconfig/util/ScannerConfigUtil.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++
src/org/eclipse/cdt/make/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.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/core/scannerconfig/util/SymbolEntry.java
===================================================================
RCS file:
src/org/eclipse/cdt/make/core/scannerconfig/util/SymbolEntry.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/util/SymbolEntry.java
--- /dev/null           1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/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.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:
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.vmir.cdt.scannerconfig.make.core.IScannerConfigBuilderInfo#isAutoDiscoveryEnabled()
+                                */
+                               public boolean isAutoDiscoveryEnabled() {
+ return
getBoolean(BUILD_SCANNER_CONFIG_ENABLED);
+                               }
+
+                               /* (non-Javadoc)
+ * @see
org.vmir.cdt.scannerconfig.make.core.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: 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           18 Feb 2004 21:47:23 -0000
@@ -46,3 +46,5 @@

MakefileEditor.name=Makefile Editor

+PropertyScannerConfig.name=Project 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          18 Feb 2004 21:47:24 -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 18 Feb
2004 21:47:26 -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 18 Feb 2004
21:47:26 -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
18 Feb 2004 21:47:26 -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), 1);
+ 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();
+               }
+}


_______________________________________________
cdt-patch mailing list
cdt-patch@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/cdt-patch





Back to the top