diff --git a/core/org.eclipse.cdt.core/.classpath b/core/org.eclipse.cdt.core/.classpath
index 3dc95b34efc..1c9f189c9d3 100644
--- a/core/org.eclipse.cdt.core/.classpath
+++ b/core/org.eclipse.cdt.core/.classpath
@@ -1,10 +1,10 @@
+ * Abstract base class to make the life of ICTool implementers + * somewhat simpler. + *
+ * Provides default implementations of all methods, such that + * a basic tool can be defined simply by calling the appropriate + * constructor. + *
+ * Examples: + *
+ *
+ * class CGenericTool extends ACTool {
+ * CGenericTool() {
+ * super("typeid", "toolid", "toolname");
+ * }
+ * }
+ *
+ * class CExplicitTool extends ACTool {
+ * CGenericTool(IPath pathToTool) {
+ * super("typeid", "toolid", pathToTool);
+ * }
+ * }
+ *
+ */
+public abstract class ACTool implements ICTool {
+
+ private String fTypeId;
+ private String fToolId;
+ private IPath fToolPath;
+
+ /**
+ * Constructor.
+ *
+ * Create a tool with the given type ID and unqiue ID by specifying
+ * the absolute path to the executable.
+ *
+ * @param typeId tool type ID, corresponds to a CToolType extension ID.
+ * @param id unqiue identifier for this tool instance.
+ * @param path explicit path to the tool.
+ */
+ public ACTool(String typeId, String id, IPath path) {
+ fTypeId = typeId;
+ fToolId = id;
+ fToolPath = path;
+ }
+
+ /**
+ * Constructor.
+ *
+ * Create a tool with the given type ID and unqiue ID by specifying
+ * the name of an executable. The executable is located using the
+ * "which" utility.
+ *
+ * @param typeId tool type ID, corresponds to a CToolType extension ID.
+ * @param id unqiue identifier for this tool instance.
+ * @param name name of the tool executable.
+ */
+ public ACTool(String typeId, String id, String exeName) {
+ fTypeId = typeId;
+ fToolId = id;
+ fToolPath = locateExe(exeName);
+ }
+
+ /**
+ * Locate the given executable by running "which name".
+ *
+ * @param name of executable.
+ * @param path to executable.
+ * @return path specifying the location of the executable
+ * with the given name. If the executable could not be
+ * located, returns null.
+ */
+ protected IPath locateExe(String name) {
+ IOResults ior = execHelper("which", new String[] { name }, null);
+ if (ior.stdout.size() > 0) {
+ return new Path(
+ Filesystem.getNativePath(ior.stdout.toString().trim()));
+ }
+ return null;
+ }
+
+ /**
+ * Explicity set the path to this tool's executable.
+ *
+ * @param path path to executable.
+ */
+ protected void setPath(String path) {
+ fToolPath = new Path(path);
+ }
+
+ /**
+ * Helper method that runs this tool using the provided parameters.
+ *
+ * @param parameters parameters to pass to tool when executing.
+ * @param workingDir working directory for tool execution.
+ * @return object IOResults object containing the stdout and stderr
+ * streams that resulted from running the tool.
+ */
+ protected IOResults execHelper(String[] parameters, String workingDir) {
+ return execHelper(
+ fToolPath.toString(),
+ parameters,
+ new File(workingDir));
+ }
+
+ /**
+ * Helper method that runs a specified tool using the provided parameters.
+ *
+ * @param exeName name of executable; may be a simple name or a full path.
+ * @param parameters parameters to pass to tool when executing.
+ * @param workingDir working directory for tool execution.
+ * @return object IOResults object containing the stdout and stderr
+ * streams that resulted from running the tool.
+ */
+ protected IOResults execHelper(
+ String exeName,
+ String[] parameters,
+ File dir) {
+ IOResults ior = new IOResults();
+ String[] cmds = new String[parameters.length + 1];
+
+ cmds[0] = exeName;
+ for (int i = 1; i < cmds.length; i++) {
+ cmds[i] = parameters[i - 1];
+ }
+
+ try {
+ ProcessFactory pf = ProcessFactory.getFactory();
+ Process pid = pf.exec(cmds, null, dir);
+ ProcessClosure pc = new ProcessClosure(pid, ior.stdout, ior.stderr);
+ pc.runBlocking();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return ior;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICTool#getTypeId()
+ */
+ public String getTypeId() {
+ return fTypeId;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICTool#getId()
+ */
+ public String getId() {
+ return fToolId;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICTool#getPath()
+ */
+ public IPath getPath() {
+ return (IPath) fToolPath.clone();
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICTool#exists()
+ */
+ public boolean exists() {
+ return fToolPath.toFile().exists();
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICTool#exec(String[], String)
+ */
+ public IOResults exec(String[] parameters, String workingDir) {
+ return execHelper(parameters, workingDir);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ACToolchainProvider.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ACToolchainProvider.java
new file mode 100644
index 00000000000..decaf3f352f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ACToolchainProvider.java
@@ -0,0 +1,132 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.core.builder.model.ICToolchain;
+import org.eclipse.cdt.core.builder.model.ICToolchainProvider;
+
+/**
+ * Abstract base class to make the life of ICToolchainProvider
+ * implementers somewhat simpler.
+ *
+ * Provides default implementations of all methods, such that + * a basic toolchain can be defined simply by implementing the + * abstract doRefresh() method. + *
+ * Examples: + *
+ *
+ * class CGenericToolchain extends ACToolchainProvider {
+ * void doRefresh() {
+ * ICToolchain tc = readToolchainInfoFromFile();
+ * addToolchain(tc.getId(), tc);
+ * }
+ * }
+ *
+ */
+public abstract class ACToolchainProvider implements ICToolchainProvider {
+
+ /**
+ * Internal map of toolchain ID to toolchain instances.
+ */
+ private Map fToolchainMap;
+
+ /**
+ * Constructor.
+ *
+ * Creates a new toolchain map, then calls the abstract
+ * doRefresh() method to allow derived classes to populate
+ * the map.
+ */
+ public ACToolchainProvider() {
+ fToolchainMap = new HashMap();
+ doRefresh();
+ }
+
+ /**
+ * Determines if a toolchain exists in the internal map of
+ * toolchain instances.
+ *
+ * @param id toolchain identifier.
+ * @return true if there is a toolchain instances that corresponds
+ * to the provided id.
+ */
+ protected boolean toolchainExists(String id) {
+ return fToolchainMap.containsKey(id);
+ }
+
+ /**
+ * Add a toolchain to the internal map of toolchain instances.
+ *
+ * @param id toolchain identifier.
+ * @param tc toolchain instance.
+ */
+ protected void addToolchain(String id, ICToolchain tc) {
+ fToolchainMap.put(id, tc);
+ }
+
+ /**
+ * Helper method used to retrieve a toolchain from the internal
+ * map of toolchain instances.
+ *
+ * @param id toolchain identifier.
+ * @return toolchain instance, or null if not found.
+ */
+ protected ICToolchain getToolchainHelper(String id) {
+ ICToolchain tc = null;
+ Object obj = fToolchainMap.get(id);
+ if (obj instanceof ICToolchain) {
+ tc = (ICToolchain) obj;
+ }
+ return tc;
+ }
+
+ /**
+ * Remove a toolchain from the internal map of toolchain instances.
+ *
+ * @param id toolchain identifier.
+ * @return true if toolchain is removed.
+ */
+ protected boolean removeToolchain(String id) {
+ boolean exists = toolchainExists(id);
+ if (exists) {
+ Object obj = fToolchainMap.remove(id);
+ obj = null;
+ }
+ return exists;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICToolchainProvider#getToolchain(String)
+ */
+ public ICToolchain getToolchain(String id) {
+ return getToolchainHelper(id);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICToolchainProvider#getToolchains()
+ */
+ public ICToolchain[] getToolchains() {
+ Collection tcc = fToolchainMap.values();
+ return (ICToolchain[]) tcc.toArray(new ICToolchain[tcc.size()]);
+ }
+
+ /**
+ * Implemented by derived classes. Called whenever the toolchain list needs
+ * to be refreshed.
+ */
+ abstract public void doRefresh();
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/BuilderPlugin.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/BuilderPlugin.java
new file mode 100644
index 00000000000..41baeaf18c2
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/BuilderPlugin.java
@@ -0,0 +1,247 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.builder.internal.CBuildConfigPoint;
+import org.eclipse.cdt.core.builder.internal.CBuildVariablePoint;
+import org.eclipse.cdt.core.builder.internal.CToolPoint;
+import org.eclipse.cdt.core.builder.internal.CToolTypePoint;
+import org.eclipse.cdt.core.builder.internal.CToolchainPoint;
+import org.eclipse.cdt.core.builder.model.ICToolType;
+import org.eclipse.cdt.core.builder.model.internal.CBuildConfigManager;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPluginDescriptor;
+
+/**
+ * Fragments aren't first class citizens in the Eclipse world.
+ * This class lets me write code in the experimental builder
+ * fragment as if there was a real plugin class that implemented
+ * some of these methods.
+ *
+ * Also - I'm not sure that some of these methods don't belong + * elsewhere. Suggestions are welcome. + */ +public class BuilderPlugin { + + // Pretend this is a real plugin. + static private BuilderPlugin thisPlugin; + + // Pretend this is a real plugin. + static { + thisPlugin = new BuilderPlugin(); + thisPlugin.loadToolTypes(); + thisPlugin.loadToolProviders(); + thisPlugin.loadToolchainProviders(); + thisPlugin.loadConfigProviders(); + thisPlugin.loadBuildVarProviders(); + thisPlugin.dump(); + } + + // Pretend this is a real plugin. + private BuilderPlugin() { + fBuildConfigManager = new CBuildConfigManager(); + } + + // Pretend this is a real plugin. + private void dump() { + for (Iterator iter = fToolTypes.entrySet().iterator(); + iter.hasNext(); + ) { + ICToolType element = + (ICToolType) ((Map.Entry) iter.next()).getValue(); + System.err.println( + "Tool type (" + + element.getName() + + ", " + + element.getId() + + ")"); + } + for (Iterator iter = fToolProviders.entrySet().iterator(); + iter.hasNext(); + ) { + ICToolPoint element = + (ICToolPoint) ((Map.Entry) iter.next()).getValue(); + System.err.println( + "Tool (" + + element.getName() + + ", " + + element.getId() + + ", " + + element.getProviderClassName() + + ")"); + } + for (Iterator iter = fToolchainProviders.entrySet().iterator(); + iter.hasNext(); + ) { + ICToolchainPoint element = + (ICToolchainPoint) ((Map.Entry) iter.next()).getValue(); + System.err.println( + "Toolchain (" + + element.getId() + + ", " + + element.getProviderClassName() + + ")"); + } + for (Iterator iter = fBuildConfigProviders.entrySet().iterator(); + iter.hasNext(); + ) { + ICBuildConfigPoint element = + (ICBuildConfigPoint) ((Map.Entry) iter.next()).getValue(); + System.err.println( + "BuildConfig (" + + element.getName() + + ", " + + element.getId() + + ", " + + element.getProviderClassName() + + ")"); + } + for (Iterator iter = fBuildVarProviders.entrySet().iterator(); + iter.hasNext(); + ) { + ICBuildVariablePoint element = + (ICBuildVariablePoint) ((Map.Entry) iter.next()).getValue(); + System.err.println( + "BuildVar (" + + element.getId() + + ", " + + element.getProviderClassName() + + ")"); + } + } + + // Pretend this is a real plugin. + static public BuilderPlugin getDefault() { + return thisPlugin; + } + + // Pretend this is a real plugin. + public IPluginDescriptor getDescriptor() { + return CCorePlugin.getDefault().getDescriptor(); + } + + /* + * Data and methods to merge with CCorePlugin + */ + + private CBuildConfigManager fBuildConfigManager; + private Map fToolTypes; + private Map fToolProviders; + private Map fToolchainProviders; + private Map fBuildConfigProviders; + private Map fBuildVarProviders; + + public CBuildConfigManager getBuildConfigurationManager() { + return fBuildConfigManager; + } + + public Map getToolTypes() { + return fToolTypes; + } + + public Map getToolProviders() { + return fToolProviders; + } + + public Map getToolchainProviders() { + return fToolchainProviders; + } + + public Map getBuildConfigurationProviders() { + return fBuildConfigProviders; + } + + public Map getBuildVariableProviders() { + return fBuildVarProviders; + } + + private void loadToolTypes() { + IPluginDescriptor descriptor = getDefault().getDescriptor(); + IExtensionPoint extensionPoint = + descriptor.getExtensionPoint("CToolType"); + IExtension[] exts = extensionPoint.getExtensions(); + IConfigurationElement[] infos = + extensionPoint.getConfigurationElements(); + fToolTypes = new HashMap(infos.length); + for (int i = 0; i < infos.length; i++) { + IConfigurationElement configurationElement = infos[i]; + CToolTypePoint provider = new CToolTypePoint(configurationElement); + fToolTypes.put(provider.getId(), provider); + } + } + + private void loadToolProviders() { + IPluginDescriptor descriptor = getDefault().getDescriptor(); + IExtensionPoint extensionPoint = descriptor.getExtensionPoint("CTool"); + IConfigurationElement[] infos = + extensionPoint.getConfigurationElements(); + fToolProviders = new HashMap(infos.length); + for (int i = 0; i < infos.length; i++) { + IConfigurationElement configurationElement = infos[i]; + CToolPoint provider = new CToolPoint(configurationElement); + fToolProviders.put(provider.getId(), provider); + } + } + + private void loadToolchainProviders() { + IPluginDescriptor descriptor = getDefault().getDescriptor(); + IExtensionPoint extensionPoint = + descriptor.getExtensionPoint("CToolchain"); + IConfigurationElement[] infos = + extensionPoint.getConfigurationElements(); + fToolchainProviders = new HashMap(infos.length); + for (int i = 0; i < infos.length; i++) { + IConfigurationElement configurationElement = infos[i]; + CToolchainPoint provider = + new CToolchainPoint(configurationElement); + fToolchainProviders.put(provider.getId(), provider); + } + } + + private void loadConfigProviders() { + IPluginDescriptor descriptor = getDefault().getDescriptor(); + IExtensionPoint extensionPoint = + descriptor.getExtensionPoint("CBuildConfig"); + IConfigurationElement[] infos = + extensionPoint.getConfigurationElements(); + fBuildConfigProviders = new HashMap(infos.length); + for (int i = 0; i < infos.length; i++) { + IConfigurationElement configurationElement = infos[i]; + CBuildConfigPoint provider = + new CBuildConfigPoint(configurationElement); + fBuildConfigProviders.put(provider.getId(), provider); + } + } + + private void loadBuildVarProviders() { + IPluginDescriptor descriptor = getDefault().getDescriptor(); + IExtensionPoint extensionPoint = + descriptor.getExtensionPoint("CBuildVariable"); + IConfigurationElement[] infos = + extensionPoint.getConfigurationElements(); + fBuildVarProviders = new HashMap(infos.length); + for (int i = 0; i < infos.length; i++) { + IConfigurationElement configurationElement = infos[i]; + CBuildVariablePoint provider = + new CBuildVariablePoint(configurationElement); + fBuildVarProviders.put(provider.getId(), provider); + } + } + +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICBuildConfigPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICBuildConfigPoint.java new file mode 100644 index 00000000000..584dfb3a3f2 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICBuildConfigPoint.java @@ -0,0 +1,59 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder; + +import org.eclipse.cdt.core.builder.model.ICBuildConfigProvider; +import org.eclipse.core.runtime.CoreException; + +/** + * Interface representing an instance of + * a CBuildConfig extension point. + */ +public interface ICBuildConfigPoint { + + /** + * Returns the unique id for the provider. + * + * @return unique id. + */ + public String getId(); + + /** + * Returns the name of the provider. + * + * @return provider name. + */ + public String getName(); + + /** + * Returns the natures supported by the provider. + * + * @return natures supported by the provider. + */ + public String[] getNatures(); + + /** + * Returns the name of the provider's + * implementing class. + * + * @return name of the provider's implementing class. + */ + public String getProviderClassName(); + + /** + * Returns an instance of the provider's + * implementing class. + * + * @return instance of ICBuildConfigProvider. + */ + public ICBuildConfigProvider getProvider() throws CoreException; +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICBuildVariablePoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICBuildVariablePoint.java new file mode 100644 index 00000000000..6e17d20d87f --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICBuildVariablePoint.java @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder; + +import org.eclipse.cdt.core.builder.model.ICBuildVariableProvider; +import org.eclipse.core.runtime.CoreException; + +/** + * Interface representing an instance of + * a CBuildVariable extension point. + */ +public interface ICBuildVariablePoint { + /** + * Returns the unique id for the provider. + * + * @return unique id. + */ + public String getId(); + + /** + * Returns the the natures supported by the provider. + * + * @return the natures supported by the provider. + */ + public String[] getNatures(); + + /** + * Returns the name of the provider's + * implementing class. + * + * @return name of the provider's implementing class. + */ + public String getProviderClassName(); + + /** + * Returns an instance of the provider's + * implementing class. + * + * @return instance of ICBuildVariableProvider. + */ + public ICBuildVariableProvider getProvider() throws CoreException; +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolPoint.java new file mode 100644 index 00000000000..07e66fa7079 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolPoint.java @@ -0,0 +1,59 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder; + +import org.eclipse.cdt.core.builder.model.ICTool; +import org.eclipse.core.runtime.CoreException; + +/** + * Interface representing an instance of + * a CTool extension point. + */ +public interface ICToolPoint { + + /** + * Returns the unique id for the provider. + * + * @return unique id. + */ + public String getId(); + + /** + * Returns the name of the provider. + * + * @return provider name. + */ + public String getName(); + + /** + * Returns the string identifying the type of tool. + * + * @return type string. + */ + public String getType(); + + /** + * Returns the name of the provider's + * implementing class. + * + * @return name of the provider's implementing class. + */ + public String getProviderClassName(); + + /** + * Returns an instance of the provider's + * implementing class. + * + * @return instance of ICToolProvider. + */ + public ICTool getProvider() throws CoreException; +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolTypePoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolTypePoint.java new file mode 100644 index 00000000000..769942ea309 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolTypePoint.java @@ -0,0 +1,24 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder; + +import org.eclipse.cdt.core.builder.model.ICToolType; + +/** + * Interface representing an instance of + * a CToolType extension point. + *
+ * This interface exists solely to parallel the + * other extension point interfaces (ICToolPoint, etc.) + */ +public interface ICToolTypePoint extends ICToolType { +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolchainPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolchainPoint.java new file mode 100644 index 00000000000..bd9deed7a61 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ICToolchainPoint.java @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder; + +import org.eclipse.cdt.core.builder.model.ICToolchainProvider; +import org.eclipse.core.runtime.CoreException; + +/** + * Interface representing an instance of + * a CToolchain extension point. + */ +public interface ICToolchainPoint { + /** + * Returns the unique id for the provider. + * + * @return unique id. + */ + public String getId(); + + /** + * Returns the natures supported by the provider. + * + * @return natures supported by the provider. + */ + public String[] getNatures(); + + /** + * Returns the name of the provider's + * implementing class. + * + * @return name of the provider's implementing class. + */ + public String getProviderClassName(); + + /** + * Returns an instance of the provider's + * implementing class. + * + * @return instance of ICToolchainProvider. + */ + public ICToolchainProvider getProvider() throws CoreException; +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/ACExtensionPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/ACExtensionPoint.java new file mode 100644 index 00000000000..01e92047df8 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/ACExtensionPoint.java @@ -0,0 +1,124 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.internal; + +import java.util.StringTokenizer; +import java.util.Vector; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Abstract base class that represents information + * associated with a declared extension point. + *
+ * Derived classes are expected to implement their + * own getter functions to return data from the + * associated IConfigurationElement in a reasonable + * format. + */ +public abstract class ACExtensionPoint { + + public final static String FIELD_ID = "id"; //$NON-NLS-1$ + public final static String FIELD_NAME = "name"; //$NON-NLS-1$ + public final static String FIELD_TYPE = "name"; //$NON-NLS-1$ + public final static String FIELD_NATURES = "natures"; //$NON-NLS-1$ + public final static String FIELD_CLASS = "class"; //$NON-NLS-1$ + + /** + * Configuration element associated with this class. + * CONSIDER: is it expensive to hold on to this? + */ + private IConfigurationElement fElement; + + /** + * Constructor. + * + * @param element configuration element for the build configuration provider. + */ + public ACExtensionPoint(IConfigurationElement element) { + fElement = element; + } + + /** + * Returns the configuration element for the build configuration provider. + * + * @return configuration element + */ + protected IConfigurationElement getConfigurationElement() { + return fElement; + } + + /** + * Breaks up a token-delimited string into individual tokens. + * + * @param data string to tokenize. + * @param sep delimiter character(s). + * @return array of tokens extracted from the string. + */ + protected String[] parseField(String data, String sep) { + Vector res = new Vector(); + StringTokenizer st = new StringTokenizer(data, sep); + while (st.hasMoreElements()) { + res.add(st.nextElement()); + } + return (String[]) res.toArray(new String[res.size()]); + } + + /** + * Returns the value of the named field from the configuration element. + * If the named field is not present or has no value, returns an empty + * string. + * + * @param fieldName name of field. + * @return value of named field, or "". + */ + protected String getField(String fieldName) { + return getField(fieldName, ""); //$NON-NLS-1$ + } + + /** + * Returns the value of the named field from the configuration element. + * If the named field is not present or has no value, returns the + * specified default value. + * + * @param fieldName name of field. + * @param defaultValue default value if field not present. + * @return value of named field, or default. + */ + protected String getField(String fieldName, String defaultValue) { + String val = getConfigurationElement().getAttribute(fieldName); + return val != null ? val : defaultValue; + } + + /** + * Returns an instance of of an implementing class. This + * method uses the value of the FIELD_CLASS attribute in + * the configuration element to create the class. + * + * @return instance of provider class. + */ + protected Object getClassInstance() throws CoreException { + return getClassInstance(FIELD_CLASS); + } + + /** + * Returns an instance of of an implementing class. + * + * @param fieldName name of field. + * @return instance of provider class. + */ + protected Object getClassInstance(String fieldName) throws CoreException { + return getConfigurationElement().createExecutableExtension(fieldName); + } + +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CBuildConfigPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CBuildConfigPoint.java new file mode 100644 index 00000000000..7ffd3293b9f --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CBuildConfigPoint.java @@ -0,0 +1,70 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.internal; + +import org.eclipse.cdt.core.builder.ICBuildConfigPoint; +import org.eclipse.cdt.core.builder.model.ICBuildConfigProvider; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Simple wrapper for the data associated with an instance of + * a CBuildConfig extension point. + */ +public class CBuildConfigPoint + extends ACExtensionPoint + implements ICBuildConfigPoint { + + /** + * Constructor. + * + * @param element configuration element for the build configuration provider. + */ + public CBuildConfigPoint(IConfigurationElement element) { + super(element); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildConfigPoint#getId() + */ + public String getId() { + return getField(FIELD_ID); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildConfigPoint#getName() + */ + public String getName() { + return getField(FIELD_NAME); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildConfigPoint#getNatures() + */ + public String[] getNatures() { + return parseField(getField(FIELD_NATURES, "*"), ";"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildConfigPoint#getProviderClassName() + */ + public String getProviderClassName() { + return getField(FIELD_CLASS); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildConfigPoint#getProvider() + */ + public ICBuildConfigProvider getProvider() throws CoreException { + return (ICBuildConfigProvider) getClassInstance(FIELD_CLASS); + } +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CBuildVariablePoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CBuildVariablePoint.java new file mode 100644 index 00000000000..bb4b310aacf --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CBuildVariablePoint.java @@ -0,0 +1,64 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.internal; + +import org.eclipse.cdt.core.builder.ICBuildVariablePoint; +import org.eclipse.cdt.core.builder.model.ICBuildVariableProvider; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Simple wrapper for the data associated with an instance of + * a CBuildVariable extension point. + */ + +public class CBuildVariablePoint + extends ACExtensionPoint + implements ICBuildVariablePoint { + + /** + * Constructor. + * + * @param element configuration element for the build variable provider. + */ + public CBuildVariablePoint(IConfigurationElement element) { + super(element); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildVariablePoint#getId() + */ + public String getId() { + return getField(FIELD_ID); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildVariablePoint#getNatures() + */ + public String[] getNatures() { + return parseField(getField(FIELD_NATURES, "*"), ";"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildVariablePoint#getProviderClassName() + */ + public String getProviderClassName() { + return getField(FIELD_CLASS); + } + + /** + * @see org.eclipse.cdt.core.builder.ICBuildVariablePoint#getProvider() + */ + public ICBuildVariableProvider getProvider() throws CoreException { + return (ICBuildVariableProvider) getClassInstance(FIELD_CLASS); + } +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolPoint.java new file mode 100644 index 00000000000..95eb59e32b9 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolPoint.java @@ -0,0 +1,69 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.internal; + +import org.eclipse.cdt.core.builder.ICToolPoint; +import org.eclipse.cdt.core.builder.model.ICTool; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Simple wrapper for the data associated with an instance of + * a CTool extension point. + */ + +public class CToolPoint extends ACExtensionPoint implements ICToolPoint { + + /** + * Constructor. + * + * @param element configuration element for the tool type. + */ + public CToolPoint(IConfigurationElement element) { + super(element); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolPoint#getId() + */ + public String getId() { + return getField(FIELD_ID); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolPoint#getName() + */ + public String getName() { + return getField(FIELD_NAME); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolPoint#getType() + */ + public String getType() { + return getField(FIELD_TYPE); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolPoint#getProviderClassName() + */ + public String getProviderClassName() { + return getField(FIELD_CLASS); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolPoint#getProvider() + */ + public ICTool getProvider() throws CoreException { + return (ICTool) getClassInstance(FIELD_CLASS); + } +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolTypePoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolTypePoint.java new file mode 100644 index 00000000000..435651dd65e --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolTypePoint.java @@ -0,0 +1,48 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.internal; + +import org.eclipse.cdt.core.builder.ICToolTypePoint; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Simple wrapper for the data associated with an instance of + * a CToolType extension point. + */ +public class CToolTypePoint + extends ACExtensionPoint + implements ICToolTypePoint { + + /** + * Constructor. + * + * @param element configuration element for the tool type. + */ + public CToolTypePoint(IConfigurationElement element) { + super(element); + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolType#getId() + */ + public String getId() { + return getField(FIELD_ID); + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolType#getName() + */ + public String getName() { + return getField(FIELD_NAME); + } + +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolchainPoint.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolchainPoint.java new file mode 100644 index 00000000000..7ccb3fea301 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/internal/CToolchainPoint.java @@ -0,0 +1,64 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.internal; + +import org.eclipse.cdt.core.builder.ICToolchainPoint; +import org.eclipse.cdt.core.builder.model.ICToolchainProvider; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Simple wrapper for the data associated with an instance of + * a CToolchain extension point. + */ + +public class CToolchainPoint + extends ACExtensionPoint + implements ICToolchainPoint { + + /** + * Constructor. + * + * @param element configuration element for the toolchain provider. + */ + public CToolchainPoint(IConfigurationElement element) { + super(element); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolchainPoint#getId() + */ + public String getId() { + return getField(FIELD_ID); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolchainPoint#getNatures() + */ + public String[] getNatures() { + return parseField(getField(FIELD_NATURES, "*"), ";"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolchainPoint#getProviderClassName() + */ + public String getProviderClassName() { + return getField(FIELD_CLASS); + } + + /** + * @see org.eclipse.cdt.core.builder.ICToolchainPoint#getProvider() + */ + public ICToolchainProvider getProvider() throws CoreException { + return (ICToolchainProvider) getClassInstance(FIELD_CLASS); + } +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/CBuildVariable.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/CBuildVariable.java new file mode 100644 index 00000000000..9c38e08d020 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/CBuildVariable.java @@ -0,0 +1,138 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +/** + * Default implementation of the ICBuildVariable interface. + *
+ * This implementation is capable of handling both static + * resolution (where the variable part is fixed at generation + * time) and dynamic resolution (where the variable part + * may change over time, depending on context.) + *
+ * @see ICBuildVariable
+ * @see ICBuildVariableProvider
+ * @see ICBuildVariableResolver
+ */
+public class CBuildVariable implements ICBuildVariable {
+
+ private String fFixed;
+ private String fVariable;
+ private ICBuildVariableResolver fResolver;
+
+ /**
+ * Default implementation of ICBuildVariableResolver that
+ * simply returns a previously provided string as the
+ * resolved value for the build variable.
+ */
+ static private class StringResolver implements ICBuildVariableResolver {
+ private String fValue;
+
+ public StringResolver(String value) {
+ fValue = value;
+ }
+
+ public String resolveValue(ICBuildVariable var) {
+ return fValue + var.getFixed();
+ }
+ };
+
+ /**
+ * Create a new build variable with the given variable
+ * and fixed elements, and a static resolver that always
+ * returns the same value for the variable portion of
+ * the variable.
+ *
+ * @param name variable portion of build variable.
+ * @param fixed fixed portion of build variable.
+ * @param resolved resolved variable value.
+ */
+ public CBuildVariable(String name, String fixed, String resolved) {
+ this(name, fixed, new StringResolver(resolved));
+ }
+
+ /**
+ * Create a new build variable with the given fixed
+ * and variable values, and a dynamic resolver for
+ * the variable portion of the variable.
+ *
+ * @param name variable portion of build variable.
+ * @param fixed fixed portion of build variable.
+ * @param resolved resolved variable value.
+ */
+ public CBuildVariable(String name, String fixed, ICBuildVariableResolver resolver) {
+ fVariable = name;
+ fFixed = fixed;
+ fResolver = resolver;
+ }
+
+ /**
+ * Create a new build variable with the given fixed
+ * and variable values, and a dynamic resolver for
+ * the variable portion of the variable.
+ *
+ * @param name variable portion of build variable.
+ * @param fixed fixed portion of build variable.
+ * @param resolved resolved variable value.
+ */
+ public CBuildVariable(String name, ICBuildVariable base) {
+ fVariable = name;
+ fFixed = base.getFixed();
+ fResolver = base.getResolver();
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICBuildVariable#getVariable()
+ */
+ public String getVariable() {
+ return fVariable;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICBuildVariable#getFixed()
+ */
+ public String getFixed() {
+ return fFixed;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICBuildVariable#getResolver()
+ */
+ public ICBuildVariableResolver getResolver() {
+ return fResolver;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.model.ICBuildVariable#getValue()
+ */
+ public String getValue() {
+ return fResolver.resolveValue(this);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ int result = 17;
+ result = (result * 37) + fVariable.hashCode();
+ result = (result * 37) + fFixed.hashCode();
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "[" + fVariable + "]" + fFixed;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildCmd.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildCmd.java
new file mode 100644
index 00000000000..86d51d4d8e4
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildCmd.java
@@ -0,0 +1,50 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * A build command is generated by a tool or toolchain, and
+ * represents a command that must be executed in order to
+ * build a file.
+ */
+public interface ICBuildCmd {
+
+ /**
+ * Tool used to process the file.
+ *
+ * @return tool used to build this file.
+ */
+ ICTool getTool();
+
+ /**
+ * File this build command applies to.
+ *
+ * @return file this build command applies to.
+ */
+ IFile getFile();
+
+ /**
+ * Parameters that are to be passed to the tool
+ * when building the file.
+ *
+ * @return parameters used to build the file.
+ */
+ String[] getParameters();
+
+ /**
+ * This is a convenience method that should
+ * simply call getTool().exec(getParameters(), workingDir);
+ */
+ boolean exec(String workingDir);
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildCmdProcessor.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildCmdProcessor.java
new file mode 100644
index 00000000000..eb09e153b21
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildCmdProcessor.java
@@ -0,0 +1,37 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+/**
+ * Consumer of build commands.
+ *
+ * "Processing" a build command might mean different
+ * things for different types of processors (ex,
+ * an incremental build processor and a makefile
+ * generator.)
+ *
+ * @see ICBuildCmd
+ */
+public interface ICBuildCmdProcessor {
+
+ /**
+ * Process the provided build commands. This
+ * might me executing the associated tool, recording
+ * the build command in a file, handing the command
+ * off to a remote processor for execution on another
+ * machine, etc.
+ *
+ * @param cmds build commands to process.
+ */
+ void processCommands(ICBuildCmd[] cmds);
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfig.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfig.java
new file mode 100644
index 00000000000..b9d8e1cb4ff
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfig.java
@@ -0,0 +1,306 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Based on org.eclipse.debug.core.ILaunchConfiguration
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A build configuration describes how to build a project. It
+ * is a collection of the various tool- and toolchain-specific
+ * settings used to process the files in a project and produce
+ * some end result.
+ *
+ * A build configuration may be shared in a repository via + * standard VCM mechanisms. + *
+ * A build configuration is a handle to its underlying storage. + *
+ * A build configuration is modified by obtaining a working copy + * of a build configuration, modifying the working copy, and then + * saving the working copy. + *
+ * This interface is not intended to be implemented by clients. + *
+ * @see ICBuildConfigWorkingCopy
+ */
+public interface ICBuildConfig extends IAdaptable {
+
+ /*
+ * TBD: add convenience methods for accessing standard elements?
+ *
+ * String[] getIncludePaths();
+ * String[] getLibPaths();
+ * String[] getLibs();
+ * String[] getOptimizationFlags();
+ * String[] getDebugFlags();
+ * String[] getWarningFlags();
+ */
+
+ /**
+ * The file extension for build configuration files
+ * (value "config"
).
+ *
+ * CONSIDER: perhaps better to have a ".cdtconfig" file containing
+ * all build configuratons for the project in one spot?
+ */
+ public static final String BUILD_CONFIGURATION_FILE_EXTENSION = "build"; //$NON-NLS-1$
+
+ /**
+ * Configuration version. Text string.
+ */
+ public final static String CONFIG_VERSION = "config.version";
+
+ /**
+ * Configuration name. Text string.
+ */
+ public final static String CONFIG_NAME = "config.name";
+
+ /**
+ * Builds this configuration.
+ *
+ * @param monitor progress monitor, or null
+ */
+ public void build(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Returns the name of this build configuration.
+ *
+ * @return the name of this build configuration
+ */
+ public String getName();
+
+ /**
+ * Returns the location of this build configuration as a
+ * path.
+ *
+ * @return the location of this build configuration as a
+ * path
+ */
+ public IPath getLocation();
+
+ /**
+ * Returns whether this build configuration's underlying
+ * storage exists.
+ *
+ * @return whether this build configuration's underlying
+ * storage exists
+ */
+ public boolean exists();
+
+ /**
+ * Returns the integer-valued attribute with the given name.
+ * Returns the given default value if the attribute is undefined.
+ *
+ * @param attributeName the name of the attribute
+ * @param defaultValue the value to use if no value is found
+ * @return the value or the default value if no value was found.
+ * @exception CoreException if this method fails. Reasons include:
+ *
java.util.List
-valued attribute with the given name.
+ * Returns the given default value if the attribute is undefined.
+ *
+ * @param attributeName the name of the attribute
+ * @param defaultValue the value to use if no value is found
+ * @return the value or the default value if no value was found.
+ * @exception CoreException if this method fails. Reasons include:
+ * java.util.Map
-valued attribute with the given name.
+ * Returns the given default value if the attribute is undefined.
+ *
+ * @param attributeName the name of the attribute
+ * @param defaultValue the value to use if no value is found
+ * @return the value or the default value if no value was found.
+ * @exception CoreException if this method fails. Reasons include:
+ * null
if this configuration is stored
+ * locally with the workspace.
+ *
+ * @return the file this build configuration is stored
+ * in, or null
if this configuration is stored
+ * locally with the workspace
+ */
+ public IFile getFile();
+
+ /**
+ * Returns the project this build configuration is stored
+ * in.
+ *
+ * @return the file this build configuration is stored in.
+ */
+ public IProject getProject();
+
+ /**
+ * Returns whether this build configuration is stored
+ * locally with the workspace.
+ *
+ * @return whether this build configuration is stored
+ * locally with the workspace
+ */
+ public boolean isLocal();
+
+ /**
+ * Returns a working copy of this build configuration.
+ * Changes to the working copy will be applied to this
+ * build configuration when saved. The working copy will
+ * refer to this build configuration as its original
+ * build configuration.
+ *
+ * @return a working copy of this build configuration
+ * @exception CoreException if this method fails. Reasons include:
+ * null
for getOriginal()
).
+ * When the working copy is saved it will not effect this
+ * build configuration.
+ *
+ * @param name the name of the copy
+ * @return a copy of this build configuration
+ * @exception CoreException if this method fails. Reasons include:
+ * null
+ * if unable to generate a memento for this configuration. A memento
+ * can be used to re-create a build configuration, via the
+ * build manager.
+ *
+ * @return a memento for this configuration
+ * @see ICBuildConfigManager#getConfiguration(IProject, String)
+ * @exception CoreException if an exception occurs generating this
+ * build configuration's memento
+ */
+ public String getMemento() throws CoreException;
+
+ /**
+ * Returns whether the contents of this build configuration are
+ * equal to the contents of the given build configuration.
+ *
+ * @return whether the contents of this build configuration are equal to the contents
+ * of the specified build configuration.
+ */
+ public boolean contentsEqual(ICBuildConfig configuration);
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigListener.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigListener.java
new file mode 100644
index 00000000000..ebd7049afca
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigListener.java
@@ -0,0 +1,47 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Based on org.eclipse.debug.core.ILaunchConfigurationListener
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+/**
+ * A build configuration listener is notified of build
+ * configurations as they are added and removed from the
+ * build configuration manager.
+ * + * Clients may implement this interface. + */ +public interface ICBuildConfigListener { + + /** + * Notifies this listener that the specified + * configuration has been removed. + * + * @param configuration the removed configuration + */ + public void configurationRemoved(ICBuildConfig configuration); + + /** + * Notifies this listener that the specified configuration + * has been added. + * + * @param configuration the newly added configuration + */ + public void configurationAdded(ICBuildConfig configuration); + + /** + * Notifies this listener that the specified configuration + * has changed. + * + * @param configuration the changed configuration + */ + public void configurationChanged(ICBuildConfig configuration); +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigManager.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigManager.java new file mode 100644 index 00000000000..1c375873ee5 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigManager.java @@ -0,0 +1,125 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Based on org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; + +/** + * The build configuration manager manages the set of registered build + * configurations. Clients interested in build configuration change + * notification may register with the build configuration manager. + *
+ * Clients are not intended to implement this interface. + *
+ * @see ICBuildConfigListener + */ +public interface ICBuildConfigManager { + + /** + * Adds the given listener to the collection of registered + * configuration listeners. Has no effect if an identical + * listener is already registerd. + * + * @param listener the listener to register + */ + public void addListener(ICBuildConfigListener listener); + + /** + * Removes the given listener from the collection of registered + * configuration listeners. Has no effect if an identical listener + * is not already registerd. + * + * @param listener the listener to deregister + */ + public void removeListener(ICBuildConfigListener listener); + + /** + * Adds the specified configuration and notifies listeners. Has no + * effect if an identical configuration is already registered. + * + * @param configuration the configuration to add + */ + public void addConfiguration(ICBuildConfig configuration); + + /** + * Removes the specified configuration and notifies listeners. + * Has no effect if an identical configuration is not already + * registered. + * + * @param configuration the configuration to remove + * @since 2.0 + */ + public void removeConfiguration(ICBuildConfig configuration); + + /** + * Returns all build configurations associated with a project. + * Returns an zero-length array if no configurations are associated + * with the project. + * + * @param project project to retrieve build configurations for. + * @return all build configurations of the specified type for the project. + * @exception CoreException if an error occurs while retreiving a build configuration + */ + public ICBuildConfig[] getConfigurations(IProject project) throws CoreException; + + /** + * Returns a handle to the configuration contained in the specified + * file. The file is not verified to exist or contain a proper + * configuration. + * + * @param file configuration file + * @return a handle to the configuration contained in the specified file + */ + public ICBuildConfig getConfiguration(IFile file); + + /** + * Returns a handle to the configuration specified by the given + * memento. The configuration may not exist. + * + * @return a handle to the configuration specified by the given memento + * @exception CoreException if the given memento is invalid or + * an exception occurs parsing the memento + */ + public ICBuildConfig getConfiguration(String memento) throws CoreException; + + /** + * Returns a handle to a newly created build configuration. + * + * @param name Name of new configuration. + * @return a handle to a new configuration instance. + */ + public ICBuildConfigWorkingCopy getConfiguration(IProject project, String name); + + /** + * Returntrue
if there is a configuration with the specified name,
+ * false
otherwise.
+ *
+ * @param name the name of the configuration whose existence is being checked
+ * @exception CoreException if unable to retrieve existing configuration names
+ */
+ public boolean isExistingConfigurationName(IProject project, String name) throws CoreException;
+
+ /**
+ * Return a String that can be used as the name of a configuration. The name
+ * is guaranteed to be unique (no existing configurations will have this name).
+ * The name that is returned uses the namePrefix
as a starting point.
+ * If there is no existing configuration with this name, then namePrefix
+ * is returned. Otherwise, the value returned consists of the specified prefix plus
+ * some suffix that guarantees uniqueness.
+ *
+ * @param namePrefix the String that the returned name must begin with
+ */
+ public String generateUniqueConfigurationNameFrom(IProject project, String namePrefix);
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigProvider.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigProvider.java
new file mode 100644
index 00000000000..2a726c8c1b7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigProvider.java
@@ -0,0 +1,34 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+/**
+ * ICBuildConfigProvider represents an instance of a class
+ * that initializes an empty build configuration with
+ * reasonable default values.
+ * + * The intent is to decouple build configuration creation + * and initialization. + *
+ * See also the CBuildConfig + * extension point documentation. + */ +public interface ICBuildConfigProvider { + + /** + * Set initial values in the provided build configuration + * working copy. + * + * @param config build configuration to initialize. + */ + public void setDefaults(ICBuildConfigWorkingCopy config); +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigWorkingCopy.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigWorkingCopy.java new file mode 100644 index 00000000000..7fcf1b3501d --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildConfigWorkingCopy.java @@ -0,0 +1,142 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; + +/** + * An editable copy of a build configuration. Attributes of a + * build configuration are modified by modifying the attributes + * of a working copy, and then saving the working copy. + *
+ * This interface is not intended to be implemented by clients. + *
+ * @see ICBuildConfig
+ */
+public interface ICBuildConfigWorkingCopy extends ICBuildConfig, IAdaptable {
+
+ /**
+ * Returns whether this configuration has been modified
+ * since it was last saved or created.
+ *
+ * @return whether this configuration has been modified
+ * since it was last saved or created
+ */
+ public boolean isDirty();
+
+ /**
+ * Saves this working copy to its underlying file and returns
+ * a handle to the resulting launch configuration.
+ * Has no effect if this configuration does not need saving.
+ * Creates the underlying file if not yet created.
+ *
+ * @exception CoreException if an exception occurs while
+ * writing this configuration to its underlying file.
+ */
+ public ICBuildConfig doSave() throws CoreException;
+
+ /**
+ * Sets the integer-valued attribute with the given name.
+ *
+ * @param attributeName the name of the attribute
+ * @param value the value
+ */
+ public void setAttribute(String attributeName, int value);
+
+ /**
+ * Sets the String-valued attribute with the given name.
+ * If the value is null
, the attribute is removed from
+ * this launch configuration.
+ *
+ * @param attributeName the name of the attribute
+ * @param value the value, or null
if the attribute is to be undefined
+ */
+ public void setAttribute(String attributeName, String value);
+
+ /**
+ * Sets the java.util.List
-valued attribute with the given name.
+ * The specified List must contain only String-valued entries.
+ * If the value is null
, the attribute is removed from
+ * this launch configuration.
+ *
+ * @param attributeName the name of the attribute
+ * @param value the value, or null
if the attribute is to be undefined
+ */
+ public void setAttribute(String attributeName, List value);
+
+ /**
+ * Sets the java.util.Map
-valued attribute with the given name.
+ * The specified Map must contain only String keys and String values.
+ * If the value is null
, the attribute is removed from
+ * this launch configuration.
+ *
+ * @param attributeName the name of the attribute
+ * @param value the value, or null
if the attribute is to be undefined
+ */
+ public void setAttribute(String attributeName, Map value);
+
+ /**
+ * Sets the boolean-valued attribute with the given name.
+ *
+ * @param attributeName the name of the attribute
+ * @param value the value
+ */
+ public void setAttribute(String attributeName, boolean value);
+
+ /**
+ * Returns the original launch configuration this working copy
+ * was created from, or null
if this is a new
+ * working copy created from a launch configuration type.
+ *
+ * @return the original launch configuration, or null
+ */
+ public ICBuildConfig getOriginal();
+
+ /**
+ * Renames this build configuration to the specified name.
+ * The new name cannot be null
. Has no effect if the name
+ * is the same as the current name. If this working copy is based
+ * on an existing build configuration, this will cause
+ * the underlying build configuration file to be renamed when
+ * this working copy is saved.
+ *
+ * @param name the new name for this configuration
+ */
+ public void rename(String name);
+
+ /**
+ * Sets the container this build configuration will be stored
+ * in when saved. When set to null
, this configuration
+ * will be stored locally with the workspace. The specified
+ * container must exist, if specified.
+ *
+ * If this configuration is changed from local to non-local, + * a file will be created in the specified container when + * saved. The local file associated with this configuration + * will be deleted. + *
+ * If this configuration is changed from non-local to local, + * a file will be created locally when saved. + * The original file associated with this configuration in + * the workspace will be deleted. + *
+ * @param container the container in which to store this
+ * build configuration, or null
if this
+ * configuration is to be stored locally
+ */
+ public void setContainer(IContainer container);
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariable.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariable.java
new file mode 100644
index 00000000000..cccf5b98a74
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariable.java
@@ -0,0 +1,73 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+/**
+ * Represents a named value that is used as a variable
+ * within the build process. Build variables represent
+ * a variable prefix coupled with an optional static suffix.
+ * Using Makefile syntax as an example, the following is
+ * an examples of build variables:
+ *
+ *
+ * $(CROSS_TOOLS)/include
+ *
+ *
+ * For this particular build variable: + *
getVariable()
would return "CROSS_TOOLS"getFixed()
would return "/include"getValue()
would return the current value
+ * of the variable.+ * The intent is to introduce a mechanism similar to that + * used by the Eclipse IDE to handle ClassPath variables. + *
+ * @see ICBuildVariableProvider + * @see ICBuildVariableResolver + * @see CBuildVariable + */ +public interface ICBuildVariable { + + /** + * Get the text that makes up the variable portion + * of this build variable. + * + * @return variable portion of this build variable. + */ + String getVariable(); + + /** + * Get the text that makes up the fixed portion + * of this build variable. + * + * @return fixed portion of this build variable. + */ + String getFixed(); + + /** + * Get the current value of this build variable, + * replacing the variable portion with whatever + * value is appropriate for teh current circumstances. + * + * @return Value of this build variable. + */ + String getValue(); + + /** + * Get the resolver for this build variable, + * + * @return Resolver for this build variable. + */ + ICBuildVariableResolver getResolver(); +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariableProvider.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariableProvider.java new file mode 100644 index 00000000000..37726afa264 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariableProvider.java @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +/** + * Class that makes build variables available to the + * build process. + *
+ * Intended for use in situations where generic build + * variables (ex, system root, etc.) can be provided + * for particular project types, or generically. + *
+ * If possible the build variable provider should create + * a build variable that does not need to refer back to + * the provider for resolution. The default CBuildVariable + * implementation provides support for this type of + * build variable. + *
+ * If the build variable will need information from the + * provider in order to resolve it's value, then the + * build variables will need to keep a reference to it's + * provider (or some other class that can resolve the + * variable protion of the build variable.) The default + * CBuildVariable implementation supports this type + * of build variable as well, through use of the + * ICBuildVariableResolver interface. + *+ * See also the CBuildConfig + * extension point documentation. + *
+ * @see ICBuildVariable + * @see ICBuildVariableResolver + * @see CBuildVariable + */ +public interface ICBuildVariableProvider { + + /** + * Get the list of build variables made available + * through this provider. + * + * @return build variables. + */ + ICBuildVariable[] getVariables(); + +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariableResolver.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariableResolver.java new file mode 100644 index 00000000000..522d4aa8de1 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICBuildVariableResolver.java @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +/** + * Interface representing a class that is capable of + * resolving the variable portion of build variables + * at run time. + *
+ * See also the CBuildConfig + * extension point documentation. + *
+ * @see ICBuildVariable
+ * @see ICBuildVariableProvider
+ * @see CBuildVariable
+ */
+
+public interface ICBuildVariableResolver {
+
+ /**
+ * Given a build variable, determine what it's
+ * resolved value should be.
+ *
+ * @return resolved value, or null
.
+ */
+ public String resolveValue(ICBuildVariable var);
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICPosixBuildConstants.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICPosixBuildConstants.java
new file mode 100644
index 00000000000..d9ca2f1e092
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICPosixBuildConstants.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+/**
+ * Standard build configuration constants.
+ */
+public interface ICPosixBuildConstants {
+ public final static String CPP_INCLUDES = "posix.cpp.includes"; //$NON-NLS-1$
+ public final static String CPP_DEFINITIONS = "posix.cpp.definitions"; //$NON-NLS-1$
+
+ public final static String CC_ENABLE_PROFILE = "posix.cc.profile"; //$NON-NLS-1$
+ public final static String CC_ENABLE_DEBUG = "posix.cc.debug"; //$NON-NLS-1$
+ public final static String CC_ENABLE_OPTIMIZE = "posix.cc.optimize"; //$NON-NLS-1$
+ public final static String CC_OPTIMZE_LEVEL = "posix.cc.optimize.level"; //$NON-NLS-1$
+ public final static String CC_USER_ARGS = "posix.cc.user"; //$NON-NLS-1$
+
+ public final static String CC_OPTIMIZE_NONE = "none"; //$NON-NLS-1$
+ public final static String CC_OPTIMIZE_SOME = "some"; //$NON-NLS-1$
+ public final static String CC_OPTIMIZE_FULL = "full"; //$NON-NLS-1$
+
+ public final static String CC_WARN_ALL = "posix.cc.warn.all"; //$NON-NLS-1$
+ public final static String CC_WARN_ASERROR = "posix.cc.warn.aserror"; //$NON-NLS-1$
+ public final static String CC_WARN_FORMAT = "posix.cc.warn.format"; //$NON-NLS-1$
+ public final static String CC_WARN_POINTERAR = "posix.cc.warn.pointerar"; //$NON-NLS-1$
+ public final static String CC_WARN_SWITCH = "posix.cc.warn.switch"; //$NON-NLS-1$
+ public final static String CC_WARN_UNREACH = "posix.cc.warn.unreach"; //$NON-NLS-1$
+ public final static String CC_WARN_UNUSED = "posix.cc.warn.unused"; //$NON-NLS-1$
+
+ public final static String LD_OUTPUT = "posix.ld.output"; //$NON-NLS-1$
+ public final static String LD_USER_ARGS = "posix.ld.user"; //$NON-NLS-1$
+ public final static String LD_LINK_STATIC = "posix.ld.link.static"; //$NON-NLS-1$
+ public final static String LD_LINK_AS_PROGRAM = "posix.ld.link.as.program"; //$NON-NLS-1$
+ public final static String LD_LINK_AS_SHARED = "posix.ld.link.as.shared"; //$NON-NLS-1$
+ public final static String LD_LINK_AS_ARCHIVE = "posix.ld.link.as.archive"; //$NON-NLS-1$
+ public final static String LD_STRIP = "posix.ld.strip"; //$NON-NLS-1$
+ public final static String LD_LIBS = "posix.ld.libs"; //$NON-NLS-1$
+ public final static String LD_LIBPATHS = "posix.ld.libpaths"; //$NON-NLS-1$
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICTool.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICTool.java
new file mode 100644
index 00000000000..686cf8f0549
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICTool.java
@@ -0,0 +1,96 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+import java.io.ByteArrayOutputStream;
+
+import org.eclipse.cdt.core.IErrorParser;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * ICTool represents an instance of a tool.
+ *
+ * Tools represent a particular executable (ex, "gcc", etc.) + * that can be run in order to produce some output. The + * exec() method provides a shorthand that allows a caller + * to execute the tool and gather the resultant output + * streams. + *
+ * Toolchain providers use this interface to represent + * individual tools within a toolchain. + *
+ * Stand-alone tool providers (flex, yacc, rpcgen, etc.) make + * use of this to define generic build tools that can be "mixed + * in" to any toolchain. + *
+ * See also the CTool + * extension point documentation. + */ +public interface ICTool { + + /** + * Convenince class that just contains a reference to + * two byte array output streams named sterr and stdout. + */ + class IOResults { + public ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + public ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + } + + /** + * Returns the type ID for this tool. This type ID corresponds + * to a CToolType extension ID + * + * @return the type ID for this tool. + */ + String getTypeId(); + + /** + * Returns a unique identifuer for this tool instance. + * + * @return the type ID for this tool. + */ + String getId(); + + /** + * Returns the explicit path to the executable associated + * with this tool instance.. + * + * @return path to executable. + */ + IPath getPath(); + + /** + * Indicates whether or not the executable referenced by this + * tool instance actually exists. + * + * @return true if the associated tool executable exists. + */ + boolean exists(); + + /** + * Run the executable referenced by this tool, using the + * supplied parameters. + * + * @param parameters parameters to pass to tool when executing. + * @param workingDir working directory for tool execution. + */ + IOResults exec(String[] parameters, String workingDir); + + /** + * Get an instance of an error parser that is capable + * of dealing with the tool's output. + * + * @return error parser for the tool. + */ + IErrorParser getErrorParser(); +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolType.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolType.java new file mode 100644 index 00000000000..5bf0714cc58 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolType.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +/** + * Interface representing a particular tool classification + * (ex, GNU c compiler, etc.) + *
+ * See also the CToolType + * extension point documentation. + */ +public interface ICToolType { + /** + * Returns the unique id for the tool type. + * + * @return unique id. + */ + public String getId(); + + /** + * Returns the name of the tool type. + * + * @return provider name. + */ + public String getName(); +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolchain.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolchain.java new file mode 100644 index 00000000000..459e4541290 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolchain.java @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.model; + +import org.eclipse.core.resources.IFile; + +/** + * The ICToolchain interface represents a collection of + * associated tools. A typical toolchain might consist + * of a compiler, an assembler, a linker, etc. + *
+ * Many ICToolchain operations happen in the context of
+ * a build configuration, and so take an ICBuildConfig
+ * parameter. The build configuration provides the
+ * toolchain with information about the parameters to
+ * use when generating build commands.
+ */
+public interface ICToolchain {
+
+ /**
+ * Get the build commands needed to build a file.
+ *
+ * @param file file that needs to be built.
+ * @param cfg build configuration context.
+ * @return build command(s) needed to build this file,
+ * or null the specified file cannot (or should
+ * not) be processed by this toolchain.
+ */
+ ICBuildCmd[] getBuildCommands(IFile file, ICBuildConfig cfg);
+
+ /**
+ * Get the dependencies for a file.
+ *
+ * @param file file to compute dependencies for.
+ * @param cfg build configuration context.
+ * @return file(s) that the given file depends on,
+ * or null the specified file does not have
+ * any dependencies.
+ */
+ IFile[] getDependencies(IFile file, ICBuildConfig cfg);
+
+ /**
+ * Get the output files generated by building a file.
+ *
+ * @param file file to compute outputs for.
+ * @param cfg build configuration context.
+ * @return file(s) that will be generated in the process
+ * of building the specified file.
+ */
+ IFile[] getOutputs(IFile file, ICBuildConfig cfg);
+
+ /**
+ * Get the tools associated with this toolchain.
+ *
+ * @return tools associated with this toolchain
+ */
+ ICTool[] getTools();
+
+ /**
+ * Indicate whether or not this toolchain is capable of and
+ * interested in handling the specified file.
+ * @param file file to examine.
+ * @return true if the toolchain can process the file.
+ */
+ boolean canProcess(IFile file);
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolchainProvider.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolchainProvider.java
new file mode 100644
index 00000000000..22e85dae3cb
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/ICToolchainProvider.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model;
+
+/**
+ * Interface representing a class that makes one or more
+ * toolchains (collections of related tools) available to
+ * the IDE.
+ *
+ * Using a toolchain provider allows clients to implement
+ * toolchain location logic in whatever manner suits them
+ * best. For example, a toolchain provider may locate a
+ * toolchain by examining the local filesystem, reading
+ * a configuration file, providing UI elements to allow
+ * a user to specify particular executable to use as part
+ * of a specialize toolchain, etc.
+ *
+ * See also the CToolchain
+ * extension point documentation.
+ */
+public interface ICToolchainProvider {
+
+ /**
+ * Return the ICToolchain instances managed by this provider.
+ *
+ * @return toolchain instances managed by this provider.
+ */
+ ICToolchain[] getToolchains();
+
+ /**
+ * Return an ICToolchain instance managed by this provider.
+ *
+ * @param id toolchain ID.
+ * @return toolchain instance, or null if the
+ * provider does not recognize the toolchain ID.
+ */
+ ICToolchain getToolchain(String id);
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfig.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfig.java
new file mode 100644
index 00000000000..d01638cf368
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfig.java
@@ -0,0 +1,391 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model.internal;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xerces.dom.DocumentImpl;
+import org.eclipse.cdt.core.builder.BuilderPlugin;
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.internal.core.DebugCoreMessages;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * @author sam.robb
+ */
+public class CBuildConfig extends PlatformObject implements ICBuildConfig {
+
+ /**
+ * Location this configuration is stored in. This
+ * is the key for a build configuration handle.
+ */
+ private IPath fLocation;
+
+ /**
+ * Constructs a build configuration in the given location.
+ *
+ * @param location path to where this build configuration's
+ * underlying file is located
+ */
+ protected CBuildConfig(IPath location) {
+ setLocation(location);
+ }
+
+ /**
+ * Constructs a launch configuration from the given
+ * memento.
+ *
+ * @param memento configuration memento
+ * @exception CoreException if the memento is invalid or
+ * an exception occurrs reading the memento
+ */
+ protected CBuildConfig(String memento) throws CoreException {
+ Exception ex = null;
+ try {
+ Element root = null;
+ DocumentBuilder parser =
+ DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ StringReader reader = new StringReader(memento);
+ InputSource source = new InputSource(reader);
+ root = parser.parse(source).getDocumentElement();
+
+ String localString = root.getAttribute("local"); //$NON-NLS-1$
+ String path = root.getAttribute("path"); //$NON-NLS-1$
+
+ String message = null;
+ if (path == null) {
+ message = DebugCoreMessages.getString("LaunchConfiguration.Invalid_build_configuration_memento__missing_path_attribute_3"); //$NON-NLS-1$
+ } else if (localString == null) {
+ message = DebugCoreMessages.getString("LaunchConfiguration.Invalid_build_configuration_memento__missing_local_attribute_4"); //$NON-NLS-1$
+ }
+ if (message != null) {
+ IStatus s = newStatus(message, DebugException.INTERNAL_ERROR, null);
+ throw new CoreException(s);
+ }
+
+ IPath location = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(path);
+
+ setLocation(location);
+ return;
+ } catch (ParserConfigurationException e) {
+ ex = e;
+ } catch (SAXException e) {
+ ex = e;
+ } catch (IOException e) {
+ ex = e;
+ }
+ IStatus s = newStatus(DebugCoreMessages.getString("LaunchConfiguration.Exception_occurred_parsing_memento_5"), DebugException.INTERNAL_ERROR, ex); //$NON-NLS-1$
+ throw new CoreException(s);
+ }
+
+ /**
+ * Creates and returns a new error status based on
+ * the given mesasge, code, and exception.
+ *
+ * @param message error message
+ * @param code error code
+ * @param e exception or null
+ * @return status
+ */
+ protected IStatus newStatus(String message, int code, Throwable e) {
+ return new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), code, message, e);
+ }
+
+ /**
+ * @see ICBuildConfig#build(IProgressMonitor)
+ */
+ public void build(IProgressMonitor monitor) throws CoreException {
+ }
+
+ /**
+ * A configuration's name is that of the last segment
+ * in it's location (subtract the ".build" extension).
+ *
+ * @see ICBuildConfig#getName()
+ */
+ public String getName() {
+ return getLastLocationSegment();
+ }
+
+ private String getLastLocationSegment() {
+ String name = getLocation().lastSegment();
+ name = name.substring(0, name.length() - (BUILD_CONFIGURATION_FILE_EXTENSION.length() + 1));
+ return name;
+ }
+
+ /**
+ * @see ICBuildConfig#getLocation()
+ */
+ public IPath getLocation() {
+ return fLocation;
+ }
+
+ /**
+ * Sets the location of this configuration's underlying
+ * file.
+ *
+ * @param location the location of this configuration's underlying
+ * file
+ */
+ private void setLocation(IPath location) {
+ fLocation = location;
+ }
+
+ /**
+ * @see ICBuildConfig#exists()
+ */
+ public boolean exists() {
+ IFile file = getFile();
+ if (file == null) {
+ return getLocation().toFile().exists();
+ } else {
+ return file.exists();
+ }
+ }
+
+ /**
+ * @see ICBuildConfig#getAttribute(String, int)
+ */
+ public int getAttribute(String attributeName, int defaultValue) throws CoreException {
+ return getInfo().getIntAttribute(attributeName, defaultValue);
+ }
+
+ /**
+ * @see ICBuildConfig#getAttribute(String, String)
+ */
+ public String getAttribute(String attributeName, String defaultValue) throws CoreException {
+ return getInfo().getStringAttribute(attributeName, defaultValue);
+ }
+
+ /**
+ * @see ICBuildConfig#getAttribute(String, boolean)
+ */
+ public boolean getAttribute(String attributeName, boolean defaultValue) throws CoreException {
+ return getInfo().getBooleanAttribute(attributeName, defaultValue);
+ }
+
+ /**
+ * @see ICBuildConfig#getAttribute(String, List)
+ */
+ public List getAttribute(String attributeName, List defaultValue) throws CoreException {
+ return getInfo().getListAttribute(attributeName, defaultValue);
+ }
+
+ /**
+ * @see ICBuildConfig#getAttribute(String, Map)
+ */
+ public Map getAttribute(String attributeName, Map defaultValue) throws CoreException {
+ return getInfo().getMapAttribute(attributeName, defaultValue);
+ }
+
+ /**
+ * @see ICBuildConfig#isLocal()
+ */
+ public boolean isLocal() {
+ return getFile() == null;
+ }
+
+ /**
+ * @see ICBuildConfig#getWorkingCopy()
+ */
+ public ICBuildConfigWorkingCopy getWorkingCopy() throws CoreException {
+ return new CBuildConfigWorkingCopy(this);
+ }
+
+ /**
+ * @see ICBuildConfig#copy(String name)
+ */
+ public ICBuildConfigWorkingCopy copy(String name) throws CoreException {
+ ICBuildConfigWorkingCopy copy = new CBuildConfigWorkingCopy(this, name);
+ return copy;
+ }
+
+ /**
+ * @see ICBuildConfig#isWorkingCopy()
+ */
+ public boolean isWorkingCopy() {
+ return false;
+ }
+
+ /**
+ * @see ICBuildConfig#delete()
+ */
+ public void delete() throws CoreException {
+ if (exists()) {
+ if (isLocal()) {
+ if (!(getLocation().toFile().delete())) {
+ throw new DebugException(
+ new Status(Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, DebugCoreMessages.getString("LaunchConfiguration.Failed_to_delete_build_configuration._1"), null) //$NON-NLS-1$
+ );
+ }
+ // manually update the build manager cache since there
+ // will be no resource delta
+ getBuildConfigurationManager().configurationDeleted(this);
+ } else {
+ // delete the resource using IFile API such that
+ // resource deltas are fired.
+ IResource file = getFile();
+ if (file != null) {
+ file.delete(true, null);
+ } else {
+ // Error - the exists test passed, but could not locate file
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the info object containing the attributes
+ * of this configuration
+ *
+ * @return info for this handle
+ * @exception CoreException if unable to retrieve the
+ * info object
+ */
+ protected CBuildConfigInfo getInfo() throws CoreException {
+ return getBuildConfigurationManager().getInfo(this);
+ }
+
+ /**
+ * Returns the build manager
+ *
+ * @return build manager
+ */
+ protected CBuildConfigManager getBuildConfigurationManager() {
+ return BuilderPlugin.getDefault().getBuildConfigurationManager();
+ }
+
+ /**
+ * @see ICBuildConfig#getMemento()
+ */
+ public String getMemento() throws CoreException {
+ IPath relativePath = getFile().getFullPath();
+ relativePath = relativePath.setDevice(null);
+
+ Document doc = new DocumentImpl();
+ Element node = doc.createElement("buildConfiguration"); //$NON-NLS-1$
+ doc.appendChild(node);
+ node.setAttribute("local", (new Boolean(isLocal())).toString()); //$NON-NLS-1$
+ node.setAttribute("path", relativePath.toString()); //$NON-NLS-1$
+
+ try {
+ return CBuildConfigManager.serializeDocument(doc);
+ } catch (IOException e) {
+ IStatus status = newStatus(DebugCoreMessages.getString("LaunchConfiguration.Exception_occurred_creating_build_configuration_memento_9"), DebugException.INTERNAL_ERROR, e); //$NON-NLS-1$
+ throw new CoreException(status);
+ }
+ }
+
+ /**
+ * @see ICBuildConfig#getFile()
+ */
+ public IFile getFile() {
+ return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(getLocation());
+ }
+
+ /**
+ * @see ICBuildConfig#getProject()
+ */
+ public IProject getProject() {
+ return getFile().getProject();
+ }
+
+ /**
+ * @see ICBuildConfig#contentsEqual(ICBuildConfig)
+ */
+ public boolean contentsEqual(ICBuildConfig object) {
+ try {
+ if (object instanceof CBuildConfig) {
+ CBuildConfig otherConfig = (CBuildConfig) object;
+ return getName().equals(otherConfig.getName())
+ && getLocation().equals(otherConfig.getLocation())
+ && getInfo().equals(otherConfig.getInfo());
+ }
+ return false;
+ } catch (CoreException ce) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether this configuration is equal to the
+ * given configuration. Two configurations are equal if
+ * they are stored in the same location (and neither one
+ * is a working copy).
+ *
+ * @return whether this configuration is equal to the
+ * given configuration
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object object) {
+ if (object instanceof ICBuildConfig) {
+ if (isWorkingCopy()) {
+ return this == object;
+ }
+ ICBuildConfig config = (ICBuildConfig) object;
+ if (!config.isWorkingCopy()) {
+ return config.getLocation().equals(getLocation());
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return getLocation().hashCode();
+ }
+
+ /**
+ * Returns the container this build configuration is
+ * stored in, or null
if this build configuration
+ * is stored locally.
+ *
+ * @return the container this build configuration is
+ * stored in, or null
if this build configuration
+ * is stored locally
+ */
+ protected IContainer getContainer() {
+ IFile file = getFile();
+ if (file != null) {
+ return file.getParent();
+ }
+ return null;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigInfo.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigInfo.java
new file mode 100644
index 00000000000..112769b4198
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigInfo.java
@@ -0,0 +1,474 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model.internal;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.xerces.dom.DocumentImpl;
+import org.eclipse.cdt.core.builder.BuilderPlugin;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigManager;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.internal.core.DebugCoreMessages;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author sam.robb
+ *
+ * The information associated with a build configuration
+ * handle.
+ */
+public class CBuildConfigInfo {
+
+ /**
+ * This configurations attribute table.
+ * Keys are String
s and values
+ * are one of String
, Integer
,
+ * or Boolean
.
+ */
+ private HashMap fAttributes;
+
+ /**
+ * Constructs a new empty info
+ */
+ protected CBuildConfigInfo() {
+ setAttributeTable(new HashMap(10));
+ }
+
+ /**
+ * Returns this configuration's attribute table.
+ *
+ * @return attribute table
+ */
+ private HashMap getAttributeTable() {
+ return fAttributes;
+ }
+
+ /**
+ * Sets this configuration's attribute table.
+ *
+ * @param table attribute table
+ */
+ private void setAttributeTable(HashMap table) {
+ fAttributes = table;
+ }
+
+ /**
+ * Returns the String
attribute with the
+ * given key or the given default value if undefined.
+ *
+ * @return attribute specified by given key or the defaultValue
+ * if undefined
+ * @exception if the attribute with the given key exists
+ * but is not a String
+ */
+ protected String getStringAttribute(String key, String defaultValue) throws CoreException {
+ Object attr = getAttributeTable().get(key);
+ if (attr != null) {
+ if (attr instanceof String) {
+ return (String)attr;
+ } else {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("LaunchConfigurationInfo.Attribute_{0}_is_not_of_type_java.lang.String._1"), new String[] {key}), null //$NON-NLS-1$
+ )
+ );
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Returns the int
attribute with the
+ * given key or the given default value if undefined.
+ *
+ * @return attribute specified by given key or the defaultValue
+ * if undefined
+ * @exception if the attribute with the given key exists
+ * but is not an int
+ */
+ protected int getIntAttribute(String key, int defaultValue) throws CoreException {
+ Object attr = getAttributeTable().get(key);
+ if (attr != null) {
+ if (attr instanceof Integer) {
+ return ((Integer)attr).intValue();
+ } else {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("LaunchConfigurationInfo.Attribute_{0}_is_not_of_type_int._2"), new String[] {key}), null //$NON-NLS-1$
+ )
+ );
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Returns the boolean
attribute with the
+ * given key or the given default value if undefined.
+ *
+ * @return attribute specified by given key or the defaultValue
+ * if undefined
+ * @exception if the attribute with the given key exists
+ * but is not a boolean
+ */
+ protected boolean getBooleanAttribute(String key, boolean defaultValue) throws CoreException {
+ Object attr = getAttributeTable().get(key);
+ if (attr != null) {
+ if (attr instanceof Boolean) {
+ return ((Boolean)attr).booleanValue();
+ } else {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("LaunchConfigurationInfo.Attribute_{0}_is_not_of_type_boolean._3"), new String[] {key}), null //$NON-NLS-1$
+ )
+ );
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Returns the java.util.List
attribute with the
+ * given key or the given default value if undefined.
+ *
+ * @return attribute specified by given key or the defaultValue
+ * if undefined
+ * @exception if the attribute with the given key exists
+ * but is not a java.util.List
+ */
+ protected List getListAttribute(String key, List defaultValue) throws CoreException {
+ Object attr = getAttributeTable().get(key);
+ if (attr != null) {
+ if (attr instanceof List) {
+ return (List)attr;
+ } else {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("LaunchConfigurationInfo.Attribute_{0}_is_not_of_type_java.util.List._1"), new String[] {key}), null //$NON-NLS-1$
+ )
+ );
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Returns the java.util.Map
attribute with the
+ * given key or the given default value if undefined.
+ *
+ * @return attribute specified by given key or the defaultValue
+ * if undefined
+ * @exception if the attribute with the given key exists
+ * but is not a java.util.Map
+ */
+ protected Map getMapAttribute(String key, Map defaultValue) throws CoreException {
+ Object attr = getAttributeTable().get(key);
+ if (attr != null) {
+ if (attr instanceof Map) {
+ return (Map)attr;
+ } else {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("LaunchConfigurationInfo.Attribute_{0}_is_not_of_type_java.util.Map._1"), new String[] {key}), null //$NON-NLS-1$
+ )
+ );
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Returns a copy of this info object
+ *
+ * @return copy of this info
+ */
+ protected CBuildConfigInfo getCopy() {
+ CBuildConfigInfo copy = new CBuildConfigInfo();
+ copy.setAttributeTable((HashMap)getAttributeTable().clone());
+ return copy;
+ }
+
+ /**
+ * Sets the given attribute to the given value. Only
+ * working copy's should use this API.
+ *
+ * @param key attribute key
+ * @param value attribuet value
+ */
+ protected void setAttribute(String key, Object value) {
+ if (value == null) {
+ getAttributeTable().remove(key);
+ } else {
+ getAttributeTable().put(key, value);
+ }
+ }
+
+ /**
+ * Returns the content of this info as XML
+ *
+ * @return the content of this info as XML
+ * @exception IOException if an exception occurs creating the XML
+ */
+ protected String getAsXML() throws IOException {
+
+ Document doc = new DocumentImpl();
+ Element configRootElement = doc.createElement("buildConfiguration"); //$NON-NLS-1$
+ doc.appendChild(configRootElement);
+
+ Iterator keys = getAttributeTable().keySet().iterator();
+ while (keys.hasNext()) {
+ String key = (String)keys.next();
+ Object value = getAttributeTable().get(key);
+ if (value == null) {
+ continue;
+ }
+ Element element = null;
+ String valueString = null;
+ if (value instanceof String) {
+ valueString = (String)value;
+ element = createKeyValueElement(doc, "stringAttribute", key, valueString); //$NON-NLS-1$
+ } else if (value instanceof Integer) {
+ valueString = ((Integer)value).toString();
+ element = createKeyValueElement(doc, "intAttribute", key, valueString); //$NON-NLS-1$
+ } else if (value instanceof Boolean) {
+ valueString = ((Boolean)value).toString();
+ element = createKeyValueElement(doc, "booleanAttribute", key, valueString); //$NON-NLS-1$
+ } else if (value instanceof List) {
+ element = createListElement(doc, "listAttribute", key, (List)value); //$NON-NLS-1$
+ } else if (value instanceof Map) {
+ element = createMapElement(doc, "mapAttribute", key, (Map)value); //$NON-NLS-1$
+ }
+ configRootElement.appendChild(element);
+ }
+
+ return CBuildConfigManager.serializeDocument(doc);
+ }
+
+ /**
+ * Helper method that creates a 'key value' element of the specified type with the
+ * specified attribute values.
+ */
+ protected Element createKeyValueElement(Document doc, String elementType, String key, String value) {
+ Element element = doc.createElement(elementType);
+ element.setAttribute("key", key); //$NON-NLS-1$
+ element.setAttribute("value", value); //$NON-NLS-1$
+ return element;
+ }
+
+ protected Element createListElement(Document doc, String elementType, String listKey, List list) {
+ Element listElement = doc.createElement(elementType);
+ listElement.setAttribute("key", listKey); //$NON-NLS-1$
+ Iterator iterator = list.iterator();
+ while (iterator.hasNext()) {
+ String value = (String) iterator.next();
+ Element element = doc.createElement("listEntry"); //$NON-NLS-1$
+ element.setAttribute("value", value); //$NON-NLS-1$
+ listElement.appendChild(element);
+ }
+ return listElement;
+ }
+
+ protected Element createMapElement(Document doc, String elementType, String mapKey, Map map) {
+ Element mapElement = doc.createElement(elementType);
+ mapElement.setAttribute("key", mapKey); //$NON-NLS-1$
+ Iterator iterator = map.keySet().iterator();
+ while (iterator.hasNext()) {
+ String key = (String) iterator.next();
+ String value = (String) map.get(key);
+ Element element = doc.createElement("mapEntry"); //$NON-NLS-1$
+ element.setAttribute("key", key); //$NON-NLS-1$
+ element.setAttribute("value", value); //$NON-NLS-1$
+ mapElement.appendChild(element);
+ }
+ return mapElement;
+ }
+
+ protected void initializeFromXML(Element root) throws CoreException {
+ if (!root.getNodeName().equalsIgnoreCase("buildConfiguration")) { //$NON-NLS-1$
+ throw getInvalidFormatDebugException();
+ }
+
+ NodeList list = root.getChildNodes();
+ int length = list.getLength();
+ for (int i = 0; i < length; ++i) {
+ Node node = list.item(i);
+ short type = node.getNodeType();
+ if (type == Node.ELEMENT_NODE) {
+ Element element = (Element) node;
+ String nodeName = element.getNodeName();
+
+ if (nodeName.equalsIgnoreCase("stringAttribute")) { //$NON-NLS-1$
+ setStringAttribute(element);
+ } else if (nodeName.equalsIgnoreCase("intAttribute")) { //$NON-NLS-1$
+ setIntegerAttribute(element);
+ } else if (nodeName.equalsIgnoreCase("booleanAttribute")) { //$NON-NLS-1$
+ setBooleanAttribute(element);
+ } else if (nodeName.equalsIgnoreCase("listAttribute")) { //$NON-NLS-1$
+ setListAttribute(element);
+ } else if (nodeName.equalsIgnoreCase("mapAttribute")) { //$NON-NLS-1$
+ setMapAttribute(element);
+ }
+ }
+ }
+ }
+
+ protected void setStringAttribute(Element element) throws CoreException {
+ String key = getKeyAttribute(element);
+ String value = getValueAttribute(element);
+ setAttribute(key, value);
+ }
+
+ protected void setIntegerAttribute(Element element) throws CoreException {
+ String key = getKeyAttribute(element);
+ String value = getValueAttribute(element);
+ setAttribute(key, new Integer(value));
+ }
+
+ protected void setBooleanAttribute(Element element) throws CoreException {
+ String key = getKeyAttribute(element);
+ String value = getValueAttribute(element);
+ setAttribute(key, new Boolean(value));
+ }
+
+ protected void setListAttribute(Element element) throws CoreException {
+ String listKey = element.getAttribute("key"); //$NON-NLS-1$
+ NodeList nodeList = element.getChildNodes();
+ int entryCount = nodeList.getLength();
+ List list = new ArrayList(entryCount);
+ for (int i = 0; i < entryCount; i++) {
+ Node node = nodeList.item(i);
+ short type = node.getNodeType();
+ if (type == Node.ELEMENT_NODE) {
+ Element subElement = (Element) node;
+ String nodeName = subElement.getNodeName();
+ if (!nodeName.equalsIgnoreCase("listEntry")) { //$NON-NLS-1$
+ throw getInvalidFormatDebugException();
+ }
+ String value = getValueAttribute(subElement);
+ list.add(value);
+ }
+ }
+ setAttribute(listKey, list);
+ }
+
+ protected void setMapAttribute(Element element) throws CoreException {
+ String mapKey = element.getAttribute("key"); //$NON-NLS-1$
+ NodeList nodeList = element.getChildNodes();
+ int entryCount = nodeList.getLength();
+ Map map = new HashMap(entryCount);
+ for (int i = 0; i < entryCount; i++) {
+ Node node = nodeList.item(i);
+ short type = node.getNodeType();
+ if (type == Node.ELEMENT_NODE) {
+ Element subElement = (Element) node;
+ String nodeName = subElement.getNodeName();
+ if (!nodeName.equalsIgnoreCase("mapEntry")) { //$NON-NLS-1$
+ throw getInvalidFormatDebugException();
+ }
+ String key = getKeyAttribute(subElement);
+ String value = getValueAttribute(subElement);
+ map.put(key, value);
+ }
+ }
+ setAttribute(mapKey, map);
+ }
+
+ protected String getKeyAttribute(Element element) throws CoreException {
+ String key = element.getAttribute("key"); //$NON-NLS-1$
+ if (key == null) {
+ throw getInvalidFormatDebugException();
+ }
+ return key;
+ }
+
+ protected String getValueAttribute(Element element) throws CoreException {
+ String value = element.getAttribute("value"); //$NON-NLS-1$
+ if (value == null) {
+ throw getInvalidFormatDebugException();
+ }
+ return value;
+ }
+
+ protected DebugException getInvalidFormatDebugException() {
+ return
+ new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, DebugCoreMessages.getString("LaunchConfigurationInfo.Invalid_launch_configuration_XML._10"), null //$NON-NLS-1$
+ )
+ );
+ }
+
+ /**
+ * Two CBuildConfigInfo
objects are equal if and only if
+ * they have the same set of attributes with the same values.
+ *
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object obj) {
+
+ // Make sure it's a LaunchConfigurationInfo object
+ if (!(obj instanceof CBuildConfigInfo)) {
+ return false;
+ }
+
+ CBuildConfigInfo other = (CBuildConfigInfo) obj;
+
+ // Make sure the attributes are the same
+ return compareAttributes(fAttributes, other.getAttributeTable());
+ }
+
+ /**
+ * Returns whether the two attribute maps are equal, consulting
+ * registered comparator extensions.
+ *
+ * @param map1 attribute map
+ * @param map2 attribute map
+ * @return whether the two attribute maps are equal
+ */
+ protected boolean compareAttributes(HashMap map1, HashMap map2) {
+ ICBuildConfigManager manager = BuilderPlugin.getDefault().getBuildConfigurationManager();
+ if (map1.size() == map2.size()) {
+ Iterator attributes = map1.keySet().iterator();
+ while (attributes.hasNext()) {
+ String key = (String)attributes.next();
+ Object attr1 = map1.get(key);
+ Object attr2 = map2.get(key);
+ if (attr2 == null) {
+ return false;
+ }
+ if (!attr1.equals(attr2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigManager.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigManager.java
new file mode 100644
index 00000000000..a82144a7a98
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigManager.java
@@ -0,0 +1,415 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model.internal;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xml.serialize.Method;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.Serializer;
+import org.apache.xml.serialize.SerializerFactory;
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigListener;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigManager;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.internal.core.DebugCoreMessages;
+import org.eclipse.debug.internal.core.ListenerList;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Manages build configurations.
+ *
+ * @see ICBuildConfigManager
+ */
+public class CBuildConfigManager implements ICBuildConfigManager {
+
+ /**
+ * Collection of listeners
+ */
+ private ListenerList fListeners = new ListenerList(5);
+
+ /**
+ * Types of notifications
+ */
+ public static final int ADDED = 0;
+ public static final int REMOVED = 1;
+ public static final int CHANGED = 2;
+
+ /**
+ * Serializes a XML document into a string - encoded in UTF8 format,
+ * with platform line separators.
+ *
+ * @param doc document to serialize
+ * @return the document as a string
+ */
+ public static String serializeDocument(Document doc) throws IOException {
+ ByteArrayOutputStream s= new ByteArrayOutputStream();
+ OutputFormat format = new OutputFormat();
+ format.setIndenting(true);
+ format.setLineSeparator(System.getProperty("line.separator")); //$NON-NLS-1$
+
+ Serializer serializer =
+ SerializerFactory.getSerializerFactory(Method.XML).makeSerializer(
+ new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$
+ format);
+ serializer.asDOMSerializer().serialize(doc);
+ return s.toString("UTF8"); //$NON-NLS-1$
+ }
+
+ /**
+ * @see ICBuildConfigManager#addListener(ICBuildConfigListener)
+ */
+ public void addListener(ICBuildConfigListener listener) {
+ fListeners.add(listener);
+ }
+
+ /**
+ * @see ICBuildConfigManager#removeListener(ICBuildConfigListener)
+ */
+ public void removeListener(ICBuildConfigListener listener) {
+ fListeners.remove(listener);
+ }
+
+ /**
+ * @see ICBuildConfigManager#addConfiguration(ICBuildConfig)
+ */
+ public void addConfiguration(ICBuildConfig configuration) {
+ fireUpdate(configuration, ADDED);
+ }
+
+ /**
+ * @see ICBuildConfigManager#removeConfiguration(ICBuildConfig)
+ */
+ public void removeConfiguration(ICBuildConfig configuration) {
+ fireUpdate(configuration, REMOVED);
+ }
+
+ /**
+ * @see ICBuildConfigManager#generateUniqueConfigurationNameFrom(IProject, String)
+ */
+ public String generateUniqueConfigurationNameFrom(IProject project, String baseName) {
+ int index = 1;
+ int length= baseName.length();
+ int copyIndex = baseName.lastIndexOf(" ("); //$NON-NLS-1$
+ if (copyIndex > -1 && length > copyIndex + 2 && baseName.charAt(length - 1) == ')') {
+ String trailer = baseName.substring(copyIndex + 2, length -1);
+ if (isNumber(trailer)) {
+ try {
+ index = Integer.parseInt(trailer);
+ baseName = baseName.substring(0, copyIndex);
+ } catch (NumberFormatException nfe) {
+ }
+ }
+ }
+ String newName = baseName;
+ try {
+ StringBuffer buffer= null;
+ while (isExistingConfigurationName(project, newName)) {
+ buffer = new StringBuffer(baseName);
+ buffer.append(" ("); //$NON-NLS-1$
+ buffer.append(String.valueOf(index));
+ index++;
+ buffer.append(')');
+ newName = buffer.toString();
+ }
+ } catch (CoreException e) {
+ DebugPlugin.log(e);
+ }
+ return newName;
+ }
+
+ /**
+ * @see ICBuildConfigManager#getConfiguration(IFile)
+ */
+ public ICBuildConfig getConfiguration(IFile file) {
+ return new CBuildConfig(file.getLocation());
+ }
+
+ /**
+ * @see ICBuildConfigManager#getConfiguration(String)
+ */
+ public ICBuildConfig getConfiguration(String memento) throws CoreException {
+ return new CBuildConfig(memento);
+ }
+
+ public ICBuildConfigWorkingCopy getConfiguration(IProject project, String name) {
+ if ((name == null) || (name.length() < 1)) {
+ name = "New Configuration";
+ }
+ name = generateUniqueConfigurationNameFrom(project, name);
+ return new CBuildConfigWorkingCopy(project, name);
+ }
+
+ /**
+ * @see ICBuildConfigManager#getConfigurations(IProject)
+ */
+ public ICBuildConfig[] getConfigurations(IProject project) throws CoreException {
+ List configs = findConfigurations(project, ICBuildConfig.BUILD_CONFIGURATION_FILE_EXTENSION);
+ return (ICBuildConfig[]) configs.toArray(new ICBuildConfig[configs.size()]);
+ }
+
+ /**
+ * @see ICBuildConfigManager#isExistingConfigurationName(IProject, String)
+ */
+ public boolean isExistingConfigurationName(IProject project, String name) throws CoreException {
+ List configFiles;
+ int count = 0;
+
+ configFiles = findConfigurations(project, ICBuildConfig.BUILD_CONFIGURATION_FILE_EXTENSION);
+ count = configFiles.size();
+
+ if (count > 0) {
+ for (Iterator iter = configFiles.iterator(); iter.hasNext();) {
+ ICBuildConfig element = (ICBuildConfig) iter.next();
+ if (name.equals(element.getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Fires notification to the listeners that a configuration
+ * has been added, removed, updated, or deleted.
+ */
+ protected void fireUpdate(ICBuildConfig configuration, int update) {
+ Object[] copiedListeners = fListeners.getListeners();
+ for (int i= 0; i < copiedListeners.length; i++) {
+ ICBuildConfigListener listener = (ICBuildConfigListener) copiedListeners[i];
+ switch (update) {
+ case ADDED:
+ listener.configurationAdded(configuration);
+ break;
+ case REMOVED:
+ listener.configurationRemoved(configuration);
+ break;
+ case CHANGED:
+ listener.configurationChanged(configuration);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Notifies the manager that a configuration has been deleted.
+ *
+ * @param project the project containing the configuration
+ * @param config the configuration that was deleted
+ */
+ protected void configurationDeleted(ICBuildConfig configuration) throws CoreException {
+ fireUpdate(configuration, REMOVED);
+ }
+
+ /**
+ * Notifies the manager that a configuration has been added.
+ *
+ * @param project the project containing the configuration
+ * @param config the configuration that was added
+ */
+ protected void configurationAdded(ICBuildConfig configuration) throws CoreException {
+ if (isValid(configuration)) {
+ fireUpdate(configuration, ADDED);
+ } else {
+ fireUpdate(configuration, ADDED);
+ }
+ }
+
+ /**
+ * Notifies the manager that a configuration has been added.
+ *
+ * @param project the project containing the configuration
+ * @param config the launch configuration that was changed
+ */
+ protected void configurationChanged(ICBuildConfig configuration) {
+ if (isValid(configuration)) {
+ fireUpdate(configuration, CHANGED);
+ } else {
+ fireUpdate(configuration, REMOVED);
+ }
+ }
+
+ /**
+ * Returns the info object for the specified launch configuration.
+ * If the configuration exists, but is not yet in the cache,
+ * an info object is built and added to the cache.
+ *
+ * @exception CoreException if an exception occurs building
+ * the info object
+ * @exception DebugException if the config does not exist
+ */
+ protected CBuildConfigInfo getInfo(ICBuildConfig config) throws CoreException {
+ CBuildConfigInfo info = null;
+
+ if (config.exists()) {
+ InputStream stream = null;
+
+ try {
+ IFile file = ((CBuildConfig) config).getFile();
+ stream = file.getContents();
+ info = createInfoFromXML(stream);
+ } catch (FileNotFoundException e) {
+ throw createDebugException(MessageFormat.format(DebugCoreMessages.getString("LaunchManager.{0}_occurred_while_reading_launch_configuration_file._1"), new String[]{e.toString()}), e); //$NON-NLS-1$
+ } catch (SAXException e) {
+ throw createDebugException(MessageFormat.format(DebugCoreMessages.getString("LaunchManager.{0}_occurred_while_reading_launch_configuration_file._1"), new String[]{e.toString()}), e); //$NON-NLS-1$
+ } catch (ParserConfigurationException e) {
+ throw createDebugException(MessageFormat.format(DebugCoreMessages.getString("LaunchManager.{0}_occurred_while_reading_launch_configuration_file._1"), new String[]{e.toString()}), e); //$NON-NLS-1$
+ } catch (IOException e) {
+ throw createDebugException(MessageFormat.format(DebugCoreMessages.getString("LaunchManager.{0}_occurred_while_reading_launch_configuration_file._1"), new String[]{e.toString()}), e); //$NON-NLS-1$
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ throw createDebugException(MessageFormat.format(DebugCoreMessages.getString("LaunchManager.{0}_occurred_while_reading_launch_configuration_file._1"), new String[]{e.toString()}), e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ } else {
+ throw createDebugException(DebugCoreMessages.getString("LaunchManager.Launch_configuration_does_not_exist._6"), null); //$NON-NLS-1$
+ }
+
+ return info;
+ }
+
+ /**
+ * Return a LaunchConfigurationInfo object initialized from XML contained in
+ * the specified stream. Simply pass out any exceptions encountered so that
+ * caller can deal with them. This is important since caller may need access to the
+ * actual exception.
+ */
+ protected CBuildConfigInfo createInfoFromXML(InputStream stream)
+ throws CoreException, ParserConfigurationException, IOException, SAXException {
+ Element root = null;
+ DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ root = parser.parse(new InputSource(stream)).getDocumentElement();
+ CBuildConfigInfo info = new CBuildConfigInfo();
+ info.initializeFromXML(root);
+ return info;
+ }
+
+ /**
+ * Return an instance of DebugException containing the specified message and Throwable.
+ */
+ protected DebugException createDebugException(String message, Throwable throwable) {
+ return new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, message, throwable
+ )
+ );
+ }
+
+ /**
+ * Finds and returns all configurations in the given
+ * container (and subcontainers)
+ *
+ * @param container the container to search
+ * @exception CoreException an exception occurs traversing
+ * the container.
+ * @return all configurations in the given container
+ */
+ protected List findConfigurations(IContainer container, String extension) throws CoreException {
+ List list = new ArrayList(10);
+ if (container instanceof IProject && !((IProject)container).isOpen()) {
+ return list;
+ }
+ searchForFiles(container, extension, list);
+ Iterator iter = list.iterator();
+ List configs = new ArrayList(list.size());
+ while (iter.hasNext()) {
+ IFile file = (IFile)iter.next();
+ configs.add(getConfiguration(file));
+ }
+ return configs;
+ }
+
+ /**
+ * Recursively searches the given container for files with the given
+ * extension.
+ *
+ * @param container the container to search in
+ * @param extension the file extension being searched for
+ * @param list the list to add the matching files to
+ * @exception CoreException if an exception occurs traversing
+ * the container
+ */
+ protected void searchForFiles(IContainer container, String extension, List list) throws CoreException {
+ IResource[] members = container.members();
+ for (int i = 0; i < members.length; i++) {
+ if (members[i] instanceof IContainer) {
+ if (members[i] instanceof IProject && !((IProject)members[i]) .isOpen()) {
+ continue;
+ }
+ searchForFiles((IContainer)members[i], extension, list);
+ } else if (members[i] instanceof IFile) {
+ IFile file = (IFile)members[i];
+ if (extension.equalsIgnoreCase(file.getFileExtension())) {
+ list.add(file);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns whether the given String is composed solely of digits
+ */
+ private boolean isNumber(String string) {
+ int numChars= string.length();
+ if (numChars == 0) {
+ return false;
+ }
+ for (int i= 0; i < numChars; i++) {
+ if (!Character.isDigit(string.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns whether the given configuration passes a basic
+ * integritiy test.
+ *
+ * @param config the configuration to verify
+ * @return whether the config meets basic integrity constraints
+ */
+ protected boolean isValid(ICBuildConfig config) {
+ // TODO: Tests?
+ return (null != config);
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigWorkingCopy.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigWorkingCopy.java
new file mode 100644
index 00000000000..aa7fe2a640b
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/model/internal/CBuildConfigWorkingCopy.java
@@ -0,0 +1,490 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.model.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.internal.core.DebugCoreMessages;
+
+/**
+ * @author sam.robb
+ */
+public class CBuildConfigWorkingCopy extends CBuildConfig implements ICBuildConfigWorkingCopy {
+
+ /**
+ * Handle of original launch configuration this
+ * working copy is based on
+ */
+ private CBuildConfig fOriginal;
+
+ /**
+ * Working copy of attributes.
+ */
+ private CBuildConfigInfo fInfo;
+
+ /**
+ * Whether this working copy has been modified since
+ * it was created
+ */
+ private boolean fDirty = false;
+
+ /**
+ * The name for this configuration.
+ */
+ private String fName;
+
+ /**
+ * Indicates whether this working copy has been explicitly renamed.
+ */
+ private boolean fRenamed = false;
+
+ /**
+ * Suppress change notification until created
+ */
+ private boolean fSuppressChange = true;
+
+ /**
+ * The container this working copy will be
+ * stored in when saved.
+ */
+ private IContainer fContainer;
+
+ /**
+ * Constructs a working copy of the specified launch
+ * configuration.
+ *
+ * @param original launch configuration to make
+ * a working copy of
+ * @exception CoreException if unable to initialize this
+ * working copy's attributes based on the original configuration
+ */
+ protected CBuildConfigWorkingCopy(CBuildConfig original) throws CoreException {
+ super(original.getLocation());
+ setName(original.getName());
+ copyFrom(original);
+ setOriginal(original);
+ fSuppressChange = false;
+ }
+
+ /**
+ * Constructs a copy of the specified launch
+ * configuration, with the given (new) name.
+ *
+ * @param original launch configuration to make
+ * a working copy of
+ * @param name the new name for the copy of the launch
+ * configuration
+ * @exception CoreException if unable to initialize this
+ * working copy's attributes based on the original configuration
+ */
+ protected CBuildConfigWorkingCopy(CBuildConfig original, String name) throws CoreException {
+ super(original.getLocation());
+ copyFrom(original);
+ setName(name);
+ fSuppressChange = false;
+ }
+
+ /**
+ * Constructs a new working copy to be created in the specified
+ * location.
+ *
+ * @param container the container that the configuration will be created in
+ * or null
if to be local
+ * @param name the name of the new launch configuration
+ * @param type the type of this working copy
+ */
+ protected CBuildConfigWorkingCopy(IContainer container, String name) {
+ super((IPath)null);
+ setName(name);
+ setInfo(new CBuildConfigInfo());
+ setContainer(container);
+ fSuppressChange = false;
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#isDirty()
+ */
+ public boolean isDirty() {
+ return fDirty;
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#doSave()
+ */
+ public ICBuildConfig doSave() throws CoreException {
+ if (isDirty()) {
+ IWorkspaceRunnable wr = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor pm) throws CoreException {
+ // write the new file
+ CBuildConfigWorkingCopy.this.writeNewFile();
+ // delete the old file if this is not a new configuration
+ // or the file was renamed/moved
+ if (!CBuildConfigWorkingCopy.this.isNew()) {
+ if (CBuildConfigWorkingCopy.this.isMoved()) {
+ CBuildConfigWorkingCopy.this.getOriginal().delete();
+ }
+ }
+ resetDirty();
+ }
+ };
+
+ ResourcesPlugin.getWorkspace().run(wr, null);
+ }
+
+ return new CBuildConfig(getLocation());
+ }
+
+ /**
+ * Writes the new configuration information to a file.
+ *
+ * @exception CoreException if writing the file fails
+ */
+ protected void writeNewFile() throws CoreException {
+ String xml = null;
+ try {
+ xml = getInfo().getAsXML();
+ } catch (IOException e) {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("CBuildConfigWorkingCopy.{0}_occurred_generating_launch_configuration_XML._1"), new String[]{e.toString()}), null //$NON-NLS-1$
+ )
+ );
+ }
+
+ if (isLocal()) {
+ // use java.io to update configuration file
+ try {
+ boolean added = false;
+ File file = getLocation().toFile();
+ File dir = getLocation().removeLastSegments(1).toFile();
+ dir.mkdirs();
+ if (!file.exists()) {
+ added = true;
+ file.createNewFile();
+ }
+ FileOutputStream stream = new FileOutputStream(file);
+ stream.write(xml.getBytes("UTF8")); //$NON-NLS-1$
+ stream.close();
+ if (added) {
+ getBuildConfigurationManager().configurationAdded(new CBuildConfig(getLocation()));
+ } else {
+ getBuildConfigurationManager().configurationChanged(new CBuildConfig(getLocation()));
+ }
+ } catch (IOException e) {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, MessageFormat.format(DebugCoreMessages.getString("CBuildConfigWorkingCopy.{0}_occurred_generating_launch_configuration_XML._1"), new String[]{e.toString()}), null //$NON-NLS-1$
+ )
+ );
+ }
+ } else {
+ // use resource API to update configuration file
+ IFile file = getFile();
+ IContainer dir = file.getParent();
+ if (!dir.exists()) {
+ throw new DebugException(
+ new Status(
+ Status.ERROR, DebugPlugin.getUniqueIdentifier(),
+ DebugException.REQUEST_FAILED, DebugCoreMessages.getString("CBuildConfigWorkingCopy.Specified_container_for_launch_configuration_does_not_exist_2"), null //$NON-NLS-1$
+ )
+ );
+ }
+ ByteArrayInputStream stream = new ByteArrayInputStream(xml.getBytes());
+ if (!file.exists()) {
+ file.create(stream, false, null);
+ //getLaunchManager().CBuildConfigurationAdded(new CBuildConfig(getLocation()));
+ } else {
+ file.setContents(stream, false, false, null);
+ //getLaunchManager().CBuildConfigurationChanged(new CBuildConfig(getLocation()));
+ }
+ }
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#setAttribute(String, int)
+ */
+ public void setAttribute(String attributeName, int value) {
+ getInfo().setAttribute(attributeName, new Integer(value));
+ setDirty();
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#setAttribute(String, String)
+ */
+ public void setAttribute(String attributeName, String value) {
+ getInfo().setAttribute(attributeName, value);
+ setDirty();
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#setAttribute(String, boolean)
+ */
+ public void setAttribute(String attributeName, boolean value) {
+ getInfo().setAttribute(attributeName, new Boolean(value));
+ setDirty();
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#setAttribute(String, List)
+ */
+ public void setAttribute(String attributeName, List value) {
+ getInfo().setAttribute(attributeName, value);
+ setDirty();
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#setAttribute(String, Map)
+ */
+ public void setAttribute(String attributeName, Map value) {
+ getInfo().setAttribute(attributeName, value);
+ setDirty();
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#getOriginal()
+ */
+ public ICBuildConfig getOriginal() {
+ return fOriginal;
+ }
+
+ /**
+ * Sets the launch configuration this working copy
+ * is based on. Initializes the attributes of this
+ * working copy to the current values of the given
+ * configuration.
+ *
+ * @param originl the launch configuration this working
+ * copy is based on.
+ * @exception CoreException if unable to initialize this
+ * working copy based on the original's current attribute
+ * set
+ */
+ private void copyFrom(CBuildConfig original) throws CoreException {
+ CBuildConfigInfo info = original.getInfo();
+ setInfo(info.getCopy());
+ setContainer(original.getContainer());
+ resetDirty();
+ }
+
+ /**
+ * Sets the launch configuration this working copy
+ * is based on.
+ *
+ * @param originl the launch configuration this working
+ * copy is based on.
+ */
+ private void setOriginal(CBuildConfig original) {
+ fOriginal = original;
+ }
+
+ /**
+ * Sets the working copy info object for this working copy.
+ *
+ * @param info a copy of attributes from this working copy's
+ * original launch configuration
+ */
+ protected void setInfo(CBuildConfigInfo info) {
+ fInfo = info;
+ }
+
+ /**
+ * @see ICBuildConfig#isWorkingCopy()
+ */
+ public boolean isWorkingCopy() {
+ return true;
+ }
+
+ /**
+ * A working copy keeps a local info object that is not
+ * cached with the launch manager.
+ *
+ * @see CBuildConfig#getInfo()
+ */
+ protected CBuildConfigInfo getInfo() {
+ return fInfo;
+ }
+
+ /**
+ * Sets this working copy's state to dirty.
+ * Notifies listeners that this working copy has
+ * changed.
+ */
+ private void setDirty() {
+ fDirty = true;
+ if (!suppressChangeNotification()) {
+ getBuildConfigurationManager().configurationChanged(this);
+ }
+ }
+
+ /**
+ * Sets this working copy's state to not dirty.
+ */
+ private void resetDirty() {
+ fDirty = false;
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#rename(String)
+ */
+ public void rename(String name) {
+ if (!getName().equals(name)) {
+ setName(name);
+ fRenamed = isNew() || !(getOriginal().getName().equals(name));
+ }
+ }
+
+ /**
+ * Sets the new name for this configuration.
+ *
+ * @param name the new name for this configuration
+ */
+ private void setName(String name) {
+ fName = name;
+ setDirty();
+ }
+
+ /**
+ * @see ICBuildConfig#getName()
+ */
+ public String getName() {
+ return fName;
+ }
+
+ /**
+ * @see ICBuildConfig#isLocal()
+ */
+ public boolean isLocal() {
+ return getContainer() == null;
+ }
+
+ /**
+ * Returns the location this launch configuration will reside at
+ * when saved.
+ *
+ * @see ICBuildConfig#getLocation()
+ */
+ public IPath getLocation() {
+ if (isMoved()) {
+ IPath path = getContainer().getLocation();
+ path = path.append(getName() + "." + BUILD_CONFIGURATION_FILE_EXTENSION); //$NON-NLS-1$
+ return path;
+ } else {
+ return getOriginal().getLocation();
+ }
+ }
+
+ /**
+ * Returns whether this working copy is new, or is a
+ * working copy of another launch configuration.
+ *
+ * @return whether this working copy is new, or is a
+ * working copy of another launch configuration
+ */
+ protected boolean isNew() {
+ return getOriginal() == null;
+ }
+
+ /**
+ * Returns whether this working copy is new or if its
+ * location has changed from that of its original.
+ *
+ * @return whether this working copy is new or if its
+ * location has changed from that of its original
+ */
+ protected boolean isMoved() {
+ if (isNew() || fRenamed) {
+ return true;
+ }
+ IContainer newContainer = getContainer();
+ IContainer originalContainer = ((CBuildConfig)getOriginal()).getContainer();
+ if (newContainer == originalContainer) {
+ return false;
+ }
+ if (newContainer == null) {
+ return !originalContainer.equals(newContainer);
+ } else {
+ return !newContainer.equals(originalContainer);
+ }
+ }
+
+ /**
+ * A working copy cannot generate a memento.
+ *
+ * @see ICBuildConfig#getMemento()
+ */
+ public String getMemento() {
+ return null;
+ }
+
+ /**
+ * Returns whether change notification should be
+ * suppressed
+ */
+ protected boolean suppressChangeNotification() {
+ return fSuppressChange;
+ }
+
+ /**
+ * @see ICBuildConfigWorkingCopy#setContainer(IContainer)
+ */
+ public void setContainer(IContainer container) {
+ if (container == fContainer) {
+ return;
+ }
+ if (container != null) {
+ if (container.equals(fContainer)) {
+ return;
+ }
+ } else {
+ if (fContainer.equals(container)) {
+ return;
+ }
+ }
+ fContainer = container;
+ setDirty();
+ }
+
+ /**
+ * Returns the container this working copy will be
+ * stored in when saved, or null
if
+ * this working copy is local.
+ *
+ * @return the container this working copy will be
+ * stored in when saved, or null
if
+ * this working copy is local
+ */
+ protected IContainer getContainer() {
+ return fContainer;
+ }
+
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CCygwinFilesystem.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CCygwinFilesystem.java
new file mode 100644
index 00000000000..60d0aa444e2
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CCygwinFilesystem.java
@@ -0,0 +1,125 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.cdt.internal.core.ProcessClosure;
+import org.eclipse.cdt.utils.spawner.ProcessFactory;
+
+/**
+ * Performs file path translation on a Windows + Cygwin system.
+ *
+ * This allows for translation between "native" Windows path + * names and Cygwin style path names. + */ +public class CCygwinFilesystem implements IFilesystem { + + private static String CONVERT_CMD = "cygpath"; //$NON-NLS-1$ + private static String CONVERT_TO_UNIX = "-u"; //$NON-NLS-1$ + private static String CONVERT_TO_NATIVE = "-w"; //$NON-NLS-1$ + + private String fHome; + + public CCygwinFilesystem() { + super(); + fHome = + getNativePath(IFilesystem.FILESYSTEM_ROOT) + + IFilesystem.FILESYSTEM_ROOT; + } + + /** + * Helper function for converting native (Windows) paths to Unix paths, + * and vice versa. + * + * @param path the path to covert. + * @param cmdFlags how to convert the path. Supported values for are + * CONVERT_TO_UNIX and CONVERT_TO_NATIVE. + */ + private String convertPath(String path, String cmdFlags) { + + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + String[] cmds = { CONVERT_CMD, cmdFlags, path }; + String newPath = path; + + // In the event that cygpath is not found, or fails for some reason, + // this function will return a Cygwinized/Javaized version of the + // path (ex, "C:\foo\bar" will become "C:/foo/bar"). + + try { + ProcessFactory pf = ProcessFactory.getFactory(); + Process pid = pf.exec(cmds); + ProcessClosure pc = new ProcessClosure(pid, stdout, stderr); + + pc.runBlocking(); + + newPath = stdout.toString().trim(); + } catch (IOException e) { + e.printStackTrace(); + } + + return newPath.replace(PATHSEP_WINDOWS, PATHSEP_CYGWIN); + } + + /** + * @see org.eclipse.cdt.core.builder.util.IFilesystem#getRoot() + */ + public String getRoot() { + return fHome; + } + + /** + * @see org.eclipse.cdt.core.builder.util.IFilesystem#getNativePath(String) + */ + public String getNativePath(String path) { + return convertPath(path, CONVERT_TO_NATIVE); + } + + /** + * @see org.eclipse.cdt.core.builder.util.IFilesystem#getNativePath(File) + */ + public String getNativePath(File path) { + return getNativePath(path.toString()); + } + + /** + * @see org.eclipse.cdt.core.builder.util.IFilesystem#getUnixPath(String) + */ + public String getUnixPath(String path) { + + path = convertPath(path, CONVERT_TO_UNIX); + + // Make sure there are no spaces in the path and if there are, escape them. + String subString = new String(""); //$NON-NLS-1$ + int len = 0; + int begin = 0; + while ((len = path.indexOf(" ")) >= 0) { //$NON-NLS-1$ + subString += path.substring(begin, len); + subString += "\\ "; //$NON-NLS-1$ + path = path.substring(len + 1); + } + subString += path; + + return subString; + } + + /** + * @see org.eclipse.cdt.core.builder.util.IFilesystem#getUnixPath(File) + */ + public String getUnixPath(File path) { + return getUnixPath(path.toString()); + } + +} diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CUnixFilesystem.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CUnixFilesystem.java new file mode 100644 index 00000000000..c0616b0ee93 --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CUnixFilesystem.java @@ -0,0 +1,58 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Timesys 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: + * Timesys - Initial API and implementation + **********************************************************************/ + +package org.eclipse.cdt.core.builder.util; + +import java.io.File; + +/** + * Performs file path translation on a Unix system. + *
+ * This is essentially uninteresting, as the whole purpose of the filesystem
+ * abstraction is to provide for some minimal support for Unix-y file paths
+ * under Windows + Cygwin.
+ */
+public class CUnixFilesystem implements IFilesystem {
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getRoot()
+ */
+ public String getRoot() {
+ return IFilesystem.FILESYSTEM_ROOT;
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getNativePath(String)
+ */
+ public String getNativePath(String path) {
+ return new String(path);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getNativePath(File)
+ */
+ public String getNativePath(File path) {
+ return path.toString();
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getUnixPath(String)
+ */
+ public String getUnixPath(String path) {
+ return new String(path);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getUnixPath(File)
+ */
+ public String getUnixPath(File path) {
+ return path.toString();
+ }
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CUtil.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CUtil.java
new file mode 100644
index 00000000000..f1eef587b9b
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/CUtil.java
@@ -0,0 +1,50 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.util;
+
+/**
+ * @author sam.robb
+ *
+ * Collection of generic utility functions.
+ */
+public class CUtil {
+
+ /**
+ * Given a name, this function will decide whether the
+ * name conforms to rules for naming valid C identifiers.
+ */
+ public static boolean isValidCIdentifier(String name) {
+
+ // any sequence of letters, digits, or underscores,
+ // which begins with a letter or underscore
+
+ if ((name == null) || (name.length() < 1)) {
+ return false;
+ }
+
+ char c = name.charAt(0);
+
+ if ((c != '_') && !Character.isLetter(c)) {
+ return false;
+ }
+
+ for (int i = 1; i < name.length(); i++) {
+ c = name.charAt(i);
+ if ((c != '_') && !Character.isLetterOrDigit(c)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/Filesystem.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/Filesystem.java
new file mode 100644
index 00000000000..764ba0004ae
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/Filesystem.java
@@ -0,0 +1,161 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import org.eclipse.core.internal.runtime.Assert;
+
+/**
+ * Singleton that wraps the concept of the current OS's
+ * filesystem in a way that allows us to work properly
+ * under Cygwin.
+ */
+public class Filesystem {
+
+ private static IFilesystem fInstance;
+
+ /**
+ * Create the IFilesystem instance appropriate for the current OS.
+ *
+ * Right now, this is based off of the speratorChar reported by
+ * java.io.File; there is probably a better way to deal with this.
+ */
+ static {
+ // init to null, update with class reference if we can
+ // otherwise leave null to signal that we don't have a valid file system.
+ if (File.separatorChar == IFilesystem.FILESYSTEM_ROOT.charAt(0)) {
+ fInstance = new CUnixFilesystem();
+ } else {
+ fInstance = new CCygwinFilesystem();
+ }
+ }
+
+ private static IFilesystem getInstance() {
+ if (fInstance == null) {
+ throw new FileSystemException ("Problems encountered while searching for your file system.");
+ }
+ return fInstance;
+ }
+
+ public static boolean isValid() {
+ return (fInstance != null);
+ }
+
+ public static class FileSystemException extends Error {
+ FileSystemException (String s) {
+ super(s);
+ }
+ }
+
+ /**
+ * Private constructor to prevent instatiation.
+ *
+ * All members of this class are static, and intended to be accessed
+ * via "Filesystem.[method_name]".
+ */
+ private Filesystem() {
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getRoot()
+ */
+ public static String getRoot() {
+ return getInstance().getRoot();
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getNativePath(String)
+ */
+ public static String getNativePath(String path) {
+ return getInstance().getNativePath(path);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getNativePath(File)
+ */
+ public static String getNativePath(File path) {
+ return getInstance().getNativePath(path);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getUnixPath(String)
+ */
+ public static String getUnixPath(String path) {
+ return getInstance().getUnixPath(path);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.builder.util.IFilesystem#getUnixPath(File)
+ */
+ public static String getUnixPath(File path) {
+ return getInstance().getUnixPath(path);
+ }
+
+ /**
+ * Copy a file from sourceFile to destFile. Performs a binary file copy,
+ * reading data from sourceFile as a byte stream, and writing it to destFile
+ * as a byte stream.
+ *
+ * @param sourceFile File to copy.
+ * @param destFile Where to copy the file to.
+ * @param replaceIfExists If true, if destFile exists, it is replaced.
+ * @return True if the file was copied; false otherwise.
+ */
+ public static boolean copyFile(File sourceFile, File destFile, boolean replaceIfExists) {
+ Assert.isNotNull(sourceFile);
+ Assert.isNotNull(destFile);
+
+ if (!sourceFile.exists()) {
+ return false;
+ }
+
+ if (sourceFile.equals(destFile)) {
+ return false;
+ }
+
+ if (replaceIfExists && destFile.exists()) {
+ destFile.delete();
+ }
+
+ if (destFile.exists()) {
+ return false;
+ }
+
+ FileInputStream fis = null;
+ FileOutputStream fos = null;
+ byte[] buf = new byte[1024];
+ int i = 0;
+
+ try {
+ fis = new FileInputStream(sourceFile);
+ fos = new FileOutputStream(destFile);
+
+ while(-1 != (i = fis.read(buf))) {
+ fos.write(buf, 0, i);
+ }
+
+ fos.close();
+ fis.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ if (destFile.exists()) {
+ destFile.delete();
+ }
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/IFilesystem.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/IFilesystem.java
new file mode 100644
index 00000000000..476add3c7a4
--- /dev/null
+++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/util/IFilesystem.java
@@ -0,0 +1,66 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.core.builder.util;
+
+import java.io.File;
+
+/**
+ * Abstracts information about a filesystem in order to allow
+ * translation between native/unix pathnames.
+ */
+public interface IFilesystem {
+
+ public static String FILESYSTEM_ROOT = "/"; //$NON-NLS-1$
+ public static char PATHSEP_WINDOWS = '\\'; //$NON-NLS-1$
+ public static char PATHSEP_CYGWIN = '\\'; //$NON-NLS-1$
+
+ /**
+ * Get the root directory for the filesystem.
+ *
+ * The root directory is returned in native filesystem format
+ * (ex, "C:/cygwin/" on Windows, "/" on Unix.) The returned
+ * string is guaranteed to have a trailing path seperator.
+ */
+ public String getRoot();
+
+ /**
+ * Convert the provided path into a native path.
+ *
+ * @param path path to convert.
+ * @return native representation of path.
+ */
+ public String getNativePath(String path);
+
+ /**
+ * Convert the provided path into a native path.
+ *
+ * @param path path to convert.
+ * @return native representation of path.
+ */
+ public String getNativePath(File path);
+
+ /**
+ * Convert the provided path into a unix path.
+ *
+ * @param path path to convert.
+ * @return unix representation of path.
+ */
+ public String getUnixPath(String path);
+
+ /**
+ * Convert the provided path into a unix path.
+ *
+ * @param path path to convert.
+ * @return unix representation of path.
+ */
+ public String getUnixPath(File path);
+}
diff --git a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/BuilderModel.java b/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/BuilderModel.java
deleted file mode 100644
index 0ff359c0822..00000000000
--- a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/BuilderModel.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package org.eclipse.cdt.core.builder;
-
-/*
- * (c) Copyright QNX Software Systems Ltd. 2002.
- * All Rights Reserved.
- */
-
-import org.eclipse.core.resources.ICommand;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-
-public class BuilderModel {
-
- private static BuilderModel buildModel = null;
-
- public final static String PLUGIN_ID = "org.eclipse.cdt.core";
- public final static String BUILDER_NAME = "cbuilder";
- public final static String BUILDER_ID = PLUGIN_ID + "." + BUILDER_NAME;
-
- public static String getBuilderName () {
- return BUILDER_NAME;
- }
-
- public static String getBuilderId () {
- return BUILDER_ID;
- }
-/*
- public IBuildPath getBuildPath(IProject project) {
- return null;
- }
-
- public void setBuildPath(IProject project, IBuildPath bp) {
- }
-*/
- public void addBuildListener () {
- }
-
- public void removeBuildListener() {
- }
-
- public void build(IProject project, IPath workingDir, String[] args) {
- }
-
- /**
- * Adds default C Builder.
- */
- public void addCToBuildSpec(IProject project) throws CoreException {
- addToBuildSpec(project, getBuilderId());
- }
-
- /**
- * Adds a builder to the build spec for the given project.
- */
- public void addToBuildSpec(IProject project, String builderID) throws CoreException {
- IProjectDescription description = project.getDescription();
- ICommand[] commands = description.getBuildSpec();
- ICommand command = null;
- for (int i = 0; i < commands.length; i++) {
- if (commands[i].getBuilderName().equals(builderID)) {
- command = commands[i];
- break;
- }
- }
- if (command == null) {
- command = description.newCommand();
- command.setBuilderName(builderID);
-
- // Add a build spec before other builders (1FWJK7I)
- ICommand[] newCommands = new ICommand[commands.length + 1];
- System.arraycopy(commands, 0, newCommands, 1, commands.length);
- newCommands[0] = command;
- // Commit the spec change into the project
- description.setBuildSpec(newCommands);
- project.setDescription(description, null);
- }
- }
-
- /**
- * Removes the default C Builder.
- */
- public void removeCFromBuildSpec(IProject project) throws CoreException {
- removeFromBuildSpec(project, getBuilderId());
- }
-
- /**
- * Removes the given builder from the build spec for the given project.
- */
- public void removeFromBuildSpec(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)) {
- 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);
- project.setDescription(description, null);
- }
- }
- }
-
- private BuilderModel() {
- }
-
- public static BuilderModel getDefault() {
- if (buildModel == null) {
- buildModel = new BuilderModel();
- }
- return buildModel;
- }
-}
diff --git a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/CIncrementalBuilder.java b/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/CIncrementalBuilder.java
deleted file mode 100644
index 64257c5edf9..00000000000
--- a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/CIncrementalBuilder.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.eclipse.cdt.core.builder;
-
-import java.util.Map;
-
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.resources.IConsole;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-/*
- * (c) Copyright QNX Software Systems Ltd. 2002.
- * All Rights Reserved.
- */
-
-/**
- *
- * Note: This class/interface is part of an interim API that is still under development and
- * expected to change significantly before reaching stability. It is being made available at
- * this early stage to solicit feedback from pioneering adopters on the understanding that any
- * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.
- */
-public class CIncrementalBuilder extends IncrementalProjectBuilder {
- int kind;
- Map args;
- IProgressMonitor monitor;
-
- private ICBuilder fCurrentBuilder;
-
- public int getkind() {
- return kind;
- }
-
- public Map getMap() {
- return args;
- }
-
- public IProgressMonitor monitor() {
- return monitor;
- }
-
- public IConsole getConsole() {
- String id = fCurrentBuilder.getID();
- return CCorePlugin.getDefault().getConsole(id);
- }
-
- //FIXME: Not implemented
- public IPath getBuildDirectory() {
- return getProject().getLocation();
- }
-
- //FIXME: Not implemented
- public String[] getBuildParameters() {
- return new String[0];
- }
-
- protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
- throws CoreException {
-
- this.kind = kind;
- this.args = args;
- this.monitor = monitor;
-
- // Get the ICBuilder
- ICBuilder cbuilder[] = getCBuilder();
-
- // FIXME: Check preference for non-modal builds
- fCurrentBuilder = cbuilder[0];
- return fCurrentBuilder.build(this);
- }
-
- //FIXME: Not implemented
- private ICBuilder[] getCBuilder () throws CoreException {
- return new ICBuilder[0];
- }
-}
diff --git a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/ICBuilder.java b/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/ICBuilder.java
deleted file mode 100644
index 3b345457cd6..00000000000
--- a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/ICBuilder.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.eclipse.cdt.core.builder;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IPath;
-
-/*
- * (c) Copyright QNX Software Systems Ltd. 2002.
- * All Rights Reserved.
- */
-
-/**
- *
- * This class provides the infrastructure for defining a builder and fulfills the contract
- * specified by the org.eclipse.cdt.core.cbuilder standard extension point.
-
- * Note: This class/interface is part of an interim API that is still under development and
- * expected to change significantly before reaching stability. It is being made available at
- * this early stage to solicit feedback from pioneering adopters on the understanding that any
- * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.
- */
-public interface ICBuilder {
- /**
- * return the search include path list.
- * @return IPath[]
- */
- IPath[] getIncludePaths();
-
- /**
- * Change the search include path lists.
- * @params IPath[]
- */
- void setIncludePaths(IPath[] incPaths);
-
- /**
- * return the search library path list.
- * @return IPath[]
- */
- IPath[] getLibraryPaths();
-
- /**
- * Change the search library path lists.
- * @params IPath[]
- */
- void setLibraryPaths(IPath[] libPaths);
-
- /**
- * return the list of libraries use.
- * @return String[]
- */
- String[] getLibraries();
-
- /**
- * Change the libraries.
- * @params String[]
- */
- void setLibraries(String[] libs);
-
- /**
- * Get the Optimization level.
- * @return IOptimization
- */
- IOptimization getOptimization();
-
- /**
- * Change the Optimization level.
- * @params IOptimization
- */
- void setOptimization(IOptimization o);
-
- /**
- * Build the project.
- */
- IProject[] build(CIncrementalBuilder cbuilder);
-
- /**
- * Method getID.
- * @return String
- */
- String getID();
-}
diff --git a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/IOptimization.java b/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/IOptimization.java
deleted file mode 100644
index 5e158345689..00000000000
--- a/core/org.eclipse.cdt.core/builder/org/eclipse/cdt/core/builder/IOptimization.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.eclipse.cdt.core.builder;
-
-/*
- * (c) Copyright QNX Software Systems Ltd. 2002.
- * All Rights Reserved.
- */
-
-/**
- *
- * Note: This class/interface is part of an interim API that is still under development and
- * expected to change significantly before reaching stability. It is being made available at
- * this early stage to solicit feedback from pioneering adopters on the understanding that any
- * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.
- */
-public interface IOptimization {
- String getDescription(int level);
- int getCurrentLevel();
- void setCurrentLevel(int level);
- int[] getLevels();
-}
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index 80264df233e..d39219a0386 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -31,6 +31,52 @@
+ * This may be called by to force a button state update.
+ */
+ public void updateButtons();
+
+ /**
+ * Updates the message (or error message) shown in the message line
+ * to reflect the state of the currently active tab in the dialog.
+ *
+ * This method may be called to force a message update.
+ */
+ public void updateMessage();
+
+ /**
+ * Sets the contents of the name field to the given name.
+ *
+ * @param name new name value
+ */
+ public void setName(String name);
+
+ /**
+ * Returns the tabs currently being displayed, or
+ *
+ * This interface is intended to be implemented by clients.
+ */
+public interface ICToolTab {
+
+ /**
+ * Creates the top level control for this settings tab under
+ * the given parent composite. This method is called once on
+ * tab creation, after
+ * Implementors are responsible for ensuring that
+ * the created control can be accessed via
+ * May return
+ * An error message should describe some error state,
+ * as opposed to a message which may simply provide instruction
+ * or information to the user.
+ *
+ * A message provides instruction or information to the
+ * user, as opposed to an error message which should
+ * describe some error state.
+ *
+ * This information is typically used by the configuration dialog to
+ * decide when it is okay to save a configuration.
+ *
+ * The tab group controls which tabs are displayed for a specific
+ * tool, and provides a mechanism for overriding configuration
+ * initialization performed by tabs.
+ *
+ * This interface is intended to be implemented by clients.
+ *
+ * (Mercilessly modeled on the Eclipse launch mechanism.)
+ */
+public interface ICToolTabGroup {
+
+ /**
+ * Creates the tabs contained in this tab group. The tabs control's
+ * are not created. This is the first method called in the lifecycle
+ * of a tab group.
+ *
+ * @param dialog the tool settings dialog this tab group is contained in
+ */
+ public void createTabs(ICBuildConfigDialog dialog);
+
+ /**
+ * Returns the tabs contained in this tab group.
+ *
+ * @return the tabs contained in this tab group
+ */
+ public ICToolTab[] getTabs();
+
+ /**
+ * Notifies this tab group that it has been disposed, and disposes
+ * of this group's tabs. Marks the end of this tab group's lifecycle,
+ * allowing this tab group to perform any cleanup required.
+ */
+ public void dispose();
+
+ /**
+ * Initializes the given build configuration with default values
+ * for this tab group. This method is called when a new build
+ * configuration is created such that the configuration can be
+ * initialized with meaningful values. This method may be called
+ * before tab controls are created.
+ *
+ * @param configuration build configuration
+ */
+ public void setDefaults(ICBuildConfigWorkingCopy configuration);
+
+ /**
+ * Initializes this group's tab controls with values from the given
+ * build configuration. This method is called when a configuration
+ * is selected to view or edit.
+ *
+ * @param configuration build configuration
+ */
+ public void initializeFrom(ICBuildConfig configuration);
+
+ /**
+ * Copies values from this group's tabs into the given build configuration.
+ *
+ * @param configuration build configuration
+ */
+ public void performApply(ICBuildConfigWorkingCopy configuration);
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTabGroupPoint.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTabGroupPoint.java
new file mode 100644
index 00000000000..cddf35bd10d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTabGroupPoint.java
@@ -0,0 +1,44 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Interface representing an instance of
+ * a CToolTabGroup extension point.
+ */
+public interface ICToolTabGroupPoint {
+
+ /**
+ * Returns the unique id for the provider.
+ *
+ * @return unique id.
+ */
+ public String getId();
+
+ /**
+ * Returns the name of the provider's
+ * implementing class.
+ *
+ * @return name of the provider's implementing class.
+ */
+ public String getProviderClassName();
+
+ /**
+ * Returns an instance of the provider's
+ * implementing class.
+ *
+ * @return instance of ICToolTabGroup.
+ */
+ public ICToolTabGroup getProvider() throws CoreException;
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigDialog.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigDialog.java
new file mode 100644
index 00000000000..ae7de81834a
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigDialog.java
@@ -0,0 +1,1778 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Based on org.eclipse.debug.org.eclipse.cdt.ui.builder.internal.ui.launchConfigurations.LaunchConfigurationDialog.
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.cdt.core.builder.BuilderPlugin;
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigManager;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+import org.eclipse.cdt.core.builder.model.ICTool;
+import org.eclipse.cdt.core.builder.model.ICToolType;
+import org.eclipse.cdt.internal.ui.util.SWTUtil;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.builder.ICBuildConfigDialog;
+import org.eclipse.cdt.ui.builder.ICToolTab;
+import org.eclipse.cdt.ui.builder.ICToolTabGroup;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.internal.ui.PixelConverter;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.ui.model.WorkbenchViewerSorter;
+
+/**
+ * @author sam.robb
+ *
+ * The dialog used to edit build configurations.
+ */
+public class CBuildConfigDialog extends TitleAreaDialog
+ implements ICBuildConfigDialog {
+
+ /**
+ * List of tools available to thsi configuration
+ */
+ private ListViewer fToolList;
+
+ /**
+ * The workbench context present when this dialog is opened.
+ */
+ private Object fContext;
+
+ /**
+ * The IResource corresponding to null
+ */
+ private Control fControl;
+
+ /**
+ * The configuration dialog this tab is contained in.
+ */
+ private ICBuildConfigDialog fConfigurationDialog;
+
+ /**
+ * Current error message, or null
+ */
+ private String fErrorMessage;
+
+ /**
+ * Current message, or null
+ */
+ private String fMessage;
+
+ /**
+ * Returns the dialog this tab is contained in, or
+ * null
if not yet set.
+ *
+ * @return configuration dialog, or null
+ */
+ protected ICBuildConfigDialog getConfigurationDialog() {
+ return fConfigurationDialog;
+ }
+
+ /**
+ * Updates the buttons and message in this page's configuration dialog.
+ */
+ protected void updateConfigurationDialog() {
+ if (getConfigurationDialog() != null) {
+ getConfigurationDialog().updateButtons();
+ getConfigurationDialog().updateMessage();
+ }
+ }
+
+ /**
+ * @see ICToolTab#getControl()
+ */
+ public Control getControl() {
+ return fControl;
+ }
+
+ /**
+ * Sets the control to be displayed in this tab.
+ *
+ * @param control the control for this tab
+ */
+ protected void setControl(Control control) {
+ fControl = control;
+ }
+
+ /**
+ * @see ICToolTab#getErrorMessage()
+ */
+ public String getErrorMessage() {
+ return fErrorMessage;
+ }
+
+ /**
+ * @see ICToolTab#getMessage()
+ */
+ public String getMessage() {
+ return fMessage;
+ }
+
+ /**
+ * @see ICToolTab#setConfigurationDialog(ICBuildConfigDialog)
+ */
+ public void setConfigurationDialog(ICBuildConfigDialog dialog) {
+ fConfigurationDialog = dialog;
+ }
+
+ /**
+ * Sets this page's error message, possibly null
.
+ *
+ * @param errorMessage the error message or null
+ */
+ protected void setErrorMessage(String errorMessage) {
+ fErrorMessage = errorMessage;
+ }
+
+ /**
+ * Sets this page's message, possibly null
.
+ *
+ * @param message the message or null
+ */
+ protected void setMessage(String message) {
+ fMessage = message;
+ }
+
+ /**
+ * By default, do nothing.
+ *
+ * @see ICToolTab#dispose()
+ */
+ public void dispose() {
+ }
+
+ /**
+ * Returns the shell this tab is contained in, or null
.
+ *
+ * @return the shell this tab is contained in, or null
+ */
+ protected Shell getShell() {
+ Control control = getControl();
+ if (control != null) {
+ return control.getShell();
+ }
+ return null;
+ }
+
+ /**
+ * Creates and returns a new push button with the given
+ * label and/or image.
+ *
+ * @param parent parent control
+ * @param label button label or null
+ * @param image image of null
+ *
+ * @return a new push button
+ */
+ protected Button createPushButton(Composite parent, String label, Image image) {
+ return SWTUtil.createPushButton(parent, label, image);
+ }
+
+ /**
+ * Creates and returns a new radio button with the given
+ * label and/or image.
+ *
+ * @param parent parent control
+ * @param label button label or null
+ *
+ * @return a new radio button
+ */
+ protected Button createRadioButton(Composite parent, String label) {
+ return SWTUtil.createRadioButton(parent, label);
+ }
+
+ /**
+ * @see ICToolTab#canSave()
+ */
+ public boolean canSave() {
+ return true;
+ }
+
+ /**
+ * Create some empty space.
+ */
+ protected void createVerticalSpacer(Composite comp, int colSpan) {
+ Label label = new Label(comp, SWT.NONE);
+ GridData gd = new GridData();
+ gd.horizontalSpan = colSpan;
+ label.setLayoutData(gd);
+ }
+
+ /**
+ * @see ICToolTab#getImage()
+ */
+ public Image getImage() {
+ return null;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ACToolTabGroup.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ACToolTabGroup.java
new file mode 100644
index 00000000000..efd7858c700
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ACToolTabGroup.java
@@ -0,0 +1,90 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder;
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+
+/**
+ * Base tool tab group implementation.
+ */
+public abstract class ACToolTabGroup implements ICToolTabGroup {
+
+ /**
+ * The tabs in this tab group, or null
if not yet instantiated.
+ */
+ protected ICToolTab[] fTabs = null;
+
+ /**
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#getTabs()
+ */
+ public ICToolTab[] getTabs() {
+ return fTabs;
+ }
+
+ /**
+ * Sets the tabs in this group
+ *
+ * @param tabs the tabs in this group
+ */
+ protected void setTabs(ICToolTab[] tabs) {
+ fTabs = tabs;
+ }
+
+ /**
+ * By default, dispose all the tabs in this group.
+ *
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#dispose()
+ */
+ public void dispose() {
+ ICToolTab[] tabs = getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].dispose();
+ }
+ }
+
+ /**
+ * By default, delegate to all of the tabs in this group.
+ *
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#setDefaults(ICBuildConfigWorkingCopy)
+ */
+ public void setDefaults(ICBuildConfigWorkingCopy configuration) {
+ ICToolTab[] tabs = getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].setDefaults(configuration);
+ }
+ }
+
+ /**
+ * By default, delegate to all of the tabs in this group.
+ *
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#initializeFrom(ICBuildConfig)
+ */
+ public void initializeFrom(ICBuildConfig configuration) {
+ ICToolTab[] tabs = getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].initializeFrom(configuration);
+ }
+ }
+
+ /**
+ * By default, delegate to all of the tabs in this group.
+ *
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#performApply(ICBuildConfigWorkingCopy)
+ */
+ public void performApply(ICBuildConfigWorkingCopy configuration) {
+ ICToolTab[] tabs = getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].performApply(configuration);
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICBuildConfigDialog.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICBuildConfigDialog.java
new file mode 100644
index 00000000000..f09d15c1c97
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICBuildConfigDialog.java
@@ -0,0 +1,62 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder;
+
+/**
+ * A tool settings dialog is used to edit/view parameters passed
+ * to a tool as part of a C/'C++ build step. It contains a build
+ * configuration tab group.
+ *
+ * @see ICToolTabGroup
+ * @see ICToolTab
+ */
+public interface ICBuildConfigDialog {
+
+ /**
+ * Adjusts the enable state of this dialog's buttons
+ * to reflect the state of the active tab group.
+ * null
if none.
+ *
+ * @return currently displayed tabs, or null
+ */
+ public ICToolTab[] getTabs();
+
+ /**
+ * Returns the currently active ICToolTab
+ * being displayed, or null
if there is none.
+ *
+ * @return currently active ICToolTab
, or null
.
+ */
+ public ICToolTab getActiveTab();
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTab.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTab.java
new file mode 100644
index 00000000000..ba843b46019
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTab.java
@@ -0,0 +1,159 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder;
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A tool settings configuration tab group is used to edit/view
+ * parameters passed to a tool as part of a C/'C++ build step.
+ * CToolPoint settings are presented in a dialog with a tab folder.
+ * Each tab presents UI elements appropriate for manipulating
+ * a set of parameters for a tool.
+ * setConfigurationDialog
+ * is called.
+ * getControl
+ * null
if the control
+ * has not been created yet.
+ * null
+ */
+ public Control getControl();
+
+ /**
+ * Initializes the given configuration with default values
+ * for this tab. This method is called when a new configuration
+ * is created such that the configuration can be initialized with
+ * meaningful values. This method may be called before this
+ * tab's control is created.
+ *
+ * @param configuration configuration
+ */
+ public void setDefaults(ICBuildConfigWorkingCopy configuration);
+
+ /**
+ * Initializes this tab's controls with values from the given
+ * configuration. This method is called when a configuration is
+ * selected to view or edit, after thistab's control has been
+ * created.
+ *
+ * @param configuration configuration
+ */
+ public void initializeFrom(ICBuildConfig configuration);
+
+ /**
+ * Notifies this configuration tab that it has been disposed. Marks
+ * the end of this tab's lifecycle, allowing this tab to perform any
+ * cleanup required.
+ */
+ public void dispose();
+
+ /**
+ * Copies values from this tab into the given configuration.
+ *
+ * @param configuration configuration
+ */
+ public void performApply(ICBuildConfigWorkingCopy configuration);
+
+ /**
+ * Returns the current error message for this tab.
+ * May be null
to indicate no error message.
+ * null
if none
+ */
+ public String getErrorMessage();
+
+ /**
+ * Returns the current message for this tab.
+ * null
if none
+ */
+ public String getMessage();
+
+ /**
+ * Returns whether this tab is in a state that allows the configuration
+ * whose values this tab is showing to be saved.
+ * null
if none
+ *
+ * @return the image for this tab, or null
if none
+ */
+ public Image getImage();
+
+ /**
+ * Returns true if the current contents of a tab are valid.
+ *
+ * @param config build configuration.
+ * @return boolean true if tab contents are valid, fale if not.
+ */
+ boolean isValid(ICBuildConfigWorkingCopy config);
+
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTabGroup.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTabGroup.java
new file mode 100644
index 00000000000..2e450de48ea
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ICToolTabGroup.java
@@ -0,0 +1,83 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder;
+
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+
+/**
+ * A tool settings configuration tab group is used to edit/view
+ * parameters passed to a tool as part of a C/'C++ build step.
+ * CToolPoint settings are presented in a dialog with a tab folder.
+ * Each tab presents UI elements appropriate for manipulating
+ * a set of parameters for a tool.
+ * fContext
.
+ */
+ private IResource fResourceContext;
+
+ /**
+ * The Composite used to insert an adjustable 'sash' between the tree and the tabs.
+ */
+ private SashForm fSashForm;
+
+ /**
+ * Default weights for the SashForm that specify how wide the selection and
+ * edit areas aree relative to each other.
+ */
+ private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {11, 30};
+
+ /**
+ * The tool selection area.
+ */
+ private Composite fSelectionArea;
+
+ /**
+ * The tool configuration edit area.
+ */
+ private Composite fEditArea;
+
+ /**
+ * The 'apply' button
+ */
+ private Button fApplyButton;
+
+ /**
+ * The 'revert' button
+ */
+ private Button fRevertButton;
+
+ /**
+ * The text widget displaying the name of the
+ * build configuration under edit
+ */
+ private Text fNameText;
+
+ private String fLastSavedName = null;
+
+ /**
+ * Container for the edit area TabFolder
+ */
+ private Composite fTabComposite;
+
+ /**
+ * The tab folder that contains tabs for the selected configuration
+ */
+ private TabFolder fTabFolder;
+
+ /**
+ * Flag that indicates when the tabs are being disposed.
+ */
+ private boolean fDisposingTabs = false;
+
+ /**
+ * The current (working copy) build configuration
+ * being displayed/edited or null
if
+ * none
+ */
+ private ICBuildConfigWorkingCopy fWorkingCopy;
+
+ /**
+ * The actual (non-working copy) build configuration that underlies the current working copy
+ */
+ private ICBuildConfig fUnderlyingConfig;
+
+ /**
+ * The current tab group being displayed
+ */
+ private ICToolTabGroup fTabGroup;
+
+ /**
+ * The type of tool tabs are currently displayed for
+ */
+ private ICToolType fToolType;
+
+ /**
+ * The index of the currently selected tab
+ */
+ private int fCurrentTabIndex;
+
+ private Cursor waitCursor;
+ private Cursor arrowCursor;
+ private MessageDialog fWindowClosingDialog;
+
+ /**
+ * Whether initlialing tabs
+ */
+ private boolean fInitializingTabs = false;
+
+ /**
+ * Indicates if selection changes in the tree should be ignored
+ */
+ private boolean fIgnoreSelectionChanges = false;
+
+ /**
+ * Previously selected element in the tree
+ */
+ private Object fSelectedTreeObject;
+
+ /**
+ * The number of 'long-running' operations currently taking place in this dialog
+ */
+ private long fActiveRunningOperations = 0;
+
+ /**
+ * Id for 'Close' button.
+ */
+ protected static final int ID_CLOSE_BUTTON = IDialogConstants.CLIENT_ID + 1;
+
+ /**
+ * Id for 'Cancel' button.
+ */
+ protected static final int ID_CANCEL_BUTTON = IDialogConstants.CLIENT_ID + 2;
+
+ /**
+ * Constrant String used as key for setting and retrieving current Control with focus
+ */
+ private static final String FOCUS_CONTROL = "focusControl";//$NON-NLS-1$
+
+ /**
+ * The height in pixels of this dialog's progress indicator
+ */
+ private static int PROGRESS_INDICATOR_HEIGHT = 18;
+
+ /**
+ * Constant specifying how wide this dialog is allowed to get (as a percentage of
+ * total available screen width) as a result of tab labels in the edit area.
+ */
+ private static final float MAX_DIALOG_WIDTH_PERCENT = 0.75f;
+
+ /**
+ * Empty array
+ */
+ protected static final Object[] EMPTY_ARRAY = new Object[0];
+
+ protected static final String DEFAULT_NEW_CONFIG_NAME = "New configuration";
+
+ /**
+ * Size of this dialog if there is no preference specifying a size.
+ */
+ protected static final Point DEFAULT_INITIAL_DIALOG_SIZE = new Point(620, 560);
+
+ private String fCantSaveErrorMessage;
+
+ private static String DIALOG_SASH_WEIGHTS = CUIPlugin.getPluginId() + ".buildConfigurationDialogSashWeights";
+ private static String DIALOG_LOCATION = CUIPlugin.getPluginId() + ".buildConfigurationDialogLocation";
+ private static String DIALOG_SIZE = CUIPlugin.getPluginId() + ".buildConfigurationDialogSize";
+
+ /**
+ * Constructs a new build configuration dialog on the given
+ * parent shell.
+ *
+ * @param shell the parent shell
+ * @param selection the selection used to initialize this dialog, typically the
+ * current workbench selection
+ * @param config onfiguration to edit.
+ */
+ public CBuildConfigDialog(Shell shell, ICBuildConfig config) {
+ super(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ fUnderlyingConfig = config;
+ try {
+ setWorkingCopy(config.copy(config.getName()));
+ } catch (CoreException e) {
+ }
+ }
+
+ /**
+ * A build configuration dialog overrides this method
+ * to create a custom set of buttons in the button bar.
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, ID_CLOSE_BUTTON, "Close", false);
+ }
+
+ /**
+ * @see Dialog#buttonPressed(int)
+ */
+ protected void buttonPressed(int buttonId) {
+ if (buttonId == ID_CLOSE_BUTTON) {
+ handleClosePressed();
+ } else {
+ super.buttonPressed(buttonId);
+ }
+ }
+
+ /**
+ * Returns the appropriate text for the build button
+ */
+ protected String getBuildButtonText() {
+ return ("B&uild");
+ }
+
+ /**
+ * @see Dialog#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ Control contents = super.createContents(parent);
+ initializeBounds();
+ initializeSashForm();
+ doInitialListSelection();
+ return contents;
+ }
+
+ /**
+ * Initialize the relative weights (widths) of the 2 sides of the sash.
+ */
+ protected void initializeSashForm() {
+ int[] sashWeights = DEFAULT_SASH_WEIGHTS;
+ String sashWeightString = getPreferenceStore().getString(DIALOG_SASH_WEIGHTS);
+ if (sashWeightString.length() > 0) {
+ Point sashWeightPoint = parseCoordinates(sashWeightString);
+ if (sashWeightPoint != null) {
+ sashWeights[0] = sashWeightPoint.x;
+ sashWeights[1] = sashWeightPoint.y;
+ }
+ }
+ getSashForm().setWeights(sashWeights);
+ }
+
+ /**
+ * Set the initial selection in the tree.
+ */
+ protected void doInitialListSelection() {
+ // getListViewer().setSelection(null);
+ }
+
+ /**
+ * Write out this dialog's Shell size, location & sash weights to the preference store.
+ */
+ protected void persistShellGeometry() {
+ Point shellLocation = getShell().getLocation();
+ Point shellSize = getShell().getSize();
+ int[] sashWeights = getSashForm().getWeights();
+ String locationString = serializeCoords(shellLocation);
+ String sizeString = serializeCoords(shellSize);
+ String sashWeightString = serializeCoords(new Point(sashWeights[0], sashWeights[1]));
+ getPreferenceStore().setValue(DIALOG_LOCATION, locationString);
+ getPreferenceStore().setValue(DIALOG_SIZE, sizeString);
+ getPreferenceStore().setValue(DIALOG_SASH_WEIGHTS, sashWeightString);
+ }
+
+ /**
+ * @see Window#close()
+ */
+ public boolean close() {
+ persistShellGeometry();
+ return super.close();
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+ GridData gd;
+ Composite dialogComp = (Composite)super.createDialogArea(parent);
+ Composite topComp = new Composite(dialogComp, SWT.NONE);
+ gd = new GridData(GridData.FILL_BOTH);
+ topComp.setLayoutData(gd);
+ GridLayout topLayout = new GridLayout();
+ topLayout.numColumns = 2;
+ topLayout.marginHeight = 5;
+ topLayout.marginWidth = 0;
+ topComp.setLayout(topLayout);
+
+ // Set the things that TitleAreaDialog takes care of
+ setTitle("Build Configuration");
+ setMessage(""); //$NON-NLS-1$
+
+ // Create the SashForm that contains the selection area on the left,
+ // and the edit area on the right
+ setSashForm(new SashForm(topComp, SWT.NONE));
+ getSashForm().setOrientation(SWT.HORIZONTAL);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 2;
+ getSashForm().setLayoutData(gd);
+
+ // Create the build configuration selection area and put it into the composite.
+ Composite toolSelectionArea = createToolSelectionArea(getSashForm());
+ gd = new GridData(GridData.FILL_VERTICAL);
+ toolSelectionArea.setLayoutData(gd);
+
+ // Create the build configuration edit area and put it into the composite.
+ Composite editAreaComp = createEditArea(getSashForm());
+ gd = new GridData(GridData.FILL_BOTH);
+ editAreaComp.setLayoutData(gd);
+
+ // Build the separator line that demarcates the button bar
+ Label separator = new Label(topComp, SWT.HORIZONTAL | SWT.SEPARATOR);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ separator.setLayoutData(gd);
+
+ dialogComp.layout(true);
+
+ return dialogComp;
+ }
+
+ /**
+ * Returns tab group for the given type of tool.
+ * Tabs are initialized to be contained in this dialog.
+ *
+ * @exception CoreException if unable to instantiate a tab group
+ */
+ protected ICToolTabGroup createGroup(final ICToolType configType) throws CoreException {
+ // Use a final Object array to store the tab group and any exception that
+ // results from the Runnable
+ final Object[] finalArray = new Object[2];
+ Runnable runnable = new Runnable() {
+ public void run() {
+ ICToolTabGroup tabGroup = null;
+ try {
+ tabGroup = CBuildConfigPresentationManager.getDefault().getTabGroup(configType);
+ finalArray[0] = tabGroup;
+ } catch (CoreException ce) {
+ finalArray[1] = ce;
+ return;
+ }
+ tabGroup.createTabs(CBuildConfigDialog.this);
+ ICToolTab[] tabs = tabGroup.getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].setConfigurationDialog(CBuildConfigDialog.this);
+ }
+ }
+ };
+
+ // Creating the tabs can result in plugin loading, so we show the busy cursor
+ BusyIndicator.showWhile(getDisplay(), runnable);
+
+ // Re-throw any CoreException if there was one
+ if (finalArray[1] != null) {
+ throw (CoreException)finalArray[1];
+ }
+
+ // Otherwise return the tab group
+ return (ICToolTabGroup)finalArray[0];
+ }
+
+ /**
+ * Convenience method to set the selection on the configuration tree.
+ */
+ protected void setListViewerSelection(ISelection selection) {
+ getListViewer().setSelection(selection);
+ }
+
+ private void setLastSavedName(String lastSavedName) {
+ this.fLastSavedName = lastSavedName;
+ }
+
+ private String getLastSavedName() {
+ return fLastSavedName;
+ }
+
+ /**
+ * Update buttons and message.
+ */
+ protected void refreshStatus() {
+ updateButtons();
+ updateMessage();
+ }
+
+ /**
+ * Verify the attributes common to all build configuration.
+ * Indicate failure by throwing a CoreException
.
+ */
+ protected void verifyStandardAttributes() throws CoreException {
+ verifyName();
+ }
+
+ /**
+ * Verify that the build configuration name is valid.
+ */
+ protected void verifyName() throws CoreException {
+ String currentName = getNameTextWidget().getText().trim();
+
+ // If there is no name, complain
+ if (currentName.length() < 1) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CUIPlugin.getPluginId(),
+ 0,
+ "A name is required for this build configuration",
+ null));
+ }
+
+ // If the name hasn't changed from the last saved name, do nothing
+ if (currentName.equals(getLastSavedName())) {
+ return;
+ }
+
+ // See if name contains any 'illegal' characters
+ IStatus status = ResourcesPlugin.getWorkspace().validateName(currentName, IResource.FILE);
+ if (status.getCode() != IStatus.OK) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CUIPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
+ 0,
+ status.getMessage(),
+ null));
+ }
+
+ // Otherwise, if there's already a config with the same name, complain
+ if (getBuildConfigManager().isExistingConfigurationName(fUnderlyingConfig.getProject(), currentName)) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CUIPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
+ 0,
+ "A build configuration with this name already exists",
+ null));
+ }
+ }
+
+ /**
+ * If the name is valid, rename the current build configuration. Otherwise, show an
+ * appropriate error message.
+ */
+ protected void updateConfigFromName() {
+ if (getConfiguration() != null) {
+ try {
+ verifyName();
+ } catch (CoreException ce) {
+ refreshStatus();
+ return;
+ }
+
+ getConfiguration().rename(getNameTextWidget().getText().trim());
+ refreshStatus();
+ }
+ }
+
+ protected Display getDisplay() {
+ Shell shell = getShell();
+ if (shell != null) {
+ return shell.getDisplay();
+ } else {
+ return Display.getDefault();
+ }
+ }
+
+ class ToolListElement {
+ private ICToolType fToolType;
+ public ToolListElement(Object o) {
+ fToolType = (ICToolType) o;
+ }
+ public String toString() {
+ return fToolType.getName();
+ }
+ }
+
+ class ToolListContentProvider implements IStructuredContentProvider {
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ Map types = BuilderPlugin.getDefault().getToolTypes();
+ Object[] objs = new Object[types.size()];
+ int i = 0;
+ for (Iterator iter = types.entrySet().iterator(); iter.hasNext(); i++) {
+ Map.Entry element = (Map.Entry) iter.next();
+ objs[i] = new ToolListElement(element.getValue());
+ }
+ return objs;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer, Object, Object)
+ */
+ public void inputChanged(
+ Viewer viewer,
+ Object oldInput,
+ Object newInput) {
+ }
+
+ }
+
+ class ToolListLabelProvider extends LabelProvider {
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelProvider#getText(Object)
+ */
+ public String getText(Object element) {
+ return super.getText(element);
+ }
+
+ }
+
+ /**
+ * Creates the build configuration selection area of the dialog.
+ * This area displays a list of available tools that the user
+ * may select.
+ *
+ * @return the composite used for tools configuration selection area
+ */
+ protected Composite createToolSelectionArea(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ setSelectionArea(comp);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ layout.marginHeight = 0;
+ layout.marginWidth = 5;
+ comp.setLayout(layout);
+
+ Label treeLabel = new Label(comp, SWT.NONE);
+ treeLabel.setText("Build Tools"); //$NON-NLS-1$
+ GridData gd = new GridData();
+ gd.horizontalSpan = 3;
+ treeLabel.setLayoutData(gd);
+
+ ListViewer list = new ListViewer(comp);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 3;
+ // Set width hint to 0 to force tree to only be as wide as the combined
+ // width of the 'New' & 'Delete' buttons. Otherwise tree wants to be much wider.
+ gd.widthHint = 0;
+ list.getControl().setLayoutData(gd);
+ list.setContentProvider(new ToolListContentProvider());
+ list.setLabelProvider(new ToolListLabelProvider());
+ list.setSorter(new WorkbenchViewerSorter());
+ setListViewer(list);
+ list.setInput(ResourcesPlugin.getWorkspace().getRoot());
+
+ return comp;
+ }
+
+ /**
+ * Creates the build configuration edit area of the dialog.
+ * This area displays the name of the build configuration
+ * currently being edited, as well as a tab folder of tabs
+ * that are applicable to the currently selected tool.
+ *
+ * @return the composite used for build configuration editing
+ */
+ protected Composite createEditArea(Composite parent) {
+ Composite outerComp = new Composite(parent, SWT.NONE);
+ GridLayout outerCompLayout = new GridLayout();
+ outerCompLayout.numColumns = 1;
+ outerCompLayout.marginHeight = 0;
+ outerCompLayout.marginWidth = 0;
+ outerComp.setLayout(outerCompLayout);
+
+ Composite comp = new Composite(outerComp, SWT.NONE);
+ setEditArea(comp);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginHeight = 0;
+ layout.marginWidth = 5;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
+
+ Label nameLabel = new Label(comp, SWT.HORIZONTAL | SWT.LEFT);
+ nameLabel.setText("&Name");
+ gd = new GridData(GridData.BEGINNING);
+ nameLabel.setLayoutData(gd);
+
+ Text nameText = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ nameText.setLayoutData(gd);
+ setNameTextWidget(nameText);
+
+ getNameTextWidget().addModifyListener(
+ new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateConfigFromName();
+ }
+ }
+ );
+
+ Label spacer = new Label(comp, SWT.NONE);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ spacer.setLayoutData(gd);
+
+ fTabComposite = new Composite(comp, SWT.NONE);
+ GridLayout outerTabCompositeLayout = new GridLayout();
+ outerTabCompositeLayout.marginHeight = 0;
+ outerTabCompositeLayout.marginWidth = 0;
+ fTabComposite.setLayout(outerTabCompositeLayout);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 2;
+ fTabComposite.setLayoutData(gd);
+
+ TabFolder tabFolder = new TabFolder(fTabComposite, SWT.NONE);
+ setTabFolder(tabFolder);
+ gd = new GridData(GridData.FILL_BOTH);
+ tabFolder.setLayoutData(gd);
+ getTabFolder().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleTabSelected();
+ }
+ });
+
+ Composite buttonComp = new Composite(comp, SWT.NONE);
+ GridLayout buttonCompLayout = new GridLayout();
+ buttonCompLayout.numColumns = 2;
+ buttonComp.setLayout(buttonCompLayout);
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ gd.horizontalSpan = 2;
+ buttonComp.setLayoutData(gd);
+
+ setApplyButton(new Button(buttonComp, SWT.PUSH));
+ getApplyButton().setText("&Apply");
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ getApplyButton().setLayoutData(gd);
+ SWTUtil.setButtonDimensionHint(getApplyButton());
+ getApplyButton().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleApplyPressed();
+ }
+ });
+
+ setRevertButton(new Button(buttonComp, SWT.PUSH));
+ getRevertButton().setText("Revert");
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ getRevertButton().setLayoutData(gd);
+ SWTUtil.setButtonDimensionHint(getRevertButton());
+ getRevertButton().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleRevertPressed();
+ }
+ });
+
+ return outerComp;
+ }
+
+ /**
+ * @see Dialog#createButtonBar(Composite)
+ */
+ protected Control createButtonBar(Composite parent) {
+ Composite composite= new Composite(parent, SWT.NULL);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ GridLayout pmLayout = new GridLayout();
+ pmLayout.numColumns = 3;
+
+ return super.createButtonBar(composite);
+ }
+
+ /**
+ * Sets the title for the dialog, and establishes the help context.
+ *
+ * @see org.eclipse.jface.window.Window#configureShell(Shell)
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText(("Tools"));
+ WorkbenchHelp.setHelp(
+ shell,
+ CUIPlugin.getPluginId() + ".build_configuration_dialog");
+ }
+
+ /**
+ * @see Window#getInitialLocation(Point)
+ */
+ protected Point getInitialLocation(Point initialSize) {
+ String locationString = getPreferenceStore().getString(DIALOG_LOCATION);
+ if (locationString.length() > 0) {
+ Point locationPoint = parseCoordinates(locationString);
+ if (locationPoint != null) {
+ return locationPoint;
+ }
+ }
+ return super.getInitialLocation(initialSize);
+ }
+
+ /**
+ * @see Window#getInitialSize()
+ */
+ protected Point getInitialSize() {
+ String sizeString = getPreferenceStore().getString(DIALOG_SIZE);
+ if (sizeString.length() > 0) {
+ Point sizePoint = parseCoordinates(sizeString);
+ if (sizePoint != null) {
+ return sizePoint;
+ }
+ }
+ return DEFAULT_INITIAL_DIALOG_SIZE;
+ }
+
+ /**
+ * Given a coordinate String of the form "123x456" return a Point object whose
+ * X value is 123 and Y value is 456. Return null
if the String
+ * is not in the specified form.
+ */
+ protected Point parseCoordinates(String coordString) {
+ int byIndex = coordString.indexOf('x');
+ if (byIndex < 0) {
+ return null;
+ }
+
+ try {
+ int x = Integer.parseInt(coordString.substring(0, byIndex));
+ int y = Integer.parseInt(coordString.substring(byIndex + 1));
+ return new Point(x, y);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ }
+
+ /**
+ * Given a Point object, return a String of the form "XCoordxYCoord".
+ */
+ protected String serializeCoords(Point coords) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(coords.x);
+ buffer.append('x');
+ buffer.append(coords.y);
+ return buffer.toString();
+ }
+
+ private void setSashForm(SashForm sashForm) {
+ fSashForm = sashForm;
+ }
+
+ protected SashForm getSashForm() {
+ return fSashForm;
+ }
+
+ /**
+ * Sets the tree viewer used to display build configurations.
+ *
+ * @param viewer the tree viewer used to display tool tabs
+ */
+ private void setListViewer(ListViewer viewer) {
+ fToolList = viewer;
+ }
+
+ /**
+ * Returns the tree viewer used to display tool tabs
+ *
+ * @param the tree viewer used to display tool tabs
+ */
+ protected ListViewer getListViewer() {
+ return fToolList;
+ }
+
+ protected IStructuredSelection getListViewerSelection() {
+ return (IStructuredSelection)getListViewer().getSelection();
+ }
+
+ protected Object getListViewerFirstSelectedElement() {
+ IStructuredSelection selection = getListViewerSelection();
+ if (selection == null) {
+ return null;
+ }
+ return selection.getFirstElement();
+ }
+
+ /**
+ * Returns the build manager.
+ *
+ * @return the build manager
+ */
+ protected ICBuildConfigManager getBuildConfigManager() {
+ return BuilderPlugin.getDefault().getBuildConfigurationManager();
+ }
+
+ /**
+ * Returns whether this dialog is currently open
+ */
+ protected boolean isVisible() {
+ return getListViewer() != null;
+ }
+
+ /**
+ * Utility method with conventions
+ */
+ protected void errorDialog(Shell shell, String title, String message, Throwable t) {
+ CUIPlugin.getDefault().log(t);
+ IStatus status;
+ if (t instanceof CoreException) {
+ status= ((CoreException)t).getStatus();
+ // if the 'message' resource string and the IStatus' message are the same,
+ // don't show both in the dialog
+ if (status != null && message.equals(status.getMessage())) {
+ message= null;
+ }
+ } else {
+ status= new Status(IStatus.ERROR, CUIPlugin.getPluginId(), IStatus.ERROR, "Error within plugin UI: ", t); //$NON-NLS-1$
+ }
+ ErrorDialog.openError(shell, title, message, status);
+ }
+
+ /**
+ * Sets the configuration to display/edit.
+ * Updates the tab folder to contain the appropriate pages.
+ * Sets all configuration-related state appropriately.
+ *
+ * @param config the build configuration to display/edit
+ * @param init whether to initialize the config with default values
+ */
+ protected void setBuildConfiguration(ICBuildConfig config, boolean init) {
+ try {
+
+ // turn on initializing flag to ignore message updates
+ setInitializingTabs(true);
+
+ getEditArea().setVisible(true);
+
+ if (config.isWorkingCopy()) {
+ setWorkingCopy((ICBuildConfigWorkingCopy)config);
+ } else {
+ setWorkingCopy(config.getWorkingCopy());
+ }
+ fUnderlyingConfig = getConfiguration().getOriginal();
+
+ // update the name field before to avoid verify error
+ getNameTextWidget().setText(config.getName());
+
+ // Set the defaults for all tabs before any are initialized
+ // so that every tab can see ALL the default values
+ if (init) {
+ getTabGroup().setDefaults(getConfiguration());
+ }
+
+ // update the tabs with the new working copy
+ getTabGroup().initializeFrom(getConfiguration());
+
+ // update the name field after in case client changed it
+ getNameTextWidget().setText(config.getName());
+
+ // turn off initializing flag to update message
+ setInitializingTabs(false);
+
+ refreshStatus();
+
+ } catch (CoreException ce) {
+ errorDialog(getShell(), "Error", "Exception occurred setting build configuration", ce);
+ clearBuildConfiguration();
+ return;
+ }
+ }
+
+ /**
+ * Clears the configuration being shown/edited.
+ * Resets all configuration-related state.
+ */
+ protected void clearBuildConfiguration() {
+ setWorkingCopy(null);
+ fUnderlyingConfig = null;
+ setLastSavedName(null);
+ getNameTextWidget().setText(""); //$NON-NLS-1$
+ refreshStatus();
+ }
+
+ /**
+ * Populate the tabs in the configuration edit area to be appropriate to the current
+ * build configuration type.
+ */
+ protected void showTabsForConfigType(ICToolType configType) {
+
+ // Don't do any work if the current tabs are for the current config type
+ if (getTabType() != null && getTabType().equals(configType)) {
+ return;
+ }
+
+ // Avoid flicker
+ getEditArea().setVisible(false);
+
+ // Dispose the current tabs
+ disposeExistingTabs();
+
+ // Build the new tabs
+ ICToolTabGroup group = null;
+ try {
+ group = createGroup(configType);
+ } catch (CoreException ce) {
+ errorDialog(getShell(), "Error", "Exception occurred creating build configuration tabs",ce);
+ return;
+ }
+
+ // Create the Control for each tab, and determine the maximum tab dimensions
+ PixelConverter pixelConverter = new PixelConverter(getTabFolder());
+ int runningTabWidth = 0;
+ ICToolTab[] tabs = group.getTabs();
+ Point contentSize = new Point(0, 0);
+ for (int i = 0; i < tabs.length; i++) {
+ TabItem tab = new TabItem(getTabFolder(), SWT.NONE);
+ String name = tabs[i].getName();
+ if (name == null) {
+ name = "unspecified";
+ }
+ tab.setText(name);
+ Image image = tabs[i].getImage();
+ tab.setImage(image);
+ runningTabWidth += pixelConverter.convertWidthInCharsToPixels(name.length() + 5);
+ if (image != null) {
+ runningTabWidth += image.getBounds().width;
+ }
+ tabs[i].createControl(tab.getParent());
+ Control control = tabs[i].getControl();
+ if (control != null) {
+ tab.setControl(control);
+ Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ if (size.x > contentSize.x) {
+ contentSize.x = size.x;
+ }
+ if (size.y > contentSize.y) {
+ contentSize.y = size.y;
+ }
+ }
+ }
+
+ // Determine if more space is needed to show all tab labels across the top of the
+ // tab folder. If so, only increase size of dialog to some percent of the available
+ // screen real estate.
+ if (runningTabWidth > contentSize.x) {
+ int maxAllowedWidth = (int) (getDisplay().getBounds().width * MAX_DIALOG_WIDTH_PERCENT);
+ int otherWidth = getSashForm().SASH_WIDTH + getSelectionArea().getBounds().width;
+ int totalWidth = runningTabWidth + otherWidth;
+ if (totalWidth > maxAllowedWidth) {
+ contentSize.x = maxAllowedWidth - otherWidth;
+ } else {
+ contentSize.x = runningTabWidth;
+ }
+ }
+
+ // Adjust the maximum tab dimensions to account for the extra space required for the tab labels
+ Rectangle tabFolderBoundingBox = getTabFolder().computeTrim(0, 0, contentSize.x, contentSize.y);
+ contentSize.x = tabFolderBoundingBox.width;
+ contentSize.y = tabFolderBoundingBox.height;
+
+ // Force recalculation of sizes
+ getTabFolder().layout(true);
+
+ // Calculate difference between required space for tab folder and current size,
+ // then increase size of this dialog's Shell by that amount
+ Rectangle rect = fTabComposite.getClientArea();
+ Point containerSize= new Point(rect.width, rect.height);
+ int hdiff= contentSize.x - containerSize.x;
+ int vdiff= contentSize.y - containerSize.y;
+ // Only increase size of dialog, never shrink it
+ if (hdiff > 0 || vdiff > 0) {
+ int[] newSashWeights = null;
+ if (hdiff > 0) {
+ newSashWeights = calculateNewSashWeights(hdiff);
+ }
+ hdiff= Math.max(0, hdiff);
+ vdiff= Math.max(0, vdiff);
+ Shell shell= getShell();
+ Point shellSize= shell.getSize();
+ setShellSize(shellSize.x + hdiff, shellSize.y + vdiff);
+ // Adjust the sash weights so that all of the increase in width
+ // is given to the tab area
+ if (newSashWeights != null) {
+ getSashForm().setWeights(newSashWeights);
+ }
+ }
+
+ setTabGroup(group);
+ setTabType(configType);
+ getEditArea().setVisible(true);
+ }
+
+ /**
+ * Calculate & return a 2 element integer array that specifies the relative
+ * weights of the selection area and the edit area, based on the specified
+ * increase in width of the owning shell. The point of this method is calculate
+ * sash weights such that when the shell gets wider, all of the increase in width
+ * is given to the edit area (tab folder), and the selection area (tree) stays
+ * the same width.
+ */
+ protected int[] calculateNewSashWeights(int widthIncrease) {
+ int[] newWeights = new int[2];
+ newWeights[0] = getSelectionArea().getBounds().width;
+ newWeights[1] = getEditArea().getBounds().width + widthIncrease;
+ return newWeights;
+ }
+
+ /**
+ * Increase the size of this dialog's Shell
by the specified amounts.
+ * Do not increase the size of the Shell beyond the bounds of the Display.
+ */
+ private void setShellSize(int width, int height) {
+ Rectangle bounds = getShell().getDisplay().getBounds();
+ getShell().setSize(Math.min(width, bounds.width), Math.min(height, bounds.height));
+ }
+
+ protected void disposeExistingTabs() {
+ setDisposingTabs(true);
+ TabItem[] oldTabs = getTabFolder().getItems();
+ for (int i = 0; i < oldTabs.length; i++) {
+ oldTabs[i].dispose();
+ }
+ if (getTabGroup() != null) {
+ getTabGroup().dispose();
+ }
+ setTabGroup(null);
+ setTabType(null);
+ setDisposingTabs(false);
+ }
+
+ /**
+ * Sets the current build configuration that is being
+ * displayed/edited.
+ */
+ protected void setWorkingCopy(ICBuildConfigWorkingCopy workingCopy) {
+ fWorkingCopy = workingCopy;
+ }
+
+ protected boolean isWorkingCopyDirty() {
+ ICBuildConfigWorkingCopy workingCopy = getConfiguration();
+ if (workingCopy == null) {
+ return false;
+ }
+
+ // Working copy hasn't been saved
+ if (workingCopy.getOriginal() == null) {
+ return true;
+ }
+
+ // Name has changed. Normally, this would be caught in the 'contentsEqual'
+ // check below, however there are some circumstances where this fails, such as
+ // when the name is invalid
+ if (isNameDirty()) {
+ return true;
+ }
+
+ updateWorkingCopyFromPages();
+ ICBuildConfig original = workingCopy.getOriginal();
+ return !original.contentsEqual(workingCopy);
+ }
+
+ /**
+ * Return true
if the name has been modified since the last time it was saved.
+ */
+ protected boolean isNameDirty() {
+ String currentName = getNameTextWidget().getText().trim();
+ return !currentName.equals(getLastSavedName());
+ }
+
+ /**
+ * Sets the text widget used to display the name
+ * of the configuration being displayed/edited
+ *
+ * @param widget the text widget used to display the name
+ * of the configuration being displayed/edited
+ */
+ private void setNameTextWidget(Text widget) {
+ fNameText = widget;
+ }
+
+ /**
+ * Returns the text widget used to display the name
+ * of the configuration being displayed/edited
+ *
+ * @return the text widget used to display the name
+ * of the configuration being displayed/edited
+ */
+ protected Text getNameTextWidget() {
+ return fNameText;
+ }
+
+ /**
+ * Sets the 'apply' button.
+ *
+ * @param button the 'apply' button.
+ */
+ private void setApplyButton(Button button) {
+ fApplyButton = button;
+ }
+
+ /**
+ * Returns the 'apply' button
+ *
+ * @return the 'apply' button
+ */
+ protected Button getApplyButton() {
+ return fApplyButton;
+ }
+
+ /**
+ * Sets the 'revert' button.
+ *
+ * @param button the 'revert' button.
+ */
+ private void setRevertButton(Button button) {
+ fRevertButton = button;
+ }
+
+ /**
+ * Returns the 'revert' button
+ *
+ * @return the 'revert' button
+ */
+ protected Button getRevertButton() {
+ return fRevertButton;
+ }
+
+ private void setDisposingTabs(boolean disposing) {
+ fDisposingTabs = disposing;
+ }
+
+ private boolean isDisposingTabs() {
+ return fDisposingTabs;
+ }
+
+ /**
+ * Sets the tab folder
+ *
+ * @param folder the tab folder
+ */
+ private void setTabFolder(TabFolder folder) {
+ fTabFolder = folder;
+ }
+
+ /**
+ * Returns the tab folder
+ *
+ * @return the tab folder
+ */
+ protected TabFolder getTabFolder() {
+ return fTabFolder;
+ }
+
+ /**
+ * Sets the current tab group being displayed
+ *
+ * @param group the current tab group being displayed
+ */
+ private void setTabGroup(ICToolTabGroup group) {
+ fTabGroup = group;
+ }
+
+ /**
+ * Returns the current tab group
+ *
+ * @return the current tab group, or null
if none
+ */
+ public ICToolTabGroup getTabGroup() {
+ return fTabGroup;
+ }
+
+ /**
+ * @see ICBuildConfigDialog#getTabs()
+ */
+ public ICToolTab[] getTabs() {
+ if (getTabGroup() == null) {
+ return null;
+ } else {
+ return getTabGroup().getTabs();
+ }
+ }
+
+ protected void setIgnoreSelectionChanges(boolean ignore) {
+ fIgnoreSelectionChanges = ignore;
+ }
+
+ protected boolean ignoreSelectionChanges() {
+ return fIgnoreSelectionChanges;
+ }
+
+ /**
+ * Return whether the current configuration can be discarded. This involves determining
+ * if it is dirty, and if it is, asking the user what to do.
+ */
+ protected boolean canDiscardCurrentConfig() {
+ // If there is no working copy, there's no problem, return true
+ ICBuildConfigWorkingCopy workingCopy = getConfiguration();
+ if (workingCopy == null) {
+ return true;
+ }
+
+ if (isWorkingCopyDirty()) {
+ return showUnsavedChangesDialog();
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Show the user a dialog appropriate to whether the unsaved changes in the current config
+ * can be saved or not. Return true
if the user indicated that they wish to replace
+ * the current config, either by saving changes or by discarding the, return false
+ * otherwise.
+ */
+ protected boolean showUnsavedChangesDialog() {
+ if (canSaveConfig()) {
+ return showSaveChangesDialog();
+ } else {
+ return showDiscardChangesDialog();
+ }
+ }
+
+ /**
+ * Create and return a dialog that asks the user whether they want to save
+ * unsaved changes. Return true
if they chose to save changes,
+ * false
otherwise.
+ */
+ protected boolean showSaveChangesDialog() {
+ StringBuffer buffer = new StringBuffer("The configuration '");
+ buffer.append(getConfiguration().getName());
+ buffer.append("' has unsaved changes. Do you wish to save them?");
+ MessageDialog dialog = new MessageDialog(getShell(),
+ ("Save changes?"),
+ null,
+ buffer.toString(),
+ MessageDialog.QUESTION,
+ new String[] {"Yes", "No", "Cancel"},
+ 0);
+ // If user clicked 'Cancel' or closed dialog, return false
+ int selectedButton = dialog.open();
+ if ((selectedButton < 0) || (selectedButton == 2)) {
+ return false;
+ }
+
+ // If they hit 'Yes', save the working copy
+ if (selectedButton == 0) {
+ saveConfig();
+ }
+
+ return true;
+ }
+
+ /**
+ * Create and return a dialog that asks the user whether they want to discard
+ * unsaved changes. Return true
if they chose to discard changes,
+ * false
otherwise.
+ */
+ protected boolean showDiscardChangesDialog() {
+ StringBuffer buffer = new StringBuffer("The configuration '");
+ buffer.append(getNameTextWidget().getText());
+ buffer.append("' has unsaved changes that CANNOT be saved because of the following error:");
+ buffer.append(fCantSaveErrorMessage);
+ buffer.append("Do you wish to discard changes?");
+ MessageDialog dialog = new MessageDialog(getShell(),
+ "Discard changes?",
+ null,
+ buffer.toString(),
+ MessageDialog.QUESTION,
+ new String[] {"Yes", "No"},
+ 1);
+ // If user clicked 'Yes', return true
+ int selectedButton = dialog.open();
+ if (selectedButton == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Return true
if the current configuration can be saved, false
+ * otherwise. Note this is NOT the same thing as the config simply being valid. It is
+ * possible to save a config that does not validate. This method determines whether the
+ * config can be saved without causing a serious error. For example, a shared config that
+ * has no specified location would cause this method to return false
.
+ */
+ protected boolean canSaveConfig() {
+
+ fCantSaveErrorMessage = null;
+
+ // First make sure that name doesn't prevent saving the config
+ try {
+ verifyName();
+ } catch (CoreException ce) {
+ fCantSaveErrorMessage = ce.getStatus().getMessage();
+ return false;
+ }
+
+ // Next, make sure none of the tabs object to saving the config
+ ICToolTab[] tabs = getTabs();
+ if (tabs == null) {
+ fCantSaveErrorMessage = "No tabs found";
+ return false;
+ }
+ for (int i = 0; i < tabs.length; i++) {
+ if (!tabs[i].canSave()) {
+ fCantSaveErrorMessage = tabs[i].getErrorMessage();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Notification the 'Close' button has been pressed.
+ */
+ protected void handleClosePressed() {
+ if (canDiscardCurrentConfig()) {
+ disposeExistingTabs();
+ cancelPressed();
+ }
+ }
+
+ /**
+ * Notification that the 'Apply' button has been pressed
+ */
+ protected void handleApplyPressed() {
+ saveConfig();
+ getListViewer().setSelection(new StructuredSelection(fUnderlyingConfig));
+ }
+
+ /**
+ * Notification that the 'Revert' button has been pressed
+ */
+ protected void handleRevertPressed() {
+ setBuildConfiguration(getConfiguration().getOriginal(), false);
+ }
+
+ protected void saveConfig() {
+ try {
+ // trim name
+ Text widget = getNameTextWidget();
+ widget.setText(widget.getText().trim());
+ doSave();
+ } catch (CoreException e) {
+ errorDialog(getShell(), "Error", "Exception occurred while saving build configuration", e);
+ return;
+ }
+
+ updateButtons();
+ }
+
+ /**
+ * Notification that a tab has been selected
+ *
+ * Disallow tab changing when the current tab is invalid.
+ * Update the config from the tab being left, and refresh
+ * the tab being entered.
+ */
+ protected void handleTabSelected() {
+ if (isDisposingTabs()) {
+ return;
+ }
+ ICToolTab[] tabs = getTabs();
+ if (fCurrentTabIndex == getTabFolder().getSelectionIndex() || tabs == null || tabs.length == 0 || fCurrentTabIndex > (tabs.length - 1)) {
+ return;
+ }
+ if (fCurrentTabIndex != -1) {
+ ICToolTab tab = tabs[fCurrentTabIndex];
+ ICBuildConfigWorkingCopy wc = getConfiguration();
+ if (wc != null) {
+ // apply changes when leaving a tab
+ tab.performApply(getConfiguration());
+ // re-initialize a tab when entering it
+ getActiveTab().initializeFrom(wc);
+ }
+ }
+ fCurrentTabIndex = getTabFolder().getSelectionIndex();
+ refreshStatus();
+ }
+
+ /**
+ * Iterate over the pages to update the working copy
+ */
+ protected void updateWorkingCopyFromPages() {
+ ICBuildConfigWorkingCopy workingCopy = getConfiguration();
+ if (getTabGroup() != null) {
+ getTabGroup().performApply(workingCopy);
+ }
+ }
+
+ /**
+ * Do the save
+ */
+ protected void doSave() throws CoreException {
+ ICBuildConfigWorkingCopy workingCopy = getConfiguration();
+ updateWorkingCopyFromPages();
+ if (isWorkingCopyDirty()) {
+ fUnderlyingConfig = workingCopy.doSave();
+ setWorkingCopy(fUnderlyingConfig.getWorkingCopy());
+ setLastSavedName(fUnderlyingConfig.getName());
+ }
+ }
+
+ protected IPreferenceStore getPreferenceStore() {
+ return CUIPlugin.getDefault().getPreferenceStore();
+ }
+
+ /**
+ * Sets the given cursor for all shells currently active
+ * for this window's display.
+ *
+ * @param cursor the cursor
+ */
+ private void setDisplayCursor(Cursor cursor) {
+ Shell[] shells = getShell().getDisplay().getShells();
+ for (int i = 0; i < shells.length; i++)
+ shells[i].setCursor(cursor);
+ }
+
+ /**
+ * Checks whether it is alright to close this dialog
+ * and performed standard cancel processing. If there is a
+ * long running operation in progress, this method posts an
+ * alert message saying that the dialog cannot be closed.
+ *
+ * @return true
if it is alright to close this dialog, and
+ * false
if it is not
+ */
+ private boolean okToClose() {
+ if (fActiveRunningOperations > 0) {
+ synchronized (this) {
+ fWindowClosingDialog = createDialogClosingDialog();
+ }
+ fWindowClosingDialog.open();
+ synchronized (this) {
+ fWindowClosingDialog = null;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates and return a new wizard closing dialog without opening it.
+ */
+ private MessageDialog createDialogClosingDialog() {
+ MessageDialog result= new MessageDialog(
+ getShell(),
+ JFaceResources.getString("WizardClosingDialog.title"), //$NON-NLS-1$
+ null,
+ JFaceResources.getString("WizardClosingDialog.message"), //$NON-NLS-1$
+ MessageDialog.QUESTION,
+ new String[] {IDialogConstants.OK_LABEL},
+ 0 );
+ return result;
+ }
+
+ protected ICBuildConfigWorkingCopy getConfiguration() {
+ return fWorkingCopy;
+ }
+
+ /**
+ * @see ICBuildConfigDialog#updateButtons()
+ */
+ public void updateButtons() {
+ if (isInitializingTabs()) {
+ return;
+ }
+
+ // Get the current selection
+ IStructuredSelection sel = (IStructuredSelection)getListViewer().getSelection();
+ boolean singleSelection = sel.size() == 1;
+ boolean firstItemConfig = sel.getFirstElement() instanceof ICBuildConfig;
+ boolean firstItemConfigType = sel.getFirstElement() instanceof ICTool;
+
+ // Apply & Launch buttons
+ if (sel.isEmpty()) {
+ getApplyButton().setEnabled(false);
+ } else {
+ getApplyButton().setEnabled(true);
+ }
+
+ // Revert button
+ if (sel.isEmpty() || sel.size() > 1) {
+ getRevertButton().setEnabled(false);
+ } else {
+ if (firstItemConfig && isWorkingCopyDirty()) {
+ getRevertButton().setEnabled(true);
+ } else {
+ getRevertButton().setEnabled(false);
+ }
+ }
+ }
+
+ /**
+ * @see ICBuildConfigDialog#getActiveTab()
+ */
+ public ICToolTab getActiveTab() {
+ TabFolder folder = getTabFolder();
+ ICToolTab[] tabs = getTabs();
+ if (folder != null && tabs != null) {
+ int pageIndex = folder.getSelectionIndex();
+ if (pageIndex >= 0) {
+ return tabs[pageIndex];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the currently active TabItem
+ *
+ * @return build configuration tab item
+ */
+ protected TabItem getActiveTabItem() {
+ TabFolder folder = getTabFolder();
+ TabItem tabItem = null;
+ int selectedIndex = folder.getSelectionIndex();
+ if (selectedIndex >= 0) {
+ tabItem = folder.getItem(selectedIndex);
+ }
+ return tabItem;
+ }
+
+ /**
+ * @see ICBuildConfigDialog#updateMessage()
+ */
+ public void updateMessage() {
+ if (isInitializingTabs()) {
+ return;
+ }
+
+ // If there is no current working copy, show a default informational message and clear the error message
+ if (getConfiguration() == null) {
+ setErrorMessage(null);
+ setMessage("Select a type of configuration to create, and press 'new'");
+ return;
+ }
+
+ try {
+ verifyStandardAttributes();
+ } catch (CoreException ce) {
+ setErrorMessage(ce.getMessage());
+ return;
+ }
+
+ // Get the active tab. If there isn't one, clear the informational & error messages
+ ICToolTab activeTab = getActiveTab();
+ if (activeTab == null) {
+ setMessage(null);
+ setErrorMessage(null);
+ return;
+ }
+
+ // Always set the informational (non-error) message based on the active tab
+ setMessage(activeTab.getMessage());
+
+ // The bias is to show the active page's error message, but if there isn't one,
+ // show the error message for one of the other tabs that has an error. Set the icon
+ // for all tabs according to whether they contain errors.
+ String errorMessage = checkTabForError(activeTab);
+ boolean errorOnActiveTab = errorMessage != null;
+ setTabIcon(getActiveTabItem(), errorOnActiveTab, activeTab);
+
+ ICToolTab[] allTabs = getTabs();
+ for (int i = 0; i < allTabs.length; i++) {
+ if (getTabFolder().getSelectionIndex() == i) {
+ continue;
+ }
+ String tabError = checkTabForError(allTabs[i]);
+ TabItem tabItem = getTabFolder().getItem(i);
+ boolean errorOnTab = tabError != null;
+ setTabIcon(tabItem, errorOnTab, allTabs[i]);
+ if (errorOnTab && !errorOnActiveTab) {
+ errorMessage = '[' + removeAmpersandsFrom(tabItem.getText()) + "]: " + tabError; //$NON-NLS-1$
+ }
+ }
+ setErrorMessage(errorMessage);
+ }
+
+ /**
+ * Force the tab to update it's error state and return any error message.
+ */
+ protected String checkTabForError(ICToolTab tab) {
+ tab.isValid(getConfiguration());
+ return tab.getErrorMessage();
+ }
+
+ /**
+ * Set the specified tab item's icon to an error icon if error
is true,
+ * or a transparent icon of the same size otherwise.
+ */
+ protected void setTabIcon(TabItem tabItem, boolean error, ICToolTab tab) {
+ Image image = null;
+ if (error) {
+ image = tab.getImage(); /* CBuildConfigManager.getErrorTabImage(tab) */
+ } else {
+ image = tab.getImage();
+ }
+ tabItem.setImage(image);
+ }
+
+ /**
+ * Return a copy of the specified string
+ */
+ protected String removeAmpersandsFrom(String string) {
+ String newString = new String(string);
+ int index = newString.indexOf('&');
+ while (index != -1) {
+ newString = string.substring(0, index) + newString.substring(index + 1, newString.length());
+ index = newString.indexOf('&');
+ }
+ return newString;
+ }
+
+ /**
+ * Returns the build configuration selection area control.
+ *
+ * @return control
+ */
+ protected Composite getSelectionArea() {
+ return fSelectionArea;
+ }
+
+ /**
+ * Sets the build configuration selection area control.
+ *
+ * @param editArea control
+ */
+ private void setSelectionArea(Composite selectionArea) {
+ fSelectionArea = selectionArea;
+ }
+
+ /**
+ * Returns the build configuration edit area control.
+ *
+ * @return control
+ */
+ protected Composite getEditArea() {
+ return fEditArea;
+ }
+
+ /**
+ * Sets the build configuration edit area control.
+ *
+ * @param editArea control
+ */
+ private void setEditArea(Composite editArea) {
+ fEditArea = editArea;
+ }
+
+ /**
+ * Returns the type that tabs are currently displayed
+ * for, or null
if none.
+ *
+ * @return build configuration type or null
+ */
+ protected ICToolType getTabType() {
+ return fToolType;
+ }
+
+ /**
+ * Sets the type that tabs are currently displayed
+ * for, or null
if none.
+ *
+ * @param tabType build configuration type
+ */
+ private void setTabType(ICToolType tabType) {
+ fToolType = tabType;
+ }
+
+ protected Object getSelectedTreeObject() {
+ return fSelectedTreeObject;
+ }
+
+ protected void setSelectedTreeObject(Object obj) {
+ fSelectedTreeObject = obj;
+ }
+
+ /**
+ * @see ICBuildConfigDialog#setName(String)
+ */
+ public void setName(String name) {
+ if (isVisible()) {
+ if (name == null) {
+ name = ""; //$NON-NLS-1$
+ }
+ fNameText.setText(name.trim());
+ refreshStatus();
+ }
+ }
+
+ /**
+ * Sets whether this dialog is initializing pages
+ * and should not bother to refresh status (butttons
+ * and message).
+ */
+ private void setInitializingTabs(boolean init) {
+ fInitializingTabs = init;
+ }
+
+ /**
+ * Returns whether this dialog is initializing pages
+ * and should not bother to refresh status (butttons
+ * and message).
+ */
+ protected boolean isInitializingTabs() {
+ return fInitializingTabs;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigPresentationManager.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigPresentationManager.java
new file mode 100644
index 00000000000..58049009727
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigPresentationManager.java
@@ -0,0 +1,121 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import java.text.MessageFormat;
+import java.util.Hashtable;
+
+import org.eclipse.cdt.core.builder.model.ICToolType;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.builder.ICToolTabGroup;
+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.IPluginDescriptor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.ui.IDebugUIConstants;
+
+/**
+ * @author sam.robb
+ *
+ * Manages contributed configuration tabs
+ */
+public class CBuildConfigPresentationManager {
+
+ /**
+ * The singleton configuration presentation manager
+ */
+ private static CBuildConfigPresentationManager fgDefault;
+
+ /**
+ * Collection of configuration tab group extensions
+ * defined in plug-in xml. Entries are keyed by
+ * type identifier (String
), and entires
+ * are CToolTabGroupPoint
.
+ */
+ private Hashtable fTabGroupExtensions;
+
+ /**
+ * Constructs the singleton configuration presentation manager.
+ */
+ private CBuildConfigPresentationManager() {
+ fgDefault = this;
+ initializeTabGroupExtensions();
+ }
+
+ /**
+ * Returns the configuration presentation manager
+ */
+ public static CBuildConfigPresentationManager getDefault() {
+ if (fgDefault == null) {
+ fgDefault = new CBuildConfigPresentationManager();
+ }
+ return fgDefault;
+ }
+
+ /**
+ * Creates launch configuration tab group extensions for each extension
+ * defined in XML, and adds them to the table of tab group extensions.
+ */
+ private void initializeTabGroupExtensions() {
+ fTabGroupExtensions = new Hashtable();
+ IPluginDescriptor descriptor= CUIPlugin.getDefault().getDescriptor();
+ IExtensionPoint extensionPoint= descriptor.getExtensionPoint(IDebugUIConstants.EXTENSION_POINT_LAUNCH_CONFIGURATION_TAB_GROUPS);
+ IConfigurationElement[] groups = extensionPoint.getConfigurationElements();
+ for (int i = 0; i < groups.length; i++) {
+ CToolTabGroupPoint group = new CToolTabGroupPoint(groups[i]);
+ String typeId = group.getId();
+ if (typeId == null) {
+ IExtension ext = groups[i].getDeclaringExtension();
+ IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.STATUS_INVALID_EXTENSION_DEFINITION,
+ MessageFormat.format("Configuration tab group extension {0} does not specify configuration type", (new String[] {ext.getUniqueIdentifier()})), null); //$NON-NLS-1$
+ DebugUIPlugin.log(status);
+ } else {
+ // verify it references a valid launch configuration type
+ ILaunchConfigurationType lct = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(typeId);
+ if (lct == null) {
+ IExtension ext = groups[i].getDeclaringExtension();
+ IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.STATUS_INVALID_EXTENSION_DEFINITION,
+ MessageFormat.format("Launch configuration tab group extension {0} refers to non-existant launch configuration_type_{1}", (new String[] {ext.getUniqueIdentifier(), typeId})), null); //$NON-NLS-1$
+ DebugUIPlugin.log(status);
+ }
+ }
+ if (typeId != null) {
+ fTabGroupExtensions.put(typeId, group);
+ }
+ }
+ }
+
+ /**
+ * Returns the tab group for the given type of launch configuration.
+ *
+ * @return the tab group for the given type of launch configuration
+ * @exception CoreException if an exception occurrs creating the group
+ */
+ public ICToolTabGroup getTabGroup(ICToolType type) throws CoreException {
+ CToolTabGroupPoint ext = (CToolTabGroupPoint)fTabGroupExtensions.get(type.getId());
+ if (ext == null) {
+ IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, IDebugUIConstants.INTERNAL_ERROR,
+ MessageFormat.format("No tab group defined for configuration type {0}", (new String[] {type.getId()})), null); ; //$NON-NLS-1$
+ throw new CoreException(status);
+ } else {
+ return ext.getProvider();
+ }
+ }
+
+}
+
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigView.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigView.java
new file mode 100644
index 00000000000..4dc0ee8ab8b
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildConfigView.java
@@ -0,0 +1,825 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.cdt.core.CProjectNature;
+import org.eclipse.cdt.core.builder.BuilderPlugin;
+import org.eclipse.cdt.core.builder.model.ICBuildConfig;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigManager;
+import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy;
+import org.eclipse.cdt.core.resources.MakeUtil;
+import org.eclipse.core.internal.runtime.Assert;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+
+/**
+ * Shows the build configuration wizard
+ */
+public class CBuildConfigView extends ViewPart implements IResourceChangeListener {
+ private TreeViewer viewer;
+
+ /**
+ * Configuration life cycle actions
+ */
+ private Action actionEditConfig;
+ private Action actionNewConfig;
+ private Action actionMakePrimary;
+ private Action actionDeleteConfig;
+ private Action doubleClickAction;
+ //private Action actionBuild;
+
+ /**
+ * Message constants
+ */
+ private final String MSG_CANDELETE = "Remove build configuration";
+ private final String MSG_NODELETE = "Cannot delete primary build configuration";
+ private final String MSG_MAKEPRIMARY = "Make this build configuration the primary configuration";
+ private final String MSG_ALREADYPRIMARY = "This build configuration is the primary configuration";
+ private final String KEY_LASTPROJECT = "LastProject";
+
+ /**
+ * Menu entry for the collection of CBuildConfigurationAction
+ * objects
+ */
+ class CBuildAction extends Action {
+ private IProject m_project;
+ private ICBuildConfig m_config;
+
+ public CBuildAction(IProject prj, ICBuildConfig config) {
+ m_project = prj;
+ m_config = config;
+ setText("Build");
+ setToolTipText("Performing Build");
+ setImageDescriptor(CBuilderImages.DESC_IMG_ACTION_BUILD_CONFIG);
+ setMenuCreator(new CTargetsMenuCreator(m_project, m_config));
+ }
+ }
+
+ class CTargetsMenuCreator implements IMenuCreator {
+
+ private IProject m_project;
+ private ICBuildConfig m_config;
+
+ public CTargetsMenuCreator(IProject prj, ICBuildConfig config) {
+ m_project = prj;
+ m_config = config;
+ }
+
+ private Menu createContents(Menu targets) {
+
+ // walk the list of targets in the project and add them to the target menu
+ String strTargets[] = MakeUtil.getPersistentTargets(m_project);
+ for (int nIndex = 0; nIndex < strTargets.length; nIndex++) {
+ MenuItem newItem = new MenuItem(targets, SWT.NONE);
+ newItem.setText(strTargets[nIndex]);
+ newItem.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent selEvent) {
+ // cheasy, but good enough for this, the name of the menu is the build target
+ String strConfig = ((MenuItem) selEvent.getSource()).getText();
+ // System.out.println("Building configuration " + strConfig + " on project " + m_project.getName() + " using configuration " + m_config.getName());
+ IRunnableWithProgress builder = new ConfigurationBuilder(m_project, m_config, strConfig);
+ try {
+ new ProgressMonitorDialog(getSite().getShell()).run(true, true, builder);
+ }
+ catch (InterruptedException e) {}
+ catch (InvocationTargetException e) {}
+ }
+ });
+ }
+
+ return targets;
+ }
+
+ /**
+ * @see org.eclipse.jface.action.IMenuCreator#dispose()
+ */
+ public void dispose() {
+ m_project = null;
+ }
+
+ /**
+ * @see org.eclipse.jface.action.IMenuCreator#getMenu(Control)
+ */
+ public Menu getMenu(Control parent) {
+ Menu theMenu = new Menu(parent);
+ return createContents(theMenu);
+ }
+
+ /**
+ * @see org.eclipse.jface.action.IMenuCreator#getMenu(Menu)
+ */
+ public Menu getMenu(Menu parent) {
+ Menu theMenu = new Menu(parent);
+ return createContents(theMenu);
+ }
+
+ }
+
+ /**
+ * this class builds the selected configuration
+ */
+ class ConfigurationBuilder implements IRunnableWithProgress {
+ private IProject m_prj;
+ private ICBuildConfig m_config;
+ private String m_target;
+
+ public ConfigurationBuilder(IProject prj, ICBuildConfig bldConfig, String strTarget) {
+ m_prj = prj;
+ m_config = bldConfig;
+ m_target = strTarget;
+ }
+
+ /**
+ * @see org.eclipse.jface.operation.IRunnableWithProgress#run(IProgressMonitor)
+ */
+ public void run(IProgressMonitor monitor) {
+ Assert.isNotNull(m_prj, "Project reference cannot be null");
+ Assert.isNotNull(m_config, "Configuration reference cannot be null");
+ try {
+ MakeUtil.setSessionBuildDir(m_prj, m_prj.getLocation().toOSString());
+ MakeUtil.setSessionTarget(m_prj, m_target);
+ MakeUtil.setSessionConsoleMode(m_prj, true);
+ m_prj.build(IncrementalProjectBuilder.FULL_BUILD, monitor);
+ }
+ catch (CoreException e) { }
+ }
+ }
+
+ /*
+ * The content provider class is responsible for
+ * providing objects to the view. It can wrap
+ * existing objects in adapters or simply return
+ * objects as-is. These objects may be sensitive
+ * to the current input of the view, or ignore
+ * it and always show the same content
+ * (like Task List, for example).
+ */
+ abstract class TreeObject implements IAdaptable {
+ private String fName;
+ private TreeObject fParent;
+ private ArrayList fChildren;
+
+ public TreeObject(String name) {
+ this(name, null);
+ }
+
+ abstract public void doRefreshChildren();
+
+ public TreeObject(String name, TreeObject parent) {
+ setName(name);
+ setParent(parent);
+ fChildren = new ArrayList();
+ }
+
+ public void refreshChildren() {
+ fChildren.clear();
+ doRefreshChildren();
+ for (Iterator iter = fChildren.iterator(); iter.hasNext();) {
+ TreeObject element = ((TreeObject) iter.next());
+ element.refreshChildren();
+ }
+ }
+
+ public void addChild(TreeObject child) {
+ fChildren.add(child);
+ child.setParent(this);
+ }
+
+ public void removeChild(TreeObject child) {
+ fChildren.remove(child);
+ child.setParent(null);
+ }
+
+ public TreeObject[] getChildren() {
+ return (TreeObject[]) fChildren.toArray(new TreeObject[fChildren.size()]);
+ }
+
+ public boolean hasChildren() {
+ return (fChildren.size() > 0);
+ }
+
+ public void setName(String name) {
+ fName = ((name != null) ? name : "");
+ }
+
+ public void setParent(TreeObject parent) {
+ fParent = parent;
+ }
+
+ public String getName() {
+ return fName;
+ }
+
+ public TreeObject getParent() {
+ return fParent;
+ }
+
+ public Object getAdapter(Class key) {
+ return null;
+ }
+
+ public Image getImage() {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+ }
+
+ public String toString() {
+ return getName();
+ }
+ }
+
+ /**
+ * The tree parent class contains a list of projects
+ */
+ class TreeRoot extends TreeObject {
+
+ public TreeRoot() {
+ super("");
+ }
+
+ /**
+ * Return a list of all child objects (projects)
+ * that support the C project nature.
+ */
+ public void doRefreshChildren() {
+ IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
+ if (wsRoot != null) {
+ IProject[] projects = wsRoot.getProjects();
+ if (projects != null) {
+ for (int i = 0; i < projects.length; i++) {
+ try {
+ if (projects[i].isOpen()) {
+ if (projects[i].hasNature(CProjectNature.C_NATURE_ID)) {
+ addChild(new TreeProject(projects[i], this));
+ }
+ }
+ }
+ catch (CoreException e) {
+ }
+ }
+ }
+ }
+ }
+
+ public Image getImage() {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ }
+
+ }
+
+ class TreeProject extends TreeObject {
+ private IProject fProject;
+
+ public TreeProject(IProject project, TreeRoot parent) {
+ super(project.getName(), parent);
+ setProject(project);
+ }
+
+ private void setProject(IProject project) {
+ fProject = project;
+ }
+
+ public IProject getProject() {
+ return fProject;
+ }
+
+ public void doRefreshChildren() {
+ try {
+ ICBuildConfig[] configs = getBuildConfigurationManager().getConfigurations(fProject);
+ for (int i = 0; i < configs.length; i++) {
+ addChild(new TreeConfiguration(configs[i]));
+ }
+ } catch (CoreException e) {
+ }
+ }
+
+ public Image getImage() {
+ return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ }
+ }
+
+ class TreeConfiguration extends TreeObject {
+ private ICBuildConfig fConfig;
+
+ public TreeConfiguration(ICBuildConfig config) {
+ super(config.getName());
+ fConfig = config;
+ }
+
+ public void doRefreshChildren() {
+ }
+
+ public ICBuildConfig getConfiguration() {
+ return fConfig;
+ }
+
+ public IProject getProject() {
+ return fConfig.getProject();
+ }
+ }
+
+ class ViewContentProvider implements IStructuredContentProvider,
+ ITreeContentProvider {
+ private TreeRoot invisibleRoot;
+
+ public ViewContentProvider() {
+ invisibleRoot = new TreeRoot();
+ invisibleRoot.refreshChildren();
+ }
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput) {
+ invisibleRoot.refreshChildren();
+ }
+
+ public void dispose() {
+ }
+
+ public Object[] getElements(Object parent) {
+ if (parent.equals(ResourcesPlugin.getWorkspace())) {
+ return getChildren(invisibleRoot);
+ }
+ return getChildren(parent);
+ }
+
+ public Object getParent(Object child) {
+ if (child instanceof TreeObject) {
+ return ((TreeObject) child).getParent();
+ }
+ return null;
+ }
+
+ public Object[] getChildren(Object parent) {
+ if (parent instanceof TreeObject) {
+ return ((TreeObject) parent).getChildren();
+ }
+ return new Object[0];
+ }
+
+ public boolean hasChildren(Object parent) {
+ if (parent instanceof TreeObject) {
+ return ((TreeObject) parent).hasChildren();
+ }
+ return false;
+ }
+ }
+
+ class ViewLabelProvider extends LabelProvider {
+
+ public String getText(Object obj) {
+ return obj.toString();
+ }
+
+ public Image getImage(Object obj) {
+ Image image = null; // this is the image that will represent the obj parameter
+
+ // if this is a build configuration, get the image for the build configuration
+ if (obj instanceof TreeObject) {
+ image = ((TreeObject) obj).getImage();
+ } else {
+ // er, this is a bit odd, means we're not looking at one of our own classes
+ image = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+ }
+
+ return image;
+ }
+ }
+
+ /**
+ * The constructor.
+ */
+ public CBuildConfigView() {
+ }
+
+ /**
+ * This is a callback that will allow us
+ * to create the viewer and initialize it.
+ *
+ * @param parent the owner of the control
+ */
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new ViewContentProvider());
+ viewer.setLabelProvider(new ViewLabelProvider());
+ viewer.setSorter(new ViewerSorter(){});
+ viewer.setInput(ResourcesPlugin.getWorkspace());
+ makeActions();
+ hookContextMenu();
+ hookDoubleClickAction();
+ contributeToActionBars();
+
+ // register the listener for changes to the tree
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+
+ // Set this button to disable by default since there is no valid selection at this point.
+ actionEditConfig.setEnabled(false);
+ }
+
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("_#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ CBuildConfigView.this.fillContextMenu(manager);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ private void hookDoubleClickAction() {
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ ISelection selItem = viewer.getSelection();
+ Object objItem = ((IStructuredSelection) selItem).getFirstElement();
+ if (objItem.getClass().equals(TreeObject.class)) {
+ actionEditConfig.run();
+ }
+ else {
+ // be nice and expand or contract the tree when the user double clicks on a node
+ for (Iterator iter = ((IStructuredSelection) selItem).iterator(); iter.hasNext(); ) {
+ Object objNode = iter.next();
+ if (viewer.getExpandedState(objNode)) {
+ viewer.collapseToLevel(objNode, 1);
+ }
+ else {
+ viewer.expandToLevel(objNode, 1);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ fillLocalPullDown(bars.getMenuManager());
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+ private void fillLocalPullDown(IMenuManager manager) {
+ manager.add(actionEditConfig);
+ manager.add(new Separator());
+ //manager.add(actionBuild);
+ }
+
+ /**
+ * this method populates the right-click menu
+ */
+ private void fillContextMenu(IMenuManager manager) {
+
+ ISelection selItem = viewer.getSelection();
+ Object objItem = ((IStructuredSelection)selItem).getFirstElement();
+
+ if (objItem instanceof TreeProject) {
+ manager.add(actionNewConfig);
+ // manager.add(actionBuild);
+ } else if (objItem instanceof TreeConfiguration) {
+ TreeConfiguration treeConf = (TreeConfiguration) objItem;
+ manager.add(actionEditConfig);
+ manager.add(actionNewConfig);
+ CBuildAction build = new CBuildAction(treeConf.getProject(), treeConf.getConfiguration());
+ build.setImageDescriptor(CBuilderImages.DESC_IMG_ACTION_BUILD_CONFIG);
+ manager.add(build);
+
+ ICBuildConfig item = treeConf.getConfiguration();
+
+ if (item != null) {
+ // TODO: fix this
+ // actionMakePrimary.setEnabled(!item.getIsPrimary());
+ actionMakePrimary.setDescription(actionMakePrimary.isEnabled() ? MSG_MAKEPRIMARY : MSG_ALREADYPRIMARY);
+ actionMakePrimary.setToolTipText(actionMakePrimary.getDescription());
+ // TODO: fix this
+ // actionDeleteConfig.setEnabled(!item.getIsPrimary());
+ actionDeleteConfig.setDescription(actionDeleteConfig.isEnabled() ? MSG_CANDELETE : MSG_NODELETE);
+ actionDeleteConfig.setToolTipText(actionDeleteConfig.getDescription());
+ manager.add(actionMakePrimary);
+ manager.add(actionDeleteConfig);
+ }
+ }
+
+ // Other plug-ins can contribute there actions here
+ manager.add(new Separator("Additions"));
+ }
+
+ private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(actionEditConfig);
+ //manager.add(actionBuild);
+ manager.add(new Separator());
+ }
+
+ private void updateActionEnabled () {
+ IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();
+ TreeObject child = (TreeObject) sel.getFirstElement();
+ boolean enabled = ((sel.size() > 0) && (child instanceof TreeConfiguration));
+
+ actionEditConfig.setEnabled(enabled);
+ //actionBuild.setEnabled(true);
+ }
+
+ private ICBuildConfigManager getBuildConfigurationManager() {
+ return BuilderPlugin.getDefault().getBuildConfigurationManager();
+ }
+
+ private Shell getShell() {
+ return viewer.getControl().getShell();
+ }
+
+ private Object getElementFromSelection(ISelection sel) {
+ Object element = null;
+ if (sel instanceof IStructuredSelection) {
+ element = ((IStructuredSelection) sel).getFirstElement();
+ }
+ return element;
+ }
+
+ private void makeActions() {
+
+ //////////////////////////////////////////////
+ // Action: EDIT
+ //////////////////////////////////////////////
+
+ actionEditConfig = new Action() {
+ public void run() {
+ Object element = getElementFromSelection(viewer.getSelection());
+ if ((element != null) && (element instanceof TreeConfiguration)) {
+ TreeConfiguration treeConf = (TreeConfiguration) element;
+ CBuildConfigDialog dlg = null;
+
+ dlg = new CBuildConfigDialog(getShell(), treeConf.getConfiguration());
+
+ if (dlg.open() == dlg.OK) {
+ viewer.refresh();
+ }
+ }
+ }
+ };
+
+ actionEditConfig.setText("Edit...");
+ actionEditConfig.setToolTipText("Edit Configuration");
+ actionEditConfig.setImageDescriptor(CBuilderImages.DESC_IMG_ACTION_EDIT_CONFIG);
+
+ //////////////////////////////////////////////
+ // Action: BUILD
+ //////////////////////////////////////////////
+
+// actionBuild = new Action() {
+// public void run() {
+// IStructuredSelection selList = (IStructuredSelection) viewer.getSelection();
+// for (Iterator iter = selList.iterator(); iter.hasNext();) {
+// Object selItem = (Object) iter.next();
+// if (selItem instanceof TreeObject) {
+// TreeObject selConfig = (TreeObject) selItem;
+// IRunnableWithProgress builder = new CBuildConfig(selConfig.getAssocProject(), selConfig.getBuildConfig());
+// try {
+// new ProgressMonitorDialog(getSite().getShell()).run(true, true, builder);
+// }
+// catch (InterruptedException e) {}
+// catch (InvocationTargetException e) {}
+// }
+// }
+// }
+// };
+//
+// actionBuild.setText("Build");
+// actionBuild.setToolTipText("Performing Build");
+// actionBuild.setImageDescriptor(CBuilderImages.DESC_IMG_ACTION_BUILD_CONFIG);
+//
+// doubleClickAction = new Action() {
+// public void run() {
+// ISelection selection = viewer.getSelection();
+// Object obj = ((IStructuredSelection)selection).getFirstElement();
+// showMessage("Try to perform a build here" + obj.toString());
+// }
+// };
+
+ //////////////////////////////////////////////
+ // Action: NEW
+ //////////////////////////////////////////////
+
+ actionNewConfig = new Action() {
+ public void run() {
+ Object element = getElementFromSelection(viewer.getSelection());
+ if ((element != null) && (element instanceof TreeProject)) {
+ TreeProject treeProject = (TreeProject) element;
+ ICBuildConfigWorkingCopy cfg = null;
+ CBuildConfigDialog dlg = null;
+
+ cfg = getBuildConfigurationManager().getConfiguration(treeProject.getProject(), null);
+ dlg = new CBuildConfigDialog(getShell(), cfg);
+
+ if (dlg.open() == dlg.OK) {
+ viewer.refresh();
+ }
+ }
+ }
+ };
+
+ actionNewConfig.setText("New...");
+ actionNewConfig.setToolTipText("Add new configuration");
+ actionNewConfig.setImageDescriptor(CBuilderImages.DESC_IMG_ACTION_NEW_CONFIG);
+
+ //////////////////////////////////////////////
+ // Action: MAKE PRIMARY
+ //////////////////////////////////////////////
+
+ actionMakePrimary = new Action() {
+ public void run() {
+ Object element = getElementFromSelection(viewer.getSelection());
+ if ((element != null) && (element instanceof TreeConfiguration)) {
+ TreeConfiguration treeConfig = (TreeConfiguration) element;
+ // TODO: Use getBuildConfigurationManager(),
+ // treeConfig.getBuildConfig() to set primary config
+ viewer.refresh();
+ }
+ }
+ };
+
+ actionMakePrimary.setText("Make Primary");
+ actionMakePrimary.setToolTipText("Make this the primary configuration");
+// actionMakePrimary.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
+// getImageDescriptor(ISharedImages.IMG_OBJS_TASK_TSK));
+
+
+ //////////////////////////////////////////////
+ // Action: DELETE
+ //////////////////////////////////////////////
+
+ actionDeleteConfig = new Action() {
+ public void run() {
+ Object element = getElementFromSelection(viewer.getSelection());
+ if ((element != null) && (element instanceof TreeConfiguration)) {
+ TreeConfiguration treeConfig = (TreeConfiguration) element;
+ if (MessageDialog.openConfirm(getShell(), "Removing build configuration", "Are you sure you want to remove this build configuration?")) {
+ viewer.refresh();
+ }
+ }
+ }
+ };
+
+ actionDeleteConfig.setText("Remove");
+ actionDeleteConfig.setToolTipText("Remove this configuration");
+ actionMakePrimary.setImageDescriptor(CBuilderImages.DESC_IMG_ACTION_DELETE_CONFIG);
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged (SelectionChangedEvent event) {
+ updateActionEnabled();
+ }
+ });
+ }
+
+ private void showMessage(String message) {
+ MessageDialog.openInformation(getShell(), "Build Configuration", message);
+ }
+
+ /**
+ * Passing the focus request to the viewer's control.
+ */
+ public void setFocus() {
+ viewer.getControl().setFocus();
+ }
+
+ /**
+ * clean-up
+ */
+ public void dispose()
+ {
+ // remove from the workspace our listener
+ //getViewSite().getPage().removePostSelectionListener(this);
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ }
+
+ /**
+ * given a project, updates the view with the contents of
+ * the build configuration for that project
+ *
+ * @param prjTarget the new project that this view should adjust to
+ */
+ private void updateView(IProject prjTarget)
+ {
+ Assert.isNotNull(prjTarget);
+ }
+
+ class CResourceDeltaVisitor implements IResourceDeltaVisitor {
+
+ private boolean bRefreshView = false;
+
+ public boolean visit(IResourceDelta delta) {
+
+ IResource resource = delta.getResource();
+ boolean bVisitChildren = true;
+ int nKind;
+
+ if (resource instanceof IProject) {
+ nKind = delta.getKind();
+ if (nKind == IResourceDelta.OPEN || nKind == IResourceDelta.ADDED || nKind == IResourceDelta.REMOVED || nKind == IResourceDelta.CHANGED) {
+ bRefreshView = true;
+ }
+ // don't recurse past the project level
+ bVisitChildren = false;
+ }
+
+ return bVisitChildren;
+ }
+
+ public boolean getRefreshView() {
+ return bRefreshView;
+ }
+
+ }
+
+
+ /**
+ * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(IResourceChangeEvent)
+ */
+ public void resourceChanged(IResourceChangeEvent event) {
+
+ CResourceDeltaVisitor changeVisitor = new CResourceDeltaVisitor();
+
+ try {
+ event.getDelta().accept(changeVisitor);
+ }
+ catch (CoreException e) {
+ System.err.println(e.toString());
+ }
+
+ // refresh the view so the user can see the changes.
+ if (changeVisitor.getRefreshView()) {
+ this.refresh();
+ }
+
+ }
+
+ /**
+ * Wrapper for users of this object to force a view refresh
+ */
+ public void refresh() {
+ Display.getDefault().syncExec(new Runnable()
+ {
+ public void run() {
+ viewer.refresh();
+ }
+ }
+ );
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildVariableDialog.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildVariableDialog.java
new file mode 100644
index 00000000000..186cf3f058d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuildVariableDialog.java
@@ -0,0 +1,297 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.cdt.core.builder.BuilderPlugin;
+import org.eclipse.cdt.core.builder.ICBuildVariablePoint;
+import org.eclipse.cdt.core.builder.model.CBuildVariable;
+import org.eclipse.cdt.core.builder.model.ICBuildVariable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author gene.sally
+ *
+ * This class displays the selection tool for library paths or libraries
+ *
+ */
+public class CBuildVariableDialog extends Dialog {
+
+ private static final int DLG_WIDTH = 60; // for setting the height and width of the dialog
+ private static final int DLG_HEIGHT = 25;
+
+ private Combo fBrowseHow; // combo control
+ private TreeViewer fTree; // tree view control
+ private String fTitle; // title for dialog
+ private Map fBuildVariables;
+ private ICBuildVariable fSelection;
+
+ private class CNoFiles implements FileFilter {
+ public boolean accept(File file) {
+ return (file.isDirectory() && !file.getName().equals(".metadata"));
+ }
+ }
+
+ private class FileLabelProvider extends LabelProvider {
+
+ private final Image IMG_FOLDER= PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ private final Image IMG_FILE= PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
+
+ public Image getImage(Object element) {
+ if (element instanceof File) {
+ File curr= (File) element;
+ if (curr.isDirectory()) {
+ return IMG_FOLDER;
+ } else {
+ return IMG_FILE;
+ }
+ }
+ return null;
+ }
+
+ public String getText(Object element) {
+ if (element instanceof File) {
+ return ((File) element).getName();
+ }
+ return super.getText(element);
+ }
+ }
+
+ private class FileContentProvider implements ITreeContentProvider {
+
+ private final Object[] EMPTY= new Object[0];
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof File) {
+ File[] children = ((File) parentElement).listFiles(new CNoFiles());
+
+ if (children != null) {
+ return children;
+ }
+ }
+ return EMPTY;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof File) {
+ return ((File) element).getParentFile();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ public Object[] getElements(Object element) {
+ return getChildren(element);
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+ private class CDoubleClickInTree implements IDoubleClickListener {
+
+ public void doubleClick(DoubleClickEvent event) {
+
+ ISelection selection;
+
+ selection = fTree.getSelection();
+ if (selection != null) {
+ updateSelection();
+ getButton(OK).notifyListeners(SWT.Selection, new Event());
+ }
+
+ }
+
+ }
+
+ public CBuildVariableDialog(Shell parentShell, String title) {
+ super(parentShell);
+ fTitle = title;
+ fBuildVariables = getBuildVariables();
+ }
+
+ public ICBuildVariable getSelection() {
+ return fSelection;
+ }
+
+ protected Control createContents(Composite parent) {
+
+ super.createContents(parent);
+
+ Composite composite = (Composite) getDialogArea();
+
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 5;
+ layout.marginWidth = 5;
+ layout.numColumns = 2;
+ layout.makeColumnsEqualWidth = false;
+ composite.setLayout(layout);
+
+ // row 1
+ new Label(composite, SWT.NULL).setText(("Starting_Point_1")); //$NON-NLS-1$
+
+ fBrowseHow = new Combo(composite, SWT.LEFT | SWT.BORDER | SWT.READ_ONLY);
+ fBrowseHow.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
+
+ for (Iterator iter = fBuildVariables.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry element = (Map.Entry) iter.next();
+ String value = element.getValue().toString();
+ fBrowseHow.add(value);
+ }
+
+ fBrowseHow.setData(fBuildVariables);
+ fBrowseHow.addSelectionListener(new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent sel) {
+ String strSelection = fBrowseHow.getText();
+ if (strSelection != null && fTree != null) {
+ IPath path = expandBuildVar(strSelection);
+ if (path != null) {
+ fTree.setInput(path.toFile());
+ CBuildVariableDialog.this.getButton(IDialogConstants.OK_ID).setEnabled(fTree.getTree().getItemCount() != 0);
+ }
+ }
+ }
+ }
+
+ );
+ fBrowseHow.select(0);
+
+ // row 2
+ fTree = new TreeViewer(composite, SWT.LEFT | SWT.BORDER | SWT.READ_ONLY);
+ GridData gdTree = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_BOTH);
+ gdTree.horizontalSpan = 2;
+
+ gdTree.widthHint= convertWidthInCharsToPixels(DLG_WIDTH);
+ gdTree.heightHint= convertHeightInCharsToPixels(DLG_HEIGHT);
+ fTree.getControl().setLayoutData(gdTree);
+ fTree.setLabelProvider(new FileLabelProvider());
+ fTree.setSorter(new ViewerSorter() {});
+ fTree.setContentProvider(new FileContentProvider());
+
+ fTree.setInput(expandBuildVar((String) fBuildVariables.keySet().iterator().next()));
+
+ fTree.addDoubleClickListener(new CDoubleClickInTree());
+
+ return composite;
+ }
+
+ /**
+ * Method expandBuildVar.
+ * @param string
+ */
+ private IPath expandBuildVar(String name) {
+ ICBuildVariable bv = (ICBuildVariable) fBuildVariables.get(name);
+ return new Path((null != bv) ? bv.getValue() : "");
+ }
+
+
+ /**
+ * Method getBuildVariables.
+ * @return Map
+ */
+ private Map getBuildVariables() {
+ Map vars = new HashMap();
+ try {
+ Map providers = BuilderPlugin.getDefault().getBuildVariableProviders();
+ for (Iterator iter = providers.entrySet().iterator(); iter.hasNext();) {
+ ICBuildVariablePoint expt = (ICBuildVariablePoint) iter.next();
+ ICBuildVariable[] bv = expt.getProvider().getVariables();
+ for (int i = 0; i < bv.length; i++) {
+ vars.put(bv[i].getFixed(), bv[i]);
+ }
+ }
+ } catch (CoreException e) {
+ vars.clear();
+ }
+ return vars;
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ protected void okPressed() {
+ updateSelection();
+ super.okPressed();
+ }
+
+ /**
+ * @see org.eclipse.jface.window.Window#configureShell(Shell)
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(fTitle);
+ }
+
+ private void updateSelection() {
+
+ ISelection selection; // the current selection
+
+ // store the result of the user selection
+ selection = fTree.getSelection();
+ if (selection != null) {
+ File selectedPath = (File) ((StructuredSelection) selection).getFirstElement();
+ if (selectedPath != null) {
+ String strCurrRoot = fBrowseHow.getText();
+ IPath selPath = new Path(selectedPath.getAbsolutePath());
+ ICBuildVariable bv = (ICBuildVariable) fBuildVariables.get(strCurrRoot);
+ IPath currPath = new Path((null != bv) ? bv.getValue() : "");
+ int nMatchCount = currPath.matchingFirstSegments(selPath);
+ IPath delta = selPath.removeFirstSegments(nMatchCount);
+ delta = delta.setDevice(null);
+ fSelection = new CBuildVariable(delta.toString(), bv);
+ }
+ }
+
+ }
+
+
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuilderImages.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuilderImages.java
new file mode 100644
index 00000000000..3ba665f942d
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CBuilderImages.java
@@ -0,0 +1,149 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author gene.sally
+ *
+ * Container for C Builder images. Defines constants to the images in the project
+ * and creates the image descriptor objects for these files so we can have nice
+ * cached image management the way Eclipse intended.
+ *
+ * To add an image:
+ * 1) Place it in the icons/all folder in this project.
+ * 2) Create a IMG_* constant for it's name along.
+ * 3) Create a DESC_IMG_* constant for the image.
+ */
+public class CBuilderImages {
+
+ // NO I18N on these strings!!!
+ private static final String NAME_PREFIX = "org.eclipse.cdt.ui.builder."; //$NON-NLS-1$
+ private static final int NAME_PREFIX_LENGTH = NAME_PREFIX.length();
+
+ private static URL m_IconFolder = null;
+ private static ImageRegistry m_ImageRegistry = null;
+
+ /**
+ * the icon folder won't change and the other static
+ * methods/constants need this, so init as a static
+ */
+ static
+ {
+ try {
+ m_IconFolder = new URL( CUIPlugin.getDefault().getDescriptor().getInstallURL(), "icons/"); //$NON-NLS-1$
+ } catch( MalformedURLException e ) {
+ /* do nothing right now, but we should be doing something */
+ }
+ }
+
+ // the following lists all of the images in the system,
+ // the constants will be expanded to something on the filesystem when converted into
+ // image descroptors that are later turned into real Image Objects when needed.
+
+ public final static String IMG_CONFIG_COMPILER = NAME_PREFIX + "config-compiler.gif"; //$NON-NLS-1$
+ public final static String IMG_CONFIG_LINKER = NAME_PREFIX + "config-linker.gif"; //$NON-NLS-1$
+ public final static String IMG_CONFIG_PREPOCESSOR = NAME_PREFIX + "config-preprocessor.gif"; //$NON-NLS-1$
+ public final static String IMG_CONFIG_DEBUG = NAME_PREFIX + "config-debug.gif"; //$NON-NLS-1$
+ public final static String IMG_CONFIG_PROFILE = NAME_PREFIX + "config-profile.gif"; //$NON-NLS-1$
+ public final static String IMG_CONFIG_RELEASE = NAME_PREFIX + "config-release.gif"; //$NON-NLS-1$
+ public final static String IMG_ACTION_NEW_CONFIG = NAME_PREFIX + "action-newconfig.gif"; //$NON-NLS-1$
+ public final static String IMG_ACTION_EDIT_CONFIG = NAME_PREFIX + "action-editconfig.gif"; //$NON-NLS-1$
+ public final static String IMG_ACTION_BUILD_CONFIG = NAME_PREFIX + "action-buildconfig.gif"; //$NON-NLS-1$
+ public final static String IMG_ACTION_DELETE_CONFIG = NAME_PREFIX + "action-deleteconfig.gif"; //$NON-NLS-1$
+
+ // image prefix. for our purposes, slam all fo these into the same folder
+ // but leave the opporiunity for us to create sub-folders if necessary
+
+ public final static String PREFIX_ALL = "full/build16"; //$NON-NLS-1$
+
+ // create the image descriptors from the above constants
+
+ public final static ImageDescriptor DESC_IMG_CONFIG_COMPILER = getImageDescriptor(PREFIX_ALL, IMG_CONFIG_COMPILER);
+ public final static ImageDescriptor DESC_IMG_CONFIG_LINKER = getImageDescriptor(PREFIX_ALL, IMG_CONFIG_LINKER);
+ public final static ImageDescriptor DESC_IMG_CONFIG_PREPOCESSOR = getImageDescriptor(PREFIX_ALL, IMG_CONFIG_PREPOCESSOR);
+ public final static ImageDescriptor DESC_IMG_CONFIG_DEBUG = getImageDescriptor(PREFIX_ALL, IMG_CONFIG_DEBUG);
+ public final static ImageDescriptor DESC_IMG_CONFIG_PROFILE = getImageDescriptor(PREFIX_ALL, IMG_CONFIG_PROFILE);
+ public final static ImageDescriptor DESC_IMG_CONFIG_RELEASE = getImageDescriptor(PREFIX_ALL, IMG_CONFIG_RELEASE);
+ public final static ImageDescriptor DESC_IMG_ACTION_NEW_CONFIG = getImageDescriptor(PREFIX_ALL, IMG_ACTION_NEW_CONFIG);
+ public final static ImageDescriptor DESC_IMG_ACTION_EDIT_CONFIG = getImageDescriptor(PREFIX_ALL, IMG_ACTION_EDIT_CONFIG);
+ public final static ImageDescriptor DESC_IMG_ACTION_BUILD_CONFIG = getImageDescriptor(PREFIX_ALL, IMG_ACTION_BUILD_CONFIG);
+ public final static ImageDescriptor DESC_IMG_ACTION_DELETE_CONFIG = getImageDescriptor(PREFIX_ALL, IMG_ACTION_DELETE_CONFIG);
+
+ private static ImageRegistry getImageRegistry() {
+ if (null == m_ImageRegistry) {
+ Display display = (Display.getCurrent() != null) ? Display.getCurrent() : Display.getDefault();
+ m_ImageRegistry = new ImageRegistry(display);
+ }
+ return m_ImageRegistry;
+ }
+
+ /**
+ * Returns the image object from the image cache matching the requested name
+ *
+ * @param strImageIdent the identifier of the inmage, see one of the static IMG_ decls in this calss
+ * @return the image for this item, null if the image was not found
+ *
+ */
+ public static Image getImage(String strImageIdent) {
+ return getImageRegistry().get(strImageIdent);
+ }
+
+ /**
+ * Gets the location of an image based on it's location on the file system,
+ *
+ * @param strPrefix the folder under the icon folder where this file resides
+ * @param strName name of the image file
+ *
+ * @return the URL to the image requested.
+ */
+ private static URL getFilesystemName(String strPrefix, String strName) throws MalformedURLException {
+ if (m_IconFolder == null) {
+ throw new MalformedURLException();
+ }
+ StringBuffer buffer = new StringBuffer(strPrefix);
+ buffer.append('/');
+ buffer.append(strName);
+ return new URL(m_IconFolder, buffer.toString());
+
+ }
+
+ /**
+ * Creates an image descriptor for the requrested image
+ *
+ * @param strPrefix the folder under the icon folder where this file resides
+ * @param strName name of the image file
+ *
+ * @return the requested image descriptor, or image not found if the image could not be located on the file system.
+ */
+ private static ImageDescriptor getImageDescriptor(String strPrefix, String strName) {
+ ImageDescriptor descriptor = null;
+
+ try {
+ descriptor = ImageDescriptor.createFromURL(getFilesystemName(strPrefix, strName.substring(NAME_PREFIX_LENGTH)));
+ getImageRegistry().put(strName, descriptor);
+ }
+ catch(MalformedURLException e) {
+ descriptor = ImageDescriptor.getMissingImageDescriptor();
+ }
+
+ return descriptor;
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CLibFileDialog.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CLibFileDialog.java
new file mode 100644
index 00000000000..d1ecc526ffc
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CLibFileDialog.java
@@ -0,0 +1,421 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.HashMap;
+
+import org.eclipse.cdt.core.builder.model.ICBuildVariable;
+import org.eclipse.cdt.core.builder.model.ICToolchain;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author gene.sally
+ *
+ * To change this generated comment edit the template variable "typecomment":
+ * Window>Preferences>Java>Templates.
+ * To enable and disable the creation of type comments go to
+ * Window>Preferences>Java>Code Generation.
+ */
+public class CLibFileDialog extends Dialog {
+
+ private static final int DLG_WIDTH = 60;
+ private static final int DLG_HEIGHT = 25;
+
+ private ICBuildVariable[] fLibPaths; // the list of library paths used to populate the drop down
+ private ICToolchain fToolchain; // selected toolchain
+ private TreeViewer fFileTree; // tree control that's displayed
+ private File fSelection; // what the user selected in the dialog
+ private List fLibNames;
+
+ private class CItemSelectedIsLibrary implements ISelectionChangedListener {
+
+ /**
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+
+ // only enable the OK button when the user is resting on a file
+ Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ getButton(OK).setEnabled(selection instanceof File);
+ }
+ }
+
+ private class CDoubleClickInTree implements IDoubleClickListener {
+
+ public void doubleClick(DoubleClickEvent event) {
+
+ // make sure that the user has double-clicked on a file before accepting this as the
+ // selection
+ Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (selection instanceof File) {
+ getButton(OK).notifyListeners(SWT.Selection, new Event());
+ }
+ }
+ }
+
+ private class FileLabelProvider extends LabelProvider {
+
+ private final Image IMG_FOLDER= PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ private final Image IMG_FILE= PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
+
+ public Image getImage(Object element) {
+
+ if (element instanceof File) {
+ if (((File) element).isFile()) {
+ return IMG_FILE;
+ }
+ }
+ else if (element instanceof TreeLibPathObject) {
+ return IMG_FOLDER;
+ }
+
+ return null;
+ }
+
+ public String getText(Object element) {
+
+ if (element instanceof File) {
+ return ((File) element).getName();
+ } else if (element instanceof TreeLibPathObject) {
+ return ((TreeLibPathObject) element).toString();
+ }
+
+ return super.getText(element);
+ }
+ }
+
+ private class CNoDirectories implements FileFilter {
+
+ /**
+ * @see java.io.FileFilter#accept(File)
+ */
+ public boolean accept(File pathname) {
+
+ boolean isLibFile = false;
+ if (pathname.isFile()) {
+ String name = pathname.getName();
+ if ((name.endsWith(".lib")) || (name.endsWith(".a")) || (name.indexOf(".so") != -1)) {
+ isLibFile = true;
+ }
+ }
+ return (isLibFile);
+ }
+ }
+
+
+ private class TreeLibPathObject implements IAdaptable {
+
+ private ICBuildVariable m_location; // the location this object represents
+ private File m_fileSystem; // the representation of this object on the file system
+ private TreeParent m_parent; // parent of this object
+
+ public TreeLibPathObject(ICBuildVariable location, ICToolchain toolchain) {
+
+ if (location != null) {
+ m_location = location;
+ m_fileSystem = new File(location.getValue());
+ }
+
+ }
+
+ public File[] getChildren() {
+
+ // get the files in the file system matching this item
+ File[] children = m_fileSystem.listFiles(new CNoDirectories());
+
+ return children;
+ }
+
+ public boolean hasChildren() {
+
+ // ug, not the best for performance, consider caching
+ return getChildren().length != 0;
+ }
+
+ public Object getAdapter(Class key) {
+ return null;
+ }
+
+ public ICBuildVariable getBuildVar() {
+ return m_location;
+ }
+
+ public String toString() {
+ return m_location.toString();
+ }
+
+ public TreeParent getParent() {
+ return m_parent;
+ }
+
+ public void setParent(TreeParent parent) {
+ m_parent = parent;
+ }
+
+ }
+
+ private class TreeParent {
+
+ private HashMap m_children;
+
+ public TreeParent() {
+ m_children = new HashMap();
+ }
+ public void addChild(TreeLibPathObject child) {
+ m_children.put(child.m_fileSystem.getAbsolutePath(), child);
+ child.setParent(this);
+ }
+ public void removeChild(TreeLibPathObject child) {
+ m_children.remove(child.m_fileSystem.getAbsolutePath());
+ child.setParent(null);
+ }
+ public TreeLibPathObject[] getChildren() {
+
+ int nArraySize = m_children.entrySet().size();
+ TreeLibPathObject[] retval = (TreeLibPathObject[]) m_children.values().toArray(new TreeLibPathObject[nArraySize]);
+
+ return retval;
+
+ }
+
+ public boolean hasChildren() {
+ return m_children.entrySet().size() > 0;
+ }
+ public TreeLibPathObject matchingParent(File test) {
+
+ String parentPath = test.getParent();
+
+ if (m_children.keySet().contains(parentPath)) {
+ return (TreeLibPathObject) m_children.get(parentPath);
+ }
+
+ return null;
+ }
+ }
+
+ class ViewContentProvider implements IStructuredContentProvider,
+ ITreeContentProvider {
+
+ private TreeParent invisibleRoot;
+
+ public void inputChanged(Viewer v, Object oldInput, Object newInput) {}
+ public void dispose() {}
+
+ public Object[] getElements(Object parent) {
+
+ if (parent.equals(ResourcesPlugin.getWorkspace())) {
+ // if (parent instanceof TreeRoot) {
+
+ if (invisibleRoot == null) {
+ initialize();
+ }
+
+ return getChildren(invisibleRoot);
+ }
+
+ return getChildren(parent);
+ }
+
+ public Object getParent(Object child) {
+
+ // this is where things are going to get icky.
+ // when the child is a file type, inspect the path and see if
+ // it matches any of the parents in the list
+ if (child instanceof File) {
+ File currfile = (File) child;
+ return invisibleRoot.matchingParent(currfile);
+
+ }
+ else if (child instanceof TreeLibPathObject) {
+ return ((TreeLibPathObject) child).getParent();
+ }
+
+ return null;
+ }
+
+ public Object [] getChildren(Object parent) {
+
+ // the root of the tree
+ if (parent instanceof TreeParent) {
+
+ return ((TreeParent) parent).getChildren();
+
+ // the first level
+ } else if (parent instanceof TreeLibPathObject) {
+
+ return ((TreeLibPathObject) parent).getChildren();
+
+ }
+
+ // since we're not showing anything past the first level,
+ // just return an empty array
+ return new Object[0];
+ }
+
+ public boolean hasChildren(Object parent) {
+
+ // the root of the tree
+ if (parent instanceof TreeParent) {
+
+ return ((TreeParent) parent).hasChildren();
+
+ // the first level
+ } else if (parent instanceof TreeLibPathObject) {
+
+ return ((TreeLibPathObject) parent).hasChildren();
+
+ }
+
+ // since we're not showing anything past the first level,
+ // just return an empty array
+ return false;
+
+ }
+
+ private void initialize() {
+
+ invisibleRoot = new TreeParent();
+
+ // read from the parent's list of items
+ for (int nIndex = 0; nIndex < fLibPaths.length; nIndex++) {
+ invisibleRoot.addChild(new TreeLibPathObject(fLibPaths[nIndex], fToolchain));
+ }
+
+ }
+ }
+
+ // methods for CLibFileDialog
+ public CLibFileDialog(Shell shell, ICToolchain toolchain, ICBuildVariable[] libPaths) {
+
+ super(shell);
+ fLibPaths = libPaths;
+ fToolchain = toolchain;
+ fLibNames = new List (shell, shell.getStyle());
+
+ }
+
+ // methods for CLibFileDialog
+ public CLibFileDialog(Shell shell, ICToolchain toolchain, ICBuildVariable[] libPaths, List libList) {
+
+ super(shell);
+ fLibPaths = libPaths;
+ fToolchain = toolchain;
+ fLibNames = libList;
+
+ }
+ protected Control createContents(Composite parent) {
+
+ super.createContents(parent);
+
+ Composite composite = (Composite) getDialogArea();
+
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 5;
+ layout.marginWidth = 5;
+ layout.numColumns = 1;
+ composite.setLayout(layout);
+
+ // row 1
+ fFileTree = new TreeViewer(composite, SWT.LEFT | SWT.BORDER | SWT.READ_ONLY);
+ GridData gdTree = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_BOTH);
+
+ gdTree.widthHint= convertWidthInCharsToPixels(DLG_WIDTH);
+ gdTree.heightHint= convertHeightInCharsToPixels(DLG_HEIGHT);
+ fFileTree.getControl().setLayoutData(gdTree);
+ fFileTree.setLabelProvider(new FileLabelProvider());
+ fFileTree.setSorter(new ViewerSorter() {});
+ fFileTree.setContentProvider(new ViewContentProvider());
+
+ fFileTree.setInput(ResourcesPlugin.getWorkspace());
+
+ fFileTree.addSelectionChangedListener(new CItemSelectedIsLibrary());
+ fFileTree.addDoubleClickListener(new CDoubleClickInTree());
+
+ return composite;
+ }
+
+ /**
+ * @see org.eclipse.jface.window.Window#configureShell(Shell)
+ */
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(("Select_Library_1")); //$NON-NLS-1$
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ protected void okPressed() {
+
+ ISelection selection; // the current selection
+
+ selection = fFileTree.getSelection();
+ if (selection != null) {
+ fSelection = (File) ((StructuredSelection) selection).getFirstElement();
+ }
+
+ // Let's check if this name exists or not.
+ if (fLibNames.getItemCount() > 0) {
+ boolean exists = checkExistance();
+ if (exists) {
+ return;
+ }
+ }
+ super.okPressed();
+ }
+
+ public File getSelection() {
+ return fSelection;
+ }
+
+ private boolean checkExistance () {
+ String[] existingItems = fLibNames.getItems();
+ for (int i = 0; i < existingItems.length; i++) {
+ if (existingItems[i].toString().equals(getSelection().getName())) {
+ String errorMsg = "This Identifier already exists in the Preprocessor definitions for this project";
+ MessageDialog.openError(this.getShell(), "Naming problems", errorMsg);
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CNameValueDialog.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CNameValueDialog.java
new file mode 100644
index 00000000000..5fef2bb7be7
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CNameValueDialog.java
@@ -0,0 +1,275 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import org.eclipse.cdt.core.builder.util.CUtil;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author sam.robb
+ *
+ * Simple dialog for creating/editing name-value pairs.
+ */
+public class CNameValueDialog extends Dialog {
+
+ /**
+ * Dialog title.
+ */
+ String fTitle = "Variable";
+
+ /**
+ * Description of property name (ex, "Definition")
+ */
+ String fNameLabel = "Name";
+
+ /**
+ * Description of property value (ex, "Value")
+ */
+ String fValueLabel = "Value";
+
+ /**
+ * Property name.
+ */
+ String fName = "";
+
+ /**
+ * Property value.
+ */
+ String fValue = "";
+
+ /**
+ * Internal list to keep track of existing macro names.
+ */
+ private List reservedNames;
+
+ private Button btnOK = null;
+ private Button btnCancel = null;
+ private Text textName = null;
+ private Text textValue = null;
+
+ /**
+ * Constructor for CEntryDialog.
+ *
+ * @param parent
+ */
+ public CNameValueDialog(Shell parent) {
+ super(parent);
+ reservedNames = new List (parent, parent.getStyle());
+ }
+
+ /**
+ * Second Constructor
+ * @param Shell parent, List list
+ */
+ public CNameValueDialog (Shell parent, List list) {
+ super (parent);
+ reservedNames = list;
+ }
+
+ /**
+ * Set the title for the dialog.
+ *
+ * @param title Title to use for the dialog.
+ */
+ public void setTitle(String title) {
+ fTitle = title;
+ }
+
+ /**
+ * Set the label for the "Name" edit field in the dialog
+ *
+ * @param nameLabel Label to use for the "Name" edit field.
+ */
+ public void setNameLabel(String nameLabel) {
+ fNameLabel = nameLabel;
+ }
+
+ /**
+ * Set the label for the "Value" edit field in the dialog
+ *
+ * @param valueLabel Label to use for the "Value" edit field.
+ */
+ public void setValueLabel(String valueLabel) {
+ fValueLabel = valueLabel;
+ }
+
+ /**
+ * Set the inital contents of the "Name" edit field in the dialog
+ *
+ * @param name Initial value for the "Name" edit field.
+ */
+ public void setName(String name) {
+ fName = name;
+ }
+
+ /**
+ * Set the inital contents of the "Value" edit field in the dialog
+ *
+ * @param value Initial value for the "Value" edit field.
+ */
+ public void setValue(String value) {
+ fValue = value;
+ }
+
+ /**
+ * Returns the contents of the "Name" edit field in the dialog.
+ *
+ * @return Property name.
+ */
+ public String getName() {
+ return fName;
+ }
+
+ /**
+ * Returns the contents of the "Value" edit field in the dialog.
+ *
+ * @return Property value.
+ */
+ public String getValue() {
+ return fValue;
+ }
+
+ protected Control createContents(Composite parent) {
+ Control result = super.createContents(parent);
+ updateButtonsState();
+ return result;
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText(fTitle);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+
+ layout.marginWidth = 5;
+ layout.numColumns = 2;
+
+ composite.setLayout(layout);
+
+ GC gc = new GC(composite);
+ gc.setFont(composite.getFont());
+ FontMetrics metrics = gc.getFontMetrics();
+ gc.dispose();
+
+ int fieldWidthHint = convertWidthInCharsToPixels(metrics, 50);
+ GridData gd = null;
+ Label label = null;
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(fNameLabel + ":");
+
+ textName = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_BOTH);
+
+ gd.grabExcessHorizontalSpace = true;
+ gd.widthHint = fieldWidthHint;
+
+ textName.setLayoutData(gd);
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(fValueLabel + ":");
+
+ textValue = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_BOTH);
+
+ gd.grabExcessHorizontalSpace = true;
+ gd.widthHint = fieldWidthHint;
+
+ textValue.setLayoutData(gd);
+
+ textName.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtonsState();
+ }
+ });
+
+ textValue.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtonsState();
+ }
+ });
+
+ textName.setText(fName);
+ textValue.setText(fValue);
+
+ return composite;
+ }
+
+ protected void createButtonsForButtonBar(Composite parent) {
+ btnOK = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ btnCancel = createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ private void updateButtonsState() {
+ if (btnOK != null) {
+ btnOK.setEnabled(textName.getText().trim().length() > 0);
+ }
+ }
+
+ protected void okPressed() {
+ fName = textName.getText().trim();
+ fValue = textValue.getText().trim();
+ textValue.setText(fValue);
+
+ // Let's first check if this name already exists or not.
+ if (reservedNames.getItemCount() > 0) {
+ boolean exists = checkExistance();
+ if (exists) {
+ return;
+ }
+ }
+
+ // Validate the user input here.
+ boolean isValid = CUtil.isValidCIdentifier(fName);
+ if (!isValid) {
+ String errorMsg = fName + " is not a valid identifier name.";
+ MessageDialog.openError(this.getShell(), "Problem with Identifier name", errorMsg);
+ return;
+ }
+
+ setReturnCode(OK);
+ close();
+ }
+
+
+
+ private boolean checkExistance () {
+ String[] existingItems = reservedNames.getItems();
+ for (int i = 0; i < existingItems.length; i++) {
+ if (existingItems[i].toString().equals(fName)) {
+ String errorMsg = "This Identifier already exists in the Preprocessor definitions for this project";
+ MessageDialog.openError(this.getShell(), "Naming problems", errorMsg);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CToolTabGroupPoint.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CToolTabGroupPoint.java
new file mode 100644
index 00000000000..0ef7fec3793
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/internal/CToolTabGroupPoint.java
@@ -0,0 +1,57 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003 Timesys 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:
+ * Timesys - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.ui.builder.internal;
+
+import org.eclipse.cdt.core.builder.internal.ACExtensionPoint;
+import org.eclipse.cdt.ui.builder.ICToolTabGroup;
+import org.eclipse.cdt.ui.builder.ICToolTabGroupPoint;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+
+/**
+ * @author sam.robb
+ */
+public class CToolTabGroupPoint
+ extends ACExtensionPoint
+ implements ICToolTabGroupPoint {
+
+ /**
+ * Constructor.
+ *
+ * @param element configuration element for the build configuration provider.
+ */
+ public CToolTabGroupPoint(IConfigurationElement element) {
+ super(element);
+ }
+
+ /**
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroupPoint#getId()
+ */
+ public String getId() {
+ return getField(FIELD_ID);
+ }
+
+ /**
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroupPoint#getProviderClassName()
+ */
+ public String getProviderClassName() {
+ return getField(FIELD_CLASS);
+ }
+
+ /**
+ * @see org.eclipse.cdt.ui.builder.ICToolTabGroupPoint#getProvider()
+ */
+ public ICToolTabGroup getProvider() throws CoreException {
+ return (ICToolTabGroup) getClassInstance(FIELD_CLASS);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/action-buildconfig.gif b/core/org.eclipse.cdt.ui/icons/full/build16/action-buildconfig.gif
new file mode 100644
index 00000000000..a016684742d
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/action-buildconfig.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/action-deleteconfig.gif b/core/org.eclipse.cdt.ui/icons/full/build16/action-deleteconfig.gif
new file mode 100644
index 00000000000..f6837693523
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/action-deleteconfig.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/action-editconfig.gif b/core/org.eclipse.cdt.ui/icons/full/build16/action-editconfig.gif
new file mode 100644
index 00000000000..2eca02b9dc8
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/action-editconfig.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/action-newconfig.gif b/core/org.eclipse.cdt.ui/icons/full/build16/action-newconfig.gif
new file mode 100644
index 00000000000..d9f2cdef678
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/action-newconfig.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/build_configs.gif b/core/org.eclipse.cdt.ui/icons/full/build16/build_configs.gif
new file mode 100644
index 00000000000..a016684742d
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/build_configs.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/config-compiler.gif b/core/org.eclipse.cdt.ui/icons/full/build16/config-compiler.gif
new file mode 100644
index 00000000000..20e7baed143
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/config-compiler.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/config-debug.gif b/core/org.eclipse.cdt.ui/icons/full/build16/config-debug.gif
new file mode 100644
index 00000000000..3052a80cd67
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/config-debug.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/config-linker.gif b/core/org.eclipse.cdt.ui/icons/full/build16/config-linker.gif
new file mode 100644
index 00000000000..91eec0f7dae
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/config-linker.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/config-preprocessor.gif b/core/org.eclipse.cdt.ui/icons/full/build16/config-preprocessor.gif
new file mode 100644
index 00000000000..082e49fbe66
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/config-preprocessor.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/config-profile.gif b/core/org.eclipse.cdt.ui/icons/full/build16/config-profile.gif
new file mode 100644
index 00000000000..45d614829bf
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/config-profile.gif differ
diff --git a/core/org.eclipse.cdt.ui/icons/full/build16/config-release.gif b/core/org.eclipse.cdt.ui/icons/full/build16/config-release.gif
new file mode 100644
index 00000000000..b7b23708e09
Binary files /dev/null and b/core/org.eclipse.cdt.ui/icons/full/build16/config-release.gif differ
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index 731508c4ed9..4216b2cbe50 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -424,4 +424,92 @@