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 @@ - + @@ -12,6 +12,6 @@ - + diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 640d1008390..8ab15444130 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,10 @@ +2003-02-17 Doug Schaefer + + Merged in Sam Robb's source for the build model. The source can be + found in the build source folder. There are new extension point schema + in the schema folder. As well a number of extension points and extensions + have been added to the plugin.xml file. + 2003-02-13 Alain Magloire * src/org/eclipse/cdt/core/CCorePlugin.java: diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ACTool.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ACTool.java new file mode 100644 index 00000000000..1f6bb37d41d --- /dev/null +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/builder/ACTool.java @@ -0,0 +1,197 @@ +/********************************************************************** + * 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.io.File; +import java.io.IOException; + +import org.eclipse.cdt.core.builder.model.ICTool; +import org.eclipse.cdt.core.builder.util.Filesystem; +import org.eclipse.cdt.internal.core.ProcessClosure; +import org.eclipse.cdt.utils.spawner.ProcessFactory; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + *

+ * 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: + *

+ */ + public int getAttribute(String attributeName, int defaultValue) + throws CoreException; + + /** + * Returns the string-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: + * + */ + public String getAttribute(String attributeName, String defaultValue) + throws CoreException; + + /** + * Returns the boolean-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: + * + */ + public boolean getAttribute(String attributeName, boolean defaultValue) + throws CoreException; + + /** + * Returns the 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: + * + */ + public List getAttribute(String attributeName, List defaultValue) + throws CoreException; + + /** + * Returns the 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: + * + */ + public Map getAttribute(String attributeName, Map defaultValue) + throws CoreException; + + /** + * Returns the file this build configuration is stored + * in, or 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: + * + * @see ICBuildConfigWorkingCopy#getOriginal() + */ + public ICBuildConfigWorkingCopy getWorkingCopy() throws CoreException; + + /** + * Returns a copy of this build configuration, as a + * working copy, with the specified name. The new + * working copy does not refer back to this configuration + * as its original build configuration (the working copy + * will return 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: + * + * @see ICBuildConfigWorkingCopy#getOriginal() + */ + public ICBuildConfigWorkingCopy copy(String name) throws CoreException; + + /** + * Returns whether this build configuration is a working + * copy. + * + * @return whether this build configuration is a working + * copy + */ + public boolean isWorkingCopy(); + + /** + * Deletes this build configuration. This configuration's underlying + * storage is deleted. Has no effect if this configuration + * does not exist. + * + * @exception CoreException if this method fails. Reasons include: + * + */ + public void delete() throws CoreException; + + /** + * Returns a memento for this build configuration, or 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); + + /** + * Return true 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: + *

+ *

+ * 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 Strings 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter description of this extension point] + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + a translatable name that will be used to identify this build +configuration in UI elements. + + + + + + + name of a Java class implementing the ICBuildConfigurationProvider interface. + + + + + + + + + + a unique name that will be used to idenitfy this build configuration. + + + + + + + project nature this build configuration is associated with. +If '*' or not specified, it is associated with all project natures. + + + + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core/schema/CBuildVariable.exsd b/core/org.eclipse.cdt.core/schema/CBuildVariable.exsd new file mode 100644 index 00000000000..adc32bed304 --- /dev/null +++ b/core/org.eclipse.cdt.core/schema/CBuildVariable.exsd @@ -0,0 +1,109 @@ + + + + + + + + + [Enter description of this extension point] + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + name of a Java class implementing the ICBuildVariableProvider +interface. + + + + + + + + + + a unique name that will be used to idenitfy this build variable provider. + + + + + + + project nature this build variable provider is associated with. +If '*' or not specified, it is associated with all project natures. + + + + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core/schema/CTool.exsd b/core/org.eclipse.cdt.core/schema/CTool.exsd new file mode 100644 index 00000000000..30a6a4fcc76 --- /dev/null +++ b/core/org.eclipse.cdt.core/schema/CTool.exsd @@ -0,0 +1,114 @@ + + + + + + + + + [Enter description of this extension point] + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + a translatable name that will be used to identify this tool in UI elements. + + + + + + + name of a Java class implementing the ICTool interface. + + + + + + + + + + a unique name that will be used to idenitfy this tool. + + + + + + + the type of this tool (corresponds to a CToolType id). + + + + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core/schema/CToolType.exsd b/core/org.eclipse.cdt.core/schema/CToolType.exsd new file mode 100644 index 00000000000..75cf1b49b1e --- /dev/null +++ b/core/org.eclipse.cdt.core/schema/CToolType.exsd @@ -0,0 +1,98 @@ + + + + + + + + + [Enter description of this extension point] + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + a unique name that will be used to idenitfy this type of tool. + + + + + + + a translatable name that will be used to identify this type of +tool in UI elements. + + + + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core/schema/CToolchain.exsd b/core/org.eclipse.cdt.core/schema/CToolchain.exsd new file mode 100644 index 00000000000..c762e9e53e5 --- /dev/null +++ b/core/org.eclipse.cdt.core/schema/CToolchain.exsd @@ -0,0 +1,109 @@ + + + + + + + + + [Enter description of this extension point] + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + a unique name that will be used to identify this toolchain provider. + + + + + + + name of a Java class implementing the ICToolchainProvider +interface. + + + + + + + + + + project nature this build configuration is associated with. +If '*' or not specified, it is associated with all project natures. + + + + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.ui/.classpath b/core/org.eclipse.cdt.ui/.classpath index 0bcc542d2a9..9aecda4f3ac 100644 --- a/core/org.eclipse.cdt.ui/.classpath +++ b/core/org.eclipse.cdt.ui/.classpath @@ -2,6 +2,7 @@ + diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index 3f842b09fa6..9364c77841d 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,11 @@ +2003-02-17 Doug Schaefer + + Merged in Sam Robb's source for the build model. The source can be + found in the build source folder. There are new extension point schema + in the schema folder. There are build icons in the icons/full/build16 + folder. As well a number of extension points and extensions have been + added to the plugin.xml file. + 2003-02-17 Judy N. Green * plugin.xml * icons/full/ctool16/convert-normal.gif diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderDebug.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderDebug.java new file mode 100644 index 00000000000..fd972d6b9aa --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderDebug.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.gnu.tools; + +import org.eclipse.cdt.core.builder.model.ICBuildConfigProvider; +import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy; +import org.eclipse.cdt.core.builder.model.ICPosixBuildConstants; + +/** + * Default implementation of a "Debug" build configuration + * provider for GNU toolchains. + */ +public class CConfigProviderDebug implements ICBuildConfigProvider { + + /** + * @see org.eclipse.cdt.core.builder.model.ICBuildConfigProvider#setDefaults(ICBuildConfigWorkingCopy) + */ + public void setDefaults(ICBuildConfigWorkingCopy config) { + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_DEBUG, true); + config.setAttribute(ICPosixBuildConstants.CC_WARN_ALL, true); + config.setAttribute(ICPosixBuildConstants.LD_STRIP, false); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_PROFILE, false); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_OPTIMIZE, false); + config.setAttribute(ICPosixBuildConstants.CC_OPTIMZE_LEVEL, + ICPosixBuildConstants.CC_OPTIMIZE_NONE); + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderProfile.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderProfile.java new file mode 100644 index 00000000000..4d93f85075a --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderProfile.java @@ -0,0 +1,40 @@ +/********************************************************************** + * 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.gnu.tools; + +import org.eclipse.cdt.core.builder.model.ICBuildConfigProvider; +import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy; +import org.eclipse.cdt.core.builder.model.ICPosixBuildConstants; + +/** + * Default implementation of a "Profile" build configuration + * provider for GNU toolchains. + */ +public class CConfigProviderProfile implements ICBuildConfigProvider { + + /** + * @see org.eclipse.cdt.core.builder.model.ICBuildConfigProvider#setDefaults(ICBuildConfigWorkingCopy) + */ + public void setDefaults(ICBuildConfigWorkingCopy config) { + + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_DEBUG, false); + config.setAttribute(ICPosixBuildConstants.CC_WARN_ALL, true); + config.setAttribute(ICPosixBuildConstants.LD_STRIP, true); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_PROFILE, true); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_OPTIMIZE, true); + config.setAttribute(ICPosixBuildConstants.CC_OPTIMZE_LEVEL, + ICPosixBuildConstants.CC_OPTIMIZE_FULL); + + + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderRelease.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderRelease.java new file mode 100644 index 00000000000..c6769332ad2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CConfigProviderRelease.java @@ -0,0 +1,39 @@ +/********************************************************************** + * 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.gnu.tools; + +import org.eclipse.cdt.core.builder.model.ICBuildConfigProvider; +import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy; +import org.eclipse.cdt.core.builder.model.ICPosixBuildConstants; + +/** + * Default implementation of a "Release" build configuration + * provider for GNU toolchains. + */ +public class CConfigProviderRelease implements ICBuildConfigProvider { + + /** + * @see org.eclipse.cdt.core.builder.model.ICBuildConfigProvider#setDefaults(ICBuildConfigWorkingCopy) + */ + public void setDefaults(ICBuildConfigWorkingCopy config) { + + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_DEBUG, false); + config.setAttribute(ICPosixBuildConstants.CC_WARN_ALL, true); + config.setAttribute(ICPosixBuildConstants.LD_STRIP, true); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_PROFILE, false); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_OPTIMIZE, true); + config.setAttribute(ICPosixBuildConstants.CC_OPTIMZE_LEVEL, + ICPosixBuildConstants.CC_OPTIMIZE_FULL); + + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuTool.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuTool.java new file mode 100644 index 00000000000..20bfdf44416 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuTool.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.gnu.tools; + +import org.eclipse.cdt.core.IErrorParser; +import org.eclipse.cdt.core.builder.ACTool; + +/** + * Represents a generic GNU tool. + */ +public class CGnuTool extends ACTool { + + private final static String TOOL_TYPE_PREFIX = "org.eclipse.cdt.core.builder."; + private final static String TOOL_ID_PREFIX = "org.eclipse.cdt.gnu.tools."; + + CGnuTool(String id, String exeName) { + super(TOOL_TYPE_PREFIX + id, TOOL_ID_PREFIX + id, exeName); + }; + + /** + * @see org.eclipse.cdt.core.builder.model.ICTool#getErrorParser() + */ + public IErrorParser getErrorParser() { + // TODO: implementation + return null; + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuToolchain.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuToolchain.java new file mode 100644 index 00000000000..014311b009f --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuToolchain.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.gnu.tools; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.builder.model.ICBuildCmd; +import org.eclipse.cdt.core.builder.model.ICBuildConfig; +import org.eclipse.cdt.core.builder.model.ICTool; +import org.eclipse.cdt.core.builder.model.ICToolchain; +import org.eclipse.core.resources.IFile; + +/** + * Standard GNU toolchain. + */ +public class CGnuToolchain implements ICToolchain { + + private Map fToolMap; + + public CGnuToolchain() { + fToolMap = new HashMap(); + doRefresh(); + } + + protected void doRefresh() { + addTool(new CGnuTool("CC", "gcc")); + addTool(new CGnuTool("CXX", "c++")); + addTool(new CGnuTool("CPP", "gcc")); + addTool(new CGnuTool("AS", "as")); + addTool(new CGnuTool("LD", "ld")); + addTool(new CGnuTool("AR", "ar")); + addTool(new CGnuTool("DEBUGGER", "gdb")); + addTool(new CGnuTool("PROFILER", "gprof")); + addTool(new CGnuTool("STRIP", "strip")); + } + + /** + * Determines if a tools exists in the internal map of + * tool instances. + * + * @param id tool identifier. + * @return true if there is a tool instances that corresponds + * to the provided id. + */ + protected boolean toolExists(String id) { + return fToolMap.containsKey(id); + } + + /** + * Add a tool to the internal map of tool instances. + * + * @param id tool identifier. + * @param tc tool instance. + */ + protected void addTool(ICTool tool) { + fToolMap.put(tool.getId(), tool); + } + + /** + * Helper method used to retrieve a tool from the internal + * map of tool instances. + * + * @param id tool identifier. + * @return tool instance, or null if not found. + */ + protected ICTool getToolHelper(String id) { + ICTool tool = null; + Object obj = fToolMap.get(id); + if (obj instanceof ICTool) { + tool = (ICTool) obj; + } + return tool; + } + + /** + * Remove a toolchain from the internal map of toolchain instances. + * + * @param id toolchain identifier. + * @return true if toolchain is removed. + */ + protected boolean removeTool(String id) { + boolean exists = toolExists(id); + if (exists) { + Object obj = fToolMap.remove(id); + obj = null; + } + return exists; + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolchain#canProcess(IFile) + */ + public boolean canProcess(IFile file) { + // TODO: add logic + return true; + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolchain#getBuildCommands(IFile, ICBuildConfig) + */ + public ICBuildCmd[] getBuildCommands(IFile file, ICBuildConfig cfg) { + // TODO: add logic + return null; + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolchain#getDependencies(IFile, ICBuildConfig) + */ + public IFile[] getDependencies(IFile file, ICBuildConfig cfg) { + // TODO: add logic + // Either depend on gcc -MM, or CDOM + return null; + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolchain#getOutputs(IFile, ICBuildConfig) + */ + public IFile[] getOutputs(IFile file, ICBuildConfig cfg) { + // TODO: add logic + // Either depend on gcc -MM, or CDOM + return null; + } + + /** + * @see org.eclipse.cdt.core.builder.model.ICToolchain#getTools() + */ + public ICTool[] getTools() { + Collection tcc = fToolMap.values(); + return (ICTool[]) fToolMap.values().toArray(new ICTool[fToolMap.size()]); + } +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuToolchainProvider.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuToolchainProvider.java new file mode 100644 index 00000000000..285f8320119 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/CGnuToolchainProvider.java @@ -0,0 +1,38 @@ +/********************************************************************** + * 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.gnu.tools; + +import org.eclipse.cdt.core.builder.ACToolchainProvider; + +/** + * Standard GNU toolchain provider. + */ +public class CGnuToolchainProvider extends ACToolchainProvider { + + /** + * Prefix used to construct toolchain identifiers for this + * provider. + */ + public final static String PROVIDER_ID = "org.eclipse.cdt.gnu.tools"; + + /** + * This toolchain provider. + */ + public final static String NATIVE_ID = PROVIDER_ID + ".native"; + + /** + * @see org.eclipse.cdt.core.builder.ACToolchainProvider#doRefresh() + */ + public void doRefresh() { + addToolchain(NATIVE_ID, new CGnuToolchain()); + } +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/ToolsPlugin.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/ToolsPlugin.java new file mode 100644 index 00000000000..c1cf24dc894 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/ToolsPlugin.java @@ -0,0 +1,77 @@ +/********************************************************************** + * 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.gnu.tools; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPluginDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * The main plugin class to be used in the desktop. + */ +public class ToolsPlugin extends AbstractUIPlugin { + //The shared instance. + private static ToolsPlugin plugin; + //Resource bundle. + private ResourceBundle resourceBundle; + + /** + * The constructor. + */ + public ToolsPlugin(IPluginDescriptor descriptor) { + super(descriptor); + plugin = this; + try { + resourceBundle= ResourceBundle.getBundle("org.eclipse.cdt.gnu.tools.ToolsPluginResources"); + } catch (MissingResourceException x) { + resourceBundle = null; + } + } + + /** + * Returns the shared instance. + */ + public static ToolsPlugin getDefault() { + return plugin; + } + + /** + * Returns the workspace instance. + */ + public static IWorkspace getWorkspace() { + return ResourcesPlugin.getWorkspace(); + } + + /** + * Returns the string from the plugin's resource bundle, + * or 'key' if not found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle= ToolsPlugin.getDefault().getResourceBundle(); + try { + return bundle.getString(key); + } catch (MissingResourceException e) { + return key; + } + } + + /** + * Returns the plugin's resource bundle, + */ + public ResourceBundle getResourceBundle() { + return resourceBundle; + } +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCC.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCC.java new file mode 100644 index 00000000000..525b4ef6634 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCC.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.gnu.tools.tabgroup; + +import org.eclipse.cdt.gnu.tools.tabs.CTabCompiler; +import org.eclipse.cdt.ui.builder.ACToolTabGroup; +import org.eclipse.cdt.ui.builder.ICBuildConfigDialog; +import org.eclipse.cdt.ui.builder.ICToolTab; + +/** + * Tab group for gcc. + */ +public class CTabGroupCC extends ACToolTabGroup { + + /** + * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#createTabs(ICBuildConfigDialog) + */ + public void createTabs(ICBuildConfigDialog dialog) { + ICToolTab[] tabs = new ICToolTab[] { + new CTabCompiler() + }; + setTabs(tabs); + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCPP.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCPP.java new file mode 100644 index 00000000000..a580c5600ae --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCPP.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.gnu.tools.tabgroup; + +import org.eclipse.cdt.gnu.tools.tabs.CTabPreprocessor; +import org.eclipse.cdt.ui.builder.ACToolTabGroup; +import org.eclipse.cdt.ui.builder.ICBuildConfigDialog; +import org.eclipse.cdt.ui.builder.ICToolTab; + +/** + * Tab group for cpp. + */ +public class CTabGroupCPP extends ACToolTabGroup { + + /** + * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#createTabs(ICBuildConfigDialog) + */ + public void createTabs(ICBuildConfigDialog dialog) { + ICToolTab[] tabs = new ICToolTab[] { + new CTabPreprocessor() + }; + setTabs(tabs); + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCXX.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCXX.java new file mode 100644 index 00000000000..a355e4a8b35 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupCXX.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.gnu.tools.tabgroup; + +import org.eclipse.cdt.gnu.tools.tabs.CTabCompiler; +import org.eclipse.cdt.ui.builder.ACToolTabGroup; +import org.eclipse.cdt.ui.builder.ICBuildConfigDialog; +import org.eclipse.cdt.ui.builder.ICToolTab; + +/** + * Tab group for g++. + */ +public class CTabGroupCXX extends ACToolTabGroup { + + /** + * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#createTabs(ICBuildConfigDialog) + */ + public void createTabs(ICBuildConfigDialog dialog) { + ICToolTab[] tabs = new ICToolTab[] { + new CTabCompiler() + }; + setTabs(tabs); + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupLD.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupLD.java new file mode 100644 index 00000000000..4e5fb97fe22 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabgroup/CTabGroupLD.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.gnu.tools.tabgroup; + +import org.eclipse.cdt.gnu.tools.tabs.CTabLinker; +import org.eclipse.cdt.ui.builder.ACToolTabGroup; +import org.eclipse.cdt.ui.builder.ICBuildConfigDialog; +import org.eclipse.cdt.ui.builder.ICToolTab; + +/** + * Tab group for ld. + */ +public class CTabGroupLD extends ACToolTabGroup { + + /** + * @see org.eclipse.cdt.ui.builder.ICToolTabGroup#createTabs(ICBuildConfigDialog) + */ + public void createTabs(ICBuildConfigDialog dialog) { + ICToolTab[] tabs = new ICToolTab[] { + new CTabLinker() + }; + setTabs(tabs); + } + +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabCompiler.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabCompiler.java new file mode 100644 index 00000000000..7c702fab8e2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabCompiler.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.gnu.tools.tabs; +import java.util.HashMap; + +import org.eclipse.cdt.core.builder.model.ICBuildConfig; +import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy; +import org.eclipse.cdt.core.builder.model.ICPosixBuildConstants; +import org.eclipse.cdt.ui.builder.ACToolTab; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.swt.SWT; +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.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** + * The control for editing and viewing compiler options. + */ +public class CTabCompiler extends ACToolTab { + + private Combo fOptimizationLevel; + private Button btnDebugging; + private Button btnProfiling; + private Text fUserOptions; + private Table fWarningsTable; + private TableItem fWarnAll; + private TableItem fWarnAsErrors; + private TableItem fWarnFormatStrings; + private TableItem fWarnPointerArith; + private TableItem fWarnSwitch; + private TableItem fWarnUnreachable; + private TableItem fWarnUnused; + private HashMap optLevelMap = new HashMap(); + + private final String[] OPT_LEVELS = {"None", "Medium", "High" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + private final String[] OPT_ARGS = {"-O0", "-O1", "-O2" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + /** + * Constructs the object + */ + public CTabCompiler() { + // populate hash map + for (int nIndex = 0; nIndex < OPT_LEVELS.length; nIndex++) + { + optLevelMap.put(OPT_ARGS[nIndex], OPT_LEVELS[nIndex]); + } + + } + + /** + * Helper to add an item to the table of compiler settings + * + * @param parent the owning control + * @param txtLabel text for the table item + */ + private TableItem createTableItem(Table parent, String txtLabel) + { + TableItem retval = new TableItem(parent, SWT.NONE); + + if (retval != null) { + retval.setText(txtLabel); + } + + return retval; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#createControl(Composite) + */ + public void createControl(Composite parent) { + + Composite ths = new Composite(parent, SWT.NONE); + + // Panel + + ths.setLayout(new GridLayout(2, true)); + ths.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // -------------------------------------------------- + // Left column + // -------------------------------------------------- + + Composite cmpLeft = new Composite(ths, SWT.NONE); + + cmpLeft.setLayout(new GridLayout()); + cmpLeft.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // row 1 + new Label(cmpLeft, SWT.LEFT).setText(("Optimization_Level_7")); //$NON-NLS-1$ + + // row 2 + fOptimizationLevel = new Combo(cmpLeft, SWT.RIGHT | SWT.TOP | SWT.READ_ONLY); + fOptimizationLevel.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); + + // row 3 + btnDebugging = new Button(cmpLeft, SWT.CHECK | SWT.LEFT); + btnDebugging.setText(("Enable_Debugging_9")); //$NON-NLS-1$ + + // row 4 + btnProfiling = new Button(cmpLeft, SWT.CHECK | SWT.LEFT); + btnProfiling.setText(("Enable_Profiling_10")); //$NON-NLS-1$ + + // row 5 + new Label(cmpLeft, SWT.LEFT).setText(("Additional_Options_11")); //$NON-NLS-1$ + + // row 6 + fUserOptions = new Text(cmpLeft, SWT.BORDER | SWT.LEFT); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_VERTICAL); + gridData.verticalAlignment = GridData.BEGINNING; + fUserOptions.setLayoutData(gridData); + + // -------------------------------------------------- + // Right column + // -------------------------------------------------- + + Composite cmpRight = new Composite(ths, SWT.NONE); + + cmpRight.setLayout(new GridLayout()); + cmpRight.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // row 1 + new Label(cmpRight, SWT.LEFT).setText(("Warnings__8")); //$NON-NLS-1$ + + // row 2 + fWarningsTable = new Table(cmpRight, SWT.BORDER | SWT.MULTI | SWT.CHECK | SWT.HIDE_SELECTION); + fWarnAll = createTableItem(fWarningsTable, "All Warnings"); + fWarnAsErrors = createTableItem(fWarningsTable, "Warnings as errors"); + fWarnFormatStrings = createTableItem(fWarningsTable, "Bad format strings"); + fWarnPointerArith = createTableItem(fWarningsTable, "pointer aritemetic"); + fWarnSwitch = createTableItem(fWarningsTable, "No default switch statement"); + fWarnUnreachable = createTableItem(fWarningsTable, "Unreachable code"); + fWarnUnused = createTableItem(fWarningsTable, "Unused parameter"); + + GridData grdWarnings = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL); + GC gc = new GC(fWarningsTable); + gc.setFont(fWarningsTable.getFont()); + grdWarnings.widthHint = org.eclipse.jface.dialogs.Dialog.convertWidthInCharsToPixels(gc.getFontMetrics(), 35); + gc.dispose(); + fWarningsTable.setLayoutData(grdWarnings); + + // set the size of this control + ths.setSize(ths.computeSize(SWT.DEFAULT, SWT.DEFAULT)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#initializeFrom(ICBuildConfig) + */ + public void initializeFrom(ICBuildConfig config) { + boolean debug = false; + boolean profile = false; + boolean optimize = true; + boolean[] warn = new boolean[7]; + int optLevel = 0; + String userArgs = ""; + + // can't populate with null data pointer + if (config == null) { + return; + } + + try { + profile = config.getAttribute(ICPosixBuildConstants.CC_ENABLE_PROFILE, false); + debug = config.getAttribute(ICPosixBuildConstants.CC_ENABLE_DEBUG, false); + optimize = config.getAttribute(ICPosixBuildConstants.CC_ENABLE_OPTIMIZE, false); + optLevel = config.getAttribute(ICPosixBuildConstants.CC_OPTIMZE_LEVEL, 0); + userArgs = config.getAttribute(ICPosixBuildConstants.CC_USER_ARGS, ""); + warn[0] = config.getAttribute(ICPosixBuildConstants.CC_WARN_ALL, false); + warn[1] = config.getAttribute(ICPosixBuildConstants.CC_WARN_ASERROR, false); + warn[2] = config.getAttribute(ICPosixBuildConstants.CC_WARN_FORMAT, false); + warn[3] = config.getAttribute(ICPosixBuildConstants.CC_WARN_POINTERAR, false); + warn[4] = config.getAttribute(ICPosixBuildConstants.CC_WARN_SWITCH, false); + warn[5] = config.getAttribute(ICPosixBuildConstants.CC_WARN_UNREACH, false); + warn[6] = config.getAttribute(ICPosixBuildConstants.CC_WARN_UNUSED, false); + } catch (CoreException e) { + } + + btnProfiling.setSelection(profile); + btnDebugging.setSelection(debug); + if (optimize) { + fOptimizationLevel.select(optLevel); + } + fUserOptions.setText(userArgs); + + // check for all of the warnings (could have been better...) + fWarnAll.setChecked(warn[0]); + fWarnAsErrors.setChecked(warn[1]); + fWarnFormatStrings.setChecked(warn[2]); + fWarnPointerArith.setChecked(warn[3]); + fWarnSwitch.setChecked(warn[4]); + fWarnUnreachable.setChecked(warn[5]); + fWarnUnused.setChecked(warn[6]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#performApply(ICBuildConfigWorkingCopy) + */ + public void performApply(ICBuildConfigWorkingCopy config) { + + boolean debug = false; + boolean profile = false; + boolean optimize = true; + boolean[] warn = new boolean[7]; + int optLevel = 0; + String userArgs = ""; + + // can't populate with null data pointer + if (config == null) { + return; + } + + profile = btnProfiling.getSelection(); + debug = btnDebugging.getSelection(); + // optimize = ???; + optLevel = fOptimizationLevel.getSelectionIndex(); + userArgs = fUserOptions.getText(); + + // check for all of the warnings (could have been better...) + warn[0] = fWarnAll.getChecked(); + warn[1] = fWarnAsErrors.getChecked(); + warn[2] = fWarnFormatStrings.getChecked(); + warn[3] = fWarnPointerArith.getChecked(); + warn[4] = fWarnSwitch.getChecked(); + warn[5] = fWarnUnreachable.getChecked(); + warn[6] = fWarnUnused.getChecked(); + + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_PROFILE, profile); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_DEBUG, debug); + config.setAttribute(ICPosixBuildConstants.CC_ENABLE_OPTIMIZE, optimize); + config.setAttribute(ICPosixBuildConstants.CC_OPTIMZE_LEVEL, optLevel); + config.setAttribute(ICPosixBuildConstants.CC_USER_ARGS, userArgs); + config.setAttribute(ICPosixBuildConstants.CC_WARN_ALL, warn[0]); + config.setAttribute(ICPosixBuildConstants.CC_WARN_ASERROR, warn[1]); + config.setAttribute(ICPosixBuildConstants.CC_WARN_FORMAT, warn[2]); + config.setAttribute(ICPosixBuildConstants.CC_WARN_POINTERAR, warn[3]); + config.setAttribute(ICPosixBuildConstants.CC_WARN_SWITCH, warn[4]); + config.setAttribute(ICPosixBuildConstants.CC_WARN_UNREACH, warn[5]); + config.setAttribute(ICPosixBuildConstants.CC_WARN_UNUSED, warn[6]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#setDefaults(ICBuildConfigWorkingCopy) + */ + public void setDefaults(ICBuildConfigWorkingCopy config) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#isValid(ICBuildConfigWorkingCopy) + */ + public boolean isValid(ICBuildConfigWorkingCopy config) { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#getName() + */ + public String getName() { + return "Compiler"; + } +} diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabLinker.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabLinker.java new file mode 100644 index 00000000000..8d4edd7b14a --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabLinker.java @@ -0,0 +1,583 @@ +/********************************************************************** + * 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.gnu.tools.tabs; + +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.cdt.core.builder.model.CBuildVariable; +import org.eclipse.cdt.core.builder.model.ICBuildConfig; +import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy; +import org.eclipse.cdt.core.builder.model.ICBuildVariable; +import org.eclipse.cdt.core.builder.model.ICPosixBuildConstants; +import org.eclipse.cdt.core.builder.model.ICToolchain; +import org.eclipse.cdt.ui.builder.ACToolTab; +import org.eclipse.cdt.ui.builder.internal.CBuildVariableDialog; +import org.eclipse.cdt.ui.builder.internal.CLibFileDialog; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.util.Assert; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Text; + +/** + * The control for editing and viewing linker options. + */ +public class CTabLinker extends ACToolTab { + + private Text fOutputFileName; + private Text fCmdLine; + private Button btnStatic; + private Button btnSharedObject; + private Button btnStripSybmols; + private List fLibPaths; + private List fLibs; + private List fLibFileList; // Used for validation. + private Button btnAddLib; // this set of buttons controls the lib of libraries + private Button btnRemoveLib; + private Button btnMoveUp; + private Button btnMoveDown; + private Button btnRemove; // set of buttons for the library paths + + class addLibraryPath extends SelectionAdapter + { + public void widgetSelected(SelectionEvent sel) + { + CBuildVariableDialog selectFolder = new CBuildVariableDialog(getShell(), ("Select_Library_Path_1")); //$NON-NLS-1$ + if (selectFolder.open() == selectFolder.OK) { + ICBuildVariable result = selectFolder.getSelection(); + fLibPaths.add(result.toString()); + } + } + }; + + class addLibraryFile extends SelectionAdapter + { + public void widgetSelected(SelectionEvent sel) + { + + // create list of item to send to the library picker + ICBuildVariable[] libPaths = new CBuildVariable[fLibPaths.getItemCount()]; + for (int nIndex = 0; nIndex < fLibPaths.getItemCount(); nIndex++) { + String item = fLibPaths.getItem(nIndex); + int nCloseBracePos = item.indexOf("]");//$NON-NLS-1$ + String name = item.substring(1, nCloseBracePos); + String val = item.substring(nCloseBracePos + 2); + libPaths[nIndex] = new CBuildVariable(name, val, "");// fLibPaths.getItem(nIndex)); + } + + fLibFileList = fLibs; + CLibFileDialog selectFile = new CLibFileDialog(getShell(), + (ICToolchain) null /* getToolchain() */, + libPaths, + fLibFileList); + if (selectFile.open() == selectFile.OK) { + fLibs.add(selectFile.getSelection().getName()); + } + + // Update the move down button. + if (fLibs.getItemCount() > 1) { + btnMoveDown.setEnabled(true); + } + } + }; + + class delLibraryPath extends SelectionAdapter + { + public void widgetSelected(SelectionEvent sel) + { + int[] nSelItems = fLibPaths.getSelectionIndices(); + + if (nSelItems != null) { + fLibPaths.remove(nSelItems); + } + } + }; + + class delLibraryFile extends SelectionAdapter + { + public void widgetSelected(SelectionEvent sel) + { + int[] nSelItems = fLibs.getSelectionIndices(); + + if (nSelItems != null) { + fLibs.remove(nSelItems); + } + + // Added to make sure that if nothing is selected the move up/down buttons are appropriately enabled or + // disabled. + nSelItems = fLibs.getSelectionIndices(); + if ((nSelItems != null) && (nSelItems.length == 0)) { + btnMoveUp.setEnabled(false); + btnMoveDown.setEnabled(false); + } + } + }; + + class moveLibs extends SelectionAdapter + { + int m_nDelta; + + public moveLibs(int delta) { + Assert.isTrue(delta == -1 || delta == 1, ("Delta_must_be_1_or_-1_2")); //$NON-NLS-1$ + m_nDelta = delta; + } + + private boolean CanMove(int selections, int delta ) { + boolean canMove = true; + + // First of all check if we can even move the selected lib names up or down. + if ((selections == 0) && (delta == -1)) { + btnMoveUp.setEnabled(false); + + if (fLibs.getItemCount() > 1) { + btnMoveDown.setEnabled(true); + } + canMove = false; + } + if ((selections == (fLibs.getItemCount() - 1)) && (delta == 1)) { + btnMoveDown.setEnabled(false); + + if (fLibs.getItemCount() > 1) { + btnMoveUp.setEnabled(true); + } + canMove = false; + } + + return canMove; + } + + public void widgetSelected(SelectionEvent sel) { + + int[] selections = fLibs.getSelectionIndices(); + if ((selections != null) && (m_nDelta != 0)) { + int nStart = (m_nDelta < 0) ? 0 : selections.length - 1; + int nEnd = (m_nDelta < 0) ? selections.length : -1; + String strTemp; + + boolean bCanMove = CanMove(selections[nStart], m_nDelta); + // this loop moves group of items based on the delta and moves them + for (int nIndex = nStart ; nIndex != nEnd && bCanMove; nIndex += (m_nDelta * -1)) { + // remove and re-add the list box + strTemp = fLibs.getItem(selections[nIndex]); + fLibs.remove(selections[nIndex]); + fLibs.add(strTemp, selections[nIndex] + m_nDelta); + // adjust the index in the selection list so we can re-highlight the block + selections[nIndex] = selections[nIndex] + m_nDelta; + + bCanMove = CanMove(selections[nIndex], m_nDelta); + } + fLibs.select(selections); + } + } + }; + + + // decl these after defining the vars + addLibraryPath m_addLibraryPath = new addLibraryPath(); + delLibraryPath m_delLibraryPath = new delLibraryPath(); + addLibraryFile m_addLibraryFile = new addLibraryFile(); + delLibraryFile m_delLibraryFile = new delLibraryFile(); + + public CTabLinker() { + super(); + } + + class TextWidth { + private int width_ = 0; + public TextWidth(Composite composite, String[] labels) { + GC gc = new GC(composite); + gc.setFont(composite.getFont()); + for (int i = 0; i < labels.length; i++) { + int newWidth = gc.textExtent(labels[i]).x + 10; //$NON-NLS-1$ + if (newWidth > width_) { + width_ = newWidth; + } + } + } + public int getWidth() { + return width_; + } + } + + /** + * Helper function for creating a grid layout to spec. + * + * @param columns Number of columns in layout. + * @param equalWidth True if columns are of equal width. + * @param marginHeight Margin height for layout. + * @param marginWidth Margin width for layout. + * + * @return Newly created GridLayout with the specified properties. + */ + private GridLayout createGridLayout(int columns, boolean equalWidth, int marginHeight, int marginWidth) { + GridLayout layout = new GridLayout(columns, equalWidth); + layout.marginHeight = marginHeight; + layout.marginWidth = marginWidth; + return layout; + } + + /** + * helper routine for putting the values in the list box + * + * @param lstTarget the control to fill with values + * @param data linker properties data + * @param data parameter name to fetch from data + * + */ + private void setList(org.eclipse.swt.widgets.List target, java.util.List list) + { + target.removeAll(); + if (null != list) { + for (Iterator iter = list.iterator(); iter.hasNext();) { + target.add((String) iter.next()); + } + } + } + + /** + * helper routine for getting data from a list control + * @param control contol to get data from + */ + private java.util.List getList(List control) + { + String[] items = fLibs.getItems(); + Vector vec = new Vector(); + for (int i = 0; i < items.length; i++) { + vec.add(items[i]); + } + return vec; + } + + /** + * helper routine for getting data from a text control + * @param control contol to get data from + */ + private String readText(Text control) + { + String str = control.getText(); + if (str != null) { + str.trim(); + } else { + str = ""; + } + return str; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#createControl(Composite) + */ + public void createControl(Composite parent) { + + final String[] BUTTON_LABELS = { + ("Add..._5"), //$NON-NLS-1$ + ("Remove_7"), //$NON-NLS-1$ + ("Add_12"), //$NON-NLS-1$ + ("Remove_13"), //$NON-NLS-1$ + ("Move_Up_14"), //$NON-NLS-1$ + ("Move_Down_15") //$NON-NLS-1$ + }; + + Composite ths = new Composite(parent, SWT.NONE); + int BUTTON_WIDTH = new TextWidth(ths, BUTTON_LABELS).getWidth(); + + // Panel + + ths.setLayout(new GridLayout(2, true)); + ths.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_BOTH)); + fLibFileList = new List(parent, SWT.NONE); + + // -------------------------------------------------- + // Left column + // -------------------------------------------------- + + Composite cmpLeft = new Composite(ths, SWT.NONE); + + cmpLeft.setLayout(createGridLayout(1, true, 2, 2)); + cmpLeft.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // row 1 + new Label(cmpLeft, SWT.NULL).setText(("Output_File_Name_3")); //$NON-NLS-1$ + + // row 2 + fOutputFileName = new Text(cmpLeft, SWT.LEFT | SWT.BORDER); + fOutputFileName.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL)); + + // row 3 + btnStatic = new Button(cmpLeft, SWT.CHECK | SWT.LEFT); + btnStatic.setText(("Perform_Static_Linking_6")); //$NON-NLS-1$ + btnStatic.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING)); + + // row 4 + btnSharedObject = new Button(cmpLeft, SWT.CHECK | SWT.LEFT); + btnSharedObject.setText(("Create_Shared_Object_8")); //$NON-NLS-1$ + btnSharedObject.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL)); + + // row 5 + btnStripSybmols = new Button(cmpLeft, SWT.CHECK | SWT.LEFT); + btnStripSybmols.setText(("Strip_Symbols_9")); //$NON-NLS-1$ + btnStripSybmols.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL)); + + // row 6 + new Label(cmpLeft, SWT.NULL).setText(("Additional_Options_11")); //$NON-NLS-1$ + + // row 7 + fCmdLine = new Text(cmpLeft, SWT.LEFT | SWT.BORDER); + fCmdLine.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL)); + + + // -------------------------------------------------- + // Right column + // -------------------------------------------------- + + Composite cmpRight = new Composite(ths, SWT.NONE); + + cmpRight.setLayout(createGridLayout(1, true, 2, 2)); + cmpRight.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Lib paths + + Group grpLibPaths = new Group(cmpRight, SWT.SHADOW_NONE); + grpLibPaths.setLayout(createGridLayout(1, true, 2, 2)); + grpLibPaths.setLayoutData(new GridData(GridData.FILL_BOTH)); + grpLibPaths.setText(("Library_Paths__4")); //$NON-NLS-1$ + + Composite cmpLibPaths = new Composite(grpLibPaths, SWT.NONE); + cmpLibPaths.setLayout(createGridLayout(1, true, 2, 2)); + cmpLibPaths.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Composite cmpPathCtrls = new Composite(cmpLibPaths, SWT.NONE); + cmpPathCtrls.setLayout(createGridLayout(2, false, 2, 2)); + cmpPathCtrls.setLayoutData(new GridData(GridData.FILL_BOTH)); + + fLibPaths = new List(cmpPathCtrls, SWT.LEFT | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + fLibPaths.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Composite cmpPathButtons = new Composite(cmpPathCtrls, SWT.NONE); + cmpPathButtons.setLayout(createGridLayout(1, true, 2, 2)); + GridData gdPathBtns = new GridData(); + gdPathBtns.widthHint = BUTTON_WIDTH; + cmpPathButtons.setLayoutData(gdPathBtns); + + Button btnNew = new Button(cmpPathButtons, SWT.NULL); + btnNew.setText(("Add..._5")); //$NON-NLS-1$ + btnNew.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + btnRemove = new Button(cmpPathButtons, SWT.NULL); + btnRemove.setText(("Remove_7")); //$NON-NLS-1$ + btnRemove.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // Libs + + Group grpLibs = new Group(cmpRight, SWT.SHADOW_NONE); + grpLibs.setLayout(createGridLayout(1, true, 2, 2)); + grpLibs.setLayoutData(new GridData(GridData.FILL_BOTH)); + grpLibs.setText(("Libraries_10")); //$NON-NLS-1$ + + Composite cmpLibs = new Composite(grpLibs, SWT.NONE); + cmpLibs.setLayout(createGridLayout(1, true, 2, 2)); + cmpLibs.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Composite cmpLibCtrls = new Composite(cmpLibs, SWT.NONE); + cmpLibCtrls.setLayout(createGridLayout(2, false, 2, 2)); + cmpLibCtrls.setLayoutData(new GridData(GridData.FILL_BOTH)); + + fLibs = new List(cmpLibCtrls, SWT.LEFT | SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); + fLibs.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Composite cmpLibButtons = new Composite(cmpLibCtrls, SWT.NONE); + cmpLibButtons.setLayout(createGridLayout(1, true, 2, 2)); + GridData gdLibBtns = new GridData(); + gdLibBtns.widthHint = BUTTON_WIDTH; + cmpLibButtons.setLayoutData(gdLibBtns); + + btnAddLib = new Button(cmpLibButtons, SWT.NULL); + btnAddLib.setText(("Add_12")); //$NON-NLS-1$ + btnAddLib.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + btnRemoveLib = new Button(cmpLibButtons, SWT.NULL); + btnRemoveLib.setText(("Remove_13")); //$NON-NLS-1$ + btnRemoveLib.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + btnMoveUp = new Button(cmpLibButtons, SWT.NULL); + btnMoveUp.setText(("Move_Up_14")); //$NON-NLS-1$ + btnMoveUp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + btnMoveDown = new Button(cmpLibButtons, SWT.NULL); + btnMoveDown.setText(("Move_Down_15")); //$NON-NLS-1$ + btnMoveDown.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + /* + * create the listener events the controls + * + */ + btnNew.addSelectionListener(m_addLibraryPath); + btnRemove.addSelectionListener(m_delLibraryPath); + + fLibPaths.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) { + int[] selection = fLibPaths.getSelectionIndices(); + btnRemove.setEnabled(selection.length > 0); + } + + } + ); + +// fLibPaths.addKeyListener(new KeyAdapter() +// { +// public void keyPressed(KeyEvent key) {} +// public void keyReleased(KeyEvent key) {} +// public void keyTyped(KeyEvent key) +// { +// if (key.keyCode == SWT.DEL) { +// m_delLibraryPath.widgetSelected(null); +// } +// else if (key.keyCode == SWT.INSERT) { +// m_addLibraryPath.widgetSelected(null); +// } +// } +// +// } +// ); + + btnAddLib.addSelectionListener(m_addLibraryFile); + btnRemoveLib.addSelectionListener(m_delLibraryFile); + + fLibs.addFocusListener(new FocusAdapter() + { + public void focusLost(FocusEvent e) { + // btnMoveDown.setEnabled(false); + // btnMoveUp.setEnabled(false); + super.focusLost(e); + } + } + ); + + fLibs.addSelectionListener(new SelectionAdapter() + { + public void widgetSelected(SelectionEvent e) { + + int[] selections = fLibs.getSelectionIndices(); + if (selections.length > 0) { + // see if we should enable the up button + btnMoveUp.setEnabled(selections[0] > 0); + btnMoveDown.setEnabled(selections[selections.length - 1] < fLibs.getItemCount() - 1); + btnRemoveLib.setEnabled(true); + } + else { + // don't enable the buttons if the user hasn't made any selections + btnMoveUp.setEnabled(false); + btnMoveDown.setEnabled(false); + btnRemoveLib.setEnabled(false); + } + + super.widgetSelected(e); + } + } + ); + + btnMoveDown.addSelectionListener(new moveLibs(1)); + btnMoveUp.addSelectionListener(new moveLibs(-1)); + + // the user hasn't made selections yet, so turn these buttons off + btnMoveDown.setEnabled(false); + btnMoveUp.setEnabled(false); + btnRemoveLib.setEnabled(false); + btnRemove.setEnabled(false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#initializeFrom(ICBuildConfig) + */ + public void initializeFrom(ICBuildConfig config) { + String output = ""; + String cmdLine = ""; + boolean isStatic = false; + boolean isShared = false; + boolean isStrip = false; + java.util.List libs = null; + java.util.List libPaths = null; + + try { + output = config.getAttribute(ICPosixBuildConstants.LD_OUTPUT, ""); + cmdLine = config.getAttribute(ICPosixBuildConstants.LD_USER_ARGS, ""); + isStatic = config.getAttribute(ICPosixBuildConstants.LD_LINK_STATIC, false); + isShared = config.getAttribute(ICPosixBuildConstants.LD_LINK_AS_SHARED, false); + isStrip = config.getAttribute(ICPosixBuildConstants.LD_STRIP, false); + libs = config.getAttribute(ICPosixBuildConstants.LD_LIBS, libs); + libPaths = config.getAttribute(ICPosixBuildConstants.LD_LIBPATHS, libPaths); + } catch (CoreException e) { + } + + fOutputFileName.setText(output); + fCmdLine.setText(cmdLine); + btnStatic.setSelection(isStatic); + btnSharedObject.setSelection(isShared); + btnStripSybmols.setSelection(isStrip); + setList(fLibs, libs); + setList(fLibs, libPaths); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#performApply(ICBuildConfigWorkingCopy) + */ + public void performApply(ICBuildConfigWorkingCopy config) { + config.setAttribute(ICPosixBuildConstants.LD_OUTPUT, readText(fOutputFileName)); + config.setAttribute(ICPosixBuildConstants.LD_USER_ARGS, readText(fCmdLine)); + config.setAttribute(ICPosixBuildConstants.LD_LIBS, getList(fLibs)); + config.setAttribute(ICPosixBuildConstants.LD_LIBPATHS, getList(fLibPaths)); + config.setAttribute(ICPosixBuildConstants.LD_LINK_STATIC, btnStatic.getSelection()); + config.setAttribute(ICPosixBuildConstants.LD_STRIP, btnStripSybmols.getSelection()); + + if (btnSharedObject.getSelection()) { + config.setAttribute(ICPosixBuildConstants.LD_LINK_AS_SHARED, true); + config.setAttribute(ICPosixBuildConstants.LD_LINK_AS_ARCHIVE, false); + config.setAttribute(ICPosixBuildConstants.LD_LINK_AS_PROGRAM, false); + } else { + config.setAttribute(ICPosixBuildConstants.LD_LINK_AS_SHARED, false); + config.setAttribute(ICPosixBuildConstants.LD_LINK_AS_ARCHIVE, false); + config.setAttribute(ICPosixBuildConstants.LD_LINK_AS_PROGRAM, true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#setDefaults(ICBuildConfigWorkingCopy) + */ + public void setDefaults(ICBuildConfigWorkingCopy configuration) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#isValid(ICBuildConfigWorkingCopy) + */ + public boolean isValid(ICBuildConfigWorkingCopy config) { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#getName() + */ + public String getName() { + return "Linker"; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabPreprocessor.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabPreprocessor.java new file mode 100644 index 00000000000..f5d24239e1c --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/gnu/tools/tabs/CTabPreprocessor.java @@ -0,0 +1,547 @@ +/********************************************************************** + * 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.gnu.tools.tabs; + +import java.util.Iterator; + +import org.eclipse.cdt.core.builder.model.ICBuildConfig; +import org.eclipse.cdt.core.builder.model.ICBuildConfigWorkingCopy; +import org.eclipse.cdt.core.builder.model.ICPosixBuildConstants; +import org.eclipse.cdt.ui.builder.ACToolTab; +import org.eclipse.cdt.ui.builder.internal.CBuildVariableDialog; +import org.eclipse.cdt.ui.builder.internal.CNameValueDialog; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Group; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + + +/** + * The control for editing and viewing compiler options. + */ +public class CTabPreprocessor extends ACToolTab { + private Table fDefineTable; + private Table fIncludeTable; + private Button btnIncludeAdd; + private Button btnIncludeRemove; + private Button btnIncludeMoveUp; + private Button btnIncludeMoveDown; + private Button btnDefineAdd; + private Button btnDefineRemove; + private Button btnDefineEdit; + private List fIncludePaths; + private List fDefineMacros; + + /** + * Constructs the object + * + * @param parent owning window + * @param style modal or not + */ + public CTabPreprocessor() { + super(); + } + + /** + * Helper function for creating a grid layout to spec. + * + * @param columns Number of columns in layout. + * @param equalWidth True if columns are of equal width. + * @param marginHeight Margin height for layout. + * @param marginWidth Margin width for layout. + * + * @return Newly created GridLayout with the specified properties. + */ + private GridLayout createGridLayout(int columns, boolean equalWidth, int marginHeight, int marginWidth) { + GridLayout layout = new GridLayout(columns, equalWidth); + layout.marginHeight = marginHeight; + layout.marginWidth = marginWidth; + return layout; + } + + /** + * "Add Include" button handler. + */ + private void handleIncludeAdd(SelectionEvent e) { + + TableItem[] existingItems = fIncludeTable.getItems(); + fIncludePaths.removeAll(); + for (int i = 0; i < fIncludeTable.getItemCount(); i++) { + fIncludePaths.add(existingItems[i].getText()); + } + + CBuildVariableDialog dlg = new CBuildVariableDialog(getShell(), ("Select_Include_Path_12")); //$NON-NLS-1$ + + if (dlg.open() == dlg.OK) { + TableItem item = new TableItem(fIncludeTable, SWT.NONE); + item.setText(dlg.getSelection().toString()); + fIncludeTable.select(fIncludeTable.indexOf(item)); + fIncludeTable.setFocus(); + } + + handleIncludeTableSelectionChanged(); + } + + /** + * "Remove Include" button handler. + */ + private void handleIncludeRemove(SelectionEvent e) { + handleTableRemove(fIncludeTable); + handleIncludeTableSelectionChanged(); + } + + + + /** + * "Move Up Include" button handler. + */ + private void handleIncludeMoveUp(SelectionEvent e) { + int itemIndex = fIncludeTable.getSelectionIndex(); + String itemText = fIncludeTable.getItem(itemIndex).getText(); + + fIncludeTable.remove(itemIndex); + + new TableItem(fIncludeTable, SWT.NONE, itemIndex - 1).setText(itemText); + + fIncludeTable.setFocus(); + fIncludeTable.select(itemIndex - 1); + + handleIncludeTableSelectionChanged(); + } + + /** + * "Move Down Include" button handler. + */ + private void handleIncludeMoveDown(SelectionEvent e) { + int itemIndex = fIncludeTable.getSelectionIndex(); + String itemText = fIncludeTable.getItem(itemIndex).getText(); + + fIncludeTable.remove(itemIndex); + + new TableItem(fIncludeTable, SWT.NONE, itemIndex + 1).setText(itemText); + + fIncludeTable.setFocus(); + fIncludeTable.select(itemIndex + 1); + + handleIncludeTableSelectionChanged(); + } + + /** + * Include table selection change handler. + */ + private void handleIncludeTableSelectionChanged() { + int itemIndex = fIncludeTable.getSelectionIndex(); + int itemCount = fIncludeTable.getItemCount(); + + // Add always enabled + btnIncludeAdd.setEnabled(true); + + // Remove enabled if > 1 item selected + btnIncludeRemove.setEnabled(-1 != itemIndex); + + // Move up/down enabled if: + // > 1 item in list + // 1 item selected + // Item is not first item (up) or last item (down) + + btnIncludeMoveUp.setEnabled((-1 != itemIndex) && (itemCount > 1) && (0 != itemIndex)); + btnIncludeMoveDown.setEnabled((-1 != itemIndex) && (itemCount > 1) && ((itemCount - 1) != itemIndex)); + } + + /** + * "Add Define" button handler. + */ + private void handleDefineAdd(SelectionEvent e) { + + TableItem[] existingItems = fDefineTable.getItems(); + fDefineMacros.removeAll(); + for (int i =0; i < fDefineTable.getItemCount(); i++) { + fDefineMacros.add(existingItems[i].getText()); + } + + CNameValueDialog dlg = new CNameValueDialog(getShell(), fDefineMacros); + + dlg.setTitle(("New_Preprocessor_Definition_13")); //$NON-NLS-1$ + + if (dlg.open() == dlg.OK) { + TableItem item = new TableItem(fDefineTable, SWT.NONE); + item.setText(0, dlg.getName()); + item.setText(1, dlg.getValue()); + fDefineTable.select(fDefineTable.indexOf(item)); + fDefineTable.setFocus(); + } + + handleDefineTableSelectionChanged(); + } + + /** + * "Remove Define" button handler. + */ + private void handleDefineRemove(SelectionEvent e) { + handleTableRemove(fDefineTable); + handleDefineTableSelectionChanged(); + } + + /** + * "Edit Define" button handler. + */ + private void handleDefineEdit(SelectionEvent e) { + int itemIndex = fDefineTable.getSelectionIndex(); + + if (-1 != itemIndex) { + TableItem item = fDefineTable.getItem(itemIndex); + + CNameValueDialog dlg = new CNameValueDialog(getShell()); + + dlg.setTitle(("Edit_Preprocessor_Definition_14")); //$NON-NLS-1$ + dlg.setName(item.getText(0)); + dlg.setValue(item.getText(1)); + + if (dlg.open() == dlg.OK) { + item.setText(0, dlg.getName()); + item.setText(1, dlg.getValue()); + } + + fDefineTable.select(itemIndex); + fDefineTable.setFocus(); + } + + handleDefineTableSelectionChanged(); + } + + /** + * Define table selection change handler. + */ + private void handleDefineTableSelectionChanged() { + TableItem[] items = fDefineTable.getSelection(); + + // Add always enabled + btnDefineAdd.setEnabled(true); + + // Remove enabled if > 1 item selected + btnDefineRemove.setEnabled((null != items) && (1 >= items.length)); + + // Edit enabled if exactly 1 item selected + btnDefineEdit.setEnabled((null != items) && (1 == items.length)); + } + + /** + * Generic "remove selected entry from table" method. + * + * @param Table to remove entry from. + */ + private void handleTableRemove(Table table) { + int itemIndex = table.getSelectionIndex(); + if (-1 != itemIndex) { + TableItem item = table.getItem(itemIndex); + item.dispose(); + int itemCount = table.getItemCount(); + table.select(0 == itemIndex ? 0 : (itemIndex >= itemCount ? itemCount - 1 : itemIndex)); + table.setFocus(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#createControl(Composite) + */ + public void createControl(Composite parent) { + Composite cmpGroup = null; + Composite cmpCtrls = null; + Composite cmpButtons = null; + Group group = null; + Table table = null; + Button button = null; + TableColumn column = null; + GridLayout gridLayout = null; + GridData gridData = null; + GC gc = null; + + Composite ths = new Composite(parent, SWT.NONE); + + // Panel + + ths.setLayout(new GridLayout()); + ths.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Initialize our list containing existing paths, + fIncludePaths = new List(parent, SWT.NONE); + fDefineMacros = new List(parent, SWT.NONE); + + // Includes + + group = new Group(ths, SWT.SHADOW_NONE); + group.setLayout(createGridLayout(1, true, 2, 2)); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + group.setText(("Include_Paths_1")); //$NON-NLS-1$ + + cmpGroup = new Composite(group, SWT.NONE); + cmpGroup.setLayout(createGridLayout(1, true, 2, 2)); + cmpGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + + cmpCtrls = new Composite(cmpGroup, SWT.NONE); + cmpCtrls.setLayout(createGridLayout(2, false, 2, 2)); + cmpCtrls.setLayoutData(new GridData(GridData.FILL_BOTH)); + + table = new Table(cmpCtrls, SWT.BORDER | SWT.SINGLE | SWT.HIDE_SELECTION); + table.setLayout(new GridLayout()); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + + table.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleIncludeTableSelectionChanged(); + } + }); + + fIncludeTable = table; + cmpButtons = new Composite(cmpCtrls, SWT.NONE); + gridLayout = createGridLayout(1, true, 2, 2); + gridData = new GridData(); + gc = new GC(cmpButtons); + + gc.setFont(cmpButtons.getFont()); + gridData.widthHint = gc.getFontMetrics().getAverageCharWidth() * 20; + gc.dispose(); + cmpButtons.setLayout(gridLayout); + cmpButtons.setLayoutData(gridData); + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Add_2")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleIncludeAdd(e); + } + }); + btnIncludeAdd = button; + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Remove_3")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleIncludeRemove(e); + } + }); + btnIncludeRemove = button; + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Move_Up_4")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleIncludeMoveUp(e); + } + }); + btnIncludeMoveUp = button; + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Move_Down_5")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleIncludeMoveDown(e); + } + }); + btnIncludeMoveDown = button; + + // Defines + + group = new Group(ths, SWT.SHADOW_NONE); + group.setLayout(createGridLayout(1, true, 2, 2)); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + group.setText(("Preprocessor_Definitions_6")); //$NON-NLS-1$ + + cmpGroup = new Composite(group, SWT.NONE); + cmpGroup.setLayout(createGridLayout(1, true, 2, 2)); + cmpGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + + cmpCtrls = new Composite(cmpGroup, SWT.NONE); + cmpCtrls.setLayout(createGridLayout(2, false, 2, 2)); + cmpCtrls.setLayoutData(new GridData(GridData.FILL_BOTH)); + + table = new Table(cmpCtrls, SWT.BORDER | SWT.SINGLE | SWT.HIDE_SELECTION); + TableLayout tblLayout = new TableLayout(); + table.setLayout(tblLayout); + table.setHeaderVisible(true); + table.setLinesVisible(true); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + + column = new TableColumn(table, SWT.NULL); + column.setText(("Name_7")); //$NON-NLS-1$ + tblLayout.addColumnData(new ColumnWeightData(30)); + + column = new TableColumn(table, SWT.NULL); + column.setText(("Value_8")); //$NON-NLS-1$ + tblLayout.addColumnData(new ColumnWeightData(30)); + + table.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleDefineTableSelectionChanged(); + } + }); + + fDefineTable = table; + cmpButtons = new Composite(cmpCtrls, SWT.NONE); + gridLayout = createGridLayout(1, true, 2, 2); + gridData = new GridData(); + gc = new GC(cmpButtons); + + gc.setFont(cmpButtons.getFont()); + gridData.widthHint = gc.getFontMetrics().getAverageCharWidth() * 20; + gc.dispose(); + cmpButtons.setLayout(gridLayout); + cmpButtons.setLayoutData(gridData); + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Add_9")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleDefineAdd(e); + } + }); + btnDefineAdd = button; + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Remove_10")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleDefineRemove(e); + } + }); + btnDefineRemove = button; + + button = new Button(cmpButtons, SWT.PUSH); + button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + button.setEnabled(true); + button.setText(("Edit_11")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleDefineEdit(e); + } + }); + btnDefineEdit = button; + + // Since no paths or macros have been added yet, disabled the following buttons. + btnDefineEdit.setEnabled(false); + btnDefineRemove.setEnabled(false); + btnIncludeMoveDown.setEnabled(false); + btnIncludeMoveUp.setEnabled(false); + btnIncludeRemove.setEnabled(false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#initializeFrom(ICBuildConfig) + */ + public void initializeFrom(ICBuildConfig config) { + + java.util.List includes = null; + java.util.List defines = null; + + try { + includes = config.getAttribute(ICPosixBuildConstants.CPP_INCLUDES, (java.util.List) null); + defines = config.getAttribute(ICPosixBuildConstants.CPP_DEFINITIONS, (java.util.List) null); + } catch (CoreException e) { + } + + if (includes != null) { + for (Iterator iter = includes.iterator(); iter.hasNext();) { + TableItem item = new TableItem(fIncludeTable, SWT.NONE); + item.setText((String) iter.next()); + } + } + + if (defines != null) { + for (Iterator iter = defines.iterator(); iter.hasNext();) { + TableItem item = new TableItem(fDefineTable, SWT.NONE); + + String define = (String) iter.next(); + int index = define.indexOf('='); + + if (-1 == index) { + item.setText(0, define.trim()); + } else { + item.setText(0, define.substring(0, index).trim()); + if (index < define.length()) { + item.setText(1, define.substring(index + 1).trim()); + } + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#performApply(ICBuildConfigWorkingCopy) + */ + public void performApply(ICBuildConfigWorkingCopy config) { + TableItem[] includes = fIncludeTable.getItems(); + TableItem[] defines = fDefineTable.getItems(); + java.util.List includeList = new java.util.Vector(); + java.util.List defineList = new java.util.Vector(); + + for (int i = 0; i < includes.length; i++) { + includeList.add(includes[i].getText()); + } + + for (int i = 0; i < defines.length; i++) { + String name = defines[i].getText(0); + String value = defines[i].getText(1); + if (value.length() > 0) { + defineList.add(name + "=" + value); + } else { + defineList.add(name); + } + } + + config.setAttribute(ICPosixBuildConstants.CPP_INCLUDES, includeList); + config.setAttribute(ICPosixBuildConstants.CPP_DEFINITIONS, defineList); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#setDefaults(ICBuildConfigWorkingCopy) + */ + public void setDefaults(ICBuildConfigWorkingCopy configuration) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#isValid(ICBuildConfigWorkingCopy) + */ + public boolean isValid(ICBuildConfigWorkingCopy config) { + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.builder.ICToolTab#getName() + */ + public String getName() { + return "Preprocessor"; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ACToolTab.java b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ACToolTab.java new file mode 100644 index 00000000000..9b5dcc1a15e --- /dev/null +++ b/core/org.eclipse.cdt.ui/build/org/eclipse/cdt/ui/builder/ACToolTab.java @@ -0,0 +1,195 @@ +/********************************************************************** + * 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.debug.internal.ui.SWTUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +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.Shell; + +/** + * Base tool tab implementation. + */ +public abstract class ACToolTab implements ICToolTab { + + /** + * The control for this page, or 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. + *

+ * 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 + * 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. + *

+ * 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 setConfigurationDialog + * is called. + *

+ * Implementors are responsible for ensuring that + * the created control can be accessed via getControl + *

+ * + * @param parent the parent composite + */ + public void createControl(Composite parent); + + /** + * Returns the top level control for this tab. + *

+ * May return null if the control + * has not been created yet. + *

+ * + * @return the top level control or 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. + *

+ * An error message should describe some error state, + * as opposed to a message which may simply provide instruction + * or information to the user. + *

+ * + * @return the error message, or null if none + */ + public String getErrorMessage(); + + /** + * Returns the current message for this tab. + *

+ * A message provides instruction or information to the + * user, as opposed to an error message which should + * describe some error state. + *

+ * + * @return the message, or 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. + *

+ * This information is typically used by the configuration dialog to + * decide when it is okay to save a configuration. + *

+ * + * @return whether this tab is in a state that allows the current + * configuration to be saved + */ + public boolean canSave(); + + /** + * Sets the configuration dialog that hosts this tab. This is the + * first method called on a configuration tab, and marks the beginning + * of this tab's lifecycle. + * + * @param dialog configuration dialog + */ + public void setConfigurationDialog(ICBuildConfigDialog dialog); + + /** + * Returns the name of this tab. + * + * @return the name of this tab + */ + public String getName(); + + /** + * Returns the image for this tab, or 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. + *

+ * 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 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.ui/schema/CToolTabGroup.exsd b/core/org.eclipse.cdt.ui/schema/CToolTabGroup.exsd new file mode 100644 index 00000000000..606c100dea1 --- /dev/null +++ b/core/org.eclipse.cdt.ui/schema/CToolTabGroup.exsd @@ -0,0 +1,101 @@ + + + + + + + + + [Enter description of this extension point] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a unique name that will be used to idenitfy this tab group. + + + + + + + name of a Java class implementing the ICToolConfigurationTabGroup +interface. + + + + + + + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + + + + + + + + +