diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml index e54cc6a881b..7294ce182ed 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml @@ -19,6 +19,7 @@ + diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd index 1e2ccbe535b..a5affee6f5c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd +++ b/build/org.eclipse.cdt.managedbuilder.core/schema/buildDefinitions.exsd @@ -108,6 +108,16 @@ + + + + Specifies the name of the class that implements IProjectBuildMacroSupplier + + + + + + @@ -338,6 +348,16 @@ + + + + Specifies the name of the class that implements IConfigurationBuildMacroSupplier + + + + + + @@ -1153,6 +1173,122 @@ Additional special types exist to flag options of special relevance to the build + + + + The value of this attribute should be set to the expression representing the builder variable format. For example, to generate macros with the ${macro} format, the attribute would contain ${=}. To generate macros with the @macro format, the attribute would contain @=. +This information would be used wile buildfile generation to keep the environment build macros unresolved in the makefile. +If the attribute is not specified or contains the empty string, this would mean that the builder can not treat environment variables as its own variables. In this case, the build macros that contain environment variables are resolved by MBS to their actual value. + + + + + + + Specifies whether the builder variables are case sensitive or not. Can be set to either "true" or "false". The default is "true". If the builder does not support case-sensitive variables and there are some build environment variables that differ only in case (Environment variables on Unix-like operating systems are case sensitive), then those macros will always get resolved in the buildfile. + + + + + + + Comma-separated list of reserved macro names. The macro name could contain either the exact name or the java regular expression. The latter could be used to supply the pattern of variable names that are generated by MBS in case the "buildVariable" attribute of the "InputType" element is not specified, etc. +If this attribute is specified and the reservedMacroNameSupplier is not specified, the following macro names will be treated as reserved: +1. a macro name that is equal to one of the names specified in the reservedMacroNames value +2. a macro name that matches one of the regexp patterns specified in the reservedMacroNames value +3. a macro name that is equal to one of the build variable names specified InputType elements of the tools used in the tool-chain +If this attribute is not specified, MBS will assume that there are no reserved macro names that could conflict with the build environment variable macros, except names specified in the "buildVariable" attribute of the "InputType" elements: these names will always be treated as reserved + + + + + + + Should be set to the name of the class that implements the IReservedMacroNameSupplier interface. If this attribute is specified the reservedMacroNames attribute is ignored, and the following macro names will be treated as reserved: +1. macro names that the IReservedMacroNamesSupplier specifies as reserved +2. a macro name that is equal to one of the build variable names specified int the InputType elements of the tools used in the tool-chain + + + + + + + + + + Represents the InputFileName macro value. The macro specifies the input file name. The input file has the following meaning: +1. If a tool does not accept building multiple files of the primary input type with one tool invocation, the input file is the file of the primary input type being built. +2. If a tool accepts building multiple files of the primary input type with one tool invocation the input file is undefined and the macros representing the input file contain information about one of the inputs of the primary input type being built. + + + + + + + + Represents the InputFileExt macro value. The macro specifies the extension of the input file. + + + + + + + Represents the InputFileBaseName macro value. The macro specifies the base name of the input file. That is the file name with an extension stripped. + + + + + + + Represents the InputFileRelPath macro value. The macro specifies the input file path relative to the builder current directory. + + + + + + + Represents the InputDirRelPath macro value. The macro specifies the input file directory path relative to the builder current directory. + + + + + + + Represents the OutputFileName macro value. The macro specifies the output file name. The output file has the following meaning: +1. If a tool is not capable of producing multiple files of the primary output type with one tool invocation the output file is the file of the primary output type that is built with a given tool invocation. +2. If a tool is capable of producing multiple files of the primary output type with one tool invocation the output file is undefined and the macros representing the output file contain information about one of the files of the primary output type that are built with a given tool invocation. + + + + + + + + Represents the OutputFileExt macro value. The macro specifies the output file extension. + + + + + + + Represents the OutputFileBaseName macro value. The macro specifies the output file base name. That is the output file name with an extension stripped. + + + + + + + Represents the OutputFileRelPath macro value. The macro specifies the output file path relative to the current builder directory. + + + + + + + Represents the OutputDirRelPath macro value. The macro specifies the output file directory path relative to the current builder directory. + + + @@ -1281,12 +1417,20 @@ Version identifier for the managed build extension point. It is a string represe - + The build path type. Can be one of the following: "buildpathInclude", "buildpathLibrary" + + + + + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuilder.java index e325c1793d2..7ac7902b3a9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IBuilder.java @@ -10,11 +10,13 @@ **********************************************************************/ package org.eclipse.cdt.managedbuilder.core; +import org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues; +import org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier; import org.eclipse.core.runtime.IConfigurationElement; /** * This class represents the utility that drives the build process - * (typically, but not necessarily, a variant of “make”). It defines + * (typically, but not necessarily, a variant of "make"). It defines * the command needed to invoke the build utility in the command attribute. * Any special flags that need to be passed to the builder are defined * in the arguments attribute. The builder can specify the error parser(s) @@ -32,6 +34,12 @@ public interface IBuilder extends IBuildObject { public static final String VERSIONS_SUPPORTED = "versionsSupported"; //$NON-NLS-1$ public static final String CONVERT_TO_ID = "convertToId"; //$NON-NLS-1$ + public static final String VARIABLE_FORMAT = "variableFormat"; //$NON-NLS-1$ + public static final String IS_VARIABLE_CASE_SENSITIVE = "isVariableCaseSensitive"; //$NON-NLS-1$ + public static final String RESERVED_MACRO_NAMES = "reservedMacroNames"; //$NON-NLS-1$ + public static final String RESERVED_MACRO_NAME_SUPPLIER = "reservedMacroNameSupplier"; //$NON-NLS-1$ + + /** * Returns the command line arguments to pass to the build/make utility used @@ -192,4 +200,40 @@ public interface IBuilder extends IBuildObject { */ public void setConvertToId(String convertToId); + /** + * Returns the IFileContextBuildMacroValues interface reference that specifies + * the file-context macro-values provided by the tool-integrator + * + * @return IFileContextBuildMacroValues + */ + public IFileContextBuildMacroValues getFileContextBuildMacroValues(); + + /** + * Returns String representing the build variable pattern to be used while makefile generation + * + * @return String + */ + public String getBuilderVariablePattern(); + + /** + * Returns whether the builder supports case sensitive variables or not + * + * @return boolean + */ + public boolean isVariableCaseSensitive(); + + /** + * Returns an array of Strings representing the patterns of the builder/buildfile-generator + * reserved variables + * + * @return String[] + */ + public String[] getReservedMacroNames(); + + /** + * Returns the tool-integrator defined implementation of the IReservedMacroNameSupplier + * to be used for detecting the builder/buildfile-generator reserved variables + * @return IReservedMacroNameSupplier + */ + public IReservedMacroNameSupplier getReservedMacroNameSupplier(); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java index 8cfd99aa511..8aa56652ce1 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IConfiguration.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.managedbuilder.core; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; @@ -452,4 +453,13 @@ public interface IConfiguration extends IBuildObject { * @return IConfigurationEnvironmentVariableSupplier */ public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(); + + /** + * Returns the tool-integrator provided implementation of the configuration build macro supplier + * or null if none. + * + * @return IConfigurationBuildMacroSupplier + */ + public IConfigurationBuildMacroSupplier getBuildMacroSupplier(); + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java index 7e0303d843f..c93dd202c62 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IManagedBuildInfo.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.managedbuilder.core; import java.util.List; import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; +import org.eclipse.core.runtime.IPath; /* * There is a ManagedBuildInfo per CDT managed build project. Here are @@ -55,6 +56,14 @@ public interface IManagedBuildInfo { /** * Returns IManagedCommandLineInfo for source with extension + * The command line info contains values with + * build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * command line info contains values contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the command line info contains values contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * * @param sourceExtension - source extension * @param flags - build flags * @param outputFlag - output flag for build tool @@ -62,10 +71,35 @@ public interface IManagedBuildInfo { * @param outputName * @param inputResources * @return IManagedCommandLineInfo + * + * @deprecated - use generateToolCommandLineInfo instead */ public IManagedCommandLineInfo generateCommandLineInfo( String sourceExtension, String[] flags, String outputFlag, String outputPrefix, String outputName, String[] inputResources ); + /** + * Returns IManagedCommandLineInfo for source with extension + * The command line info contains values with + * build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * command line info contains values contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the command line info contains values contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param sourceExtension + * @param flags + * @param outputFlag + * @param outputPrefix + * @param outputName + * @param inputResources + * @param inputLocation + * @param outputLocation + * @return + */ + public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, + String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ); + /** * Answers a String containing the arguments to be passed to make. * For example, if the user has selected a build that keeps going on error, the @@ -164,22 +198,74 @@ public interface IManagedBuildInfo { * Returns a String containing the flags, including * those overridden by the user, for the tool in the configuration * defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved * * @param extension * @return + * + * @deprecated - use getToolFlagsForConfiguration */ public String getFlagsForConfiguration(String extension); + /** + * Returns a String containing the flags, including + * those overridden by the user, for the tool in the configuration + * defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param extension + * @param inputLocation + * @param outputLocation + * @return + */ + public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation); + /** * Returns a String containing the flags, including * those overridden by the user, for the tool that handles the * type of source file defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved * * @param extension * @return + * + * @deprecated - use getToolFlagsForSource */ public String getFlagsForSource(String extension); + /** + * Returns a String containing the flags, including + * those overridden by the user, for the tool that handles the + * type of source file defined by the argument. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param extension + * @param inputLocation + * @param outputLocation + * @return + */ + public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation); + /** * Answers the libraries the project links in. * diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java index 993669bd3b0..03679ec48e4 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IProjectType.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.managedbuilder.core; import org.eclipse.cdt.managedbuilder.envvar.IProjectEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.macros.IProjectBuildMacroSupplier; /** * This class represents project-types in the managed build system. @@ -25,7 +26,7 @@ import org.eclipse.cdt.managedbuilder.envvar.IProjectEnvironmentVariableSupplier * sharing of configurations. If you have defined a project type that * should not be selected by the user, but is a root for other project * types, it may be declared abstract by setting the isAbstract attribute - * to ‘true’. Abstract project types do not appear in the UI. You must + * to 'true'. Abstract project types do not appear in the UI. You must * provide a unique identifier for the project type in the id attribute. * Children of the abstract project type will have the same configurations * that the abstract project type has, unless they are explicitly named @@ -48,6 +49,7 @@ public interface IProjectType extends IBuildObject { public static final String IS_TEST = "isTest"; //$NON-NLS-1$ public static final String CONFIGURATION_NAME_PROVIDER = "configurationNameProvider"; //$NON-NLS-1$ public static final String PROJECT_ENVIRONMENT_SUPPLIER = "projectEnvironmentSupplier"; //$NON-NLS-1$ + public static final String PROJECT_MACRO_SUPPLIER = "projectMacroSupplier"; //$NON-NLS-1$ /** * Creates a configuration for this project-type populated with the tools @@ -154,4 +156,12 @@ public interface IProjectType extends IBuildObject { * @return IProjectEnvironmentVariableSupplier */ public IProjectEnvironmentVariableSupplier getEnvironmentVariableSupplier(); + + /** + * Returns the tool-integrator provided implementation of the project build macro supplier + * or null if none. + * + * @return IProjectBuildMacroSupplier + */ + public IProjectBuildMacroSupplier getBuildMacroSupplier(); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java index 81d8efe4de8..97b4860a800 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ITool.java @@ -44,6 +44,7 @@ public interface ITool extends IBuildObject { public static final String ANNOUNCEMENT = "announcement"; //$NON-NLS-1$ public static final String TOOL_ELEMENT_NAME = "tool"; //$NON-NLS-1$ public static final String WHITE_SPACE = " "; //$NON-NLS-1$ + public static final String EMPTY_STRING = ""; //$NON-NLS-1$ public static final String VERSIONS_SUPPORTED = "versionsSupported"; //$NON-NLS-1$ public static final String CONVERT_TO_ID = "convertToId"; //$NON-NLS-1$ @@ -629,19 +630,70 @@ public interface ITool extends IBuildObject { /** * Returns an array of command line arguments that have been specified for * the tool. + * The flags contain build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the flags contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the flags contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * * @return String[] * @throws BuildException + * + * @deprecated - use getToolCommandFlags instead */ public String[] getCommandFlags() throws BuildException; /** * Returns the command line arguments that have been specified for * the tool. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved * * @return String + * + * @deprecated - use getToolCommandFlagsString instead */ public String getToolFlags() throws BuildException ; + /** + * Returns an array of command line arguments that have been specified for + * the tool. + * The flags contain build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the flags contain all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the flags contain + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param inputFileLocation + * @param outputFileLocation + * @return + * @throws BuildException + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException; + + /** + * Returns the command line arguments that have been specified for + * the tool. + * The string contains build macros resolved to the makefile format. + * That is if a user has chosen to expand all macros in the buildfile, + * the string contains all macro references resolved, otherwise, if a user has + * chosen to keep the environment build macros unresolved, the string contains + * the environment macro references converted to the buildfile variable format, + * all other macro references are resolved + * + * @param inputFileLocation + * @param outputFileLocation + * @return + * @throws BuildException + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException; + /** * Options are organized into categories for UI purposes. * These categories are organized into a tree. This is the root diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java index ff6da2e3fcd..1011e74a34a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/IToolChain.java @@ -11,11 +11,12 @@ package org.eclipse.cdt.managedbuilder.core; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; /** * This interface represents a tool-integrator-defined, ordered set of tools - * that transform the project’s input into the project’s outputs. A + * that transform the project's input into the project's outputs. A * tool-chain can be defined as part of a configuration, or as an * independent specification that is referenced in a separate configuration * via the toolChain superclass attribute. @@ -24,7 +25,7 @@ import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSu * the tools used in the tool-chain. The toolChain contains one child of * type targetPlatform. This defines the architecture/os combination where * the outputs of the project can be deployed. The toolChain contains one - * child of type builder. This defines the “build” or “make” utility that + * child of type builder. This defines the "build" or "make" utility that * is used to drive the transformation of the inputs into outputs. * * @since 2.1 @@ -40,6 +41,7 @@ public interface IToolChain extends IBuildObject { public static final String SECONDARY_OUTPUTS = "secondaryOutputs"; //$NON-NLS-1$ public static final String IS_TOOL_CHAIN_SUPPORTED = "isToolChainSupported"; //$NON-NLS-1$ public static final String CONFIGURATION_ENVIRONMENT_SUPPLIER = "configurationEnvironmentSupplier"; //$NON-NLS-1$ + public static final String CONFIGURATION_MACRO_SUPPLIER = "configurationMacroSupplier"; //$NON-NLS-1$ // The attribute name for the scanner info collector public static final String SCANNER_CONFIG_PROFILE_ID = "scannerConfigDiscoveryProfileId"; //$NON-NLS-1$ @@ -352,4 +354,12 @@ public interface IToolChain extends IBuildObject { * @return IConfigurationEnvironmentVariableSupplier */ public IConfigurationEnvironmentVariableSupplier getEnvironmentVariableSupplier(); + + /** + * Returns the tool-integrator provided implementation of the configuration build macro supplier + * or null if none. + * + * @return IConfigurationBuildMacroSupplier + */ + public IConfigurationBuildMacroSupplier getBuildMacroSupplier(); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java index 971cfec298d..f06ca93114f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java @@ -49,21 +49,23 @@ import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; import org.eclipse.cdt.managedbuilder.internal.core.Builder; import org.eclipse.cdt.managedbuilder.internal.core.Configuration; import org.eclipse.cdt.managedbuilder.internal.core.DefaultManagedConfigElement; +import org.eclipse.cdt.managedbuilder.internal.core.InputType; import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo; import org.eclipse.cdt.managedbuilder.internal.core.ManagedCommandLineGenerator; import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject; import org.eclipse.cdt.managedbuilder.internal.core.Option; import org.eclipse.cdt.managedbuilder.internal.core.OptionCategory; -import org.eclipse.cdt.managedbuilder.internal.core.ProjectType; -import org.eclipse.cdt.managedbuilder.internal.core.InputType; import org.eclipse.cdt.managedbuilder.internal.core.OutputType; +import org.eclipse.cdt.managedbuilder.internal.core.ProjectType; import org.eclipse.cdt.managedbuilder.internal.core.ResourceConfiguration; import org.eclipse.cdt.managedbuilder.internal.core.Target; import org.eclipse.cdt.managedbuilder.internal.core.TargetPlatform; import org.eclipse.cdt.managedbuilder.internal.core.Tool; import org.eclipse.cdt.managedbuilder.internal.core.ToolChain; import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.cdt.managedbuilder.makegen.gnu.GnuMakefileGenerator; import org.eclipse.cdt.managedbuilder.projectconverter.UpdateManagedProjectManager; @@ -2048,4 +2050,14 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI public static IEnvironmentVariableProvider getEnvironmentVariableProvider(){ return EnvironmentVariableProvider.getDefault(); } + + /** + * Returns the instance of the Build Macro Provider + * + * @return IBuildMacroProvider + */ + public static IBuildMacroProvider getBuildMacroProvider(){ + return BuildMacroProvider.getDefault(); + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IConfigurationEnvironmentVariableSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IConfigurationEnvironmentVariableSupplier.java index 9fd80574782..e490b010216 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IConfigurationEnvironmentVariableSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IConfigurationEnvironmentVariableSupplier.java @@ -22,7 +22,7 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; public interface IConfigurationEnvironmentVariableSupplier{ /** * - * @param variableName the variable mane + * @param variableName the variable name * @param configuration configuration * @param provider the instance of the environment variable provider to be used for querying the * environment variables from within the supplier. The supplier should use this provider to obtain diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IEnvironmentVariableSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IEnvironmentVariableSupplier.java index 257ad01bf97..df91a5f34e3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IEnvironmentVariableSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IEnvironmentVariableSupplier.java @@ -18,7 +18,7 @@ public interface IEnvironmentVariableSupplier { /** * - * @param name the variable mane + * @param name the variable name * @param context the context * @return the reference to the IBuildEnvironmentVariable interface representing * the variable of a given name diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IProjectEnvironmentVariableSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IProjectEnvironmentVariableSupplier.java index fb1b3cc789c..da10547486f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IProjectEnvironmentVariableSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/envvar/IProjectEnvironmentVariableSupplier.java @@ -22,7 +22,7 @@ import org.eclipse.cdt.managedbuilder.core.IManagedProject; public interface IProjectEnvironmentVariableSupplier{ /** * - * @param variableName the variable mane + * @param variableName the variable name * @param project the managed project * @param provider the instance of the environment variable provider to be used for querying the * environment variables from within the supplier. The supplier should use this provider to obtain diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java index 94f368d91f6..2f7e01a1939 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java @@ -15,11 +15,15 @@ import java.util.List; import java.util.StringTokenizer; import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IProjectType; -import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.core.IProjectType; +import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextBuildMacroValues; +import org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues; +import org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -42,6 +46,12 @@ public class Builder extends BuildObject implements IBuilder { private IConfigurationElement buildFileGeneratorElement; private String versionsSupported; private String convertToId; + private FileContextBuildMacroValues fileContextBuildMacroValues; + private String builderVariablePattern; + private Boolean isVariableCaseSensitive; + private String[] reservedMacroNames; + private IReservedMacroNameSupplier reservedMacroNameSupplier; + private IConfigurationElement reservedMacroNameSupplierElement; // Miscellaneous private boolean isExtensionBuilder = false; @@ -152,6 +162,22 @@ public class Builder extends BuildObject implements IBuilder { } buildFileGeneratorElement = builder.buildFileGeneratorElement; + if(builder.fileContextBuildMacroValues != null){ + fileContextBuildMacroValues = (FileContextBuildMacroValues)builder.fileContextBuildMacroValues.clone(); + fileContextBuildMacroValues.setBuilder(this); + } + + builderVariablePattern = builder.builderVariablePattern; + + if(builder.isVariableCaseSensitive != null) + isVariableCaseSensitive = new Boolean(builder.isVariableCaseSensitive.booleanValue()); + + if(builder.reservedMacroNames != null) + reservedMacroNames = (String[])builder.reservedMacroNames.clone(); + + reservedMacroNameSupplierElement = builder.reservedMacroNameSupplierElement; + reservedMacroNameSupplier = builder.reservedMacroNameSupplier; + setDirty(true); } @@ -186,6 +212,26 @@ public class Builder extends BuildObject implements IBuilder { // Get the 'convertToId' attribute convertToId = element.getAttribute(CONVERT_TO_ID); + // get the 'variableFormat' attribute + builderVariablePattern = element.getAttribute(VARIABLE_FORMAT); + + // get the 'isVariableCaseSensitive' attribute + String isCS = element.getAttribute(IS_VARIABLE_CASE_SENSITIVE); + if(isCS != null) + isVariableCaseSensitive = new Boolean("true".equals(isCS)); //$NON-NLS-1$ + + // get the reserved macro names + String reservedNames = element.getAttribute(RESERVED_MACRO_NAMES); + if(reservedNames != null) + reservedMacroNames = reservedNames.split(","); //$NON-NLS-1$ + + // Get the reservedMacroNameSupplier configuration element + String reservedMacroNameSupplier = element.getAttribute(RESERVED_MACRO_NAME_SUPPLIER); + if(reservedMacroNameSupplier != null && element instanceof DefaultManagedConfigElement){ + reservedMacroNameSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + + // isAbstract String isAbs = element.getAttribute(IProjectType.IS_ABSTRACT); if (isAbs != null){ @@ -206,6 +252,9 @@ public class Builder extends BuildObject implements IBuilder { if (buildfileGenerator != null && element instanceof DefaultManagedConfigElement) { buildFileGeneratorElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); } + + //load the File Context Build Macro Values + fileContextBuildMacroValues = new FileContextBuildMacroValues(this,element); } /* (non-Javadoc) @@ -618,4 +667,58 @@ public class Builder extends BuildObject implements IBuilder { return; } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuilder#getFileContextBuildMacroValues() + */ + public IFileContextBuildMacroValues getFileContextBuildMacroValues(){ + if(fileContextBuildMacroValues == null && superClass != null) + return superClass.getFileContextBuildMacroValues(); + return fileContextBuildMacroValues; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuilder#getBuilderVariablePattern() + */ + public String getBuilderVariablePattern(){ + if(builderVariablePattern == null && superClass != null) + return superClass.getBuilderVariablePattern(); + return builderVariablePattern; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuilder#isVariableCaseSensitive() + */ + public boolean isVariableCaseSensitive(){ + if(isVariableCaseSensitive == null){ + if(superClass != null) + return superClass.isVariableCaseSensitive(); + return true; + } + return isVariableCaseSensitive.booleanValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuilder#getReservedMacroNames() + */ + public String[] getReservedMacroNames(){ + if(reservedMacroNames == null && superClass != null) + return superClass.getReservedMacroNames(); + return reservedMacroNames; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IBuilder#getReservedMacroNameSupplier() + */ + public IReservedMacroNameSupplier getReservedMacroNameSupplier(){ + if(reservedMacroNameSupplier == null && reservedMacroNameSupplierElement != null){ + try{ + reservedMacroNameSupplier = (IReservedMacroNameSupplier)reservedMacroNameSupplierElement.createExecutableExtension(RESERVED_MACRO_NAME_SUPPLIER); + }catch(CoreException e){ + } + } + if(reservedMacroNameSupplier == null && superClass != null) + return superClass.getReservedMacroNameSupplier(); + return reservedMacroNameSupplier; + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java index 565e58227c6..a2f48fe1287 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.core.ResourceConfiguration; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -298,7 +299,7 @@ public class Configuration extends BuildObject implements IConfiguration { // For each tool element child of the tool-chain that is the child of // the selected configuration element, create a tool element child of - // the cloned configuration’s tool-chain element that specifies the + // the cloned configuration's tool-chain element that specifies the // original tool element as its superClass. Iterator iter = superChain.getToolList().listIterator(); while (iter.hasNext()) { @@ -1355,4 +1356,16 @@ public class Configuration extends BuildObject implements IConfiguration { return toolChain.getEnvironmentVariableSupplier(); return null; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IConfiguration#getBuildMacroSupplier() + */ + public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ + IToolChain toolChain = getToolChain(); + if(toolChain != null) + return toolChain.getBuildMacroSupplier(); + return null; + + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java index 1006ac31fe1..05d1a8f4352 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java @@ -31,6 +31,8 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -75,10 +77,35 @@ public class GeneratedMakefileBuilder extends ACBuilder { public ResourceDeltaVisitor(IManagedBuildInfo info) { buildInfo = info; String ext = buildInfo.getBuildArtifactExtension(); + //try to resolve build macros in the build artifact extension + try{ + ext = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + ext, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + String name = buildInfo.getBuildArtifactName(); + //try to resolve build macros in the build artifact name + try{ + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + name, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + name = resolved; + } catch (BuildMacroException e){ + } + if (ext.length() > 0) { - buildGoalName = buildInfo.getOutputPrefix(ext) + buildInfo.getBuildArtifactName() + "." + ext; //$NON-NLS-1$ + buildGoalName = buildInfo.getOutputPrefix(ext) + name + "." + ext; //$NON-NLS-1$ } else { - buildGoalName = buildInfo.getBuildArtifactName(); + buildGoalName = name; } reservedNames = Arrays.asList(new String[]{".cdtbuild", ".cdtproject", ".project"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } @@ -558,7 +585,21 @@ public class GeneratedMakefileBuilder extends ACBuilder { } // Flag to the user that make is about to be called - IPath makeCommand = new Path(info.getBuildCommand()); + String makeCmd = info.getBuildCommand(); + //try to resolve the build macros in the builder command + try{ + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + makeCmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + makeCmd = resolved; + } catch (BuildMacroException e){ + } + + IPath makeCommand = new Path(makeCmd); if (makeCommand != null) { String[] msgs = new String[2]; msgs[0] = makeCommand.toString(); @@ -609,12 +650,18 @@ public class GeneratedMakefileBuilder extends ACBuilder { // Set the environmennt IBuildEnvironmentVariable variables[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true); + IBuildMacroProvider macroProvier = ManagedBuildManager.getBuildMacroProvider(); String[] env = null; ArrayList envList = new ArrayList(); if (variables != null) { for(int i = 0; i < variables.length; i++){ + //resolve the build macros in environment variables + try{ + envList.add(variables[i].getName() + "=" + macroProvier.resolveValue(variables[i].getValue(),""," ",IBuildMacroProvider.CONTEXT_CONFIGURATION,cfg)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + }catch(BuildMacroException e){ envList.add(variables[i].getName() + "=" + variables[i].getValue()); //$NON-NLS-1$ } + } env = (String[]) envList.toArray(new String[envList.size()]); } @@ -637,6 +684,16 @@ public class GeneratedMakefileBuilder extends ACBuilder { String[] makeTargets; String prebuildStep = info.getPrebuildStep(); + //try to resolve the build macros in the prebuildStep + try{ + prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + prebuildStep, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + cfg); + } catch (BuildMacroException e){ + } boolean prebuildStepPresent = (prebuildStep.length() > 0); Process proc = null; boolean isuptodate = false; diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java index 92fa003c498..4126cf0356c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java @@ -43,7 +43,10 @@ import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -337,13 +340,20 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForSource(java.lang.String) */ public String getFlagsForSource(String extension) { + return getToolFlagsForSource(extension,null,null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForSource(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolFlagsForSource(String extension, IPath inputLocation, IPath outputLocation){ // Get all the tools for the current config ITool[] tools = getFilteredTools(); for (int index = 0; index < tools.length; index++) { ITool tool = tools[index]; if (tool != null && tool.buildsFileType(extension)) { try { - return tool.getToolFlags(); + return tool.getToolCommandFlagsString(inputLocation,outputLocation); } catch (BuildException e) { return null; } @@ -356,6 +366,13 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getFlagsForConfiguration(java.lang.String) */ public String getFlagsForConfiguration(String extension) { + return getToolFlagsForConfiguration(extension, null, null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#getToolFlagsForConfiguration(java.lang.String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolFlagsForConfiguration(String extension, IPath inputLocation, IPath outputLocation){ // Treat null extensions as an empty string String ext = extension == null ? new String() : extension; @@ -365,7 +382,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { ITool tool = tools[index]; if (tool.producesFileType(ext)) { try { - return tool.getToolFlags(); + return tool.getToolCommandFlagsString(inputLocation,outputLocation); } catch (BuildException e) { return null; } @@ -723,12 +740,35 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { public IManagedCommandLineInfo generateCommandLineInfo( String sourceExtension, String[] flags, String outputFlag, String outputPrefix, String outputName, String[] inputResources) { + return generateToolCommandLineInfo( sourceExtension, flags, + outputFlag, outputPrefix, outputName, inputResources, null, null ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#generateToolCommandLineInfo(java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public IManagedCommandLineInfo generateToolCommandLineInfo( String sourceExtension, String[] flags, + String outputFlag, String outputPrefix, String outputName, String[] inputResources, IPath inputLocation, IPath outputLocation ){ ITool[] tools = getFilteredTools(); for (int index = 0; index < tools.length; index++) { ITool tool = tools[index]; if (tool.buildsFileType(sourceExtension)) { + String cmd = tool.getToolCommand(); + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(inputLocation,outputLocation,null,getDefaultConfiguration().getToolChain())); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - return gen.generateCommandLineInfo( tool, tool.getToolCommand(), + return gen.generateCommandLineInfo( tool, cmd, flags, outputFlag, outputPrefix, outputName, inputResources, tool.getCommandLinePattern() ); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java index b7c52a5001a..55a111da89b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedProject.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2004 Intel Corporation and others. + * Copyright (c) 2004, 2005 Intel 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 @@ -22,6 +22,7 @@ import org.eclipse.cdt.managedbuilder.core.IManagedProject; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IncrementalProjectBuilder; @@ -49,6 +50,8 @@ public class ManagedProject extends BuildObject implements IManagedProject { private boolean isDirty = false; private boolean isValid = true; private boolean resolved = true; + //holds the user-defined macros + private StorableMacros userDefinedMacros; /* * C O N S T R U C T O R S @@ -103,7 +106,11 @@ public class ManagedProject extends BuildObject implements IManagedProject { Node configElement = configElements.item(i); if (configElement.getNodeName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME)) { Configuration config = new Configuration(this, (Element)configElement); + }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { + //load user-defined macros + userDefinedMacros = new StorableMacros((Element)configElement); } + } } else { setValid(false); @@ -168,6 +175,13 @@ public class ManagedProject extends BuildObject implements IManagedProject { config.serialize(doc, configElement); } + //serialize user-defined macros + if(userDefinedMacros != null){ + Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); + element.appendChild(macrosElement); + userDefinedMacros.serialize(doc,macrosElement); + } + // I am clean now isDirty = false; } @@ -380,6 +394,11 @@ public class ManagedProject extends BuildObject implements IManagedProject { // If I need saving, just say yes if (isDirty) return true; + //check whether the project - specific macros are dirty + if(userDefinedMacros != null && userDefinedMacros.isDirty()) + return true; + + // Otherwise see if any configurations need saving Iterator iter = getConfigurationList().listIterator(); while (iter.hasNext()) { @@ -421,4 +440,14 @@ public class ManagedProject extends BuildObject implements IManagedProject { this.isValid = isValid; } + /* + * this method is called by the UserDefinedMacroSupplier to obtain user-defined + * macros available for this managed project + */ + public StorableMacros getUserDefinedMacros(){ + if(userDefinedMacros == null) + userDefinedMacros = new StorableMacros(); + return userDefinedMacros; + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties index 4fef4b4ba0e..4a59fd107bc 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties @@ -82,4 +82,18 @@ GnuMakefileGenerator.message.postproc.dep.file=Verifying contents of dependency # Tool strings Tool.default.announcement=Invoking: #Environment loader messages -StorableEnvironmentLoader.storeOutputStream.wrong.arguments="Wrong arguments" +StorableEnvironmentLoader.storeOutputStream.wrong.arguments=Wrong arguments + +#User Defined Macro Supplier +UserDefinedMacroSupplier.storeOutputStream.wrong.arguments=Failed to persist macros: Wrong arguments + +# BuildMacroStatus messages +BuildMacroStatus.status.macro.undefined=Macro {0} is undefined +BuildMacroStatus.status.reference.eachother=Macros {0} and {1} reference each other +BuildMacroStatus.status.reference.incorrect=Macro {0} reference is incorrect +BuildMacroStatus.status.macro.not.string=Macro {0} is not of String type +BuildMacroStatus.status.macro.not.stringlist=Macro {0} is not of String-list type +BuildMacroStatus.status.error=Error occured +BuildMacroStatus.value.undefined= + + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java index bdb556b572d..70156a4c1e3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ProjectType.java @@ -21,9 +21,10 @@ import org.eclipse.cdt.managedbuilder.core.IProjectType; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IProjectEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.macros.IProjectBuildMacroSupplier; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.cdt.managedbuilder.envvar.IProjectEnvironmentVariableSupplier; public class ProjectType extends BuildObject implements IProjectType { @@ -46,6 +47,8 @@ public class ProjectType extends BuildObject implements IProjectType { private IConfigurationElement environmentVariableSupplierElement = null; private IProjectEnvironmentVariableSupplier environmentVariableSupplier = null; + private IConfigurationElement buildMacroSupplierElement = null; + private IProjectBuildMacroSupplier buildMacroSupplier = null; // Miscellaneous private boolean resolved = true; @@ -159,6 +162,13 @@ public class ProjectType extends BuildObject implements IProjectType { if(environmentVariableSupplier != null && element instanceof DefaultManagedConfigElement){ environmentVariableSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); } + + // Get the buildMacroSupplier configuration element + String buildMacroSupplier = element.getAttribute(PROJECT_MACRO_SUPPLIER); + if(buildMacroSupplier != null && element instanceof DefaultManagedConfigElement){ + buildMacroSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + } /* @@ -463,4 +473,38 @@ public class ProjectType extends BuildObject implements IProjectType { } return null; } + + /** + * Returns the plugin.xml element of the projectMacroSupplier extension or null if none. + * + * @return IConfigurationElement + */ + public IConfigurationElement getBuildMacroSupplierElement(){ + if (buildMacroSupplierElement == null) { + if (superClass != null && superClass instanceof ProjectType) { + return ((ProjectType)superClass).getBuildMacroSupplierElement(); + } + } + return buildMacroSupplierElement; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IProjectType#getBuildMacroSupplier() + */ + public IProjectBuildMacroSupplier getBuildMacroSupplier(){ + if (buildMacroSupplier != null) { + return buildMacroSupplier; + } + IConfigurationElement element = getBuildMacroSupplierElement(); + if (element != null) { + try { + if (element.getAttribute(PROJECT_MACRO_SUPPLIER) != null) { + buildMacroSupplier = (IProjectBuildMacroSupplier) element.createExecutableExtension(PROJECT_MACRO_SUPPLIER); + return buildMacroSupplier; + } + } catch (CoreException e) {} + } + return null; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java index a55bd8d726b..d06d5c95c8f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java @@ -22,17 +22,23 @@ import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IEnvVarBuildPath; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; +import org.eclipse.cdt.managedbuilder.core.IOutputType; import org.eclipse.cdt.managedbuilder.core.IProjectType; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IOutputType; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; -import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildfileMacroSubstitutor; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.CoreException; @@ -2160,12 +2166,35 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { * @see org.eclipse.cdt.managedbuilder.core.ITool#getCommandFlags() */ public String[] getCommandFlags() throws BuildException { + return getToolCommandFlags(null,null); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.build.managed.ITool#getToolFlags() + */ + public String getToolFlags() throws BuildException { + return getToolCommandFlagsString(null,null); + } + + /** + * this method used internaly by the Tool to obtain the command flags with the build macros resolved, + * but could be also used by other MBS components to adjust the tool flags resolution + * behavior by passing the method some custom macro substitutor + * + * @param inputFileLocation + * @param outputFileLocation + * @param macroSubstitutor + * @return + * @throws BuildException + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation, IMacroSubstitutor macroSubstitutor) throws BuildException{ IOption[] opts = getOptions(); ArrayList flags = new ArrayList(); StringBuffer sb = new StringBuffer(); for (int index = 0; index < opts.length; index++) { IOption option = opts[index]; sb.setLength( 0 ); + try{ switch (option.getValueType()) { case IOption.BOOLEAN : String boolCmd; @@ -2190,54 +2219,79 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { case IOption.STRING : String strCmd = option.getCommand(); String val = option.getStringValue(); - if (val.length() > 0) { + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(inputFileLocation,outputFileLocation,option,getParent())); + if (val.length() > 0 && (val = MacroResolver.resolveToString(val,macroSubstitutor)).length() > 0) { sb.append( evaluateCommand( strCmd, val ) ); } break; case IOption.STRING_LIST : String listCmd = option.getCommand(); - String[] list = option.getStringListValue(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(inputFileLocation,outputFileLocation,option,getParent())); + String[] list = MacroResolver.resolveStringListValues(option.getStringListValue(),macroSubstitutor,true); + if(list != null){ for (int j = 0; j < list.length; j++) { String temp = list[j]; + if(temp.length() > 0) sb.append( evaluateCommand( listCmd, temp ) + WHITE_SPACE ); } + } break; case IOption.INCLUDE_PATH : String incCmd = option.getCommand(); - String[] paths = option.getIncludePaths(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(inputFileLocation,outputFileLocation,option,getParent())); + String[] paths = MacroResolver.resolveStringListValues(option.getIncludePaths(),macroSubstitutor,true); + if(paths != null){ for (int j = 0; j < paths.length; j++) { String temp = paths[j]; + if(temp.length() > 0) sb.append( evaluateCommand( incCmd, temp ) + WHITE_SPACE); } + } break; case IOption.PREPROCESSOR_SYMBOLS : String defCmd = option.getCommand(); - String[] symbols = option.getDefinedSymbols(); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(inputFileLocation,outputFileLocation,option,getParent())); + String[] symbols = MacroResolver.resolveStringListValues(option.getDefinedSymbols(),macroSubstitutor,true); + if(symbols != null){ for (int j = 0; j < symbols.length; j++) { String temp = symbols[j]; + if(temp.length() > 0) sb.append( evaluateCommand( defCmd, temp ) + WHITE_SPACE); } + } break; default : break; } + if( sb.toString().trim().length() > 0 ) flags.add( sb.toString().trim() ); + } catch (BuildMacroException e) { + + } } String[] f = new String[ flags.size() ]; return (String[])flags.toArray( f ); } /* (non-Javadoc) - * @see org.eclipse.cdt.core.build.managed.ITool#getToolFlags() + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) */ - public String getToolFlags() throws BuildException { + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + IMacroSubstitutor macroSubstitutor = new BuildfileMacroSubstitutor(null,EMPTY_STRING,WHITE_SPACE); + return getToolCommandFlags(inputFileLocation, outputFileLocation, macroSubstitutor ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ // Get all of the optionList StringBuffer buf = new StringBuffer(); - String[] flags = getCommandFlags(); + String[] flags = getToolCommandFlags(inputFileLocation,outputFileLocation); for (int index = 0; index < flags.length; index++) { if( flags[ index ] != null ) { buf.append( flags[ index ] + WHITE_SPACE ); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java index aa76a5ff413..6c497812f7c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolChain.java @@ -21,14 +21,16 @@ import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; -import org.eclipse.cdt.managedbuilder.core.IOutputType; import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported; +import org.eclipse.cdt.managedbuilder.core.IOutputType; import org.eclipse.cdt.managedbuilder.core.IProjectType; import org.eclipse.cdt.managedbuilder.core.ITargetPlatform; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolChain; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.w3c.dom.Document; @@ -64,11 +66,15 @@ public class ToolChain extends BuildObject implements IToolChain { private IManagedIsToolChainSupported managedIsToolChainSupported = null; private IConfigurationElement environmentVariableSupplierElement = null; private IConfigurationEnvironmentVariableSupplier environmentVariableSupplier = null; + private IConfigurationElement buildMacroSupplierElement = null; + private IConfigurationBuildMacroSupplier buildMacroSupplier = null; // Miscellaneous private boolean isExtensionToolChain = false; private boolean isDirty = false; private boolean resolved = true; + //holds the user-defined macros + private StorableMacros userDefinedMacros; /* * C O N S T R U C T O R S @@ -181,6 +187,9 @@ public class ToolChain extends BuildObject implements IToolChain { // TODO: report error } builder = new Builder(this, (Element)configElement); + }else if (configElement.getNodeName().equals(StorableMacros.MACROS_ELEMENT_NAME)) { + //load user-defined macros + userDefinedMacros = new StorableMacros((Element)configElement); } } } @@ -234,6 +243,9 @@ public class ToolChain extends BuildObject implements IToolChain { environmentVariableSupplierElement = toolChain.environmentVariableSupplierElement; environmentVariableSupplier = toolChain.environmentVariableSupplier; + buildMacroSupplierElement = toolChain.buildMacroSupplierElement; + buildMacroSupplier = toolChain.buildMacroSupplier; + // Clone the children if (toolChain.builder != null) { int nnn = ManagedBuildManager.getRandomNumber(); @@ -363,6 +375,13 @@ public class ToolChain extends BuildObject implements IToolChain { if(environmentVariableSupplier != null && element instanceof DefaultManagedConfigElement){ environmentVariableSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); } + + // Get the configurationMacroSupplier configuration element + String buildMacroSupplier = element.getAttribute(CONFIGURATION_MACRO_SUPPLIER); + if(buildMacroSupplier != null && element instanceof DefaultManagedConfigElement){ + buildMacroSupplierElement = ((DefaultManagedConfigElement)element).getConfigurationElement(); + } + } /* (non-Javadoc) @@ -566,6 +585,20 @@ public class ToolChain extends BuildObject implements IToolChain { // TODO: issue warning? } + + // Note: buildMacroSupplier cannot be specified in a project file because + // an IConfigurationElement is needed to load it! + if(buildMacroSupplierElement != null) { + // TODO: issue warning? + } + + //serialize user-defined macros + if(userDefinedMacros != null){ + Element macrosElement = doc.createElement(StorableMacros.MACROS_ELEMENT_NAME); + element.appendChild(macrosElement); + userDefinedMacros.serialize(doc,macrosElement); + } + // I am clean now isDirty = false; } @@ -1085,6 +1118,10 @@ public class ToolChain extends BuildObject implements IToolChain { // If I need saving, just say yes if (isDirty) return true; + //check whether the tool-chain - specific macros are dirty + if(userDefinedMacros != null && userDefinedMacros.isDirty()) + return true; + // Otherwise see if any tools need saving Iterator iter = getToolList().listIterator(); while (iter.hasNext()) { @@ -1221,32 +1258,32 @@ public class ToolChain extends BuildObject implements IToolChain { return; } - private IManagedIsToolChainSupported getIsToolChainSupported(){ - if(managedIsToolChainSupported == null && managedIsToolChainSupportedElement != null){ - try{ - if(managedIsToolChainSupportedElement.getAttribute(IS_TOOL_CHAIN_SUPPORTED) != null) - managedIsToolChainSupported = - (IManagedIsToolChainSupported)managedIsToolChainSupportedElement.createExecutableExtension(IS_TOOL_CHAIN_SUPPORTED); - - } - catch(CoreException e){ + private IConfigurationElement getIsToolChainSupportedElement(){ + if (managedIsToolChainSupportedElement == null) { + if (superClass != null && superClass instanceof ToolChain) { + return ((ToolChain)superClass).getIsToolChainSupportedElement(); } } - return managedIsToolChainSupported; + return managedIsToolChainSupportedElement; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.IToolChain#isSupported() */ public boolean isSupported(){ - IManagedIsToolChainSupported isSupported = getIsToolChainSupported(); - if(isSupported != null){ - //TODO: pass the version to the "isSupported" method - return isSupported.isSupported(this,null,null); + if (managedIsToolChainSupported == null) { + IConfigurationElement element = getIsToolChainSupportedElement(); + if (element != null) { + try { + if (element.getAttribute(IS_TOOL_CHAIN_SUPPORTED) != null) { + managedIsToolChainSupported = (IManagedIsToolChainSupported) element.createExecutableExtension(IS_TOOL_CHAIN_SUPPORTED); + } + } catch (CoreException e) {} + } } - else if(superClass != null) - return superClass.isSupported(); - else + + if(managedIsToolChainSupported != null) + return managedIsToolChainSupported.isSupported(this,null,null); return true; } @@ -1284,4 +1321,52 @@ public class ToolChain extends BuildObject implements IToolChain { return null; } + /* + * this method is called by the UserDefinedMacroSupplier to obtain user-defined + * macros available for this tool-chain + */ + public StorableMacros getUserDefinedMacros(){ + if(isExtensionToolChain) + return null; + + if(userDefinedMacros == null) + userDefinedMacros = new StorableMacros(); + return userDefinedMacros; + } + + /** + * Returns the plugin.xml element of the configurationMacroSupplier extension or null if none. + * + * @return IConfigurationElement + */ + public IConfigurationElement getBuildMacroSupplierElement(){ + if (buildMacroSupplierElement == null) { + if (superClass != null && superClass instanceof ToolChain) { + return ((ToolChain)superClass).getBuildMacroSupplierElement(); + } + } + return buildMacroSupplierElement; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IToolChain#getBuildMacroSupplier() + */ + public IConfigurationBuildMacroSupplier getBuildMacroSupplier(){ + if (buildMacroSupplier != null) { + return buildMacroSupplier; + } + IConfigurationElement element = getBuildMacroSupplierElement(); + if (element != null) { + try { + if (element.getAttribute(CONFIGURATION_MACRO_SUPPLIER) != null) { + buildMacroSupplier = (IConfigurationBuildMacroSupplier) element.createExecutableExtension(CONFIGURATION_MACRO_SUPPLIER); + return buildMacroSupplier; + } + } catch (CoreException e) {} + } + return null; + } + + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java index bdbe2e49916..9d5f8f69694 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java @@ -814,6 +814,21 @@ public class ToolReference implements IToolReference { return parent.getCommandFlags(); } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlags(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String[] getToolCommandFlags(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + return getCommandFlags(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.ITool#getToolCommandFlagsString(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath) + */ + public String getToolCommandFlagsString(IPath inputFileLocation, IPath outputFileLocation) throws BuildException{ + return getToolFlags(); + + } + /* (non-Javadoc) * @see java.lang.Object#toString() */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableProvider.java index e5c251bfc06..5a4bb4700e9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableProvider.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableProvider.java @@ -79,7 +79,7 @@ public class EnvironmentVariableProvider implements } - EnvironmentVariableProvider(){ + protected EnvironmentVariableProvider(){ } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/StorableEnvironment.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/StorableEnvironment.java index 5c9119534c1..294f19b6b1a 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/StorableEnvironment.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/StorableEnvironment.java @@ -29,7 +29,8 @@ import org.w3c.dom.NodeList; * * @since 3.0 * - */public class StorableEnvironment { + */ +public class StorableEnvironment { public static final String ENVIRONMENT_ELEMENT_NAME = "environment"; //$NON-NLS-1$ private Map fVariables; private boolean fIsDirty = false; @@ -183,13 +184,15 @@ import org.w3c.dom.NodeList; return var; } - public void deleteAll(){ + public boolean deleteAll(){ Map map = getMap(); if(map.size() > 0){ fIsDirty = true; fIsChanged = true; + map.clear(); + return true; } - map.clear(); + return false; } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/UserDefinedEnvironmentSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/UserDefinedEnvironmentSupplier.java index 92d8c54b1c2..d80209d10ec 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/UserDefinedEnvironmentSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/UserDefinedEnvironmentSupplier.java @@ -280,7 +280,7 @@ public class UserDefinedEnvironmentSupplier extends if(env == null) return; - env.deleteAll(); + if(env.deleteAll()) setRebuildStateForContext(context); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacro.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacro.java new file mode 100644 index 00000000000..80d08b257d9 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacro.java @@ -0,0 +1,78 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus; + +/** + * This is the trivial implementation of the IBuildMacro used internaly by the MBS + * + * @since 3.0 + */ +public class BuildMacro implements IBuildMacro { + protected String fName; + protected int fType; + protected String fStringValue; + protected String fStringListValue[]; + + protected BuildMacro(){ + + } + + public BuildMacro(String name, int type, String value){ + fName = name; + fType = type; + fStringValue = value; + } + + public BuildMacro(String name, int type, String value[]){ + fName = name; + fType = type; + fStringListValue = value; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getName() + */ + public String getName() { + return fName; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getMacroValueType() + */ + public int getMacroValueType() { + return fType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringValue() + */ + public String getStringValue() throws BuildMacroException { + if(MacroResolver.isStringListMacro(fType)) + throw new BuildMacroException(IBuildMacroStatus.TYPE_MACRO_NOT_STRING,fName,null,fName,0,null); + + return fStringValue; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringListValue() + */ + public String[] getStringListValue() throws BuildMacroException { + if(!MacroResolver.isStringListMacro(fType)) + throw new BuildMacroException(IBuildMacroStatus.TYPE_MACRO_NOT_STRINGLIST,fName,null,fName,0,null); + + return fStringListValue; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacroProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacroProvider.java new file mode 100644 index 00000000000..986dc80a612 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacroProvider.java @@ -0,0 +1,305 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; + +/** + * The default IBuildMacroProvider implementation + * @since 3.0 + */ +public class BuildMacroProvider implements IBuildMacroProvider { + static private BuildMacroProvider fDefault; + + public static UserDefinedMacroSupplier fUserDefinedMacroSupplier = UserDefinedMacroSupplier.getInstance(); + public static ExternalExtensionMacroSupplier fExternalExtensionMacroSupplier = ExternalExtensionMacroSupplier.getInstance(); + public static EnvironmentMacroSupplier fEnvironmentMacroSupplier = EnvironmentMacroSupplier.getInstance(); + public static MbsMacroSupplier fMbsMacroSupplier = MbsMacroSupplier.getInstance(); + public static CdtPathEntryMacroSupplier fCdtPathEntryMacroSupplier = CdtPathEntryMacroSupplier.getInstance(); + public static EclipseVariablesMacroSupplier fEclipseVariablesMacroSupplier = EclipseVariablesMacroSupplier.getInstance(); + + protected BuildMacroProvider(){ + + } + + public static BuildMacroProvider getDefault(){ + if(fDefault == null) + fDefault = new BuildMacroProvider(); + return fDefault; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#getMacro(java.lang.String, int, java.lang.Object, boolean) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData, boolean includeParentContexts) { + return getMacro(macroName, + getMacroContextInfo(contextType,contextData),includeParentContexts); + } + + /** + * @param macroName + * @param contextInfo + * @param includeParentContexts + * @return + */ + static public IBuildMacro getMacro(String macroName, IMacroContextInfo contextInfo, boolean includeParentContexts) { + if(contextInfo == null || macroName == null) + return null; + + do{ + IBuildMacroSupplier suppliers[] = contextInfo.getSuppliers(); + if(suppliers != null){ + for(int i = 0; i < suppliers.length; i++){ + IBuildMacro macro = suppliers[i].getMacro(macroName,contextInfo.getContextType(),contextInfo.getContextData()); + if(macro != null) + return macro; + } + } + }while(includeParentContexts && (contextInfo = contextInfo.getNext()) != null); + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#getMacros(int, java.lang.Object, boolean) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData, + boolean includeParentContexts) { + return getMacros(getMacroContextInfo(contextType,contextData), + includeParentContexts); + } + + /** + * @param contextInfo + * @param includeParentContexts + * @return + */ + static public IBuildMacro[] getMacros(IMacroContextInfo contextInfo, + boolean includeParentContexts) { + if(contextInfo == null) + return null; + + Map map = new HashMap(); + + do{ + IBuildMacroSupplier suppliers[] = contextInfo.getSuppliers(); + if(suppliers != null){ + for(int i = suppliers.length - 1; i >= 0; i--){ + IBuildMacro macros[] = suppliers[i].getMacros(contextInfo.getContextType(),contextInfo.getContextData()); + if(macros != null){ + for(int j = 0; j < macros.length; j++){ + map.put(macros[j].getName(),macros[j]); + } + } + } + } + }while(includeParentContexts && (contextInfo = contextInfo.getNext()) != null); + + Collection values = map.values(); + return (IBuildMacro[])values.toArray(new IBuildMacro[values.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#getSuppliers(int, java.lang.Object) + */ + public IBuildMacroSupplier[] getSuppliers(int contextType, + Object contextData) { + IMacroContextInfo info = getMacroContextInfo(contextType,contextData); + if(info != null) + return info.getSuppliers(); + return null; + } + + /** + * @param contextType + * @param contextData + * @return + */ + public IMacroContextInfo getMacroContextInfo( + int contextType, + Object contextData){ + DefaultMacroContextInfo info = new DefaultMacroContextInfo(contextType,contextData); + if(info.getSuppliers() != null) + return info; + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#convertStringListToString(java.lang.String[], java.lang.String) + */ + public String convertStringListToString(String[] value, String listDelimiter) { + return MacroResolver.convertStringListToString(value,listDelimiter); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#resolveValue(java.lang.String, java.lang.String, java.lang.String, int, java.lang.Object) + */ + public String resolveValue(String value, String nonexistentMacrosValue, + String listDelimiter, int contextType, Object contextData) + throws BuildMacroException { + + IMacroContextInfo info = getMacroContextInfo(contextType,contextData); + if(info != null) + return MacroResolver.resolveToString(value, + getMacroSubstitutor(info,nonexistentMacrosValue, listDelimiter)); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#resolveStringListValue(java.lang.String, java.lang.String, int, java.lang.Object) + */ + public String[] resolveStringListValue(String value, + String nonexistentMacrosValue, int contextType, Object contextData) + throws BuildMacroException { + + IMacroContextInfo info = getMacroContextInfo(contextType,contextData); + if(info != null) + MacroResolver.resolveToStringList(value,getMacroSubstitutor(info,nonexistentMacrosValue, " ")); //$NON-NLS-1$ + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#resolveValueToMakefileFormat(java.lang.String, java.lang.String, java.lang.String, int, java.lang.Object) + */ + public String resolveValueToMakefileFormat(String value, + String nonexistentMacrosValue, String listDelimiter, + int contextType, Object contextData) throws BuildMacroException { + + IMacroContextInfo info = getMacroContextInfo(contextType,contextData); + if(info != null) + return MacroResolver.resolveToString(value, + getBuildfileMacroSubstitutor(info,nonexistentMacrosValue, listDelimiter)); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#resolveStringListValueToMakefileFormat(java.lang.String, java.lang.String, int, java.lang.Object) + */ + public String[] resolveStringListValueToMakefileFormat(String value, + String nonexistentMacrosValue, int contextType, Object contextData) + throws BuildMacroException { + + IMacroContextInfo info = getMacroContextInfo(contextType,contextData); + if(info != null) + MacroResolver.resolveToStringList(value,getBuildfileMacroSubstitutor(info,nonexistentMacrosValue, " ")); //$NON-NLS-1$ + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#isStringListValue(java.lang.String) + */ + public boolean isStringListValue(String value, int contextType, Object contextData) throws BuildMacroException { + try { + MacroResolver.resolveToStringList(value,getMacroSubstitutor(getMacroContextInfo(contextType,contextData)," ",null)); //$NON-NLS-1$ + }catch(BuildMacroException e){ + return false; + } + return true; + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#checkIntegrity(int, java.lang.Object) + */ + public void checkIntegrity(int contextType, Object contextData) + throws BuildMacroException { + + IMacroContextInfo info = getMacroContextInfo(contextType,contextData); + if(info != null) + MacroResolver.checkIntegrity(info,getMacroSubstitutor(info,null,"")); //$NON-NLS-1$ + } + + public IMacroSubstitutor getMacroSubstitutor(IMacroContextInfo info, String inexistentMacroValue, String listDelimiter){ + return new DefaultMacroSubstitutor(info, inexistentMacroValue, listDelimiter); + } + + public IMacroSubstitutor getBuildfileMacroSubstitutor(IMacroContextInfo info, String inexistentMacroValue, String listDelimiter){ + return new BuildfileMacroSubstitutor(info, inexistentMacroValue, listDelimiter); + } + + /* + * returns true if the first passed contextInfo is the child of the second one + */ + public boolean checkParentContextRelation(IMacroContextInfo child, IMacroContextInfo parent){ + if(child == null || parent == null) + return false; + + IMacroContextInfo enumInfo = child; + do{ + if(parent.getContextType() == enumInfo.getContextType() && + parent.getContextData() == enumInfo.getContextData()) + return true; + }while((enumInfo = enumInfo.getNext()) != null); + return false; + } + + /** + * answers whether the environment macros are to be expanded in the buildfile + * + * @param cfg + * @return + */ + public boolean areMacrosExpandedInBuildfile(IConfiguration cfg){ + boolean expanded = fUserDefinedMacroSupplier.areMacrosExpanded(cfg); + if(expanded || canKeepMacrosInBuildfile(cfg)) + return expanded; + return true; + } + + /** + * sets whether the environment macros are to be expanded in the buildfile or not + * If a bulder does not support treating environment variables as its own ones this method + * has no effect + * Returns the result of this set operation. That is whether the environment macros are to be expanded in the buildfile + * + * @param cfg + * @param expand + * @return + */ + public boolean expandMacrosInBuildfile(IConfiguration cfg, boolean expand){ + if(expand || canKeepMacrosInBuildfile(cfg)){ + fUserDefinedMacroSupplier.setMacrosExpanded(cfg,expand); + return expand; + } + return true; + } + + /** + * answers whether the builder used for the given configuration is capable + * of handling macros in the buildfile + * + * @param cfg + * @return + */ + public boolean canKeepMacrosInBuildfile(IConfiguration cfg){ + return MacroResolver.canKeepMacrosInBuildfile(cfg); + } + + /** + * answers whether the given builder is capable + * of handling macros in the buildfile + * + * @param builder + * @return + */ + public boolean canKeepMacrosInBuildfile(IBuilder builder){ + return MacroResolver.canKeepMacrosInBuildfile(builder); + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacroStatus.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacroStatus.java new file mode 100644 index 00000000000..6f33a5d2c2b --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildMacroStatus.java @@ -0,0 +1,213 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * This class implements the IBuildMacroStatus interface + * + * @since 3.0 + */ +public class BuildMacroStatus extends Status implements IBuildMacroStatus { + /* + * String constants + */ + private static final String PREFIX = "BuildMacroStatus"; //$NON-NLS-1$ + private static final String STATUS = PREFIX + ".status"; //$NON-NLS-1$ + private static final String STATUS_MACRO_UNDEFINED = STATUS + ".macro.undefined"; //$NON-NLS-1$ + private static final String STATUS_MACROS_REFERENCE_EACHOTHER = STATUS + ".reference.eachother"; //$NON-NLS-1$ + private static final String STATUS_MACRO_REFERENCE_INCORRECT = STATUS + ".reference.incorrect"; //$NON-NLS-1$ + private static final String STATUS_MACRO_NOT_STRING = STATUS + ".macro.not.string"; //$NON-NLS-1$ + private static final String STATUS_MACRO_NOT_STRINGLIST = STATUS + ".macro.not.stringlist"; //$NON-NLS-1$ + private static final String STATUS_ERROR = STATUS + ".error"; //$NON-NLS-1$ + private static final String VALUE_UNDEFINED = PREFIX + ".value.undefined"; //$NON-NLS-1$ + + private String fMacroName; + private String fExpression; + private String fReferencedName; + private int fContextType; + private Object fContextData; + + /** + * + * @param severity one of the IStatus.xxx severity statuses + * @param code one of the IBuildMacroStatus.TYPE_xxx statusses + * @param message message, can be null. In this case the default message will + * be generated base upon the other status info + * @param exception a low-level exception, or null if not + * applicable + * @param macroName the name of the build macro whose resolution caused this status creation or null if none + * @param expression the string whose resolutinon caused caused this status creation or null if none + * @param referencedName the macro name referenced in the resolution string that caused this this status creation or null if none + * @param contextType the context type used in the operation + * @param contextData the context data used in the operation + */ + public BuildMacroStatus(int severity, + int code, + String message, + Throwable exception, + String macroName, + String expression, + String referencedName, + int contextType, + Object contextData) { + super(severity,ManagedBuilderCorePlugin.getUniqueIdentifier(),code,message != null ? message : "",exception); //$NON-NLS-1$ + fExpression = expression; + fReferencedName = referencedName; + fContextType = contextType; + fContextData = contextData; + fMacroName = macroName; + if(message == null) + setMessage(generateMessage()); + } + + /** + * Creates status with the IStatus.ERROR severity + * + * @param code one of the IBuildMacroStatus.TYPE_xxx statusses + * @param message message, can be null. In this case the default message will + * be generated base upon the other status info + * @param exception a low-level exception, or null if not + * applicable + * @param macroName the name of the build macro whose resolution caused this status creation or null if none + * @param expression the string whose resolutinon caused caused this status creation or null if none + * @param referencedName the macro name referenced in the resolution string that caused this this status creation or null if none + * @param contextType the context type used in the operation + * @param contextData the context data used in the operation + */ + public BuildMacroStatus( + int code, + String message, + Throwable exception, + String macroName, + String expression, + String referencedName, + int contextType, + Object contextData) { + this(IStatus.ERROR,code,message,exception,macroName,expression,referencedName,contextType,contextData); + } + + /** + * Creates status with the IStatus.ERROR severity and with the default message + * + * @param code one of the IBuildMacroStatus.TYPE_xxx statusses + * @param exception a low-level exception, or null if not + * applicable + * @param macroName the name of the build macro whose resolution caused this status creation or null if none + * @param expression the string whose resolutinon caused caused this status creation or null if none + * @param referencedName the macro name referenced in the resolution string that caused this this status creation or null if none + * @param contextType the context type used in the operation + * @param contextData the context data used in the operation + */ + public BuildMacroStatus( + int code, + String macroName, + String expression, + String referencedName, + int contextType, + Object contextData) { + this(IStatus.ERROR,code,null,null,macroName,expression,referencedName,contextType,contextData); + } + + /** + * generates and returns the default status message based upon then status data + * + * @return String + */ + protected String generateMessage(){ + String message = null; + switch(getCode()){ + case TYPE_MACRO_UNDEFINED:{ + String refName = fReferencedName; + if(refName == null) + refName = ManagedMakeMessages.getResourceString(VALUE_UNDEFINED); + message = ManagedMakeMessages.getFormattedString(STATUS_MACRO_UNDEFINED,refName); + } + break; + case TYPE_MACROS_REFERENCE_EACHOTHER:{ + String name = fMacroName; + String refName = fReferencedName; + if(name == null) + name = ManagedMakeMessages.getResourceString(VALUE_UNDEFINED); + if(refName == null) + refName = ManagedMakeMessages.getResourceString(VALUE_UNDEFINED); + message = ManagedMakeMessages.getFormattedString(STATUS_MACROS_REFERENCE_EACHOTHER,new String[]{name,refName}); + } + break; + case TYPE_MACRO_REFERENCE_INCORRECT:{ + String refName = fReferencedName; + if(refName == null) + refName = ManagedMakeMessages.getResourceString(VALUE_UNDEFINED); + message = ManagedMakeMessages.getFormattedString(STATUS_MACRO_REFERENCE_INCORRECT,refName); + } + break; + case TYPE_MACRO_NOT_STRING:{ + String refName = fReferencedName; + if(refName == null) + refName = ManagedMakeMessages.getResourceString(VALUE_UNDEFINED); + message = ManagedMakeMessages.getFormattedString(STATUS_MACRO_NOT_STRING,refName); + } + break; + case TYPE_MACRO_NOT_STRINGLIST:{ + String refName = fReferencedName; + if(refName == null) + refName = ManagedMakeMessages.getResourceString(VALUE_UNDEFINED); + message = ManagedMakeMessages.getFormattedString(STATUS_MACRO_NOT_STRINGLIST,refName); + } + break; + case TYPE_ERROR: + default: + message = ManagedMakeMessages.getResourceString(STATUS_ERROR); + } + return message; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus#getMacroName() + */ + public String getMacroName() { + return fMacroName; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus#getExpression() + */ + public String getExpression() { + return fExpression; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus#getReferencedName() + */ + public String getReferencedMacroName() { + return fReferencedName; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus#getContextType() + */ + public int getContextType() { + return fContextType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus#getContextData() + */ + public Object getContextData() { + return fContextData; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildfileMacroSubstitutor.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildfileMacroSubstitutor.java new file mode 100644 index 00000000000..f4a3c6ce511 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/BuildfileMacroSubstitutor.java @@ -0,0 +1,237 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvVarOperationProcessor; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier; +import org.eclipse.core.resources.IResource; + +/** + * This substitutor resolves all macro references except for the environment macro references + * If a user has chosen to keep those macros in the buildfile, the environment macro references + * are converted to the buildfile variable references, otherwise those macros are also resolved + * + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor + * @since 3.0 + */ +public class BuildfileMacroSubstitutor extends DefaultMacroSubstitutor { + private static final String PATTERN_MACRO_NAME = "="; //$NON-NLS-1$ + private IConfiguration fConfiguration; + private IBuilder fBuilder; + private HashSet fCaseInsensitiveReferencedNames; + + private class DefaultReservedMacroNameSupplier implements IReservedMacroNameSupplier{ + String fReservedNames[]; + + public DefaultReservedMacroNameSupplier(IConfiguration configuration){ + IBuilder builder = configuration.getToolChain().getBuilder(); + String reservedNames[] = builder.getReservedMacroNames(); + String buildVars[] = getConfigurationReservedNames(configuration); + + if(reservedNames == null || reservedNames.length == 0) + fReservedNames = buildVars; + else if(buildVars == null || buildVars.length == 0) + fReservedNames = reservedNames; + else { + fReservedNames = new String[reservedNames.length + buildVars.length]; + System.arraycopy(reservedNames,0,fReservedNames,0,reservedNames.length); + System.arraycopy(buildVars,0,fReservedNames,reservedNames.length,buildVars.length); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IReservedMacroNameSupplier#isReservedName(java.lang.String, org.eclipse.cdt.managedbuilder.core.IConfiguration) + */ + public boolean isReservedName(String macroName, IConfiguration configuration) { + if(fReservedNames != null && fReservedNames.length > 0){ + for(int i = 0; i < fReservedNames.length; i++){ + Pattern p = Pattern.compile(fReservedNames[i]); + Matcher m = p.matcher(macroName); + if(m.matches()) + return true; + } + } + return false; + } + + protected String[] getConfigurationReservedNames(IConfiguration configuration){ + ITool tools[] = configuration.getFilteredTools(); + if(tools != null){ + Set set = new HashSet(); + for(int i = 0; i < tools.length; i++){ + IOutputType ots[] = tools[i].getOutputTypes(); + if(ots != null){ + for(int j = 0; j < ots.length; j++){ + String varName = ots[j].getBuildVariable(); + if(varName != null){ + set.add(varName); + } + } + } + + IInputType its[] = tools[i].getInputTypes(); + if(its != null){ + for(int j = 0; j < its.length; j++){ + String varName = its[j].getBuildVariable(); + if(varName != null){ + set.add(varName); + } + } + } + + } + + return (String[])set.toArray(new String[set.size()]); + } + return null; + } + } + + public BuildfileMacroSubstitutor(int contextType, Object contextData, String inexistentMacroValue, String listDelimiter){ + super(contextType, contextData, inexistentMacroValue, listDelimiter); + init(); + } + + public BuildfileMacroSubstitutor(IMacroContextInfo contextInfo, String inexistentMacroValue, String listDelimiter){ + super(contextInfo, inexistentMacroValue, listDelimiter); + init(); + } + + private void init(){ + IMacroContextInfo contextInfo = getMacroContextInfo(); + if(contextInfo == null) + return; + + int type = contextInfo.getContextType(); + switch(type){ + case IBuildMacroProvider.CONTEXT_FILE: + contextInfo = contextInfo.getNext(); + if(contextInfo == null) + break; + case IBuildMacroProvider.CONTEXT_OPTION: + contextInfo = contextInfo.getNext(); + if(contextInfo == null) + break; + case IBuildMacroProvider.CONTEXT_CONFIGURATION:{ + Object contextData = contextInfo.getContextData(); + if(contextData instanceof IConfiguration) + fConfiguration = (IConfiguration)contextData; + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT:{ + Object contextData = contextInfo.getContextData(); + if(contextData instanceof IManagedProject){ + IResource rc = ((IManagedProject)contextData).getOwner(); + if(rc != null){ + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(rc); + fConfiguration = info.getDefaultConfiguration(); + } + } + } + break; + } + if(fConfiguration != null){ + IToolChain toolChain = fConfiguration.getToolChain(); + if(toolChain != null) + fBuilder = toolChain.getBuilder(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor#resolveMacro(org.eclipse.cdt.managedbuilder.macros.IBuildMacro) + */ + protected ResolvedMacro resolveMacro(IBuildMacro macro) throws BuildMacroException{ + ResolvedMacro resolved = null; + + if(!UserDefinedMacroSupplier.getInstance().areMacrosExpanded(fConfiguration) && + macro instanceof EnvironmentMacroSupplier.EnvVarMacro){ + String ref = getMacroReference(macro); + if(ref != null) + resolved = new ResolvedMacro(macro.getName(),ref); + + } + if(resolved != null) + return resolved; + return super.resolveMacro(macro); + } + + public IConfiguration getConfiguration(){ + return fConfiguration; + } + + protected IReservedMacroNameSupplier getReservedMacroNameSupplier(){ + if(fBuilder == null) + return null; + IReservedMacroNameSupplier supplier = fBuilder.getReservedMacroNameSupplier(); + if(supplier == null) + supplier = new DefaultReservedMacroNameSupplier(fConfiguration); + + return supplier; + } + + protected String getMacroReference(IBuildMacro macro){ + String macroName = macro.getName(); + String ref = null; + IReservedMacroNameSupplier supplier = getReservedMacroNameSupplier(); + //on win32 all environment variable names are converted to upper case + macroName = EnvVarOperationProcessor.normalizeName(macroName); + if(supplier == null || !supplier.isReservedName(macroName,fConfiguration)){ + String pattern = fBuilder.getBuilderVariablePattern(); + if(pattern != null && pattern.indexOf(PATTERN_MACRO_NAME) != -1){ + if(fBuilder.isVariableCaseSensitive() || getCaseInsensitiveReferencedNames().add(macroName.toUpperCase())){ + ref = pattern.replaceAll(PATTERN_MACRO_NAME,macroName); + } + } + } + return ref; + } + + protected Set getCaseInsensitiveReferencedNames(){ + if(fCaseInsensitiveReferencedNames == null) + fCaseInsensitiveReferencedNames = new HashSet(); + return fCaseInsensitiveReferencedNames; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor#setMacroContextInfo(org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo) + */ + public void setMacroContextInfo(IMacroContextInfo info) + throws BuildMacroException{ + super.setMacroContextInfo(info); + init(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#setMacroContextInfo(int, java.lang.Object) + */ + public void setMacroContextInfo(int contextType, Object contextData) throws BuildMacroException{ + super.setMacroContextInfo(contextType, contextData); + init(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/CdtPathEntryMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/CdtPathEntryMacroSupplier.java new file mode 100644 index 00000000000..ae4d640f987 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/CdtPathEntryMacroSupplier.java @@ -0,0 +1,76 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.resources.IPathEntryVariableManager; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.core.runtime.IPath; + +/** + * This supplier suplies the macros that represent the CDT Path entry variables + * + * @since 3.0 + */ +public class CdtPathEntryMacroSupplier implements IBuildMacroSupplier { + private static CdtPathEntryMacroSupplier fInstance; + + private CdtPathEntryMacroSupplier(){ + + } + + public static CdtPathEntryMacroSupplier getInstance(){ + if(fInstance == null) + fInstance = new CdtPathEntryMacroSupplier(); + return fInstance; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData) { + if(contextType != IBuildMacroProvider.CONTEXT_WORKSPACE) + return null; + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + + IPathEntryVariableManager mngr = CCorePlugin.getDefault().getPathEntryVariableManager(); + if(mngr == null) + return null; + + IPath path = mngr.getValue(macroName); + if(path != null) + return new BuildMacro(macroName,BuildMacro.VALUE_PATH_ANY,path.toOSString()); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData) { + if(contextType != IBuildMacroProvider.CONTEXT_WORKSPACE) + return null; + IPathEntryVariableManager mngr = CCorePlugin.getDefault().getPathEntryVariableManager(); + if(mngr == null) + return null; + + String names[] = mngr.getVariableNames(); + BuildMacro macros[] = new BuildMacro[names.length]; + for(int i = 0; i < names.length; i++) + macros[i] = new BuildMacro(names[i],BuildMacro.VALUE_PATH_ANY,mngr.getValue(names[i]).toOSString()); + return macros; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/DefaultMacroContextInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/DefaultMacroContextInfo.java new file mode 100644 index 00000000000..c6bf4a41fcc --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/DefaultMacroContextInfo.java @@ -0,0 +1,208 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.cdt.managedbuilder.macros.IFileContextData; +import org.eclipse.cdt.managedbuilder.macros.IOptionContextData; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; + +/** + * This is the default implementation of the IMacroContextInfo + * + * @since 3.0 + */ +public class DefaultMacroContextInfo implements IMacroContextInfo { + private IBuildMacroSupplier fSuppliers[]; + private int fType; + private Object fData; + + public DefaultMacroContextInfo(int type, Object data){ + fType = type; + fData = data; + } + + protected DefaultMacroContextInfo(int type, Object data, IBuildMacroSupplier suppliers[]){ + fType = type; + fData = data; + fSuppliers = suppliers; + } + + protected IBuildMacroSupplier[] getSuppliers(int type, Object data){ + switch(type){ + case IBuildMacroProvider.CONTEXT_FILE: + if(data instanceof IFileContextData){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fMbsMacroSupplier + }; + } + break; + case IBuildMacroProvider.CONTEXT_OPTION: + if(data instanceof IOptionContextData){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fMbsMacroSupplier + }; + } + break; + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(data instanceof IConfiguration){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fUserDefinedMacroSupplier, + BuildMacroProvider.fExternalExtensionMacroSupplier, + BuildMacroProvider.fEnvironmentMacroSupplier, + BuildMacroProvider.fMbsMacroSupplier + }; + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(data instanceof IManagedProject){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fUserDefinedMacroSupplier, + BuildMacroProvider.fExternalExtensionMacroSupplier, + BuildMacroProvider.fEnvironmentMacroSupplier, + BuildMacroProvider.fMbsMacroSupplier + }; + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(data instanceof IWorkspace){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fUserDefinedMacroSupplier, + BuildMacroProvider.fEnvironmentMacroSupplier, + BuildMacroProvider.fMbsMacroSupplier, + BuildMacroProvider.fCdtPathEntryMacroSupplier, + BuildMacroProvider.fEclipseVariablesMacroSupplier + }; + } + break; + case IBuildMacroProvider.CONTEXT_INSTALLATIONS: + if(data == null){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fMbsMacroSupplier + }; + } + break; + case IBuildMacroProvider.CONTEXT_ECLIPSEENV: + if(data == null){ + return new IBuildMacroSupplier[]{ + BuildMacroProvider.fEnvironmentMacroSupplier + }; + } + break; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getContextType() + */ + public int getContextType() { + return fType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getContextData() + */ + public Object getContextData() { + return fData; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getSuppliers() + */ + public IBuildMacroSupplier[] getSuppliers() { + if(fSuppliers == null) + fSuppliers = getSuppliers(fType, fData); + return fSuppliers; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getNext() + */ + public IMacroContextInfo getNext() { + switch(fType){ + case IBuildMacroProvider.CONTEXT_FILE: + if(fData instanceof IFileContextData){ + IFileContextData fileContext = (IFileContextData)fData; + IOptionContextData optionContext = fileContext.getOptionContextData(); + if(optionContext != null) + return new DefaultMacroContextInfo( + IBuildMacroProvider.CONTEXT_OPTION, + optionContext); + } + break; + case IBuildMacroProvider.CONTEXT_OPTION: + if(fData instanceof IOptionContextData){ + IOptionContextData optionContext = (IOptionContextData)fData; + IBuildObject buildObj = optionContext.getParent(); + IConfiguration cfg = null; + if(buildObj instanceof IToolChain) + cfg = ((IToolChain)buildObj).getParent(); + else if(buildObj instanceof IResourceConfiguration) + cfg = ((IResourceConfiguration)buildObj).getParent(); + + if(cfg != null){ + return new DefaultMacroContextInfo( + IBuildMacroProvider.CONTEXT_CONFIGURATION, + cfg); + } + } + break; + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(fData instanceof IConfiguration){ + IConfiguration configuration = (IConfiguration)fData; + IManagedProject managedProject = configuration.getManagedProject(); + if(managedProject != null) + return new DefaultMacroContextInfo( + IBuildMacroProvider.CONTEXT_PROJECT, + managedProject); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(fData instanceof IManagedProject){ + IWorkspace wsp = ResourcesPlugin.getWorkspace(); + if(wsp != null) + return new DefaultMacroContextInfo( + IBuildMacroProvider.CONTEXT_WORKSPACE, + wsp); + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(fData instanceof IWorkspace){ + return new DefaultMacroContextInfo( + IBuildMacroProvider.CONTEXT_INSTALLATIONS, + null); + } + break; + case IBuildMacroProvider.CONTEXT_INSTALLATIONS: + if(fData == null){ + return new DefaultMacroContextInfo( + IBuildMacroProvider.CONTEXT_ECLIPSEENV, + null); + } + break; + case IBuildMacroProvider.CONTEXT_ECLIPSEENV: + if(fData == null){ + return null; + } + break; + } + return null; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/DefaultMacroSubstitutor.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/DefaultMacroSubstitutor.java new file mode 100644 index 00000000000..f8660a28e8d --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/DefaultMacroSubstitutor.java @@ -0,0 +1,424 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus; + +/** + * This substitutor resolves all macro references + * + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor + * @since 3.0 + */ +public class DefaultMacroSubstitutor implements IMacroSubstitutor { + private static final Object UNDEFINED_MACRO_VALUE = new Object(); + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private IMacroContextInfo fContextInfo; + private String fInexistentMacroValue; + private String fListDelimiter; + private String fIncorrectlyReferencedMacroValue; + + protected class ResolvedMacro extends BuildMacro{ + private boolean fIsDefined; + private boolean fIsList; + + public ResolvedMacro(String name){ + super(name, VALUE_TEXT, (String)null); + fIsDefined = false; + } + + public ResolvedMacro(String name, String value, boolean isDefined){ + super(name, VALUE_TEXT, value); + fIsDefined = isDefined; + fIsList = false; + } + + public ResolvedMacro(String name, String value){ + super(name, VALUE_TEXT, value); + fIsDefined = true; + fIsList = false; + } + + public ResolvedMacro(String name, String value[]){ + super(name, VALUE_TEXT_LIST, value); + fIsDefined = true; + fIsList = true; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringValue() + */ + public String getStringValue() throws BuildMacroException { +// if(!fIsDefined) +// throw new BuildMacroException(BuildMacroException.TYPE_MACROS_UNDEFINED,fName); + if(fIsList && fStringValue == null) + fStringValue = stringListToString(fStringListValue); + return fStringValue; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringListValue() + */ + public String[] getStringListValue() throws BuildMacroException { +// if(!fIsDefined) +// throw new BuildMacroException(BuildMacroException.TYPE_MACROS_UNDEFINED,fName); + if(!fIsList && fStringListValue == null) + fStringListValue = new String[]{fStringValue}; + return fStringListValue; + } + + protected String stringListToString(String values[]) throws BuildMacroException { + String result = null; + if(values == null) + result = null; + else if(values.length == 0) + result = EMPTY_STRING; + else if(values.length == 1) + result = values[0]; + else if(fListDelimiter != null){ + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < values.length; i++){ + buffer.append(values[i]); + if(i < values.length-1) + buffer.append(fListDelimiter); + } + result = buffer.toString(); + } else { + throw new BuildMacroException(IBuildMacroStatus.TYPE_MACRO_NOT_STRING, + null, + null, + fName, + fContextInfo != null ? fContextInfo.getContextType() : 0, + fContextInfo != null ? fContextInfo.getContextData() : null); + } + + return result; + + } + + public boolean isList(){ + return fIsList; + } + + public boolean isDefined(){ + return fIsDefined; + } + } + + /* + * describes the macro and the context where the macro was found + */ + protected class MacroDescriptor { + private String fName; + private IMacroContextInfo fInfo; + private IBuildMacro fMacro; + private boolean fInitialized; + + public MacroDescriptor(String name){ + this(name, null); + } + + public MacroDescriptor(String name, IMacroContextInfo info){ + fName = name; + fInfo = info; + } + + public MacroDescriptor(IBuildMacro macro, IMacroContextInfo info){ + fName = macro.getName(); + fInfo = info; + fMacro = macro; + } + + public MacroDescriptor getNext(){ + IMacroContextInfo info = getInfo(); + if(info != null) + info = info.getNext(); + + return get(fName,info); + } + + protected MacroDescriptor get(String name, IMacroContextInfo info){ + MacroDescriptor next = null; + IBuildMacro macro = null; + for(; info != null; info = info.getNext()){ + if((macro = BuildMacroProvider.getMacro(fName,info,false)) != null){ + next = new MacroDescriptor(macro,info); + break; + } + } + return next; + } + + private void init(){ + if(fInitialized) + return; + + MacroDescriptor des = get(fName,fContextInfo); + if(des != null){ + fInfo = des.fInfo; + fMacro = des.fMacro; + } + + fInitialized = true; + + } + + public IMacroContextInfo getInfo(){ + if(fInfo == null) + init(); + return fInfo; + } + + public IBuildMacro getMacro(){ + if(fMacro == null) + init(); + return fMacro; + } + + } + + private Map fResolvedMacros = new HashMap(); + private HashSet fMacrosUnderResolution = new HashSet(); + private Stack fMacroDescriptors = new Stack(); + + public DefaultMacroSubstitutor(int contextType, Object contextData, String inexistentMacroValue, String listDelimiter){ + this(new DefaultMacroContextInfo(contextType,contextData),inexistentMacroValue,listDelimiter); + } + + public DefaultMacroSubstitutor(IMacroContextInfo contextInfo, String inexistentMacroValue, String listDelimiter){ + this(contextInfo, inexistentMacroValue, listDelimiter, inexistentMacroValue); + } + + public DefaultMacroSubstitutor(IMacroContextInfo contextInfo, String inexistentMacroValue, String listDelimiter, String incorrectlyReferencedMacroValue){ + fContextInfo = contextInfo; + fInexistentMacroValue = inexistentMacroValue; + fListDelimiter = listDelimiter; + fIncorrectlyReferencedMacroValue = incorrectlyReferencedMacroValue; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#resolveToString(java.lang.String) + */ + public String resolveToString(String macroName) throws BuildMacroException { + String result = null; + ResolvedMacro value = getResolvedMacro(macroName); + result = value.getStringValue(); + + return result; + } + + public void setMacroContextInfo(IMacroContextInfo info) + throws BuildMacroException{ + if(fMacrosUnderResolution.size() != 0) + throw new BuildMacroException(IBuildMacroStatus.TYPE_ERROR,(String)null,null,null,0,null); + + fResolvedMacros.clear(); + fContextInfo = info; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#setMacroContextInfo(int, java.lang.Object) + */ + public void setMacroContextInfo(int contextType, Object contextData) throws BuildMacroException{ + setMacroContextInfo(getMacroContextInfo(contextType,contextData)); + } + + protected IMacroContextInfo getMacroContextInfo(int contextType, Object contextData){ + return ((BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider()).getMacroContextInfo(contextType,contextData); + } + + protected ResolvedMacro getResolvedMacro(String macroName) + throws BuildMacroException { + ResolvedMacro value = checkResolvingMacro(macroName); + + if(value == null) + { + try{ + value = resolveMacro(macroName); + }finally{ + if(value != null) + addResolvedMacro(macroName,value); + else { + value = new ResolvedMacro(macroName,fInexistentMacroValue,false); + addResolvedMacro(macroName,value); + } + } + } + + return value; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#resolveToStringList(java.lang.String) + */ + public String[] resolveToStringList(String macroName) + throws BuildMacroException { + String result[] = null; + ResolvedMacro value = getResolvedMacro(macroName); + result = value.getStringListValue(); + + return result; + } + + protected ResolvedMacro resolveMacro(String macroName) throws BuildMacroException{ + return resolveMacro(BuildMacroProvider.getMacro(macroName,fContextInfo,true)); + } + + protected ResolvedMacro resolveParentMacro(MacroDescriptor macroDes) throws BuildMacroException{ + MacroDescriptor des = macroDes.getNext(); + + ResolvedMacro macro = null; + + if(des != null){ + try{ + fMacroDescriptors.push(des); + macro = resolveMacro(des.getMacro()); + } finally { + fMacroDescriptors.pop(); + } + } + return macro; + } + + protected ResolvedMacro resolveMacro(IBuildMacro macro) throws BuildMacroException{ + if(macro == null) + return null; + + String macroName = macro.getName(); + IMacroSubstitutor substitutor = this; + + ResolvedMacro resolvedMacro = null; + + if(MacroResolver.isStringListMacro(macro.getMacroValueType())){ + String result[] = null; + String unresolvedValues[] = macro.getStringListValue(); + if(unresolvedValues == null || unresolvedValues.length == 0) + resolvedMacro = new ResolvedMacro(macroName,EMPTY_STRING); + else{ + String resolvedValues[][] = new String[unresolvedValues.length][]; + + for(int i = 0; i < unresolvedValues.length; i++){ + try{ + resolvedValues[i] = MacroResolver.resolveToStringList(unresolvedValues[i],substitutor); + } catch (BuildMacroException e) { + IBuildMacroStatus statuses[] = e.getMacroStatuses(); + if(statuses != null && statuses.length == 1){ + IBuildMacroStatus status = statuses[0]; + if(status.getMacroName() == null){ + e = new BuildMacroException(status.getCode(), + macro.getName(), + status.getExpression(), + status.getReferencedMacroName(), + fContextInfo != null ? fContextInfo.getContextType() : 0, + fContextInfo != null ? fContextInfo.getContextData() : null); + } + } + throw e; + } + } + + if(resolvedValues.length == 1) + result = resolvedValues[0]; + else{ + List list = new ArrayList(); + for(int i = 0; i < resolvedValues.length; i++) + list.addAll(Arrays.asList(resolvedValues[i])); + + result = (String[])list.toArray(new String[list.size()]); + } + resolvedMacro = new ResolvedMacro(macroName,result); + } + } else { + try{ + resolvedMacro = new ResolvedMacro(macroName,MacroResolver.resolveToString(macro.getStringValue(),substitutor)); + } catch (BuildMacroException e) { + IBuildMacroStatus statuses[] = e.getMacroStatuses(); + if(statuses != null && statuses.length == 1){ + IBuildMacroStatus status = statuses[0]; + if(status.getMacroName() == null){ + e = new BuildMacroException(status.getCode(), + macro.getName(), + status.getExpression(), + status.getReferencedMacroName(), + fContextInfo != null ? fContextInfo.getContextType() : 0, + fContextInfo != null ? fContextInfo.getContextData() : null); + } + } + throw e; + } + } + return resolvedMacro; + } + + private ResolvedMacro checkResolvingMacro(String name) + throws BuildMacroException{ + ResolvedMacro value = (ResolvedMacro)fResolvedMacros.get(name); + if(value == null){ + if(fMacrosUnderResolution.add(name)) + fMacroDescriptors.push(new MacroDescriptor(name,null)); + else { + // the macro of the specified name is referenced from the other macros that + // are referenced by the given macro + // e.g. ${macro1}="...${macro2}...", ${macro2}="...${macro1}..." + // in this case when resolving the ${macro1} value, the ${macro2} resolution will be requested, + // that in turn will call the ${macro1} resolution again. + // In this case if the fIncorrectlyReferencedMacroValue is null, the BuildMacroException will be thrown + // with the IBuildMacroStatus.TYPE_MACRO_REFERENCE_INCORRECT status + // The special case is when the , macro references itself, e.g. + // ${macro1} = "...${macro1}..." + // In the above example the ${macro1} reference will be expanded to the value of the ${macro1} macro of the + // parent context or to an empty string if there is no such macro defined in the parent contexts + MacroDescriptor last = (MacroDescriptor)fMacroDescriptors.lastElement(); + if(last != null && last.fName.equals(name)){ + value = resolveParentMacro(last); + if(value == null) + value = new ResolvedMacro(name,EMPTY_STRING,false); + }else if(fIncorrectlyReferencedMacroValue != null) + value = new ResolvedMacro(name,fIncorrectlyReferencedMacroValue,false); + else{ + throw new BuildMacroException(IBuildMacroStatus.TYPE_MACRO_REFERENCE_INCORRECT, + (String)null, + null, + name, + fContextInfo != null ? fContextInfo.getContextType() : 0, + fContextInfo != null ? fContextInfo.getContextData() : null); + } + } + } + + return value; + } + + private void addResolvedMacro(String name, ResolvedMacro value){ + fMacrosUnderResolution.remove(name); + fResolvedMacros.put(name,value); + fMacroDescriptors.pop(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor#getMacroContextInfo() + */ + public IMacroContextInfo getMacroContextInfo(){ + return fContextInfo; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/EclipseVariablesMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/EclipseVariablesMacroSupplier.java new file mode 100644 index 00000000000..e058a3544d1 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/EclipseVariablesMacroSupplier.java @@ -0,0 +1,174 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.variables.IDynamicVariable; +import org.eclipse.core.variables.IStringVariable; +import org.eclipse.core.variables.IStringVariableManager; +import org.eclipse.core.variables.IValueVariable; +import org.eclipse.core.variables.VariablesPlugin; + +/** + * This supplier suplies the macros that represent the Eclipse variables + * + * @since 3.0 + */ +public class EclipseVariablesMacroSupplier implements IBuildMacroSupplier { + private static final String VAR_PREFIX = "${"; //$NON-NLS-1$ + private static final char VAR_SUFFIX = '}'; //$NON-NLS-1$ + private static final char COLON = ':'; //$NON-NLS-1$ + + private static EclipseVariablesMacroSupplier fInstance; + + private EclipseVariablesMacroSupplier(){ + + } + + public static EclipseVariablesMacroSupplier getInstance(){ + if(fInstance == null) + fInstance = new EclipseVariablesMacroSupplier(); + return fInstance; + } + + public class EclipseVarMacro extends BuildMacro { + private IStringVariable fVariable; + private String fArgument; + private boolean fInitialized; + + private EclipseVarMacro(IStringVariable var){ + this(var,null); + } + + private EclipseVarMacro(IStringVariable var, String argument){ + fVariable = var; + fType = VALUE_TEXT; + fName = var.getName(); + if(argument != null) + fName += COLON + argument; + fArgument = argument; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringValue() + */ + public String getStringValue() throws BuildMacroException { + if(!fInitialized){ + loadValue(fVariable); + fInitialized = true; + } + return fStringValue; + } + + private void loadValue(IStringVariable var){ + if(var instanceof IDynamicVariable){ + IDynamicVariable dynamicVar = (IDynamicVariable)var; + if(fArgument == null || dynamicVar.supportsArgument()){ + try{ + fStringValue = dynamicVar.getValue(fArgument); + }catch(CoreException e){ + fStringValue = null; + } + }else + fStringValue = null; + + }else if(var instanceof IValueVariable){ + if(fArgument == null) + fStringValue = ((IValueVariable)var).getValue(); + else + fStringValue = null; + } + + } + + public IStringVariable getVariable(){ + return fVariable; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData) { + if(contextType != IBuildMacroProvider.CONTEXT_WORKSPACE) + return null; + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + + String varName = null; + String param = null; + IStringVariable var = null; + int index = macroName.indexOf(COLON); + if(index == -1) + varName = macroName; + else if(index > 0){ + varName = macroName.substring(0,index); + param = macroName.substring(index+1); + } + + if(varName != null){ + IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); + var = mngr.getValueVariable(varName); + if(var == null) + var = mngr.getDynamicVariable(varName); + } + + if(var != null) + return new EclipseVarMacro(var,param); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData) { + if(contextType != IBuildMacroProvider.CONTEXT_WORKSPACE) + return null; + + IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); + IDynamicVariable vars[] = mngr.getDynamicVariables(); + Map map = new HashMap(); + for(int i = 0; i < vars.length; i++) + map.put(vars[i].getName(),vars[i]); + + IValueVariable valVars[] = mngr.getValueVariables(); + for(int i = 0; i < valVars.length; i++) + map.put(valVars[i].getName(),valVars[i]); + + Collection collection = map.values(); + EclipseVarMacro macros[] = new EclipseVarMacro[collection.size()]; + Iterator iter = collection.iterator(); + for(int i = 0; i < macros.length ; i++) + macros[i] = new EclipseVarMacro((IStringVariable)iter.next()); + + return macros; + } + + private String getMacroValue(String name){ + IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); + try{ + return mngr.performStringSubstitution(VAR_PREFIX + name + VAR_SUFFIX); + }catch (CoreException e){ + } + + return null; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/EnvironmentMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/EnvironmentMacroSupplier.java new file mode 100644 index 00000000000..5326c5c55a5 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/EnvironmentMacroSupplier.java @@ -0,0 +1,182 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.List; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; +import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvVarOperationProcessor; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.core.resources.IWorkspace; + +/** + * This supplier suplies the macros that represent the Managed Build environment variables + * + * @since 3.0 + */ +public class EnvironmentMacroSupplier implements IBuildMacroSupplier { + private static EnvironmentMacroSupplier fInstance; + private IEnvironmentVariableProvider fEnvironmentProvider; + + public class EnvVarMacro extends BuildMacro{ + IBuildEnvironmentVariable fVariable; + private EnvVarMacro(IBuildEnvironmentVariable var){ + fName = var.getName(); + fVariable = var; + } + + private void loadValue(IBuildEnvironmentVariable var){ + String delimiter = var.getDelimiter(); + String value = var.getOperation() != IBuildEnvironmentVariable.ENVVAR_REMOVE ? + var.getValue() : null; + + if(delimiter != null && !"".equals(delimiter)){ //$NON-NLS-1$ + fType = VALUE_TEXT_LIST; + if(value != null){ + List list = EnvVarOperationProcessor.convertToList(value,delimiter); + fStringListValue = (String[])list.toArray(new String[list.size()]); + } else { + fStringListValue = null; + } + } else { + fType = VALUE_TEXT; + fStringValue = value; + } + } + + + public int getMacroValueType() { + if(fVariable != null){ + loadValue(fVariable); + + //we do not need it any more, release clean the reference + fVariable = null; + } + return super.getMacroValueType(); + } + + public String getStringValue() throws BuildMacroException { + if(fVariable != null){ + loadValue(fVariable); + + //we do not need it any more, release clean the reference + fVariable = null; + } + return super.getStringValue(); + } + + public String[] getStringListValue() throws BuildMacroException { + if(fVariable != null){ + loadValue(fVariable); + + //we do not need it any more, release clean the reference + fVariable = null; + } + return super.getStringListValue(); + } + } + + protected EnvironmentMacroSupplier(){ + this(ManagedBuildManager.getEnvironmentVariableProvider()); + } + + public EnvironmentMacroSupplier(IEnvironmentVariableProvider varProvider){ + fEnvironmentProvider = varProvider; + } + + public static EnvironmentMacroSupplier getInstance(){ + if(fInstance == null) + fInstance = new EnvironmentMacroSupplier(); + return fInstance; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData) { + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + + IBuildEnvironmentVariable var = null; + switch(contextType){ + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + var = fEnvironmentProvider.getVariable(macroName,contextData,false); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(contextData instanceof IManagedProject){ + var = fEnvironmentProvider.getVariable(macroName,contextData,false); + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(contextData instanceof IWorkspace){ + var = fEnvironmentProvider.getVariable(macroName,contextData,false); + } + break; + case IBuildMacroProvider.CONTEXT_ECLIPSEENV: + if(contextData == null){ + var = fEnvironmentProvider.getVariable(macroName,contextData,false); + } + break; + } + if(var != null && var.getOperation() != IBuildEnvironmentVariable.ENVVAR_REMOVE) + return new EnvVarMacro(var); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData) { + IBuildEnvironmentVariable vars[] = null; + + switch(contextType){ + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + vars = fEnvironmentProvider.getVariables(contextData,false); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(contextData instanceof IManagedProject){ + vars = fEnvironmentProvider.getVariables(contextData,false); + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(contextData instanceof IWorkspace){ + vars = fEnvironmentProvider.getVariables(contextData,false); + } + break; + case IBuildMacroProvider.CONTEXT_ECLIPSEENV: + if(contextData == null){ + vars = fEnvironmentProvider.getVariables(contextData,false); + } + break; + } + + if(vars != null){ + EnvVarMacro macros[] = new EnvVarMacro[vars.length]; + for(int i = 0; i < macros.length; i++) + macros[i] = new EnvVarMacro(vars[i]); + + return macros; + } + return null; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/ExplicitFileMacroCollector.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/ExplicitFileMacroCollector.java new file mode 100644 index 00000000000..83201cc2d43 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/ExplicitFileMacroCollector.java @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; + +/** + * This class is used by the MacroResolver to collect and present + * the explicit file macros referenced in the given expression + * + * @since 3.0 + */ +public class ExplicitFileMacroCollector extends DefaultMacroSubstitutor { + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private List fMacrosList = new ArrayList(); + + public ExplicitFileMacroCollector(int contextType, Object contextData){ + super(contextType, contextData, EMPTY_STRING, EMPTY_STRING); + } + + public ExplicitFileMacroCollector(IMacroContextInfo contextInfo){ + super(contextInfo, EMPTY_STRING, EMPTY_STRING); + } + + public ExplicitFileMacroCollector(ITool tool){ + super(null, EMPTY_STRING, EMPTY_STRING); + IBuildObject bo = tool.getParent(); + IConfiguration cfg = null; + if(bo instanceof IResourceConfiguration) + cfg = ((IResourceConfiguration)bo).getParent(); + else if (bo instanceof IToolChain) + cfg = ((IToolChain)bo).getParent(); + try{ + setMacroContextInfo(IBuildMacroProvider.CONTEXT_CONFIGURATION,cfg); + }catch (BuildMacroException e){ + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor#resolveMacro(org.eclipse.cdt.managedbuilder.macros.IBuildMacro) + */ + protected ResolvedMacro resolveMacro(IBuildMacro macro) throws BuildMacroException{ + if(macro instanceof MbsMacroSupplier.FileContextMacro){ + MbsMacroSupplier.FileContextMacro fileMacro = (MbsMacroSupplier.FileContextMacro)macro; + if(fileMacro.isExplicit()) + fMacrosList.add(macro); + return null; + } + return super.resolveMacro(macro); + } + + public IBuildMacro[] getExplicisFileMacros(){ + return (IBuildMacro[])fMacrosList.toArray(new IBuildMacro[fMacrosList.size()]); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/ExternalExtensionMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/ExternalExtensionMacroSupplier.java new file mode 100644 index 00000000000..17d9b37d4cb --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/ExternalExtensionMacroSupplier.java @@ -0,0 +1,225 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvVarOperationProcessor; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.cdt.managedbuilder.macros.IConfigurationBuildMacroSupplier; +import org.eclipse.cdt.managedbuilder.macros.IProjectBuildMacroSupplier; + +/** + * This supplier is used to suply macros provided by the tool-integrator + * + * @since 3.0 + */ +public class ExternalExtensionMacroSupplier implements IBuildMacroSupplier { + private static final String fNonOverloadableMacros[] = new String[]{ + //tool-integrators not allowed currently to override the "CWD" and "PWD" macros + "CWD", //$NON-NLS-1$ + "PWD" //$NON-NLS-1$ + }; + + private static ExternalExtensionMacroSupplier fInstance; + + private class ExtensionMacroProvider extends BuildMacroProvider{ + private IMacroContextInfo fStartInfo; + private int fContextType; + private Object fContextData; + private boolean fStartInitialized; + + public ExtensionMacroProvider(int contextType, Object contextData){ + fContextType = contextType; + fContextData = contextData; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider#getVariable(java.lang.String, java.lang.Object, boolean) + */ + public IBuildMacro getMacro(String macroName, + int contextType, + Object contextData, + boolean includeParent) { + if(getValidName(macroName) == null) + return null; + return super.getMacro(macroName,contextType,contextData,includeParent); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider#getMacros(int, java.lang.Object, boolean) + */ + public IBuildMacro[] getMacros(int contextType,Object contextData, boolean includeParent) { + return filterMacros(super.getMacros(contextType, contextData, includeParent)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider#getContextInfo(java.lang.Object) + */ + public IMacroContextInfo getMacroContextInfo(int contextType,Object contextData){ + IMacroContextInfo startInfo = getStartInfo(); + if(contextType == fContextType && + contextData == fContextData) + return startInfo; + + IMacroContextInfo info = super.getMacroContextInfo(contextType, contextData); + if(info == null) + return null; + + if(checkParentContextRelation(startInfo,info)) + return info; + return null; + } + + protected IMacroContextInfo getStartInfo(){ + if(fStartInfo == null && !fStartInitialized){ + IMacroContextInfo info = super.getMacroContextInfo(fContextType,fContextData); + if(info != null){ + IBuildMacroSupplier suppliers[] = info.getSuppliers(); + suppliers = filterValidSuppliers(suppliers); + if(suppliers != null) + fStartInfo = new DefaultMacroContextInfo(fContextType,fContextData,suppliers); + else + fStartInfo = info.getNext(); + fStartInitialized = true; + } + fStartInitialized = true; + } + return fStartInfo; + } + } + + + private ExternalExtensionMacroSupplier(){ + + } + + public static ExternalExtensionMacroSupplier getInstance(){ + if(fInstance == null) + fInstance = new ExternalExtensionMacroSupplier(); + return fInstance; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData) { + if((macroName = getValidName(macroName)) == null) + return null; + + switch(contextType){ + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + IConfiguration cfg = (IConfiguration)contextData; + IConfigurationBuildMacroSupplier supplier = cfg.getBuildMacroSupplier(); + if(supplier == null) + return null; + return supplier.getMacro(macroName,cfg,new ExtensionMacroProvider(contextType, contextData)); + } + case IBuildMacroProvider.CONTEXT_PROJECT: + if (contextData instanceof IManagedProject) { + IManagedProject project = (IManagedProject)contextData; + IProjectBuildMacroSupplier supplier = project.getProjectType().getBuildMacroSupplier(); + if(supplier == null) + return null; + return supplier.getMacro(macroName,project,new ExtensionMacroProvider(contextType, contextData)); + } + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData) { + IBuildMacro macros[] = null; + switch(contextType){ + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + IConfiguration cfg = (IConfiguration)contextData; + IConfigurationBuildMacroSupplier supplier = cfg.getBuildMacroSupplier(); + if(supplier != null) + macros = supplier.getMacros(cfg,new ExtensionMacroProvider(contextType, contextData)); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if (contextData instanceof IManagedProject) { + IManagedProject project = (IManagedProject)contextData; + IProjectBuildMacroSupplier supplier = project.getProjectType().getBuildMacroSupplier(); + if(supplier != null) + macros = supplier.getMacros(project,new ExtensionMacroProvider(contextType, contextData)); + } + } + return filterMacros(macros); + } + + protected String getValidName(String name){ + name = EnvVarOperationProcessor.normalizeName(name); + if(name == null) + return null; + if(fNonOverloadableMacros != null){ + for(int i = 0; i < fNonOverloadableMacros.length; i++){ + if(name.equals(fNonOverloadableMacros[i].toUpperCase())) + return null; + } + } + return name; + } + + protected IBuildMacro[] filterMacros(IBuildMacro macros[]){ + if(macros == null || macros.length == 0) + return macros; + + IBuildMacro filtered[] = new IBuildMacro[macros.length]; + int filteredNum = 0; + for(int i = 0; i < macros.length; i++){ + if(getValidName(macros[i].getName()) != null) + filtered[filteredNum++] = macros[i]; + } + + if(filteredNum != filtered.length){ + IBuildMacro m[] = new IBuildMacro[filteredNum]; + for(int i = 0; i < filteredNum; i++) + m[i] = filtered[i]; + filtered = m; + } + return filtered; + } + + protected IBuildMacroSupplier[] filterValidSuppliers(IBuildMacroSupplier suppliers[]){ + if(suppliers == null) + return null; + + int i = 0, j = 0; + for(i = 0; i < suppliers.length; i++){ + if(suppliers[i] == this) + break; + } + + + if(i >= suppliers.length) + return null; + + int startNum = i + 1; + + IBuildMacroSupplier validSuppliers[] = + new IBuildMacroSupplier[suppliers.length - startNum]; + + for(i = startNum, j = 0; i < suppliers.length; i++, j++) + validSuppliers[j] = suppliers[i]; + + return validSuppliers; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/FileContextBuildMacroValues.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/FileContextBuildMacroValues.java new file mode 100644 index 00000000000..5e46b3fc0e9 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/FileContextBuildMacroValues.java @@ -0,0 +1,127 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IManagedConfigElement; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues; + +/** + * The implementation of the IFileContextBuildMacroValues interface + * @since 3.0 + */ +public class FileContextBuildMacroValues implements + IFileContextBuildMacroValues { + + private IBuilder fBuilder; + private IFileContextBuildMacroValues fSupperClassValues; + + private HashMap fValues = new HashMap(); + private HashMap fAllValues = new HashMap(); + private boolean fInitialized; + + public FileContextBuildMacroValues(IBuilder builder, IManagedConfigElement element){ + fBuilder = builder; + load(element); + } + + private void load(IManagedConfigElement element){ + String names[] = MbsMacroSupplier.getInstance().getMacroNames(IBuildMacroProvider.CONTEXT_FILE); + fValues.clear(); + for(int i = 0; i < names.length; i++){ + String value = element.getAttribute(PREFIX + names[i] + SUFFIX); + if(value != null) + fValues.put(names[i],value); + } + } + + private void load(){ + if(!fInitialized){ + fAllValues.clear(); + IFileContextBuildMacroValues supperValues = getSupperClassValues(); + if(supperValues != null) { + String names[] = MbsMacroSupplier.getInstance().getMacroNames(IBuildMacroProvider.CONTEXT_FILE); + for(int i = 0; i < names.length; i++){ + String value = (String)fValues.get(names[i]); + if(value == null) + value = supperValues.getMacroValue(names[i]); + if(value != null && value.length() > 0) + fAllValues.put(names[i],value); + } + } else { + Iterator iter = fValues.entrySet().iterator(); + while(iter.hasNext()){ + Map.Entry entry = (Map.Entry)iter.next(); + String value = (String)entry.getValue(); + if(value != null && value.length() > 0) + fAllValues.put(entry.getKey(),value); + } + } + fInitialized = true; + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues#getSupportedMacros() + */ + public String[] getSupportedMacros() { + load(); + Set set = fAllValues.keySet(); + String names[] = new String[set.size()]; + Iterator iter = set.iterator(); + for(int i = 0; i < names.length; i++) + names[i] = (String)iter.next(); + return names; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues#getMacroValue(java.lang.String) + */ + public String getMacroValue(String macroName) { + load(); + return (String)fAllValues.get(macroName); + } + + public IFileContextBuildMacroValues getSupperClassValues(){ + if(fBuilder != null){ + IBuilder supperClass = fBuilder.getSuperClass(); + if(supperClass != null) + fSupperClassValues = supperClass.getFileContextBuildMacroValues(); + } + return fSupperClassValues; + } + + public void setBuilder(IBuilder builder){ + fBuilder = builder; + fInitialized = false; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone(){ + FileContextBuildMacroValues cloned = null; + try{ + cloned = (FileContextBuildMacroValues)super.clone(); + cloned.fValues = (HashMap)fValues.clone(); + cloned.fAllValues = (HashMap)fAllValues.clone(); + } catch (CloneNotSupportedException e){ + } + + return cloned; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/FileContextData.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/FileContextData.java new file mode 100644 index 00000000000..64c7d13fe96 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/FileContextData.java @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.macros.IFileContextData; +import org.eclipse.cdt.managedbuilder.macros.IOptionContextData; +import org.eclipse.core.runtime.IPath; + +/** + * This is a trivial implementation of the IFileContextData used internaly by the MBS + * + * @since 3.0 + */ +public class FileContextData implements IFileContextData { + private IPath fInputFileLocation; + private IPath fOutputFileLocation; + private IOptionContextData fOptionContextData; + + public FileContextData(IPath inputFileLocation, IPath outputFileLocation, IOption option, IBuildObject optionParent){ + this(inputFileLocation, outputFileLocation, new OptionContextData(option,optionParent)); + } + + public FileContextData(IPath inputFileLocation, IPath outputFileLocation, IOptionContextData optionContextData){ + fInputFileLocation = inputFileLocation; + fOutputFileLocation = outputFileLocation; + fOptionContextData = optionContextData; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IFileContextData#getInputFileLocation() + */ + public IPath getInputFileLocation() { + return fInputFileLocation; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IFileContextData#getOutputFileLocation() + */ + public IPath getOutputFileLocation() { + return fOutputFileLocation; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IFileContextData#getOption() + */ + public IOptionContextData getOptionContextData() { + return fOptionContextData; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/IMacroContextInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/IMacroContextInfo.java new file mode 100644 index 00000000000..e62ea8196a5 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/IMacroContextInfo.java @@ -0,0 +1,48 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; + +/** + * This interface represents the context information. + * + * @since 3.0 + */ +public interface IMacroContextInfo { + /** + * returns the context type + * + * @return int + */ + public int getContextType(); + + /** + * returns the context data + * + * @return Object + */ + public Object getContextData(); + + /** + * Returns suppliers to be used for this context + * + * @return IBuildMacroSupplier[] + */ + public IBuildMacroSupplier[] getSuppliers(); + + /** + * Returns context info for the next lower-precedence context + * + * @return IMacroContextInfo + */ + public IMacroContextInfo getNext(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/IMacroSubstitutor.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/IMacroSubstitutor.java new file mode 100644 index 00000000000..1fe793ea7fb --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/IMacroSubstitutor.java @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; + + +/** + * This interface represents the logic of how macro references should be resolved + * The implementer of this interface is passed to the MacroResolver and + * when the the resolve* methods of this interface are called by the MacroResolver + * each time the macro reference is encountered in the string being resolved + * to resolve the macro encountered macro reference + * + * @since 3.0 + */ +public interface IMacroSubstitutor { + + /** + * called to resolve to String the macro reference of the specified name + * + * @param macroName the macro name + * @return String + * @throws BuildMacroException + */ + public String resolveToString(String macroName) throws BuildMacroException; + + /** + * called to resolve to String-List the macro reference of the specified name + * + * @param macroName the macro name + * @return String[] + * @throws BuildMacroException + */ + public String[] resolveToStringList(String macroName) throws BuildMacroException; + + /** + * called to set the context type and context info to be used + * + * @param contextType the context type + * @param contextData the context data + * @throws BuildMacroException + */ + public void setMacroContextInfo(int contextType, Object contextData) throws BuildMacroException; + + /** + * returns the macro conttext info used + * @return IMacroContextInfo + */ + public IMacroContextInfo getMacroContextInfo(); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MacroResolver.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MacroResolver.java new file mode 100644 index 00000000000..1210ee6aa79 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MacroResolver.java @@ -0,0 +1,392 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.internal.core.Tool; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus; + +/** + * This is the utility class used to resolve macro references and that provides + * other functionality related to the macro resolving + * + * @since 3.0 + */ +public class MacroResolver { + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + public static final String MACRO_PREFIX = "${"; //$NON-NLS-1$ + public static final char MACRO_SUFFIX = '}'; //$NON-NLS-1$ + public static final char MACRO_ESCAPE_CHAR = '\\'; //$NON-NLS-1$ + private static final int MACRO_PREFIX_LENGTH = MACRO_PREFIX.length(); + private static final String PATTERN_MACRO_NAME = "="; //$NON-NLS-1$ + + static public String convertStringListToString(String value[], String listDelimiter) { + + if(value == null || value.length == 0) + return EMPTY_STRING; + + StringBuffer buffer = new StringBuffer(); + for(int i = 0; i < value.length; i++){ + buffer.append(value[i]); + if(listDelimiter != null && !EMPTY_STRING.equals(listDelimiter) && i < value.length -1 ) + buffer.append(listDelimiter); + } + return buffer.toString(); + } + + /** + * resolves macros in the given string by calling the macro subsitutor for each macro reference found + * + * @param string + * @param substitutor + * @return resolved string + * + * @throws BuildMacroException + */ + static public String resolveToString(String string, IMacroSubstitutor substitutor) + throws BuildMacroException{ + return (String)resolve(string,substitutor,false,false); + } + + /** + * finds the macro references in the given string and calls the macro substitutor for each macro found + * this could be used for obtaining the list of macros referenced in the given string, etc. + * + * @param string + * @param substitutor + * @throws BuildMacroException + */ + static public void checkMacros(String string, IMacroSubstitutor substitutor) + throws BuildMacroException{ + resolve(string, substitutor, false, true); + } + + static private Object resolve(String string, IMacroSubstitutor substitutor, boolean asList, boolean checkOnly) + throws BuildMacroException{ + if(string == null) + return EMPTY_STRING; + + int macroStart = -1; + int macroEnd = -1; + int processed = 0; + StringBuffer buffer = checkOnly ? null : new StringBuffer(); + boolean listMode = false; + String listValue[] = null; + final int length = string.length(); + + do{ + //find macro prefix + macroStart = string.indexOf(MACRO_PREFIX, macroEnd+1); + if(macroStart == -1){ + if(buffer != null) + buffer.append(string.substring(processed,length)); + break; + } + + //macro prefix found, find macro suffix + macroEnd = string.indexOf(MACRO_SUFFIX, macroStart); + if(macroEnd == -1){ + if(buffer != null) + buffer.append(string.substring(processed,length)); + break; + } + + if(asList && macroStart == 0 && macroEnd == length - 1) + listMode = true; + + //check whether macro is prepended with the back-clash + if(macroStart > 0 && MACRO_ESCAPE_CHAR == string.charAt(macroStart - 1)){ + int num; + for(num = macroStart-2; num >= 0 && MACRO_ESCAPE_CHAR == string.charAt(num); num--){} + + //number of back-slashes + num = macroStart - num - 1; + if(buffer != null) + buffer.append(string.substring(processed,macroStart - ((num + 1) >> 1))); + + if((num & 1) == 0) + processed = macroStart; + else { + if(buffer != null) + buffer.append(string.substring(macroStart,macroEnd+1)); + processed = macroEnd+1; + continue; + } + } + + if(macroStart > processed && buffer != null) + buffer.append(string.substring(processed,macroStart)); + + String name = string.substring(macroStart + MACRO_PREFIX_LENGTH, macroEnd); + if(!EMPTY_STRING.equals(name)){ + + if(listMode){ + listValue = substitutor.resolveToStringList(name); + if(listValue == null) + throw new BuildMacroException(IBuildMacroStatus.TYPE_MACRO_UNDEFINED,(String)null,string,name,0,null); + } + else{ + String resolved = substitutor.resolveToString(name); + if(resolved == null) + throw new BuildMacroException(IBuildMacroStatus.TYPE_MACRO_UNDEFINED,(String)null,string,name,0,null); + if(buffer != null) + buffer.append(resolved); + } + } + processed = macroEnd+1; + + }while(true); + + if(asList){ + String result[] = null; + if(listMode){ + if(listValue != null) + result = listValue; + else + result = new String[0]; + } + else if(buffer != null) + result = new String[]{buffer.toString()}; + return result; + } + else if(buffer != null) + return buffer.toString(); + return null; + } + + /** + * resolves macros in the array of string-list values + * @param values + * @param substitutor + * @param ignoreErrors + * @return + * @throws BuildMacroException + */ + static public String[] resolveStringListValues(String values[], IMacroSubstitutor substitutor, boolean ignoreErrors) + throws BuildMacroException { + String result[] = null; + if(values == null || values.length == 0) + result = values; + else if(values.length == 1) + try { + result = MacroResolver.resolveToStringList(values[0], substitutor); + } catch (BuildMacroException e) { + if(!ignoreErrors) + throw e; + } + else { + List list = new ArrayList(); + for(int i = 0; i < values.length; i++){ + String resolved[]; + try { + resolved = MacroResolver.resolveToStringList(values[i], substitutor); + if(resolved != null && resolved.length > 0) + list.addAll(Arrays.asList(resolved)); + } catch (BuildMacroException e) { + if(!ignoreErrors) + throw e; + } + } + + result = (String[])list.toArray(new String[list.size()]); + } + return result; + } + + /** + * Resolves macros in the given String to the String-list + * + * @param string + * @param substitutor + * @return + * @throws BuildMacroException + */ + static public String[] resolveToStringList(String string, IMacroSubstitutor substitutor) + throws BuildMacroException{ + return (String[])resolve(string,substitutor,true,false); + } + + /** + * returns true if the given macro is a String-list macro. + * + * @param macroType + * @return + */ + public static boolean isStringListMacro(int macroType){ + switch(macroType){ + case IBuildMacro.VALUE_TEXT_LIST: + case IBuildMacro.VALUE_PATH_FILE_LIST: + case IBuildMacro.VALUE_PATH_DIR_LIST: + case IBuildMacro.VALUE_PATH_ANY_LIST: + return true; + default: + return false; + } + } + + /** + * checks the macros integrity for the given context + * + * @param provider + * @param contextType + * @param contextData + * @throws BuildMacroException + */ + public static void checkIntegrity( + IMacroContextInfo info, + IMacroSubstitutor substitutor) throws BuildMacroException{ + + if(info != null){ + IBuildMacro macros[] = BuildMacroProvider.getMacros(info,true); + if(macros != null){ + for(int i = 0; i < macros.length; i++){ + IBuildMacro macro = macros[i]; + if(isStringListMacro(macro.getMacroValueType())) + substitutor.resolveToStringList(macro.getName()); + else + substitutor.resolveToString(macro.getName()); + } + } + } + } + + /** + * creates a macro reference given the macro name + * e.g. if the "macro1" name is passed, returns "${macro1}" + * + * @param name + * @return String + */ + public static String createMacroReference(String name){ + return MACRO_PREFIX + name + MACRO_SUFFIX; + } + + /** + * answers whether the builder used for the given configuration is capable + * of handling macros in the buildfile + * + * @param cfg + * @return + */ + public static boolean canKeepMacrosInBuildfile(IConfiguration cfg){ + if(cfg != null){ + IToolChain toolChain = cfg.getToolChain(); + if(toolChain != null) + return canKeepMacrosInBuildfile(toolChain.getBuilder()); + } + return false; + } + + /** + * answers whether the given builder is capable + * of handling macros in the buildfile + * + * @param builder + * @return + */ + public static boolean canKeepMacrosInBuildfile(IBuilder builder){ + if(builder != null){ + String pattern = builder.getBuilderVariablePattern(); + if(pattern != null && pattern.indexOf(PATTERN_MACRO_NAME) != -1) + return true; + } + return false; + } + + /** + * creates a macro reference in the buildfile format for the given builder. + * If the builder can not treat macros, returns null + * @param name + * @param builder + * @return String + */ + public static String createBuildfileMacroReference(String name, IBuilder builder){ + String ref = null; + if(builder != null){ + String pattern = builder.getBuilderVariablePattern(); + if(pattern != null && pattern.indexOf(PATTERN_MACRO_NAME) != -1) + ref = pattern.replaceAll(PATTERN_MACRO_NAME,name); + } + return ref; + } + + /** + * creates a macro reference in the buildfile format for the builder used for + * the given configuration. + * If the builder can not treat macros, returns null + * @param name + * @param cfg + * @return String + */ + public static String createBuildfileMacroReference(String name, IConfiguration cfg){ + String ref = null; + if(cfg != null){ + IToolChain toolChain = cfg.getToolChain(); + if(toolChain != null) + ref = createBuildfileMacroReference(name,toolChain.getBuilder()); + } + return ref; + } + + /** + * Returns the array of the explicit file macros, referenced in the tool's options + * (Explicit file macros are the file-specific macros, whose values are not provided + * by the tool-integrator. As a result these macros contain explicit values, but not the values + * specified in the format of the builder automatic variables and text functions) + * + * @param tool + * @return + */ + public static IBuildMacro[] getReferencedExplitFileMacros(ITool tool){ + if(tool instanceof Tool){ + Tool t = (Tool)tool; + ExplicitFileMacroCollector collector = new ExplicitFileMacroCollector(tool); + try { + t.getToolCommandFlags(null,null,collector); + } catch (BuildException e){ + } + return collector.getExplicisFileMacros(); + } + return new IBuildMacro[0]; + } + + /** + * Returns the array of the explicit file macros, referenced in the given string + * (Explicit file macros are the file-specific macros, whose values are not provided + * by the tool-integrator. As a result these macros contain explicit values, but not the values + * specified in the format of the builder automatic variables and text functions) + * + * @param expression + * @param contextType + * @param contextData + * @return + */ + public static IBuildMacro[] getReferencedExplitFileMacros(String expression, int contextType, Object contextData){ + ExplicitFileMacroCollector collector = new ExplicitFileMacroCollector(contextType,contextData); + try { + resolveToString(expression,collector); + } catch (BuildMacroException e){ + } + return collector.getExplicisFileMacros(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java new file mode 100644 index 00000000000..c4a080838d4 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/MbsMacroSupplier.java @@ -0,0 +1,908 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IBuilder; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IInputType; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.cdt.managedbuilder.macros.IFileContextBuildMacroValues; +import org.eclipse.cdt.managedbuilder.macros.IFileContextData; +import org.eclipse.cdt.managedbuilder.macros.IOptionContextData; +import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; + +/** + * This supplier is used to suply MBS-predefined macros + * + * @since 3.0 + */ +public class MbsMacroSupplier implements IBuildMacroSupplier { + private static MbsMacroSupplier fInstance; + public final static String DOT = "."; //$NON-NLS-1$ + public final static String EMPTY_STRING = ""; //$NON-NLS-1$ + + + private static final String fFileMacros[] = new String[]{ + "InputFileName", //$NON-NLS-1$ + "InputFileExt", //$NON-NLS-1$ + "InputFileBaseName", //$NON-NLS-1$ + "InputFileRelPath", //$NON-NLS-1$ + "InputDirRelPath", //$NON-NLS-1$ + "OutputFileName", //$NON-NLS-1$ + "OutputFileExt", //$NON-NLS-1$ + "OutputFileBaseName", //$NON-NLS-1$ + "OutputFileRelPath", //$NON-NLS-1$ + "OutputDirRelPath", //$NON-NLS-1$ + }; + + private static final String fOptionMacros[] = new String[]{ + "IncludeDefaults", //$NON-NLS-1$ + }; + + private static final String fConfigurationMacros[] = new String[]{ + "ConfigName", //$NON-NLS-1$ + "ConfigDescription", //$NON-NLS-1$ + "BuildArtifactFileName", //$NON-NLS-1$ + "BuildArtifactFileExt", //$NON-NLS-1$ + "BuildArtifactFileBaseName", //$NON-NLS-1$ + "BuildArtifactFilePrefix", //$NON-NLS-1$ + "TargetOsList", //$NON-NLS-1$ + "TargetArchList", //$NON-NLS-1$ + }; + + private static final String fProjectMacros[] = new String[]{ + "ProjName", //$NON-NLS-1$ + "ProjDirPath", //$NON-NLS-1$ + }; + + private static final String fWorkspaceMacros[] = new String[]{ + "WorkspaceDirPath", //$NON-NLS-1$ + "DirectoryDelimiter", //$NON-NLS-1$ + "PathDelimiter", //$NON-NLS-1$ + }; + + private static final String fCDTEclipseMacros[] = new String[]{ + "EclipseVersion", //$NON-NLS-1$ + "CDTVersion", //$NON-NLS-1$ + "MBSVersion", //$NON-NLS-1$ + "HostOsName", //$NON-NLS-1$ + "HostArchName", //$NON-NLS-1$ + }; + + public class FileContextMacro extends BuildMacro{ + private IFileContextData fContextData; + private IConfiguration fConfiguration; + private boolean fIsExplicit = true; + private boolean fIsInitialized; + private String fExplicitValue; + private boolean fIsExplicitResolved; + private FileContextMacro(String name, IFileContextData contextData){ + fName = name; + fType = VALUE_TEXT; + fContextData = contextData; + } + + private void loadValue(){ + if(fIsInitialized) + return; + IBuilder builder = null; + IOptionContextData optionContext = fContextData.getOptionContextData(); + if(optionContext != null){ + IBuildObject buildObject = optionContext.getParent(); + if(buildObject instanceof IToolChain){ + IToolChain toolChain = (IToolChain)buildObject; + builder = toolChain.getBuilder(); + fConfiguration = toolChain.getParent(); + } else if (buildObject instanceof IResourceConfiguration){ + fConfiguration = ((IResourceConfiguration)buildObject).getParent(); + if(fConfiguration != null){ + IToolChain toolChain = fConfiguration.getToolChain(); + if(toolChain != null) + builder = toolChain.getBuilder(); + } + } + } + + if(builder != null){ + IFileContextBuildMacroValues values = builder.getFileContextBuildMacroValues(); + String value = values.getMacroValue(fName); + if(value != null){ + fStringValue = value; + fIsExplicit = false; + } + } + + if(fStringValue == null){ + fIsExplicit = true; + fStringValue = getExplicitFileMacroValue(fName, fContextData.getInputFileLocation(), fContextData.getOutputFileLocation(), fConfiguration); + fExplicitValue = fStringValue; + fIsExplicitResolved = true; + } + + fIsInitialized = true; + } + + public String getExplicitMacroValue(){ + loadValue(); + if(!fIsExplicitResolved){ + fExplicitValue = getExplicitFileMacroValue(fName, fContextData.getInputFileLocation(), fContextData.getOutputFileLocation(), fConfiguration); + fIsExplicitResolved = true; + } + return fExplicitValue; + } + + public boolean isExplicit(){ + loadValue(); + return fIsExplicit; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacro#getStringValue() + */ + public String getStringValue(){ + loadValue(); + return fStringValue; + } + } + + private String getExplicitFileMacroValue(String name, IPath inputFileLocation, IPath outputFileLocation, IConfiguration cfg){ + String value = null; + if("InputFileName".equals(name)){ //$NON-NLS-1$ + if(inputFileLocation != null && inputFileLocation.segmentCount() > 0) + value = inputFileLocation.lastSegment(); + }else if("InputFileExt".equals(name)){ //$NON-NLS-1$ + if(inputFileLocation != null && inputFileLocation.segmentCount() > 0) + value = getExtension(inputFileLocation.lastSegment()); + }else if("InputFileBaseName".equals(name)){ //$NON-NLS-1$ + if(inputFileLocation != null && inputFileLocation.segmentCount() > 0) + value = getBaseName(inputFileLocation.lastSegment()); + }else if("InputFileRelPath".equals(name)){ //$NON-NLS-1$ + if(inputFileLocation != null && inputFileLocation.segmentCount() > 0){ + IPath workingDirectory = getBuilderCWD(cfg); + if(workingDirectory != null){ + IPath filePath = calculateRelPath(workingDirectory, inputFileLocation); + if(filePath != null) + value = filePath.toOSString(); + } + } + } + else if("InputDirRelPath".equals(name)){ //$NON-NLS-1$ + if(inputFileLocation != null && inputFileLocation.segmentCount() > 0){ + IPath workingDirectory = getBuilderCWD(cfg); + if(workingDirectory != null){ + IPath filePath = calculateRelPath(workingDirectory, inputFileLocation.removeLastSegments(1).addTrailingSeparator()); + if(filePath != null) + value = filePath.toOSString(); + } + } + } + else if("OutputFileName".equals(name)){ //$NON-NLS-1$ + if(outputFileLocation != null && outputFileLocation.segmentCount() > 0) + value = outputFileLocation.lastSegment(); + }else if("OutputFileExt".equals(name)){ //$NON-NLS-1$ + if(outputFileLocation != null && outputFileLocation.segmentCount() > 0) + value = getExtension(outputFileLocation.lastSegment()); + }else if("OutputFileBaseName".equals(name)){ //$NON-NLS-1$ + if(outputFileLocation != null && outputFileLocation.segmentCount() > 0) + value = getBaseName(outputFileLocation.lastSegment()); + }else if("OutputFileRelPath".equals(name)){ //$NON-NLS-1$ + if(outputFileLocation != null && outputFileLocation.segmentCount() > 0){ + IPath workingDirectory = getBuilderCWD(cfg); + if(workingDirectory != null){ + IPath filePath = calculateRelPath(workingDirectory, outputFileLocation); + if(filePath != null) + value = filePath.toOSString(); + } + } + }else if("OutputDirRelPath".equals(name)){ //$NON-NLS-1$ + if(outputFileLocation != null && outputFileLocation.segmentCount() > 0){ + IPath workingDirectory = getBuilderCWD(cfg); + if(workingDirectory != null){ + IPath filePath = calculateRelPath(workingDirectory, outputFileLocation.removeLastSegments(1).addTrailingSeparator()); + if(filePath != null) + value = filePath.toOSString(); + } + } + } + + return value; + } + + public String[] getMacroNames(int contextType){ + return getMacroNames(contextType,true); + } + + private String[] getMacroNames(int contextType, boolean clone){ + String names[] = null; + switch(contextType){ + case IBuildMacroProvider.CONTEXT_FILE: + names = fFileMacros; + break; + case IBuildMacroProvider.CONTEXT_OPTION: + names = fOptionMacros; + break; + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + names = fConfigurationMacros; + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + names = fProjectMacros; + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + names = fWorkspaceMacros; + break; + case IBuildMacroProvider.CONTEXT_INSTALLATIONS: + names = fCDTEclipseMacros; + break; + case IBuildMacroProvider.CONTEXT_ECLIPSEENV: + break; + } + if(names != null) + return clone ? (String[])names.clone() : names; + return null; + } + + private MbsMacroSupplier(){ + + } + + public static MbsMacroSupplier getInstance(){ + if(fInstance == null) + fInstance = new MbsMacroSupplier(); + return fInstance; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData) { + IBuildMacro macro = null; + switch(contextType){ + case IBuildMacroProvider.CONTEXT_FILE: + if(contextData instanceof IFileContextData){ + for(int i = 0; i < fFileMacros.length; i++){ + if(macroName.equals(fFileMacros[i])) + macro = new FileContextMacro(macroName,(IFileContextData)contextData); + } + } + break; + case IBuildMacroProvider.CONTEXT_OPTION: + if(contextData instanceof IOptionContextData){ + macro = getMacro(macroName, (IOptionContextData)contextData); + } + break; + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + macro = getMacro(macroName, (IConfiguration)contextData); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(contextData instanceof IManagedProject){ + macro = getMacro(macroName, (IManagedProject)contextData); + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(contextData instanceof IWorkspace){ + macro = getMacro(macroName, (IWorkspace)contextData); + } + break; + case IBuildMacroProvider.CONTEXT_INSTALLATIONS: + if(contextData == null){ + macro = getMacro(macroName); + } + break; + case IBuildMacroProvider.CONTEXT_ECLIPSEENV: + break; + } + + return macro; + } + + public IBuildMacro getMacro(String macroName, IOptionContextData optionContext){ + IBuildMacro macro = null; + if("IncludeDefaults".equals(macroName)){ //$NON-NLS-1$ + if(!canHandle(optionContext)) + optionContext = null; + macro = new OptionMacro(macroName,optionContext); + } + return macro; + } + + public IBuildMacro getMacro(String macroName, IConfiguration cfg){ + IBuildMacro macro = null; + if("ConfigName".equals(macroName)){ //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,cfg.getName()); + } + else if("ConfigDescription".equals(macroName)){ //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,cfg.getDescription()); + } + else if("BuildArtifactFileName".equals(macroName)){ //$NON-NLS-1$ + String name = cfg.getArtifactName(); + String ext = cfg.getArtifactExtension(); + if(ext != null && !EMPTY_STRING.equals(ext)) + name = name + DOT + ext; + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,name); + } + else if("BuildArtifactFileExt".equals(macroName)){ //$NON-NLS-1$ + String ext = cfg.getArtifactExtension(); + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,ext); + } + else if("BuildArtifactFileBaseName".equals(macroName)){ //$NON-NLS-1$ + String name = cfg.getArtifactName(); + ITool targetTool = cfg.getTargetTool(); + if(targetTool != null){ + IOutputType pot = targetTool.getPrimaryOutputType(); + String prefix = pot.getOutputPrefix(); + if(prefix != null && !EMPTY_STRING.equals(prefix)) + name = prefix + name; + } + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,name); + } + else if("BuildArtifactFilePrefix".equals(macroName)){ //$NON-NLS-1$ + ITool targetTool = cfg.getTargetTool(); + if(targetTool != null){ + IOutputType pot = targetTool.getPrimaryOutputType(); + String prefix = pot.getOutputPrefix(); + if(prefix == null) + prefix = EMPTY_STRING; + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,prefix); + } + } + else if("TargetOsList".equals(macroName)){ //$NON-NLS-1$ + IToolChain toolChain = cfg.getToolChain(); + String osList[] = toolChain.getOSList(); + if(osList == null) + osList = new String[0]; + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT_LIST,osList); + } + else if("TargetArchList".equals(macroName)){ //$NON-NLS-1$ + IToolChain toolChain = cfg.getToolChain(); + String archList[] = toolChain.getArchList(); + if(archList == null) + archList = new String[0]; + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT_LIST,archList); + + } + return macro; + } + + private String getBaseName(String name){ + String value = null; + int index = name.lastIndexOf('.'); + if(index == -1) + value = name; + else + value = name.substring(0,index); + return value; + } + + private String getExtension(String name){ + String value = null; + int index = name.lastIndexOf('.'); + if(index != -1) + value = name.substring(index+1); + return value; + } + + public IBuildMacro getMacro(String macroName, IManagedProject mngProj){ + IBuildMacro macro = null; + if("ProjName".equals(macroName)){ //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,mngProj.getOwner().getName()); + } + else if("ProjDirPath".equals(macroName)){ //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_PATH_DIR,mngProj.getOwner().getLocation().toOSString()); + } + return macro; + } + + public IBuildMacro getMacro(String macroName, IWorkspace wsp){ + IBuildMacro macro = null; + if("WorkspaceDirPath".equals(macroName)){ //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_PATH_DIR,wsp.getRoot().getLocation().toOSString()); + } else if("DirectoryDelimiter".equals(macroName)){ //$NON-NLS-1$ + if(isWin32()){ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,"\\"); //$NON-NLS-1$ + } else { + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,"/"); //$NON-NLS-1$ + } + } else if("PathDelimiter".equals(macroName)){ //$NON-NLS-1$ + if(isWin32()){ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,";"); //$NON-NLS-1$ + } else { + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,":"); //$NON-NLS-1$ + } + } + return macro; + } + + private boolean isWin32(){ + String os = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$ + if (os.startsWith("windows ")) //$NON-NLS-1$ + return true; + return false; + } + + public IBuildMacro getMacro(String macroName){ + IBuildMacro macro = null; + if("EclipseVersion".equals(macroName)){ //$NON-NLS-1$ + Bundle bundle = Platform.getBundle("org.eclipse.platform"); //$NON-NLS-1$ + String version = bundle != null ? + (String)bundle.getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION) : + null; + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,version); + } + else if("CDTVersion".equals(macroName)){ //$NON-NLS-1$ + String version = (String)CCorePlugin.getDefault().getBundle().getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION); + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,version); + } + else if("MBSVersion".equals(macroName)){ //$NON-NLS-1$ + String version = ManagedBuildManager.getBuildInfoVersion().toString(); + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,version); + } + else if("HostOsName".equals(macroName)){ //$NON-NLS-1$ + String os = System.getProperty("os.name"); //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,os); + } + else if("HostArchName".equals(macroName)){ //$NON-NLS-1$ + String arch = System.getProperty("os.arch"); //$NON-NLS-1$ + macro = new BuildMacro(macroName,IBuildMacro.VALUE_TEXT,arch); + } + return macro; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData) { + String names[] = getMacroNames(contextType,false); + + if(names != null){ + IBuildMacro macros[] = new IBuildMacro[names.length]; + int num = 0; + for(int i = 0; i < names.length; i++){ + IBuildMacro macro = getMacro(names[i],contextType,contextData); + if(macro != null) + macros[num++] = macro; + } + IBuildMacro result[] = new IBuildMacro[num]; + if(num > 0) + System.arraycopy(macros,0,result,0,num); + return result; + } + return null; + } + + private IPath getBuilderCWD(IConfiguration cfg){ + IPath workingDirectory = null; + IResource owner = cfg.getOwner(); + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(owner); + + if(info != null){ + if(info.getDefaultConfiguration().equals(cfg)){ + IManagedBuilderMakefileGenerator generator = ManagedBuildManager.getBuildfileGenerator(info.getDefaultConfiguration()); + generator.initialize((IProject)owner,info,null); + + IPath topBuildDir = generator.getBuildWorkingDir(); + if(topBuildDir == null) + topBuildDir = new Path(info.getConfigurationName()); + + IPath projectLocation = owner.getLocation(); + workingDirectory = projectLocation.append(topBuildDir); + } + } + return workingDirectory; + } + + private IPath calculateRelPath(IPath container, IPath contents){ + IPath path = contents; + if(container.isPrefixOf(contents)){ + path = contents.setDevice(null).removeFirstSegments(container.segmentCount()); + } else { + String file = null; + container = container.addTrailingSeparator(); + if(!contents.hasTrailingSeparator()){ + file = contents.lastSegment(); + contents = contents.removeLastSegments(1); + contents = contents.addTrailingSeparator(); + } + + IPath prefix = contents; + for(;prefix.segmentCount() > 0 && !prefix.isPrefixOf(container);prefix = prefix.removeLastSegments(1)){ + } + if(prefix.segmentCount() > 0){ + int diff = container.segmentCount() - prefix.segmentCount(); + StringBuffer buff = new StringBuffer(); + while(diff-- > 0) + buff.append("../"); //$NON-NLS-1$ + path = new Path(buff.toString()).append(contents.removeFirstSegments(prefix.segmentCount())); + if(file != null) + path = path.append(file); + } + } + return path; + } + + private IPath getOutputFilePath(IPath inputPath, IConfiguration cfg){ + ITool buildTools[] = null; + IResourceConfiguration rcCfg = cfg.getResourceConfiguration(inputPath.toOSString()); + if(rcCfg != null) + buildTools = rcCfg.getTools(); + else + buildTools = cfg.getFilteredTools(); + + String name = null; + IPath path = null; + for(int i = 0; i < buildTools.length; i++){ + ITool tool = buildTools[i]; + IInputType inputType = tool.getInputType(inputPath.getFileExtension()); + if(inputType != null){ + IOutputType prymOutType = tool.getPrimaryOutputType(); + String names[] = prymOutType.getOutputNames(); + if(names != null && names.length > 0) + name = names[0]; + } + } + if(name != null){ + IPath namePath = new Path(name); + if(namePath.isAbsolute()){ + path = namePath; + } + else{ + IPath cwd = getBuilderCWD(cfg); + if(cwd != null) + path = cwd.append(namePath); + } + } + return path; + + } + + /* (non-Javadoc) + * Returns the option that matches the option ID in this tool + */ + public IOption getOption(ITool tool, String optionId) { + if (optionId == null) return null; + + // Look for an option with this ID, or an option with a superclass with this id + IOption[] options = tool.getOptions(); + for (int i = 0; i < options.length; i++) { + IOption targetOption = options[i]; + IOption option = targetOption; + do { + if (optionId.equals(option.getId())) { + return targetOption; + } + option = option.getSuperClass(); + } while (option != null); + } + + return null; + } + + private class IncludeDefaultsSubstitutor implements IMacroSubstitutor { + private IOptionContextData fOptionContextData; + + public IncludeDefaultsSubstitutor(IOptionContextData data){ + fOptionContextData = data; + } + + public String resolveToString(String macroName) throws BuildMacroException { + if(!"IncludeDefaults".equals(macroName)) //$NON-NLS-1$ + return MacroResolver.createMacroReference(macroName); + IOptionContextData parent = getParent(fOptionContextData); + if(parent == null) + return EMPTY_STRING; + IncludeDefaultsSubstitutor sub = new IncludeDefaultsSubstitutor(parent); + IOption option = parent.getOption(); + String str = null; + String strL[] = null; + try{ + switch(option.getValueType()){ + case IOption.STRING : + str = option.getStringValue(); + break; + case IOption.STRING_LIST : + strL = option.getStringListValue(); + break; + case IOption.INCLUDE_PATH : + strL = option.getIncludePaths(); + break; + case IOption.PREPROCESSOR_SYMBOLS : + strL = option.getDefinedSymbols(); + break; + case IOption.LIBRARIES : + strL = option.getLibraries(); + break; + case IOption.OBJECTS : + strL = option.getUserObjects(); + break; + default : + break; + } + + if(str != null) + return MacroResolver.resolveToString(str,sub); + else if(strL != null){ + strL = MacroResolver.resolveStringListValues(strL,sub,true); + return MacroResolver.convertStringListToString(strL," "); //$NON-NLS-1$ + } + } catch (BuildException e){ + + } catch (BuildMacroException e){ + + } + return null; + } + + public String[] resolveToStringList(String macroName) throws BuildMacroException { + if(!"IncludeDefaults".equals(macroName)) //$NON-NLS-1$ + return new String[]{MacroResolver.createMacroReference(macroName)}; + + IOptionContextData parent = getParent(fOptionContextData); + if(parent == null) + return new String[]{EMPTY_STRING}; + IncludeDefaultsSubstitutor sub = new IncludeDefaultsSubstitutor(parent); + IOption option = parent.getOption(); + String str = null; + String strL[] = null; + try{ + switch(option.getValueType()){ + case IOption.STRING : + str = option.getStringValue(); + break; + case IOption.STRING_LIST : + strL = option.getStringListValue(); + break; + case IOption.INCLUDE_PATH : + strL = option.getIncludePaths(); + break; + case IOption.PREPROCESSOR_SYMBOLS : + strL = option.getDefinedSymbols(); + break; + case IOption.LIBRARIES : + strL = option.getLibraries(); + break; + case IOption.OBJECTS : + strL = option.getUserObjects(); + break; + default : + break; + } + + if(str != null) + return MacroResolver.resolveToStringList(str,sub); + else if(strL != null) + return MacroResolver.resolveStringListValues(strL,sub,true); + } catch (BuildException e){ + + } catch (BuildMacroException e){ + + } + return null; + } + + public void setMacroContextInfo(int contextType, Object contextData) throws BuildMacroException { + } + + public IMacroContextInfo getMacroContextInfo() { + return null; + } + } + + public class OptionMacro extends BuildMacro{ + private IOptionContextData fOptionContextData; + private IOptionContextData fParentOptionContextData; +// private IOption fParentOption; + private OptionMacro(String name, IOptionContextData optionContextData){ + fName = name; + fOptionContextData = optionContextData; + fParentOptionContextData = getParent(fOptionContextData); + load(); + } + + private boolean load(){ + fStringValue = null; + fStringListValue = null; + fType = 0; + if(fParentOptionContextData != null){ + IOption option = fParentOptionContextData.getOption(); + try{ + switch (option.getValueType()) { + case IOption.BOOLEAN: + break; + case IOption.STRING: + fType = IBuildMacro.VALUE_TEXT; + fStringValue = option.getStringValue(); + break; + case IOption.ENUMERATED: + break; + case IOption.STRING_LIST: + fType = IBuildMacro.VALUE_TEXT_LIST; + fStringListValue = option.getStringListValue(); + break; + case IOption.INCLUDE_PATH: + fType = IBuildMacro.VALUE_PATH_DIR_LIST; + fStringListValue = option.getIncludePaths(); + break; + case IOption.PREPROCESSOR_SYMBOLS: + fType = IBuildMacro.VALUE_TEXT_LIST; + fStringListValue = option.getDefinedSymbols(); + break; + case IOption.LIBRARIES: + fType = IBuildMacro.VALUE_PATH_FILE_LIST; + fStringListValue = option.getLibraries(); + break; + case IOption.OBJECTS: + fType = IBuildMacro.VALUE_PATH_FILE_LIST; + fStringListValue = option.getUserObjects(); + break; + } + if(fStringValue != null) + fStringValue = MacroResolver.resolveToString(fStringValue,new IncludeDefaultsSubstitutor(fParentOptionContextData)); + else if(fStringListValue != null) + fStringListValue = MacroResolver.resolveStringListValues(fStringListValue,new IncludeDefaultsSubstitutor(fParentOptionContextData), true); + }catch(Exception e){ + fType = 0; + } + } + + boolean result = fType != 0; + if(!result){ + fType = VALUE_TEXT; + fStringListValue = null; + fStringValue = null; + } + + return result; + } + } + + private IOptionContextData getParent(IOptionContextData optionContext){ + if(optionContext == null) + return null; + IOption option = optionContext.getOption(); + if(option == null) + return null; + IOption parentOption = null; + + ITool tool = option.getParent(); + IBuildObject bo = optionContext.getParent(); + if(tool != null && bo instanceof IResourceConfiguration){ + + IToolChain toolChain = null; + IConfiguration cfg = null; + String optId = option.getId(); + + IResourceConfiguration rc = (IResourceConfiguration)bo; + cfg = rc.getParent(); + toolChain = cfg.getToolChain(); + if(rc.getTool(tool.getId()) != null){ + //get the configuration tool + tool = tool.getSuperClass(); + IOption opts[] = tool.getOptions(); + IOption superClass = option; + do{ + for(int i = 0; i < opts.length; i++){ + if(superClass.equals(opts[i]) || superClass.equals(opts[i].getSuperClass())){ + parentOption = opts[i]; + break; + } + } + if(parentOption != null) + break; + }while((superClass = superClass.getSuperClass()) != null); + } else if(toolChain.getTool(tool.getId()) != null){ + parentOption = option.getSuperClass(); + } else { + ITool tools[] = toolChain.getTools(); + ITool superClasses[] = new ITool[tools.length]; + int i = 0; + for(i = 0; i < tools.length; i++){ + superClasses[i] = tools[i]; + } + for(i = 0; i < tools.length; i++){ + if(tool.equals(superClasses[i])) + break; + superClasses[i] = tools[i].getSuperClass(); + } + if(i < tools.length){ + tool = tools[i]; + IOption opts[] = tool.getOptions(); + IOption superClassOpts[] = new IOption[opts.length]; + for(i = 0; i < opts.length; i++){ + superClassOpts[i] = opts[i]; + } + for(i = 0; i < opts.length; i++){ + if(superClassOpts[i] != null){ + if(option.equals(superClassOpts[i])) + break; + superClassOpts[i] = superClassOpts[i].getSuperClass(); + } + } + if(i < opts.length) + parentOption = opts[i]; + } + } + } else { + parentOption = option.getSuperClass(); + } + + if(parentOption != null){ + IBuildObject parentObject = null; + ITool t = parentOption.getParent(); + if(t != null) + parentObject = t.getParent(); + return new OptionContextData(parentOption,parentObject); + } + + return null; + } + + private boolean canHandle(IOptionContextData optionData){ + IOption option = optionData.getOption(); + if(option == null) + return false; + + boolean can = false; + try{ + switch (option.getValueType()) { + case IOption.BOOLEAN: + break; + case IOption.STRING: + can = true; + break; + case IOption.ENUMERATED: + break; + case IOption.STRING_LIST: + can = true; + break; + case IOption.INCLUDE_PATH: + can = true; + break; + case IOption.PREPROCESSOR_SYMBOLS: + can = true; + break; + case IOption.LIBRARIES: + can = true; + break; + case IOption.OBJECTS: + can = true; + break; + } + }catch(BuildException e){ + can = false; + } + return can; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/OptionContextData.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/OptionContextData.java new file mode 100644 index 00000000000..505cf42b491 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/OptionContextData.java @@ -0,0 +1,44 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.macros.IOptionContextData; + +/** + * This is a trivial implementation of the IOptionContextData used internaly by the MBS + * + * @since 3.0 + */ +public class OptionContextData implements IOptionContextData { + private IOption fOption; + private IBuildObject fParent; + + public OptionContextData(IOption option, IBuildObject parent){ + fOption = option; + fParent = parent; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IOptionContextData#getOption() + */ + public IOption getOption() { + return fOption; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IOptionContextData#getParent() + */ + public IBuildObject getParent() { + return fParent; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/StorableBuildMacro.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/StorableBuildMacro.java new file mode 100644 index 00000000000..814aa9158de --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/StorableBuildMacro.java @@ -0,0 +1,158 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.ArrayList; +import java.util.List; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * This class represents the Build Macro that could be loaded + * and stored in XML + * + * @since 3.0 + * + */ +public class StorableBuildMacro extends BuildMacro { + public static final String STRING_MACRO_ELEMENT_NAME = "stringMacro"; //$NON-NLS-1$ + public static final String STRINGLIST_MACRO_ELEMENT_NAME = "stringListMacro"; //$NON-NLS-1$ + public static final String NAME = "name"; //$NON-NLS-1$ + public static final String VALUE = "value"; //$NON-NLS-1$ + public static final String TYPE = "type"; //$NON-NLS-1$ + + public static final String VALUE_ELEMENT_NAME = "value"; //$NON-NLS-1$ + public static final String VALUE_ELEMENT_VALUE = "name"; //$NON-NLS-1$ + + public static final String TYPE_TEXT = "VALUE_TEXT"; //$NON-NLS-1$ + public static final String TYPE_TEXT_LIST = "VALUE_TEXT_LIST"; //$NON-NLS-1$ + public static final String TYPE_PATH_FILE = "VALUE_PATH_FILE"; //$NON-NLS-1$ + public static final String TYPE_PATH_FILE_LIST = "VALUE_PATH_FILE_LIST"; //$NON-NLS-1$ + public static final String TYPE_PATH_DIR = "VALUE_PATH_DIR"; //$NON-NLS-1$ + public static final String TYPE_PATH_DIR_LIST = "VALUE_PATH_DIR_LIST"; //$NON-NLS-1$ + public static final String TYPE_PATH_ANY = "VALUE_PATH_ANY"; //$NON-NLS-1$ + public static final String TYPE_PATH_ANY_LIST = "VALUE_PATH_ANY_LIST"; //$NON-NLS-1$ + + public StorableBuildMacro(String name, int type, String value){ + super(name,type,value); + } + + public StorableBuildMacro(String name, int type, String value[]){ + super(name,type,value); + } + + public StorableBuildMacro(Element element){ + load(element); + } + + private void load(Element element){ + fName = element.getAttribute(NAME); + + fType = typeStringToInt(element.getAttribute(TYPE)); + + if(!MacroResolver.isStringListMacro(fType)) + fStringValue = element.getAttribute(VALUE); + else { + NodeList nodeList = element.getChildNodes(); + List values = new ArrayList(); + for (int i = 0; i < nodeList.getLength(); ++i) { + Node node = nodeList.item(i); + if (node.getNodeName().equals(VALUE_ELEMENT_NAME)) { + values.add(((Element)node).getAttribute(VALUE_ELEMENT_VALUE)); + } + } + fStringListValue = (String[])values.toArray(new String[values.size()]); + } + } + + private int typeStringToInt(String typeString){ + int type; + + if(TYPE_TEXT_LIST.equals(typeString)) + type = VALUE_TEXT_LIST; + else if(TYPE_PATH_FILE.equals(typeString)) + type = VALUE_PATH_FILE; + else if(TYPE_PATH_FILE_LIST.equals(typeString)) + type = VALUE_PATH_FILE_LIST; + else if(TYPE_PATH_DIR.equals(typeString)) + type = VALUE_PATH_DIR; + else if(TYPE_PATH_DIR_LIST.equals(typeString)) + type = VALUE_PATH_DIR_LIST; + else if(TYPE_PATH_ANY.equals(typeString)) + type = VALUE_PATH_ANY; + else if(TYPE_PATH_ANY_LIST.equals(typeString)) + type = VALUE_PATH_ANY_LIST; + else + type = VALUE_TEXT; + + return type; + } + + private String typeIntToString(int type){ + String stringType; + + switch(type){ + case VALUE_TEXT_LIST: + stringType = TYPE_TEXT_LIST; + break; + case VALUE_PATH_FILE: + stringType = TYPE_PATH_FILE; + break; + case VALUE_PATH_FILE_LIST: + stringType = TYPE_PATH_FILE_LIST; + break; + case VALUE_PATH_DIR: + stringType = TYPE_PATH_DIR; + break; + case VALUE_PATH_DIR_LIST: + stringType = TYPE_PATH_DIR_LIST; + break; + case VALUE_PATH_ANY: + stringType = TYPE_PATH_ANY; + break; + case VALUE_PATH_ANY_LIST: + stringType = TYPE_PATH_ANY_LIST; + break; + case VALUE_TEXT: + default: + stringType = TYPE_TEXT; + break; + } + + return stringType; + } + + public void serialize(Document doc, Element element){ + if(fName != null) + element.setAttribute(NAME,fName); + + element.setAttribute(TYPE,typeIntToString(fType)); + + if(!MacroResolver.isStringListMacro(fType)){ + if(fStringValue != null) + element.setAttribute(VALUE,fStringValue); + } + else { + if(fStringListValue != null && fStringListValue.length > 0){ + for(int i = 0; i < fStringListValue.length; i++){ + Element valEl = doc.createElement(VALUE_ELEMENT_NAME); + element.appendChild(valEl); + if(fStringListValue[i] != null) + valEl.setAttribute(VALUE_ELEMENT_VALUE, fStringListValue[i]); + } + } + } + + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/StorableMacros.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/StorableMacros.java new file mode 100644 index 00000000000..ddd7dcde59a --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/StorableMacros.java @@ -0,0 +1,241 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * This class represents the set of Build Macros that could be loaded + * and stored in XML + * + * @since 3.0 + * + */ +public class StorableMacros { + public static final String MACROS_ELEMENT_NAME = "macros"; //$NON-NLS-1$ + public static final String EXPAND_ENVIRONMENT_MACROS = "expandEnvironmentMacros"; //$NON-NLS-1$ + public static final String TRUE = "true"; //$NON-NLS-1$ + private Map fMacros; + private boolean fExpandInMakefile = false; + private boolean fIsDirty = false; + private boolean fIsChanged = false; + + private Map getMap(){ + if(fMacros == null) + fMacros = new HashMap(); + return fMacros; + } + + public StorableMacros() { + + } + + public StorableMacros(Element element) { + load(element); + } + + private void load(Element element){ + fExpandInMakefile = TRUE.equals(element.getAttribute(EXPAND_ENVIRONMENT_MACROS)); + + NodeList nodeList = element.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); ++i) { + Node node = nodeList.item(i); + String name = node.getNodeName(); + if (StorableBuildMacro.STRING_MACRO_ELEMENT_NAME.equals(name)) { + addMacro(new StorableBuildMacro((Element)node)); + } + else if (StorableBuildMacro.STRINGLIST_MACRO_ELEMENT_NAME.equals(name)) { + addMacro(new StorableBuildMacro((Element)node)); + } + } + fIsDirty = false; + fIsChanged = false; + } + + public void serialize(Document doc, Element element){ + if(fExpandInMakefile) + element.setAttribute(EXPAND_ENVIRONMENT_MACROS,TRUE); + + if(fMacros != null){ + Iterator iter = fMacros.values().iterator(); + while(iter.hasNext()){ + StorableBuildMacro macro = (StorableBuildMacro)iter.next(); + Element macroEl; + if(MacroResolver.isStringListMacro(macro.getMacroValueType())) + macroEl = doc.createElement(StorableBuildMacro.STRINGLIST_MACRO_ELEMENT_NAME); + else + macroEl = doc.createElement(StorableBuildMacro.STRING_MACRO_ELEMENT_NAME); + element.appendChild(macroEl); + macro.serialize(doc,macroEl); + } + } + fIsDirty = false; + } + + private void addMacro(IBuildMacro macro){ + String name = macro.getName(); + if(name == null) + return; + + getMap().put(name,macro); + } + + public IBuildMacro createMacro(String name, int type, String value){ + if(name == null || "".equals(name = name.trim()) || MacroResolver.isStringListMacro(type)) //$NON-NLS-1$ + return null; + + StorableBuildMacro macro = new StorableBuildMacro(name, type, value); + addMacro(macro); + fIsDirty = true; + fIsChanged = true; + return macro; + } + + public IBuildMacro createMacro(IBuildMacro copy){ + String name = copy.getName(); + if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ + return null; + + int type = copy.getMacroValueType(); + + StorableBuildMacro macro = null; + try{ + if(MacroResolver.isStringListMacro(type)){ + String value[] = copy.getStringListValue(); + macro = new StorableBuildMacro(name, type, value); + } + else { + String value = copy.getStringValue(); + macro = new StorableBuildMacro(name, type, value); + } + addMacro(macro); + fIsDirty = true; + fIsChanged = true; + + }catch(BuildMacroException e){ + } + return macro; + } + + public IBuildMacro createMacro(String name, int type, String value[]){ + if(name == null || "".equals(name = name.trim()) || !MacroResolver.isStringListMacro(type)) //$NON-NLS-1$ + return null; + + StorableBuildMacro macro = new StorableBuildMacro(name, type, value); + addMacro(macro); + fIsDirty = true; + fIsChanged = true; + return macro; + } + + /** + * Returns the "dirty" state for this set of macros. + * If the dirty state is true, that means that the macros + * is out of synch with the repository and the macros need to be serialized. + *

+ * The dirty state is automatically set to false when the macros are serialized + * by calling the serialize() method + * @return boolean + */ + public boolean isDirty(){ + return fIsDirty; + } + + /** + * sets the "dirty" state for this set of macros. + * @see org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros#isDirty() + * @param dirty represents the new state + */ + public void setDirty(boolean dirty){ + fIsDirty = dirty; + } + + /** + * Returns the "change" state for this set of macros. + * The "change" state represents whether the macros were changed or not. + * This state is not reset when the serialize() method is called + * Users can use this state to monitor whether the macros were changed or not. + * The "change" state can be reset only by calling the setChanged(false) method + * @return boolean + */ + public boolean isChanged(){ + return fIsChanged; + } + + public boolean isExpanded(){ + return fExpandInMakefile; + } + + public void setExpanded(boolean expand){ + if(fExpandInMakefile != expand){ + fExpandInMakefile = expand; + fIsDirty = true; + //should we set the change state here? + fIsChanged = true; + } + } + + /** + * sets the "change" state for this set of macros. + * @see org.eclipse.cdt.managedbuilder.internal.macros.StorableMacros#isChanged() + * @param changed represents the new "change" state + */ + public void setChanged(boolean changed){ + fIsChanged = changed; + } + + public IBuildMacro getMacro(String name){ + if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ + return null; + + return (IBuildMacro)getMap().get(name); + } + + public IBuildMacro[] getMacros(){ + Collection macros = getMap().values(); + + return (IBuildMacro[])macros.toArray(new IBuildMacro[macros.size()]); + } + + IBuildMacro deleteMacro(String name){ + if(name == null || "".equals(name = name.trim())) //$NON-NLS-1$ + return null; + + IBuildMacro macro = (IBuildMacro)getMap().remove(name); + if(macro != null){ + fIsDirty = true; + fIsChanged = true; + } + + return macro; + } + + public boolean deleteAll(){ + Map map = getMap(); + if(map.size() > 0){ + fIsDirty = true; + fIsChanged = true; + map.clear(); + return true; + } + return false; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/UserDefinedMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/UserDefinedMacroSupplier.java new file mode 100644 index 00000000000..466416360c2 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/macros/UserDefinedMacroSupplier.java @@ -0,0 +1,418 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.macros; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject; +import org.eclipse.cdt.managedbuilder.internal.core.ToolChain; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * This supplier is used to obtain the user-defined macros + * + * @since 3.0 + */ +public class UserDefinedMacroSupplier implements IBuildMacroSupplier { +// public static final String MACROS_ELEMENT_NAME = "macros"; //$NON-NLS-1$ + public static final String NODENAME = "macros"; //$NON-NLS-1$ + public static final String PREFNAME_WORKSPACE = "workspace"; //$NON-NLS-1$ + + private static UserDefinedMacroSupplier fInstance; + + private StorableMacros fWorkspaceMacros; + + public boolean areMacrosExpanded(IConfiguration cfg){ + StorableMacros macros = getStorableMacros(IBuildMacroProvider.CONTEXT_CONFIGURATION, cfg); + if(macros != null) + return macros.isExpanded(); + return false; + } + + public void setMacrosExpanded(IConfiguration cfg, boolean expanded){ + StorableMacros macros = getStorableMacros(IBuildMacroProvider.CONTEXT_CONFIGURATION, cfg); + if(macros != null) + macros.setExpanded(expanded); + } + + private StorableMacros getStorableMacros(int contextType, Object contextData){ + StorableMacros macros = null; + switch(contextType){ + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + IToolChain toolChain = ((IConfiguration)contextData).getToolChain(); + if(toolChain instanceof ToolChain) + macros = ((ToolChain)toolChain).getUserDefinedMacros(); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(contextData instanceof ManagedProject){ + macros = ((ManagedProject)contextData).getUserDefinedMacros(); + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(contextData instanceof IWorkspace){ + if(fWorkspaceMacros == null) + fWorkspaceMacros = loadWorkspaceMacros(); + macros = fWorkspaceMacros; + } + } + + return macros; + } + + private UserDefinedMacroSupplier(){ + + } + + public static UserDefinedMacroSupplier getInstance(){ + if(fInstance == null) + fInstance = new UserDefinedMacroSupplier(); + return fInstance; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String macroName, int contextType, + Object contextData) { + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + + StorableMacros macros = getStorableMacros(contextType,contextData); + if(macros != null) + return macros.getMacro(macroName); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData) { + StorableMacros macros = getStorableMacros(contextType,contextData); + if(macros != null) + return macros.getMacros(); + return null; + } + + public IBuildMacro createMacro(String macroName, + int type, + String value, + int contextType, + Object contextData){ + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + StorableMacros macros = getStorableMacros(contextType, contextData); + if(macros == null) + return null; + + IBuildMacro macro = macros.createMacro(macroName,type,value); + if(macro != null) + setRebuildStateForContext(contextType, contextData); + + return macro; + + } + + public IBuildMacro createMacro(String macroName, + int type, + String value[], + int contextType, + Object contextData){ + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + StorableMacros macros = getStorableMacros(contextType, contextData); + if(macros == null) + return null; + + IBuildMacro macro = macros.createMacro(macroName,type,value); + if(macro != null) + setRebuildStateForContext(contextType, contextData); + + return macro; + + } + + public IBuildMacro createMacro(IBuildMacro copy, int contextType, Object contextData){ + if(copy == null) + return null; + String macroName = copy.getName(); + if(macroName == null || "".equals(macroName)) //$NON-NLS-1$ + return null; + StorableMacros macros = getStorableMacros(contextType, contextData); + if(macros == null) + return null; + + IBuildMacro macro = macros.createMacro(copy); + if(macro != null) + setRebuildStateForContext(contextType, contextData); + + return macro; + } + + public IBuildMacro deleteMacro(String name, int contextType, Object contextData){ + StorableMacros macros = getStorableMacros(contextType,contextData); + if(macros == null) + return null; + IBuildMacro macro = macros.deleteMacro(name); + if(macro != null) + setRebuildStateForContext(contextType, contextData); + + return macro; + } + + public void deleteAll(int contextType, Object contextData){ + StorableMacros macros = getStorableMacros(contextType, contextData); + if(macros == null) + return; + + if(macros.deleteAll()) + setRebuildStateForContext(contextType, contextData); + } + + /* + * + * methods used for loadding/storing workspace macros from properties + * + */ + + public void serialize(boolean force){ + try{ + if(fWorkspaceMacros != null) + storeWorkspaceMacros(fWorkspaceMacros,force); + }catch(CoreException e){ + } + } + + private Preferences getWorkspaceNode(){ + Preferences prefNode = new InstanceScope().getNode(ManagedBuilderCorePlugin.getUniqueIdentifier()); + if(prefNode == null) + return null; + + return prefNode.node(NODENAME); + } + + + /* + * loads the stored workspace macros + */ + protected StorableMacros loadWorkspaceMacros(){ + InputStream stream = loadInputStream(getWorkspaceNode(),PREFNAME_WORKSPACE); + if(stream == null) + return new StorableMacros(); + return loadMacrosFromStream(stream); + } + + /* + * stores the given macros + */ + protected void storeWorkspaceMacros(StorableMacros macros, boolean force) throws CoreException{ + if(!macros.isDirty() && !force) + return; + + ByteArrayOutputStream stream = storeMacrosToStream(macros); + if(stream == null) + return; + storeOutputStream(stream,getWorkspaceNode(),PREFNAME_WORKSPACE); + } + + private StorableMacros loadMacrosFromStream(InputStream stream){ + try{ + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputSource inputSource = new InputSource(stream); + Document document = parser.parse(inputSource); + Element rootElement = document.getDocumentElement(); + + if(!StorableMacros.MACROS_ELEMENT_NAME.equals(rootElement.getNodeName())) + return null; + + return new StorableMacros(rootElement); + } + catch(ParserConfigurationException e){ + + } + catch(SAXException e){ + + } + catch(IOException e){ + + } + + return null; + } + + private ByteArrayOutputStream storeMacrosToStream(StorableMacros macros) throws CoreException{ + try{ + DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); + DocumentBuilder builder= factory.newDocumentBuilder(); + Document document= builder.newDocument(); + + Element rootElement = document.createElement(StorableMacros.MACROS_ELEMENT_NAME); + document.appendChild(rootElement); + macros.serialize(document,rootElement); + + Transformer transformer=TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$ + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ + DOMSource source = new DOMSource(document); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + StreamResult result = new StreamResult(stream); + + transformer.transform(source, result); + return stream; + } + catch(ParserConfigurationException e){ + throw new CoreException(new Status(IStatus.ERROR, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + -1, + e.getMessage(), + e)); + } + catch(TransformerConfigurationException e){ + throw new CoreException(new Status(IStatus.ERROR, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + -1, + e.getMessage(), + e)); + } + catch(TransformerException e){ + throw new CoreException(new Status(IStatus.ERROR, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + -1, + e.getMessage(), + e)); + } + } + + private InputStream loadInputStream(Preferences node, String key){ + if(node == null || key == null) + return null; + + String value = node.get(key,null); + if(value == null || value.length() == 0) + return null; + + byte[] bytes; + try { + bytes = value.getBytes("UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + bytes = value.getBytes(); + } + + return new ByteArrayInputStream(bytes); + } + + private void storeOutputStream(ByteArrayOutputStream stream, Preferences node, String key) throws CoreException{ + if(stream == null || node == null || key == null) + throw new CoreException(new Status(IStatus.ERROR, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + -1, + ManagedMakeMessages.getResourceString("UserDefinedMacroSupplier.storeOutputStream.wrong.arguments"), //$NON-NLS-1$ + null)); + byte[] bytes= stream.toByteArray(); + + String val = null; + try { + val= new String(bytes, "UTF-8"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + val= new String(bytes); + } + + node.put(key,val); + + try{ + node.flush(); + } + catch(BackingStoreException e){ + throw new CoreException(new Status(IStatus.ERROR, + ManagedBuilderCorePlugin.getUniqueIdentifier(), + -1, + e.getMessage(), + e)); + } + } + + protected void setRebuildStateForContext(int contextType, Object contextData){ + + switch(contextType){ + case IBuildMacroProvider.CONTEXT_CONFIGURATION: + if(contextData instanceof IConfiguration){ + ((IConfiguration)contextData).setRebuildState(true); + } + break; + case IBuildMacroProvider.CONTEXT_PROJECT: + if(contextData instanceof IManagedProject){ + IConfiguration cfgs[] = ((IManagedProject)contextData).getConfigurations(); + for(int i = 0; i < cfgs.length; i++){ + cfgs[i].setRebuildState(true); + } + } + break; + case IBuildMacroProvider.CONTEXT_WORKSPACE: + if(contextData instanceof IWorkspace){ + IProject projects[] = ((IWorkspace)contextData).getRoot().getProjects(); + for(int i = 0; i < projects.length; i++){ + if(ManagedBuildManager.manages(projects[i])){ + IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(projects[i]); + if(info != null){ + IConfiguration cfgs[] = info.getManagedProject().getConfigurations(); + for(int j = 0; j < cfgs.length; j++){ + cfgs[j].setRebuildState(true); + } + } + } + } + } + } + + + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/BuildMacroException.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/BuildMacroException.java new file mode 100644 index 00000000000..48a1b4bc318 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/BuildMacroException.java @@ -0,0 +1,114 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroStatus; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; + +/** + * This exception is thrown in the case of some build macros-related operation failure + * The exception typically contains one or more IBuildMacroStatus statuses + * + * @since 3.0 + */ +public class BuildMacroException extends CoreException { + /** + * All serializable objects should have a stable serialVersionUID + */ + private static final long serialVersionUID = 3976741380246681395L; + + /** + * Creates a new exception with the given status object. + * + * @param status the status object to be associated with this exception. + * Typically this is either the IBuildMacroStatus or the MultiStatus that holds + * the list of the IBuildMacroStatus statuses + */ + public BuildMacroException(IStatus status) { + super(status); + } + + /** + * Creates an exception containing a single IBuildMacroStatus status with the IStatus.ERROR severity + * + * @param code one of the IBuildMacroStatus.TYPE_xxx statusses + * @param message message, can be null. In this case the default message will + * be generated base upon the other status info + * @param exception a low-level exception, or null if not + * applicable + * @param macroName the name of the build macro whose resolution caused this status creation or null if none + * @param expression the string whose resolutinon caused caused this status creation or null if none + * @param referencedName the macro name referenced in the resolution string that caused this this status creation or null if none + * @param contextType the context type used in the operation + * @param contextData the context data used in the operation + */ + public BuildMacroException(int code, + String message, + Throwable exception, + String macroName, + String expression, + String referencedName, + int contextType, + Object contextData) { + super(new BuildMacroStatus(code, message, exception, macroName, expression, referencedName, contextType, contextData)); + } + + /** + * Creates an exception containing a single IBuildMacroStatus status with the IStatus.ERROR severity and with the default message + * + * @param code one of the IBuildMacroStatus.TYPE_xxx statusses + * @param exception a low-level exception, or null if not + * applicable + * @param macroName the name of the build macro whose resolution caused this status creation or null if none + * @param expression the string whose resolutinon caused caused this status creation or null if none + * @param referencedName the macro name referenced in the resolution string that caused this this status creation or null if none + * @param contextType the context type used in the operation + * @param contextData the context data used in the operation + */ + public BuildMacroException(int code, + String macroName, + String expression, + String referencedName, + int contextType, + Object contextData) { + super(new BuildMacroStatus(code, macroName, expression, referencedName, contextType, contextData)); + } + + /** + * Returns an array of the IBuildMacroStatus statuses this exception holds + * + * @return IBuildMacroStatus[] + */ + public IBuildMacroStatus[] getMacroStatuses(){ + IStatus status = getStatus(); + if(status instanceof IBuildMacroStatus) + return new IBuildMacroStatus[]{(IBuildMacroStatus)status}; + else if(status.isMultiStatus()){ + IStatus children[] = status.getChildren(); + IBuildMacroStatus result[] = new IBuildMacroStatus[children.length]; + int num = 0; + for(int i = 0; i < children.length; i++){ + if(children[i] instanceof IBuildMacroStatus) + result[num++]=(IBuildMacroStatus)children[i]; + } + if(num != children.length){ + IBuildMacroStatus tmp[] = new IBuildMacroStatus[num]; + for(int i = 0; i < num; i++) + tmp[i] = result[i]; + result = tmp; + } + return result; + } + return new IBuildMacroStatus[0]; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacro.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacro.java new file mode 100644 index 00000000000..c154437fbf7 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacro.java @@ -0,0 +1,79 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +/** + * this interface represents the given build macro + * @since 3.0 + */ +public interface IBuildMacro{ + /** + * can hold any text string + */ + public static final int VALUE_TEXT = 1; + + /** + * can hold the array of text string values + */ + public static final int VALUE_TEXT_LIST = 2; + + /** + * can hold file path + */ + public static final int VALUE_PATH_FILE = 3; + + /** + * can hold the array of file path values + */ + public static final int VALUE_PATH_FILE_LIST = 4; + + /** + * can hold dir path + */ + public static final int VALUE_PATH_DIR = 5; + + /** + * can hold the array of dir path values + */ + public static final int VALUE_PATH_DIR_LIST = 6; + + /** + * can hold both file and dir path + */ + public static final int VALUE_PATH_ANY = 7; + + /** + * can hold the array of PATH_ANY values + */ + public static final int VALUE_PATH_ANY_LIST = 8; + + /** + * Returns the macro name + * @return + */ + String getName(); + + /** + * @return IBuildMacro.VALUE_xxx + */ + int getMacroValueType(); + + /** + * @throws BuildMacroException if macro holds StringList-type value + */ + String getStringValue() throws BuildMacroException; + + /** + * @throws BuildMacroException if macro holds single String-type value + */ + String[] getStringListValue() throws BuildMacroException; +} + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroProvider.java new file mode 100644 index 00000000000..edb4aadab60 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroProvider.java @@ -0,0 +1,178 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +/** + * + * @since 3.0 + */ +public interface IBuildMacroProvider{ + public final static int CONTEXT_FILE = 1; + public final static int CONTEXT_OPTION = 2; + public final static int CONTEXT_CONFIGURATION = 3; + public final static int CONTEXT_PROJECT = 4; + public final static int CONTEXT_WORKSPACE = 5; + public final static int CONTEXT_INSTALLATIONS = 6; + public final static int CONTEXT_ECLIPSEENV = 7; + + /** + * + * Returns reference to the IBuildMacro interface representing Macro of the + * specified name or null if there is there is no such macro + * @param macroName macro name + * @param contextType represents the context type. Should be set to one of the the + * IBuildMacroProvider. CONTEXT_xxx constants + * @param contextData represents the additional data needed by the Build Macro Provider + * and Macro Suppliers in order to obtain the macro value. The type of the context data + * differs depending on the context type and can be one of the following: + * 1. IFileContextData interface � used to represent currently selected file context + * the IFileContextData interface is defined as follows: + * pulic interface IFileContextData{ + * IFile getFile(); + * IOption getOption(); + * } + * NOTE: the IFileContextData is passed that represents the current file and the option + * for that file because Macro Value Provider needs to know what option should be used + * as a context in case macro is not found for �current file� context + * 2. IOption � used to represent the currently selected option context + * 3. IConfiguration � used to represent the currently selected configuration context + * 4. IProject � used to represent current project context + * 5. IWorkspace � used to represent current workspace context + * 6. null � to represent the CDT and Eclipse installation context + * 7. null � to represent process environment context + * @param includeParentContext specifies whether lower-precedence context macros should + * be included + */ + public IBuildMacro getMacro(String macroName, + int contextType, + Object contextData, + boolean includeParentContexts); + + /** + * + * @return the array of the IBuildMacro representing all available macros + */ + public IBuildMacro[] getMacros(int contextType, + Object contextData, + boolean includeParentContexts); + + + /** + * This method is defined to be used primarily by the UI classes and should not be used by the + * tool-integrator + * @return the array of the provider-internal suppliers for the given context + */ + public IBuildMacroSupplier[] getSuppliers(int contextType, + Object contextData); + + + /** + * + * converts StringList value into String of the following format: + * "< listDelimiter >< listDelimiter > ... " + */ + public String convertStringListToString (String value[], String listDelimiter); + + /** + * + * resolves all macros in the string. + * @param value the value to be resolved + * @param nonexistentMacrosValue specifies the value that inexistent macro references will be + * expanded to. If null the BuildMacroException is thrown in case the string to be resolved + * references inexistent macros + * @param listDelimiter if not null, StringList macros are expanded as + * �< listDelimiter >< listDelimiter > ... � + * otherwise the BuildMacroException is thrown in case the string to be resolved references + * string-list macros + * @param contextType context from which the macro search should be started + * @param contextData context data + */ + public String resolveValue(String value, + String nonexistentMacrosValue, + String listDelimiter, + int contextType, + Object contextData) throws BuildMacroException; + + /** + * + * if the string contains a value that can be treated as a StringList resolves it to arrays of strings + * otherwise throws the BuildMacroException exception + * @see isStringListValue + */ + public String[] resolveStringListValue(String value, + String nonexistentMacrosValue, + int contextType, + Object contextData) throws BuildMacroException; + + /** + * + * resolves all macros in the string to the makefile format. That is: + * 1. In case when a user has specified to resolve the environment build macros all macros + * get resolved in the string + * 2. In case when the a user has specified not to resolve the environment build macros all macros + * get resolved except the build environment macros (macros whose name conflicts with one + * of reserved macro names, or string-list macros always get resolved in the buildfile). + * Macro references that are kept unresolved are converted to the makefile format + * @param value the value to be resolved + * @param nonexistentMacrosValue specifies the value that inexistent macro references will be + * expanded to. If null the BuildMacroException is thrown in case the string to be resolved + * references inexistent macros + * @param listDelimiter if not null, StringList macros are expanded as + * �< listDelimiter >< listDelimiter > ... � + * otherwise the BuildMacroException is thrown in case the string to be resolved references + * string-list macros + * @param contextType context from which the macro search should be started + * @param contextData context data + */ + public String resolveValueToMakefileFormat(String value, + String nonexistentMacrosValue, + String listDelimiter, + int contextType, + Object contextData) throws BuildMacroException; + + /** + * + * if the string contains a value that can be treated as a StringList resolves it to arrays of strings + * otherwise throws the BuildMacroException exception + * each string of the returned array will contain all macro references resolved in case of + * a user has specified to resolve the build macros, and will contain the string with the + * environment macro references unresolved and converted to the buildfile format otherwise + * @see isStringListValue + */ + public String[] resolveStringListValueToMakefileFormat(String value, + String nonexistentMacrosValue, + int contextType, + Object contextData) throws BuildMacroException; + + + /** + * + * @return true if the specified expression can be treated as StringList + * 1. The string value is �${}� + */ + public boolean isStringListValue(String value, int contextType, Object contextData) + throws BuildMacroException; + + /** + * + * checks the integrity of the Macros + * If there are inconsistencies, such as when a macro value refers to a nonexistent macro + * or when two macros refer to each other, this method will throw the BuildMacroException exception + * The BuildMacroException will contain the human-readable string describing + * the inconsistency and the array of the IBuildMacro interfaces that will represent the macros that + * caused the inconsistency. This information will be used in the UI to notify the user about + * the macro inconsistencies (see also the �User interface for viewing and editing Build Macros� + * section of this design) + */ + public void checkIntegrity(int contextType, + Object contextData) throws BuildMacroException; +} + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroStatus.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroStatus.java new file mode 100644 index 00000000000..feb488d8ff9 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroStatus.java @@ -0,0 +1,86 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.core.runtime.IStatus; + +/** + * This interface represents the status of a build macro operation + * + * @since 3.0 + */ +public interface IBuildMacroStatus extends IStatus { + /** + * This type is used to present that the inexistent macro reference + * is encountered while resolving macros in some expression + */ + public static final int TYPE_MACRO_UNDEFINED = 1; + + /** + * This type is used to present that two macros reference each other + */ + public static final int TYPE_MACROS_REFERENCE_EACHOTHER = 2; + + /** + * This type is used to present that the incorrect macro reference + * is encountered while resolving macros in some expression + */ + public static final int TYPE_MACRO_REFERENCE_INCORRECT = 3; + + /** + * The status of this type is created by the Build Macro of the String-List type + * when the String value is requested + */ + public static final int TYPE_MACRO_NOT_STRING = 4; + + /** + * The status of this type is created by the Build Macro of the String type + * when the String-List value is requested + */ + public static final int TYPE_MACRO_NOT_STRINGLIST = 5; + + /** + * This type is used to present that some error other than the one represented + * by other TYPE_xxx has occured + */ + public static final int TYPE_ERROR = -1; + + /** + * returns the name of the build macro whose resolution caused this status creation or null if none + * @return IBuildMacro + */ + public String getMacroName(); + + /** + * returns the string whose resolutinon caused caused this status creation or null if none + * @return String + */ + public String getExpression(); + + /** + * returns the macro name referenced in the resolution string that caused this this status creation or null if none + * @return String + */ + public String getReferencedMacroName(); + + /** + * returns the context type used in the operation + * @return int + */ + public int getContextType(); + + /** + * returns the context data used in the operation + * @return Object + */ + public Object getContextData(); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroSupplier.java new file mode 100644 index 00000000000..110ab62cc02 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IBuildMacroSupplier.java @@ -0,0 +1,38 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +/** + * + * @since 3.0 + */ +public interface IBuildMacroSupplier { + + /** + * + * @param macroName macro name + * @param contextType context type + * @param contextData context data + * @return IBuildMacro + */ + public IBuildMacro getMacro(String macroName, + int contextType, + Object contextData); + + /** + * + * @param contextType context type + * @param contextData context data + * @return IBuildMacro[] + */ + public IBuildMacro[] getMacros(int contextType, + Object contextData); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IConfigurationBuildMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IConfigurationBuildMacroSupplier.java new file mode 100644 index 00000000000..c52eb17ef81 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IConfigurationBuildMacroSupplier.java @@ -0,0 +1,62 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; + +/** + * + * this interface is to be implemented by the tool-integrator + * for supplying the configuration-specific macros + * + * @since 3.0 + */ +public interface IConfigurationBuildMacroSupplier { + /** + * + * @ macroName the macro name + * @param configuration configuration + * @param provider the instance of the build macro provider to be used for querying the + * build macros from within the supplier. The supplier should use this provider to obtain + * the already defined build macros instead of using the �default� provider returned by the + * ManagedBuildManager.getBuildMacroProvider(). + * The provider passed to a supplier will ignore searching macros for the levels + * higher than the current supplier level, will query only the lower-precedence suppliers + * for the current level and will query all suppliers for the lower levels. + * This is done to avoid infinite loops that could be caused if the supplier calls the provider + * and the provider in turn calls that supplier again. Also the supplier should not know anything + * about the build macros defined for the higher levels. + * @return the reference to the IBuildMacro interface representing + * the build macro of a given name or null if the macro of that name is not defined + */ + public IBuildMacro getMacro(String macroName, + IConfiguration configuration, + IBuildMacroProvider provider); + + /** + * + * @param configuration configuration + * @param provider the instance of the build macro provider to be used for querying the + * build macros from within the supplier. The supplier should use this provider to obtain + * the already defined build macros instead of using the �default� provider returned by the + * ManagedBuildManager.getBuildMacroProvider(). + * The provider passed to a supplier will ignore searching macros for the levels + * higher than the current supplier level, will query only the lower-precedence suppliers + * for the current level and will query all suppliers for the lower levels. + * This is done to avoid infinite loops that could be caused if the supplier calls the provider + * and the provider in turn calls that supplier again. Also the supplier should not know anything + * about the build macros defined for the higher levels. + * @return the IBuildMacro[] array representing defined macros + */ + public IBuildMacro[] getMacros(IConfiguration configuration, + IBuildMacroProvider provider); +} + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IFileContextBuildMacroValues.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IFileContextBuildMacroValues.java new file mode 100644 index 00000000000..bf61c2bd5dd --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IFileContextBuildMacroValues.java @@ -0,0 +1,34 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +/** + * + * @since 3.0 + */ +public interface IFileContextBuildMacroValues { + public static final String PREFIX = "macro"; //$NON-NLS-1$ + public static final String SUFFIX = "Value"; //$NON-NLS-1$ + + /** + * + * @return the array if strings representing the names of file context macros supported + * by the builder + */ + String[] getSupportedMacros(); + + /** + * + * @return the file context macro value for the given macro name + */ + String getMacroValue(String macroName); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IFileContextData.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IFileContextData.java new file mode 100644 index 00000000000..1e8ef27f950 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IFileContextData.java @@ -0,0 +1,40 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.core.runtime.IPath; + +/** + * This interface is used to represent file context data + * + * @since 3.0 + */ +public interface IFileContextData { + + /** + * Returns the input file location + * @return IPath + */ + public IPath getInputFileLocation(); + + /** + * Returns the output file location + * @return IPath + */ + public IPath getOutputFileLocation(); + + /** + * Returns the option context data + * + * @return IOptionContextData + */ + public IOptionContextData getOptionContextData(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IOptionContextData.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IOptionContextData.java new file mode 100644 index 00000000000..ea10643c972 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IOptionContextData.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.cdt.managedbuilder.core.IBuildObject; +import org.eclipse.cdt.managedbuilder.core.IOption; + +/** + * This interface is used to represent an option context data + * + * @since 3.0 + */ +public interface IOptionContextData { + /** + * Returns an option + * + * @return IOption + */ + public IOption getOption(); + + /** + * Returns IBuildObject that could be either an IToolChain or an IResourceConfiguration reference + * + * @return IBuildObject + */ + public IBuildObject getParent(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IProjectBuildMacroSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IProjectBuildMacroSupplier.java new file mode 100644 index 00000000000..504191c78bb --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IProjectBuildMacroSupplier.java @@ -0,0 +1,61 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.cdt.managedbuilder.core.IManagedProject; + +/** + * + * this interface is to be implemented by the tool-integrator + * for supplying the project-specific macros + * + * @since 3.0 + */ +public interface IProjectBuildMacroSupplier { + /** + * + * @ macroName the macro name + * @param project the instance of the managed project + * @param provider the instance of the build macro provider to be used for querying the + * build macros from within the supplier. The supplier should use this provider to obtain + * the already defined build macros instead of using the �default� provider returned by the + * ManagedBuildManager.getBuildMacroProvider(). + * The provider passed to a supplier will ignore searching macros for the levels + * higher than the current supplier level, will query only the lower-precedence suppliers + * for the current level and will query all suppliers for the lower levels. + * This is done to avoid infinite loops that could be caused if the supplier calls the provider + * and the provider in turn calls that supplier again. Also the supplier should not know anything + * about the build macros defined for the higher levels. + * @return the reference to the IBuildMacro interface representing + * the build macro of a given name or null if the macro of that name is not defined + */ + IBuildMacro getMacro(String macroName, + IManagedProject project, + IBuildMacroProvider provider); + + /** + * + * @param project the instance of the managed project + * @param provider the instance of the build macro provider to be used for querying the + * build macros from within the supplier. The supplier should use this provider to obtain + * the already defined build macros instead of using the �default� provider returned by the + * ManagedBuildManager.getBuildMacroProvider(). + * The provider passed to a supplier will ignore searching macros for the levels + * higher than the current supplier level, will query only the lower-precedence suppliers + * for the current level and will query all suppliers for the lower levels. + * This is done to avoid infinite loops that could be caused if the supplier calls the provider + * and the provider in turn calls that supplier again. Also the supplier should not know anything + * about the build macros defined for the higher levels. + * @return the IBuildMacro[] array representing defined macros + */ + IBuildMacro[] getMacros(IManagedProject project, + IBuildMacroProvider provider); +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IReservedMacroNameSupplier.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IReservedMacroNameSupplier.java new file mode 100644 index 00000000000..156ba6e9e44 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/macros/IReservedMacroNameSupplier.java @@ -0,0 +1,28 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.macros; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; + +/** + * This interface is to be implemented by the tool-integrator to specify to the MBS + * the reserved builder variable names + * + * @since 3.0 + */ +public interface IReservedMacroNameSupplier{ + + /** + * @return true if the given macro name is reserved by the builder or the makefile generator + */ + boolean isReservedName(String macroName, IConfiguration configuration); +} + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java index 63c890aa19a..d914272c940 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/DefaultGCCDependencyCalculator.java @@ -17,6 +17,10 @@ import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; import org.eclipse.core.resources.IContainer; @@ -112,9 +116,22 @@ public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerat if( resConfig != null) { ITool[] tools = resConfig.getTools(); String cmd = tools[0].getToolCommand(); + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(),null,null,info.getDefaultConfiguration().getToolChain())); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + String[] toolFlags = null; try { - toolFlags = tools[0].getCommandFlags(); + toolFlags = tools[0].getToolCommandFlags(resource.getLocation(),null); } catch( BuildException ex ) { // TODO add some routines to catch this toolFlags = EMPTY_STRING_ARRAY; @@ -133,10 +150,23 @@ public class DefaultGCCDependencyCalculator implements IManagedDependencyGenerat buildCmd = cmdLInfo.getCommandLine(); } else { String cmd = info.getToolForSource(inputExtension); - String buildFlags = "-MM -MG -P -w " + info.getFlagsForSource(inputExtension); //$NON-NLS-1$ + //try to resolve the build macros in the tool command + try{ + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resource.getLocation(),null,null,info.getDefaultConfiguration().getToolChain())); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + + String buildFlags = "-MM -MG -P -w " + info.getToolFlagsForSource(inputExtension, resource.getLocation(), null); //$NON-NLS-1$ String[] flags = buildFlags.split( "\\s" ); //$NON-NLS-1$ - cmdLInfo = info.generateCommandLineInfo( inputExtension, flags, outflag, outputPrefix, - outputFile, inputs ); + cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix, + outputFile, inputs, resource.getLocation(), null); // The command to build if( cmdLInfo == null ) buildCmd = cmd + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java index 39f78933c45..b6c974b52f6 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/makegen/gnu/GnuMakefileGenerator.java @@ -15,36 +15,39 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; -import java.util.List; -import java.util.ArrayList; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.internal.core.model.Util; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IConfiguration; -import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; -import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; -import org.eclipse.cdt.managedbuilder.core.IOption; -import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; -import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IInputType; -import org.eclipse.cdt.managedbuilder.core.IOutputType; -import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; +import org.eclipse.cdt.managedbuilder.core.IManagedOutputNameProvider; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.core.IOutputType; +import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; +import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; import org.eclipse.cdt.managedbuilder.makegen.IManagedDependencyGenerator; -import org.eclipse.cdt.managedbuilder.makegen.gnu.IManagedBuildGnuToolInfo; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -305,6 +308,32 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { buildTargetName = info.getBuildArtifactName(); // Get its extension buildTargetExt = info.getBuildArtifactExtension(); + + try{ + //try to resolve the build macros in the target extension + buildTargetExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + buildTargetExt, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + try{ + //try to resolve the build macros in the target name + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + buildTargetName, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + buildTargetName = resolved; + } catch (BuildMacroException e){ + } + + if (buildTargetExt == null) { buildTargetExt = new String(); } @@ -1086,16 +1115,39 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { private StringBuffer addTargets(List outputVarsAdditionsList, boolean rebuild) { StringBuffer buffer = new StringBuffer(); + IConfiguration config = info.getDefaultConfiguration(); + // Assemble the information needed to generate the targets String prebuildStep = info.getPrebuildStep(); - prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + try{ + //try to resolve the build macros in the prebuild step + prebuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + prebuildStep, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_CONFIGURATION, + config); + } catch (BuildMacroException e){ + } + prebuildStep = prebuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + String postbuildStep = info.getPostbuildStep(); - postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters) + try{ + //try to resolve the build macros in the postbuild step + postbuildStep = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + postbuildStep, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_CONFIGURATION, + config); + + } catch (BuildMacroException e){ + } + postbuildStep = postbuildStep.trim(); // Remove leading and trailing whitespace (and control characters) String preannouncebuildStep = info.getPreannouncebuildStep(); String postannouncebuildStep = info.getPostannouncebuildStep(); String targets = rebuild ? "clean all" : "all"; //$NON-NLS-1$ //$NON-NLS-2$ - IConfiguration config = info.getDefaultConfiguration(); ITool targetTool = config.getTargetTool(); if (targetTool == null) { targetTool = info.getToolFromOutputExtension(buildTargetExt); @@ -1188,6 +1240,31 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // Extract the build artifact to add to the dependency list String depTarget = depInfo.getBuildArtifactName(); String depExt = depInfo.getBuildArtifactExtension(); + + try{ + //try to resolve the build macros in the artifact extension + depExt = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + depExt, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + } catch (BuildMacroException e){ + } + + try{ + //try to resolve the build macros in the artifact name + String resolved = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat( + depTarget, + "", //$NON-NLS-1$ + " ", //$NON-NLS-1$ + IBuildMacroProvider.CONTEXT_CONFIGURATION, + info.getDefaultConfiguration()); + if((resolved = resolved.trim()).length() > 0) + depTarget = resolved; + } catch (BuildMacroException e){ + } + String depPrefix = depInfo.getOutputPrefix(depExt); if (depInfo.needsRebuild()) { depTargets = "clean all"; //$NON-NLS-1$ @@ -1420,26 +1497,39 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // Get the command line for this tool invocation String[] flags; try { - flags = tool.getCommandFlags(); + flags = tool.getToolCommandFlags(null,null); } catch( BuildException ex ) { // TODO report error flags = EMPTY_STRING_ARRAY; } + String command = tool.getToolCommand(); + try{ + //try to resolve the build macros in the tool command + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(command, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(null,null,null,info.getDefaultConfiguration().getToolChain())); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + command = resolvedCommand; + + } catch (BuildMacroException e){ + } String[] cmdInputs = (String[])inputs.toArray(new String[inputs.size()]); IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - IManagedCommandLineInfo cmdLInfo = gen.generateCommandLineInfo( tool, tool.getToolCommand(), + IManagedCommandLineInfo cmdLInfo = gen.generateCommandLineInfo( tool, command, flags, outflag, outputPrefix, primaryOutputs, cmdInputs, tool.getCommandLinePattern() ); // The command to build String buildCmd = null; if( cmdLInfo == null ) { String toolFlags; try { - toolFlags = tool.getToolFlags(); + toolFlags = tool.getToolCommandFlagsString(null,null); } catch( BuildException ex ) { // TODO report error toolFlags = EMPTY_STRING; } - buildCmd = tool.getToolCommand() + WHITESPACE + toolFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + primaryOutputs + WHITESPACE + IN_MACRO; + buildCmd = command + WHITESPACE + toolFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + primaryOutputs + WHITESPACE + IN_MACRO; } else buildCmd = cmdLInfo.getCommandLine(); buffer.append(TAB + AT + ECHO + WHITESPACE + buildCmd + NEWLINE); @@ -1816,7 +1906,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { String resourceName = getFileName(resource); String inputExtension = resource.getFileExtension(); - String cmd = info.getToolForSource(inputExtension); +// String cmd = info.getToolForSource(inputExtension); String outputExtension = info.getOutputExtension(inputExtension); String outflag = null; String outputPrefix = null; @@ -1862,6 +1952,26 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { tool = info.getToolFromInputExtension(inputExtension); } + //optput file location needed for the file-specific build macros + IPath outputLocation = project.getLocation().append(getBuildWorkingDir()).append(relativePath + resourceName + OptDotExt); + //the separate rule is needed for the resource in case the explicit file-specific macros + //are referenced + boolean fileExplicitMacrosReferenced = MacroResolver.getReferencedExplitFileMacros(tool).length > 0 || + MacroResolver.getReferencedExplitFileMacros(tool.getToolCommand(),IBuildMacroProvider.CONTEXT_FILE, new FileContextData(resourceLocation,outputLocation,null,config.getToolChain())).length > 0; + //get and resolve command + String cmd = tool.getToolCommand(); + try{ + String resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, + EMPTY_STRING, + WHITESPACE, + IBuildMacroProvider.CONTEXT_FILE, + new FileContextData(resourceLocation,outputLocation,null,info.getDefaultConfiguration().getToolChain())); + if((resolvedCommand = resolvedCommand.trim()).length() > 0) + cmd = resolvedCommand; + + } catch (BuildMacroException e){ + } + // figure out path to use to resource String primaryOutputName = EMPTY_STRING; String primaryDependencyName = EMPTY_STRING; @@ -1880,7 +1990,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // The rule and command to add to the makefile String home = (generatedSource)? DOT : ROOT; - if( resConfig != null) { + if( resConfig != null || fileExplicitMacrosReferenced) { // Need a hardcoded rule, not a pattern rule primaryOutputName = resourcePath + resourceName + OptDotExt; primaryDependencyName = home + SEPARATOR + resourcePath + resourceName + DOT + inputExtension; @@ -1924,14 +2034,13 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { IManagedCommandLineInfo cmdLInfo = null; Vector inputs = new Vector(); inputs.add(IN_MACRO); - if( resConfig != null) { + if( resConfig != null || fileExplicitMacrosReferenced) { buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + tool.getAnnouncement() + SINGLE_QUOTE + NEWLINE); outflag = tool.getOutputFlag(); outputPrefix = tool.getOutputPrefix(); - cmd = tool.getToolCommand(); String[] flags = null; try { - flags = tool.getCommandFlags(); + flags = tool.getToolCommandFlags(resourceLocation,outputLocation); } catch( BuildException ex ) { // TODO add some routines to catch this flags = EMPTY_STRING_ARRAY; @@ -1954,7 +2063,7 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { buffer.append(TAB + AT + ECHO + WHITESPACE + SINGLE_QUOTE + tool.getAnnouncement() + SINGLE_QUOTE + NEWLINE); String buildFlags = EMPTY_STRING; try { - buildFlags = tool.getToolFlags(); + buildFlags = tool.getToolCommandFlagsString(resourceLocation,outputLocation); } catch (BuildException e) { } outflag = info.getOutputFlag(outputExtension); @@ -1967,8 +2076,8 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { inputs.add(addlDepPaths[i].toString()); } // Call the command line generator - cmdLInfo = info.generateCommandLineInfo( inputExtension, flags, outflag, outputPrefix, - OUT_MACRO + otherPrimaryOutputs, (String[])inputs.toArray(new String[inputs.size()]) ); + cmdLInfo = info.generateToolCommandLineInfo( inputExtension, flags, outflag, outputPrefix, + OUT_MACRO + otherPrimaryOutputs, (String[])inputs.toArray(new String[inputs.size()]), resourceLocation, outputLocation ); // The command to build String buildCmd = null; if( cmdLInfo == null ) buildCmd = cmd + WHITESPACE + buildFlags + WHITESPACE + @@ -2404,8 +2513,34 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator { // Initialize the tool info array and the done state for (int i=0; i 0) + name = resolved; + } catch (BuildMacroException e){ + } + gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], true, - info.getBuildArtifactName(), info.getBuildArtifactExtension()); + name, ext); } else { gnuToolInfos[i] = new ManagedBuildGnuToolInfo(project, buildTools[i], false, null, null); } diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml index 1a2f7743335..0f2f54437f2 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/plugin.xml @@ -16,6 +16,7 @@ + @@ -1241,7 +1242,7 @@ + buildPathResolver="org.eclipse.cdt.managedbuilder.gnu.cygwin.CygwinPathResolver"> + buildPathResolver="org.eclipse.cdt.managedbuilder.gnu.cygwin.CygwinPathResolver"> + buildPathResolver="org.eclipse.cdt.managedbuilder.gnu.cygwin.CygwinPathResolver"> + buildPathResolver="org.eclipse.cdt.managedbuilder.gnu.cygwin.CygwinPathResolver"> + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/BuildSettingsBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/BuildSettingsBlock.java index 6b8055d45d0..ab2c073f152 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/BuildSettingsBlock.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/BuildSettingsBlock.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2002,2004 IBM Corporation and others. + * Copyright (c) 2002,2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v0.5 * which accompanies this distribution, and is available at @@ -14,12 +14,13 @@ package org.eclipse.cdt.managedbuilder.internal.ui; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; +import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IToolChain; -import org.eclipse.cdt.managedbuilder.core.IBuilder; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; import org.eclipse.cdt.managedbuilder.ui.properties.BuildPropertyPage; +import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.IDialogConstants; @@ -28,11 +29,6 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.accessibility.AccessibleAdapter; import org.eclipse.swt.accessibility.AccessibleEvent; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.ModifyEvent; @@ -41,7 +37,12 @@ import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; public class BuildSettingsBlock extends AbstractCOptionPage { @@ -56,6 +57,8 @@ public class BuildSettingsBlock extends AbstractCOptionPage { private static final String OUTPUT_GROUP = LABEL + ".output.group"; //$NON-NLS-1$ private static final String OUTPUT_EXT = LABEL + ".output.extension"; //$NON-NLS-1$ private static final String OUTPUT_NAME = LABEL + ".output.name"; //$NON-NLS-1$ + private static final String MACROS_GROUP = LABEL + ".macros.group"; //$NON-NLS-1$ + private static final String PACROS_EXPAND_BTN = LABEL + ".macros.expand"; //$NON-NLS-1$ private static final String EMPTY_STRING = new String(); @@ -66,6 +69,8 @@ public class BuildSettingsBlock extends AbstractCOptionPage { protected Text buildArtifactName; protected Button makeCommandDefault; protected Text makeCommandEntry; + protected Button buildMacrosExpand; + protected Group buildMacrosExpandGroup; /* * Bookeeping variables @@ -110,6 +115,9 @@ public class BuildSettingsBlock extends AbstractCOptionPage { // Create the make command group area createMakeCommandGroup(comp); + + // Create the build macros usage configuration area + createExpandMacrosGroup(comp); } /* (non-Javadoc) @@ -217,6 +225,34 @@ public class BuildSettingsBlock extends AbstractCOptionPage { makeCommandEntry.addModifyListener(widgetModified); } + /* (non-Javadoc) + * Creates the group containing the check-box that allow user to specify + * whether the environment variable macros should be expanded or kept in the makefile + * @param parent + */ + private void createExpandMacrosGroup(Composite parent) { + buildMacrosExpandGroup = new Group(parent, SWT.NONE); + buildMacrosExpandGroup.setFont(parent.getFont()); + buildMacrosExpandGroup.setText(ManagedBuilderUIMessages.getResourceString(MACROS_GROUP)); + buildMacrosExpandGroup.setLayout(new GridLayout(1, true)); + buildMacrosExpandGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + buildMacrosExpand = new Button(buildMacrosExpandGroup, SWT.CHECK | SWT.LEFT); + buildMacrosExpand.setFont(buildMacrosExpandGroup.getFont()); + buildMacrosExpand.setText(ManagedBuilderUIMessages.getResourceString(PACROS_EXPAND_BTN)); + buildMacrosExpand.setBackground(buildMacrosExpandGroup.getBackground()); + buildMacrosExpand.setForeground(buildMacrosExpandGroup.getForeground()); + buildMacrosExpand.addSelectionListener(new SelectionAdapter () { + public void widgetSelected(SelectionEvent e) { + setDirty(true); + } + }); + buildMacrosExpand.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent event) { + buildMacrosExpand = null; + } + }); + } + protected void initializeValues() { setValues(); } @@ -240,6 +276,14 @@ public class BuildSettingsBlock extends AbstractCOptionPage { } makeCommandEntry.setText(makeCommand); + BuildMacroProvider provider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + if(!provider.canKeepMacrosInBuildfile(this.parent.getSelectedConfiguration())) + buildMacrosExpandGroup.setVisible(false); + else { + buildMacrosExpandGroup.setVisible(true); + buildMacrosExpand.setSelection(provider.areMacrosExpandedInBuildfile(parent.getSelectedConfiguration())); + } + setDirty(false); } @@ -274,8 +318,11 @@ public class BuildSettingsBlock extends AbstractCOptionPage { ManagedBuildManager.setDefaultConfiguration(parent.getProject(), parent.getSelectedConfiguration()); ManagedBuildManager.saveBuildInfo(parent.getProject(), false); - setValues(); + //set the expand macros state to false + BuildMacroProvider provider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + provider.expandMacrosInBuildfile(config,false); + setValues(); makeCommandDefault.setSelection(true); makeCommandEntry.setEditable(false); @@ -342,6 +389,10 @@ public class BuildSettingsBlock extends AbstractCOptionPage { selectedConfiguration.setBuildArguments(makeArguments); } + BuildMacroProvider provider = (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + if(provider.canKeepMacrosInBuildfile(this.parent.getSelectedConfiguration())) + provider.expandMacrosInBuildfile(selectedConfiguration,buildMacrosExpand.getSelection()); + setDirty(false); } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentBlock.java index 670afa003c2..db25b173cca 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentBlock.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentBlock.java @@ -17,11 +17,14 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField; import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener; import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter; import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IManagedProject; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; @@ -33,12 +36,27 @@ import org.eclipse.cdt.managedbuilder.internal.envvar.EnvVarOperationProcessor; import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; import org.eclipse.cdt.managedbuilder.internal.envvar.IContextInfo; import org.eclipse.cdt.managedbuilder.internal.envvar.UserDefinedEnvironmentSupplier; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor; +import org.eclipse.cdt.managedbuilder.internal.macros.EclipseVariablesMacroSupplier; +import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus; +import org.eclipse.cdt.managedbuilder.ui.properties.BuildPreferencePage; +import org.eclipse.cdt.managedbuilder.ui.properties.BuildPropertyPage; import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.variables.IDynamicVariable; +import org.eclipse.core.variables.IStringVariable; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.JFacePreferences; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.IFontProvider; @@ -140,6 +158,9 @@ public class EnvironmentBlock extends AbstractCOptionPage { private ListDialogField fEditableList; //non-editable list that holds all variables other than user-defined ones private ListDialogField fNonEditableList; + //the set of names of the incorrestly defined variables + private Set fIncorrectlyDefinedVariablesNames = new HashSet(); + /* * widgets @@ -148,6 +169,8 @@ public class EnvironmentBlock extends AbstractCOptionPage { private Button fShowParentButton; //parent composite private Composite fParent; + //status label + private Label fStatusLabel; private class SystemContextInfo extends DefaultContextInfo{ protected SystemContextInfo(Object context){ @@ -349,7 +372,16 @@ public class EnvironmentBlock extends AbstractCOptionPage { * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) */ public Color getForeground(Object element){ + IBuildEnvironmentVariable var = (IBuildEnvironmentVariable)element; + boolean incorrect = false; + String name = var.getName(); + if(fUser || getUserVariable(name) == null) + incorrect = fIncorrectlyDefinedVariablesNames.contains(name); + + if(incorrect) + return JFaceResources.getColorRegistry().get(JFacePreferences.ERROR_COLOR); return null; + } @@ -361,6 +393,33 @@ public class EnvironmentBlock extends AbstractCOptionPage { } } + private class EnvVarUIMacroSubstitutor extends DefaultMacroSubstitutor{ + public EnvVarUIMacroSubstitutor(IMacroContextInfo contextInfo, String inexistentMacroValue, String listDelimiter) { + super(contextInfo, inexistentMacroValue, listDelimiter); + } + + public EnvVarUIMacroSubstitutor(int contextType, Object contextData, String inexistentMacroValue, String listDelimiter){ + super(contextType, contextData, inexistentMacroValue, listDelimiter); + } + + protected ResolvedMacro resolveMacro(IBuildMacro macro) throws BuildMacroException{ + if(macro instanceof EclipseVariablesMacroSupplier.EclipseVarMacro){ + EclipseVariablesMacroSupplier.EclipseVarMacro eclipseVarMacro = + (EclipseVariablesMacroSupplier.EclipseVarMacro)macro; + IStringVariable var = eclipseVarMacro.getVariable(); + String value = null; + if(var instanceof IDynamicVariable){ + value = "dynamic<" + var.getName() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ + } else { + value = macro.getStringValue(); + } + return new ResolvedMacro(macro.getName(),value); + } + return super.resolveMacro(macro); + } + } + + /* * constructor */ @@ -672,18 +731,8 @@ public class EnvironmentBlock extends AbstractCOptionPage { fUserSupplier = (UserDefinedEnvironmentSupplier)suppliers[0]; } - try{ fSystemContextInfo = new SystemContextInfo(context); - }catch(Exception e){ - fSystemContextInfo = null; - } - - try{ fCurrentContextInfo = new CurrentContextInfo(context); - }catch(Exception e){ - fCurrentContextInfo = null; - } - } public void setParentContextInfo(IContextInfo info){ @@ -726,6 +775,38 @@ public class EnvironmentBlock extends AbstractCOptionPage { * updates both user- and sytem- variables tables. */ public void updateValues(){ + if(fCurrentContextInfo == null) + return; + try{ + Object context = fCurrentContextInfo.getContext(); + int contextType = 0; + Object contextData = null; + if(context instanceof IConfiguration){ + contextType = IBuildMacroProvider.CONTEXT_CONFIGURATION; + contextData = context; + } else if(context instanceof IManagedProject) { + contextType = IBuildMacroProvider.CONTEXT_PROJECT; + contextData = context; + } else if(context instanceof IWorkspace){ + contextType = IBuildMacroProvider.CONTEXT_WORKSPACE; + contextData = context; + } else { + contextType = IBuildMacroProvider.CONTEXT_ECLIPSEENV; + contextData = null; + } + + BuildMacroProvider macroProvider = obtainMacroProvider(); + if(macroProvider != null){ + IMacroContextInfo macroContextInfo = macroProvider.getMacroContextInfo(contextType,contextData); + if(macroContextInfo != null){ + EnvVarUIMacroSubstitutor substitutor = new EnvVarUIMacroSubstitutor(macroContextInfo, null, " "); //$NON-NLS-2$ + MacroResolver.checkIntegrity(macroContextInfo,substitutor); + } + } + updateState(null); + } catch (BuildMacroException e){ + updateState(e); + } updateUserVariables(); updateSystemVariables(); } @@ -817,6 +898,7 @@ public class EnvironmentBlock extends AbstractCOptionPage { FormLayout layout= new FormLayout(); FormData fd; Control buttonsControl = null; + Control listControl = null; Composite composite= new Composite(parent, SWT.NULL); composite.setLayout(layout); @@ -829,7 +911,7 @@ public class EnvironmentBlock extends AbstractCOptionPage { fd.left = new FormAttachment(0,0); nameLabel.setLayoutData(fd); - Control listControl= fEditableList.getListControl(composite); + listControl= fEditableList.getListControl(composite); fEditableList.getTableViewer().getTable().addKeyListener(new KeyListener(){ public void keyPressed(KeyEvent e){ if(e.keyCode == SWT.DEL) @@ -852,7 +934,7 @@ public class EnvironmentBlock extends AbstractCOptionPage { fd.top = new FormAttachment(nameLabel,0); fd.left = new FormAttachment(0,0); fd.right = new FormAttachment(buttonsControl,-5); - fd.bottom = new FormAttachment(50,0); + fd.bottom = new FormAttachment(50,-15); listControl.setLayoutData(fd); } @@ -862,12 +944,20 @@ public class EnvironmentBlock extends AbstractCOptionPage { nameLabel.setText(ManagedBuilderUIMessages.getResourceString(SYSTEM_VAR)); fd = new FormData(); if(fEditableList != null) - fd.top = new FormAttachment(50,2); + fd.top = new FormAttachment(listControl,2); else fd.top = new FormAttachment(0,2); fd.left = new FormAttachment(0,0); nameLabel.setLayoutData(fd); + fStatusLabel = new Label(composite, SWT.LEFT); + fStatusLabel.setFont(composite.getFont()); + fStatusLabel.setForeground(JFaceResources.getColorRegistry().get(JFacePreferences.ERROR_COLOR)); + fd = new FormData(); + fd.bottom = new FormAttachment(100,-10); + fd.left = new FormAttachment(0,10); + fd.right = new FormAttachment(100,-10); + fStatusLabel.setLayoutData(fd); if(fShowParentViewCheckBox){ // Create a "show parent levels" button @@ -876,7 +966,8 @@ public class EnvironmentBlock extends AbstractCOptionPage { fShowParentButton.setText(ManagedBuilderUIMessages.getResourceString(BUTTON_CHECK_SHOW_PARENT)); fd = new FormData(); fd.left = new FormAttachment(0,0); - fd.bottom = new FormAttachment(100,0); +// fd.bottom = new FormAttachment(100,0); + fd.bottom = new FormAttachment(fStatusLabel,-10); fShowParentButton.setLayoutData(fd); fShowParentButton.setSelection(fShowParentVariables); fShowParentButton.addSelectionListener(new SelectionAdapter() { @@ -887,7 +978,7 @@ public class EnvironmentBlock extends AbstractCOptionPage { }); } - Control listControl= fNonEditableList.getListControl(composite); + listControl= fNonEditableList.getListControl(composite); fd = new FormData(); fd.top = new FormAttachment(nameLabel,0); fd.left = new FormAttachment(0,0); @@ -898,7 +989,8 @@ public class EnvironmentBlock extends AbstractCOptionPage { if(fShowParentButton != null) fd.bottom = new FormAttachment(fShowParentButton,-2); else - fd.bottom = new FormAttachment(100,0); +// fd.bottom = new FormAttachment(100,0); + fd.bottom = new FormAttachment(fStatusLabel,-10); listControl.setLayoutData(fd); @@ -974,4 +1066,50 @@ public class EnvironmentBlock extends AbstractCOptionPage { } return filtered; } + + private void updateState(BuildMacroException e){ + ICOptionContainer container = getContainer(); + fIncorrectlyDefinedVariablesNames.clear(); + + if(e != null){ + fStatusLabel.setText(e.getMessage()); + fStatusLabel.setVisible(true); + IBuildMacroStatus statuses[] = e.getMacroStatuses(); + for(int i = 0; i < statuses.length; i++){ + String name = statuses[i].getMacroName(); + if(name != null) + fIncorrectlyDefinedVariablesNames.add(name); + } + } + else{ + fStatusLabel.setVisible(false); + } + } + + /** + * Returns the build macro provider to be used for macro resolution + * In case the "Build Macros" tab is available, returns the BuildMacroProvider + * supplied by that tab. + * Unlike the default provider, that provider also contains + * the user-modified macros that are not applied yet + * If the "Build Macros" tab is not available, returns the default BuildMacroProvider + */ + protected BuildMacroProvider obtainMacroProvider(){ + ICOptionContainer container = getContainer(); + ManagedBuildOptionBlock optionBlock = null; + if(container instanceof BuildPropertyPage){ + BuildPropertyPage page = (BuildPropertyPage)container; + optionBlock = page.getOptionBlock(); + } else if(container instanceof BuildPreferencePage){ + BuildPreferencePage page = (BuildPreferencePage)container; + optionBlock = page.getOptionBlock(); + } + if(optionBlock != null){ + MacrosSetBlock block = optionBlock.getMacrosBlock(); + if(block != null) + return block.getBuildMacroProvider(); + } + return (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentSetBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentSetBlock.java index f1e3af20595..c663ddedf80 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentSetBlock.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/EnvironmentSetBlock.java @@ -11,6 +11,10 @@ package org.eclipse.cdt.managedbuilder.internal.ui; import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.DefaultContextInfo; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.IContextInfo; import org.eclipse.cdt.managedbuilder.ui.properties.BuildPropertyPage; import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; import org.eclipse.cdt.ui.dialogs.ICOptionContainer; @@ -26,16 +30,12 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; /** - * displays the tab-folder. Each tab of the tab-folder - * contains the EnvironmentBlock representinf the environment - * for the given context - * Whe used in the BuildPropertyPage the tab-folder contains the following tabs: + * When used in the BuildPropertyPage the displays the tab-folder that contains the following tabs: * 1. a tab containing configuration-specific variables * 2. a tab containing project-specific variables * - * otherwise the tab-folder contains the following tabs: - * 1. a tab containing workspace-specific variables - * 2. a tab containing eclipse process environment variables + * Otherwise displays a single EnvironmentBlock that contains + * the workspace-specific and eclipse process environment variables * */ public class EnvironmentSetBlock extends AbstractCOptionPage { @@ -59,6 +59,46 @@ public class EnvironmentSetBlock extends AbstractCOptionPage { private ICOptionContainer fParentContainer; + private UIEnvVarProvider fEnvProvider = null; + + private class UIEnvVarContextInfo extends DefaultContextInfo{ + public UIEnvVarContextInfo(Object context){ + super(context); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getNext() + */ + public IContextInfo getNext(){ + IContextInfo info = super.getNext(); + if(info != null){ + EnvironmentBlock blocks[] = getAllBlocks(); + for(int i = 0; i < blocks.length; i++){ + if(blocks[i].getContext() == info.getContext()) + return blocks[i].getContextInfo(); + } + return new UIEnvVarContextInfo(info.getContext()); + } + return null; + } + } + + /* + * The EnvironmentVariableProvider to be used in UI + * Unlike the default provider, this provider also contains + * the user-modified variables that are not applied yet + */ + private class UIEnvVarProvider extends EnvironmentVariableProvider{ + protected IContextInfo getContextInfo(Object context){ + EnvironmentBlock blocks[] = getAllBlocks(); + for(int i = 0; i < blocks.length; i++){ + if(blocks[i].getContext() == context) + return blocks[i].getContextInfo(); + } + return new UIEnvVarContextInfo(context); + } + } + private class EnvironmentTabFolder extends TabFolderOptionBlock{ private EnvironmentBlock fFolderTabs[]; public EnvironmentTabFolder() { @@ -260,4 +300,16 @@ public class EnvironmentSetBlock extends AbstractCOptionPage { else if(fEnvBlock != null) fEnvBlock.setContext(ResourcesPlugin.getWorkspace()); } + + /* + * returns the EnvironmentVariableProvider to be used in UI + * Unlike the default provider, the returned provider also contains + * the user-modified variables that are not applied yet + */ + public IEnvironmentVariableProvider getEnvironmentVariableProvider(){ + if(fEnvProvider == null) + fEnvProvider = new UIEnvVarProvider(); + return fEnvProvider; + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/MacrosBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/MacrosBlock.java new file mode 100644 index 00000000000..b33ac94c02a --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/MacrosBlock.java @@ -0,0 +1,1183 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.ui; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField; +import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener; +import org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter; +import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField; +import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvVarOperationProcessor; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacro; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroContextInfo; +import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor; +import org.eclipse.cdt.managedbuilder.internal.macros.EclipseVariablesMacroSupplier; +import org.eclipse.cdt.managedbuilder.internal.macros.EnvironmentMacroSupplier; +import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.internal.macros.UserDefinedMacroSupplier; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroStatus; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier; +import org.eclipse.cdt.managedbuilder.ui.properties.BuildPreferencePage; +import org.eclipse.cdt.managedbuilder.ui.properties.BuildPropertyPage; +import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.variables.IDynamicVariable; +import org.eclipse.core.variables.IStringVariable; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.JFacePreferences; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * displays the build macros for the given context + */ +public class MacrosBlock extends AbstractCOptionPage { + /* + * String constants + */ + private static final String PREFIX = "MacrosBlock"; //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ + + private static final String USER_MACROS = LABEL + ".user.macros"; //$NON-NLS-1$ + private static final String SYSTEM_MACROS = LABEL + ".system.macros"; //$NON-NLS-1$ + + private static final String HEADER = LABEL + ".header"; //$NON-NLS-1$ + private static final String HEADER_NAME = HEADER + ".name"; //$NON-NLS-1$ + private static final String HEADER_TYPE = HEADER + ".type"; //$NON-NLS-1$ + private static final String HEADER_VALUE = HEADER + ".value"; //$NON-NLS-1$ + + private static final String TYPE = LABEL + ".type"; //$NON-NLS-1$ + private static final String TYPE_TEXT = TYPE + ".text"; //$NON-NLS-1$ + private static final String TYPE_TEXT_LIST = TYPE + ".text.list"; //$NON-NLS-1$ + private static final String TYPE_PATH_FILE = TYPE + ".path.file"; //$NON-NLS-1$ + private static final String TYPE_PATH_FILE_LIST = TYPE + ".path.file.list"; //$NON-NLS-1$ + private static final String TYPE_PATH_DIR = TYPE + ".path.dir"; //$NON-NLS-1$ + private static final String TYPE_PATH_DIR_LIST = TYPE + ".path.dir.list"; //$NON-NLS-1$ + private static final String TYPE_PATH_ANY = TYPE + ".path.any"; //$NON-NLS-1$ + private static final String TYPE_PATH_ANY_LIST = TYPE + ".path.any.list"; //$NON-NLS-1$ + + + private static final String BUTTON = LABEL + ".button"; //$NON-NLS-1$ + private static final String BUTTON_NEW = BUTTON + ".new"; //$NON-NLS-1$ + private static final String BUTTON_EDIT = BUTTON + ".edit"; //$NON-NLS-1$ + private static final String BUTTON_DELETE = BUTTON + ".delete"; //$NON-NLS-1$ + + private static final String BUTTON_CHECK_SHOW_PARENT = BUTTON + ".check.chow.parent"; //$NON-NLS-1$ + + private static final String DELETE_CONFIRM_TITLE = LABEL + ".delete.confirm.title"; //$NON-NLS-1$ + private static final String DELETE_CONFIRM_MESSAGE = LABEL + ".delete.confirm.message"; //$NON-NLS-1$ + + private static final String DELETE_ALL_CONFIRM_TITLE = LABEL + ".delete.all.confirm.title"; //$NON-NLS-1$ + private static final String DELETE_ALL_CONFIRM_MESSAGE = LABEL + ".delete.all.confirm.message"; //$NON-NLS-1$ + + private static final String VALUE = LABEL + ".value"; //$NON-NLS-1$ + private static final String VALUE_ECLIPSE_DYNAMIC = VALUE + ".eclipse.dynamic"; //$NON-NLS-1$ + + + private static final String VALUE_DELIMITER = " || "; //$NON-NLS-1$ + + + private static final String fHiddenMacros[] = new String[]{ + //currently the "CWD" and "PWD" macros are not displayed in UI + "CWD", //$NON-NLS-1$ + "PWD" //$NON-NLS-1$ + }; + + /* + * button IDs + */ + private static final int IDX_BUTTON_NEW = 0; + private static final int IDX_BUTTON_EDIT = 1; + private static final int IDX_BUTTON_DELETE = 2; + + //macro names deleted by a user + private HashSet fDeletedUserMacroNames; + //macros added by a user + private Map fAddedUserMacros; + //specifies whether a "delete All" button was previousely pressed + private boolean fDeleteAll = false; + //specifies whether the set of the user-defined macros was changed by a user + //and the changes are not applied to the User Macro Supplier + private boolean fModified = false; + //holds the visible state. + private boolean fVisible = false; + //specifies whether the "show parent context macros" checkbox should be created + private boolean fShowParentViewCheckBox = true; + //inexistent context + private static final Object fInexistentContext = new Object(); + //the context tyte for which the macros are displayed + private int fContextType = 0; + //the context data for which the macros are displayed + private Object fContextData = fInexistentContext; + //specifies whether the parent level macros should be displayed + private boolean fShowParentMacros = false; + + private IMacroContextInfo fSystemContextInfo; + private IMacroContextInfo fCurrentContextInfo; + private IMacroContextInfo fParentContextInfo; + private boolean fUseDefaultParentContextInfo = true; + + private Set fIncorrectlyDefinedMacrosNames = new HashSet(); + + //the user defined macro supplier + private UserDefinedMacroSupplier fUserSupplier; + //editable list that displayes user-defined macros + private ListDialogField fEditableList; + //non-editable list that holds all macros other than user-defined ones + private ListDialogField fNonEditableList; + + /* + * widgets + */ + //show parent level macros check-box + private Button fShowParentButton; + //parent composite + private Composite fParent; + //status label + private Label fStatusLabel; + + + private class MacroUIMacroSubstitutor extends DefaultMacroSubstitutor{ + public MacroUIMacroSubstitutor(IMacroContextInfo contextInfo, String inexistentMacroValue, String listDelimiter) { + super(contextInfo, inexistentMacroValue, listDelimiter); + } + + public MacroUIMacroSubstitutor(int contextType, Object contextData, String inexistentMacroValue, String listDelimiter){ + super(contextType, contextData, inexistentMacroValue, listDelimiter); + } + + protected ResolvedMacro resolveMacro(String macroName) throws BuildMacroException{ + String names[] = BuildMacroProvider.fMbsMacroSupplier.getMacroNames(IBuildMacroProvider.CONTEXT_FILE); + for(int i = 0; i < names.length; i++){ + if(macroName.equals(names[i])) + return new ResolvedMacro(macroName,MacroResolver.createMacroReference(macroName)); + } + names = BuildMacroProvider.fMbsMacroSupplier.getMacroNames(IBuildMacroProvider.CONTEXT_OPTION); + for(int i = 0; i < names.length; i++){ + if(macroName.equals(names[i])) + return new ResolvedMacro(macroName,MacroResolver.createMacroReference(macroName)); + } + return super.resolveMacro(macroName); + } + + protected ResolvedMacro resolveMacro(IBuildMacro macro) throws BuildMacroException{ + if(macro instanceof EclipseVariablesMacroSupplier.EclipseVarMacro){ + EclipseVariablesMacroSupplier.EclipseVarMacro eclipseVarMacro = + (EclipseVariablesMacroSupplier.EclipseVarMacro)macro; + IStringVariable var = eclipseVarMacro.getVariable(); + String value = null; + if(var instanceof IDynamicVariable){ + value = "dynamic<" + var.getName() + ">"; //$NON-NLS-1$//$NON-NLS-2$ + } else { + value = macro.getStringValue(); + } + return new ResolvedMacro(macro.getName(),value); + } + return super.resolveMacro(macro); + } + } + + private class MacroUIMacroSontextInfo extends DefaultMacroContextInfo{ + protected MacroUIMacroSontextInfo(int contextType, Object contextData){ + super(contextType,contextData); + } + + protected IBuildMacroSupplier[] getSuppliers(int contextType, Object contextData){ + IBuildMacroSupplier suppliers[] = super.getSuppliers(contextType,contextData); + if(suppliers == null || suppliers.length == 0) + return null; + IEnvironmentVariableProvider envProvider = obtainEnvironmentVariableProvider(); + if(envProvider != null){ + for(int i = 0; i < suppliers.length; i++){ + if((suppliers[i] instanceof EnvironmentMacroSupplier)){ + suppliers[i] = new EnvironmentMacroSupplier(envProvider); + break; + } + } + } + return suppliers; + } + + } + + private class SystemContextInfo extends MacroUIMacroSontextInfo{ + protected SystemContextInfo(int contextType, Object contextData){ + super(contextType,contextData); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroContextInfo#getSuppliers(int, java.lang.Object) + */ + protected IBuildMacroSupplier[] getSuppliers(int contextType, Object contextData){ + IBuildMacroSupplier suppliers[] = super.getSuppliers(contextType,contextData); + if(suppliers == null || suppliers.length == 0) + return null; + + List list = new ArrayList(); + for(int i = 0; i < suppliers.length; i++){ + if(!(suppliers[i] instanceof UserDefinedMacroSupplier)) + list.add(suppliers[i]); + } + + return (IBuildMacroSupplier[])list.toArray(new IBuildMacroSupplier[list.size()]); + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getNext() + */ + public IMacroContextInfo getNext(){ + if(fUseDefaultParentContextInfo) + return super.getNext(); + return fParentContextInfo; + } + } + + private class CurrentContextInfo extends MacroUIMacroSontextInfo{ + protected CurrentContextInfo(int contextType, Object contextData){ + super(contextType,contextData); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroContextInfo#getSuppliers(int, java.lang.Object) + */ + public IBuildMacroSupplier[] getSuppliers(int contextType, Object contextData){ + IBuildMacroSupplier suppliers[] = super.getSuppliers(contextType,contextData); + if(fParentContextInfo == null){ + int i = 0; + } + if(suppliers == null || suppliers.length == 0) + return suppliers; + if(!(suppliers[0] instanceof UserDefinedMacroSupplier)) + return suppliers; + + List list = new ArrayList(suppliers.length); + list.add(new UIMacroSupplier()); + + for(int i = 1; i < suppliers.length; i++){ + list.add(suppliers[i]); + } + + return (IBuildMacroSupplier[])list.toArray(new IBuildMacroSupplier[list.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getNext() + */ + public IMacroContextInfo getNext(){ + if(fUseDefaultParentContextInfo) + return super.getNext(); + return fParentContextInfo; + } + } + + private class UIMacroSupplier implements IBuildMacroSupplier{ + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacro(java.lang.String, int, java.lang.Object) + */ + public IBuildMacro getMacro(String name, int contextType, Object contextData){ + if(contextType != fContextType || contextData != fContextData) + return null; + + return (IBuildMacro)getUserMacros().get(name); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.macros.IBuildMacroSupplier#getMacros(int, java.lang.Object) + */ + public IBuildMacro[] getMacros(int contextType, Object contextData){ + if(contextType != fContextType || contextData != fContextData) + return null; + + Collection macros = getUserMacros().values(); + return (IBuildMacro[])macros.toArray(new IBuildMacro[macros.size()]); + } + } + + public class ListAdapter implements IListAdapter, IDialogFieldListener { + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter#customButtonPressed(org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField, int) + */ + public void customButtonPressed(ListDialogField field, int index) { + if(field == fEditableList) + handleCustomButtonPressed(index); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter#selectionChanged(org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField) + */ + public void selectionChanged(ListDialogField field) { + handleSelectionChanged(field); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.IListAdapter#doubleClicked(org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField) + */ + public void doubleClicked(ListDialogField field) { + if (isEditable(field) && field.getSelectedElements().size() == 1) + handleCustomButtonPressed(IDX_BUTTON_EDIT); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField) + */ + public void dialogFieldChanged(DialogField field) { + } + } + + private class MacroLabelProvider extends LabelProvider implements ITableLabelProvider, IFontProvider , ITableFontProvider, IColorProvider{ + private boolean fUser; + public MacroLabelProvider(boolean user){ + fUser = user; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + public Image getImage(Object element) { + return null; // JavaPluginImages.get(JavaPluginImages.IMG_OBJS_REFACTORING_INFO); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + public String getText(Object element) { + return getColumnText(element, 0); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) + */ + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) + */ + public String getColumnText(Object element, int columnIndex) { + IBuildMacro macro = (IBuildMacro)element; + switch(columnIndex){ + case 0: + return macro.getName(); + case 1: + switch(macro.getMacroValueType()){ + case IBuildMacro.VALUE_PATH_FILE: + return ManagedBuilderUIMessages.getResourceString(TYPE_PATH_FILE); + case IBuildMacro.VALUE_PATH_FILE_LIST: + return ManagedBuilderUIMessages.getResourceString(TYPE_PATH_FILE_LIST); + case IBuildMacro.VALUE_PATH_DIR: + return ManagedBuilderUIMessages.getResourceString(TYPE_PATH_DIR); + case IBuildMacro.VALUE_PATH_DIR_LIST: + return ManagedBuilderUIMessages.getResourceString(TYPE_PATH_DIR_LIST); + case IBuildMacro.VALUE_PATH_ANY: + return ManagedBuilderUIMessages.getResourceString(TYPE_PATH_ANY); + case IBuildMacro.VALUE_PATH_ANY_LIST: + return ManagedBuilderUIMessages.getResourceString(TYPE_PATH_ANY_LIST); + case IBuildMacro.VALUE_TEXT: + return ManagedBuilderUIMessages.getResourceString(TYPE_TEXT); + case IBuildMacro.VALUE_TEXT_LIST: + return ManagedBuilderUIMessages.getResourceString(TYPE_TEXT_LIST); + default: + } + case 2: + return getDisplayedMacroValue(macro); //$NON-NLS-1$ + } + return ""; //$NON-NLS-1$ + } + + private String getDisplayedMacroValue(IBuildMacro macro){ + String value = ""; //$NON-NLS-1$ + try{ + if(macro instanceof EclipseVariablesMacroSupplier.EclipseVarMacro){ + EclipseVariablesMacroSupplier.EclipseVarMacro eclipseVarMacro = + (EclipseVariablesMacroSupplier.EclipseVarMacro)macro; + IStringVariable var = eclipseVarMacro.getVariable(); + if(var instanceof IDynamicVariable){ + value = ManagedBuilderUIMessages.getResourceString(VALUE_ECLIPSE_DYNAMIC); + } else { + value = macro.getStringValue(); + } + } else { + if(MacroResolver.isStringListMacro(macro.getMacroValueType())) + value = BuildMacroProvider.getDefault().convertStringListToString(macro.getStringListValue(),VALUE_DELIMITER); + else + value = macro.getStringValue(); + + } + }catch (BuildMacroException e){ + } + return value; + } + + private Font getValueFont(IBuildMacro macro){ + Font font = null; + if(macro instanceof EclipseVariablesMacroSupplier.EclipseVarMacro){ + EclipseVariablesMacroSupplier.EclipseVarMacro eclipseVarMacro = + (EclipseVariablesMacroSupplier.EclipseVarMacro)macro; + IStringVariable var = eclipseVarMacro.getVariable(); + if(var instanceof IDynamicVariable){ + font = JFaceResources.getFontRegistry().getItalic(JFaceResources.DIALOG_FONT); + } + } + + return font; + } + + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object) + */ + public Font getFont(Object element) { + return getFont(element, 0); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITableFontProvider#getFont(java.lang.Object, int) + */ + public Font getFont(Object element, int columnIndex) { + IBuildMacro macro = (IBuildMacro)element; + + switch(columnIndex){ + case 0: + case 1: + break; + case 2: + return getValueFont(macro); + } + + if(!fUser && getUserMacro(macro.getName()) != null) + return JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT); + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element){ + IBuildMacro macro = (IBuildMacro)element; + boolean incorrect = false; + String name = macro.getName(); + if(fUser || getUserMacro(name) == null) + incorrect = fIncorrectlyDefinedMacrosNames.contains(name); + + if(incorrect) + return JFaceResources.getColorRegistry().get(JFacePreferences.ERROR_COLOR); + return null; + } + + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element){ + return null; + } + } + + /* + * constructor + */ + public MacrosBlock(ICOptionContainer parent, String title, boolean editable, boolean showParentViewCheckBox){ + super(title); + super.setContainer(parent); + + ListAdapter adapter = new ListAdapter(); + + if(editable){ + String[] buttons= new String[] { + ManagedBuilderUIMessages.getResourceString(BUTTON_NEW), + ManagedBuilderUIMessages.getResourceString(BUTTON_EDIT), + ManagedBuilderUIMessages.getResourceString(BUTTON_DELETE), + }; + + fEditableList= new ListDialogField(adapter, buttons, new MacroLabelProvider(true)); + fEditableList.setDialogFieldListener(adapter); + + String[] columnsHeaders= new String[] { + ManagedBuilderUIMessages.getResourceString(HEADER_NAME), + ManagedBuilderUIMessages.getResourceString(HEADER_TYPE), + ManagedBuilderUIMessages.getResourceString(HEADER_VALUE), + }; + + fEditableList.setTableColumns(new ListDialogField.ColumnsDescription(columnsHeaders, true)); + fEditableList.setViewerSorter(new ViewerSorter()); + + + } + + //create non-editable list + fNonEditableList= new ListDialogField(adapter, null, new MacroLabelProvider(false)); + fNonEditableList.setDialogFieldListener(adapter); + + String[] columnsHeaders= new String[] { + ManagedBuilderUIMessages.getResourceString(HEADER_NAME), + ManagedBuilderUIMessages.getResourceString(HEADER_TYPE), + ManagedBuilderUIMessages.getResourceString(HEADER_VALUE), + }; + + fNonEditableList.setTableColumns(new ListDialogField.ColumnsDescription(columnsHeaders, true)); + fNonEditableList.setViewerSorter(new ViewerSorter()); + + fShowParentViewCheckBox = showParentViewCheckBox; + + } + + /* + * returns the map containing the user-defined macros + */ + private Map getUserMacros(){ + if(fUserSupplier == null) + return null; + Map map = new HashMap(); + + if(!fDeleteAll){ + IBuildMacro macros[] = fUserSupplier.getMacros(fContextType,fContextData); + if(macros != null) { + for(int i = 0; i < macros.length; i++){ + String name = macros[i].getName(); + map.put(name,macros[i]); + } + } + + Iterator iter = getDeletedUserMacroNames().iterator(); + while(iter.hasNext()){ + map.remove((String)iter.next()); + } + + iter = getAddedUserMacros().values().iterator(); + while(iter.hasNext()){ + IBuildMacro macro = (IBuildMacro)iter.next(); + String name = macro.getName(); + map.put(name,macro); + } + } + return map; + } + + /* + * returns the HashSet holding the names of the user-deleted macros + */ + private HashSet getDeletedUserMacroNames(){ + if(fDeletedUserMacroNames == null) + fDeletedUserMacroNames = new HashSet(); + return fDeletedUserMacroNames; + } + + /* + * returns the map holding user-created/modified macros + */ + private Map getAddedUserMacros(){ + if(fAddedUserMacros == null) + fAddedUserMacros = new HashMap(); + return fAddedUserMacros; + } + + /* + * creates a user macro + * the macros created are stored in the fAddedUserMacros Map, and are not actually added to the user supplier + * the applyUserMacros() should be called to store those macros to the user supplier + */ + private void addUserMacro(String name, int type, String value){ + if(!canCreate(name)) + return; + fDeleteAll = false; + BuildMacro newMacro = new BuildMacro(name,type,value); + getDeletedUserMacroNames().remove(name); + getAddedUserMacros().put(name,newMacro); + + fModified = true; + } + + /* + * creates a user macro + * the macros created are stored in the fAddedUserMacros Map, and are not actually added to the user supplier + * the applyUserMacros() should be called to store those macros to the user supplier + */ + private void addUserMacro(IBuildMacro newMacro){ + String name = newMacro.getName(); + if(!canCreate(name)) + return; + fDeleteAll = false; + getDeletedUserMacroNames().remove(name); + getAddedUserMacros().put(name,newMacro); + + fModified = true; + } + + /* + * creates a user macro + * the macros created are stored in the fAddedUserMacros Map, and are not actually added to the user supplier + * the applyUserMacros() should be called to store those macros to the user supplier + */ + private void addUserMacro(String name, int type, String value[]){ + if(!canCreate(name)) + return; + fDeleteAll = false; + BuildMacro newMacro = new BuildMacro(name,type,value); + getDeletedUserMacroNames().remove(name); + getAddedUserMacros().put(name,newMacro); + + fModified = true; + } + + /* + * deletes a user macro + * the macros deleted are stored in the fDeletedUserMacroNames HashSet, and are not actually deleted from the user supplier + * the applyUserMacros() should be called to delete those macros from the user supplier + */ + private void deleteUserMacro(String name){ + fDeleteAll = false; + getAddedUserMacros().remove(name); + getDeletedUserMacroNames().add(name); + + fModified = true; + } + + /* + * deletes all user macros + * the applyUserMacros() should be called to delete those macros from the user supplier + */ + private void deleteAllUserMacros(){ + fDeleteAll = true; + getDeletedUserMacroNames().clear(); + getAddedUserMacros().clear(); + + fModified = true; + } + + /* + * returns whether the user macros were modified + */ + public boolean isModified(){ + return fModified; + } + + /* + * sets the modify state + */ + public void setModified(boolean modified){ + fModified = modified; + } + + /* + * returns a user macro of a given name + */ + private IBuildMacro getUserMacro(String name){ + Map macros = getUserMacros(); + if(macros == null) + return null; + + return (IBuildMacro)macros.get(name); + } + + /* + * applies user macros. + * + */ + private void applyUserMacros(){ + if(fUserSupplier != null){ + if(fDeleteAll){ + fUserSupplier.deleteAll(fContextType,fContextData); + } + else{ + Iterator iter = getDeletedUserMacroNames().iterator(); + while(iter.hasNext()){ + fUserSupplier.deleteMacro((String)iter.next(),fContextType,fContextData); + } + + iter = getAddedUserMacros().values().iterator(); + while(iter.hasNext()){ + IBuildMacro macro = (IBuildMacro)iter.next(); + fUserSupplier.createMacro(macro,fContextType,fContextData); + } + + getDeletedUserMacroNames().clear(); + getAddedUserMacros().clear(); + } + } + } + + /* + * applies user macros and asks the user supplier to serialize + */ + private void storeUserMacros(){ + applyUserMacros(); + if(fUserSupplier != null) + fUserSupplier.serialize(false); + } + + /* + * called when the user macro selection was changed + */ + private void handleSelectionChanged(ListDialogField field){ + if(isEditable(field)){ + List selectedElements= field.getSelectedElements(); + field.enableButton(IDX_BUTTON_EDIT, selectedElements.size() == 1); + field.enableButton(IDX_BUTTON_DELETE, selectedElements.size() > 0); + } + } + + /* + * answers whether the list values can be edited + */ + private boolean isEditable(ListDialogField field) { + return field == fEditableList; + } + + /* + * called when a custom button was pressed + */ + private void handleCustomButtonPressed(int index){ + + switch(index){ + case IDX_BUTTON_NEW:{ + NewBuildMacroDialog dlg = new NewBuildMacroDialog(fParent.getShell(),this,null); + if(dlg.open() == Dialog.OK){ + IBuildMacro macro = dlg.getDefinedMacro(); + if(macro != null){ + addUserMacro(macro); + updateValues(); + } + } + } + break; + case IDX_BUTTON_EDIT:{ + IBuildMacro macros[] = getSelectedUserMacros(); + if(macros != null && macros.length == 1){ + NewBuildMacroDialog dlg = new NewBuildMacroDialog(fParent.getShell(),this,getUserMacro(macros[0].getName())); + if(dlg.open() == Dialog.OK){ + IBuildMacro macro = dlg.getDefinedMacro(); + if(macro != null){ + addUserMacro(macro); + updateValues(); + } + } + } + } + break; + case IDX_BUTTON_DELETE:{ + IBuildMacro macros[] = getSelectedUserMacros(); + if(macros != null && macros.length > 0){ + if(MessageDialog.openQuestion(fParent.getShell(), + ManagedBuilderUIMessages.getResourceString(DELETE_CONFIRM_TITLE), + ManagedBuilderUIMessages.getResourceString(DELETE_CONFIRM_MESSAGE))){ + for(int i = 0; i < macros.length; i++){ + deleteUserMacro(macros[i].getName()); + } + updateValues(); + } + } + } + break; + } + + } + + /* + * returnes the selected user-defined macros + */ + private IBuildMacro[] getSelectedUserMacros(){ + if(fEditableList == null) + return null; + + List list = fEditableList.getSelectedElements(); + return (IBuildMacro[])list.toArray(new IBuildMacro[list.size()]); + } + + /* + * sets the context for which the macros should be displayed + */ + public void setContext(int contextType, Object contextData){ + if(contextType == fContextType && contextData == fContextData) + return; + + fContextType = contextType; + fContextData = contextData; + + IBuildMacroProvider provider = BuildMacroProvider.getDefault(); + IBuildMacroSupplier suppliers[] = provider.getSuppliers(fContextType, fContextData); + if(suppliers != null && suppliers.length != 0 && suppliers[0] instanceof UserDefinedMacroSupplier){ + fUserSupplier = (UserDefinedMacroSupplier)suppliers[0]; + } + + fSystemContextInfo = new SystemContextInfo(fContextType, fContextData); + fCurrentContextInfo = new CurrentContextInfo(fContextType, fContextData); + } + + public void setParentContextInfo(IMacroContextInfo info){ + fParentContextInfo = info; + fUseDefaultParentContextInfo = false; + } + + public void resetDefaultParentContextInfo(){ + fUseDefaultParentContextInfo = true; + fParentContextInfo = null; + } + + public IMacroContextInfo getContextInfo(){ + return fCurrentContextInfo; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + public void performApply(IProgressMonitor monitor) throws CoreException { + if(fUserSupplier == null) + return; + storeUserMacros(); + setModified(false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults() + */ + public void performDefaults() { + if(MessageDialog.openQuestion(fParent.getShell(), + ManagedBuilderUIMessages.getResourceString(DELETE_ALL_CONFIRM_TITLE), + ManagedBuilderUIMessages.getResourceString(DELETE_ALL_CONFIRM_MESSAGE))){ + deleteAllUserMacros(); + updateValues(); + } + } + + /* + * updates both user- and sytem- macros tables. + */ + public void updateValues(){ + try{ + MacroResolver.checkIntegrity(fCurrentContextInfo,new MacroUIMacroSubstitutor(fCurrentContextInfo,null," "));//$NON-NLS-1$ //$NON-NLS-2$ + updateState(null); + } catch (BuildMacroException e){ + updateState(e); + } + updateUserMacros(); + updateSystemMacros(); } + + private void updateState(BuildMacroException e){ + ICOptionContainer container = getContainer(); + fIncorrectlyDefinedMacrosNames.clear(); + + if(e != null){ + fStatusLabel.setText(e.getMessage()); + fStatusLabel.setVisible(true); + IBuildMacroStatus statuses[] = e.getMacroStatuses(); + for(int i = 0; i < statuses.length; i++){ + String name = statuses[i].getMacroName(); + if(name != null) + fIncorrectlyDefinedMacrosNames.add(name); + } + } + else{ + fStatusLabel.setVisible(false); + } + } + + /* + * apdates a user-defined macros table + */ + private void updateUserMacros(){ + if(fEditableList == null || fContextType == 0) + return; + + fEditableList.selectFirstElement(); + handleSelectionChanged(fEditableList); + + if(fUserSupplier != null) + fEditableList.setElements(new ArrayList(getUserMacros().values())); + else + fEditableList.removeAllElements(); + } + + + /* + * apdates a system-defined macros table + */ + private void updateSystemMacros(){ + if(fNonEditableList == null || fContextType == 0) + return; + + List list = null; + IBuildMacro macros[] = getSystemMacros(fShowParentMacros); + if(macros != null && macros.length != 0){ + list = new ArrayList(macros.length); + for(int i = 0; i < macros.length; i++){ + list.add(macros[i]); + } + } + + if(list != null) + fNonEditableList.setElements(list); + else + fNonEditableList.removeAllElements(); + } + + /* + * return a system macro of a given name + */ + public IBuildMacro getSystemMacro(String name,boolean includeParentLevels){ + if(name == null) + return null; + if(fSystemContextInfo == null) + return null; + if(!canDisplay(name)) + return null; + + return BuildMacroProvider.getMacro(name,fSystemContextInfo,includeParentLevels); + } + + /* + * returns an array of system macros + */ + public IBuildMacro[] getSystemMacros(boolean includeParentLevels){ + IBuildMacro macros[] = BuildMacroProvider.getMacros(fSystemContextInfo,includeParentLevels); + if(macros == null) + return null; + return filterDisplayedMacros(macros); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + fParent = parent; + FormLayout layout= new FormLayout(); + FormData fd; + Control buttonsControl = null; + Control listControl = null; + + Composite composite= new Composite(parent, SWT.NULL); + composite.setLayout(layout); + + if(fEditableList != null){ + Label nameLabel = new Label(composite, SWT.LEFT); + nameLabel.setFont(composite.getFont()); + nameLabel.setText(ManagedBuilderUIMessages.getResourceString(USER_MACROS)); + fd = new FormData(); + fd.top = new FormAttachment(0,2); + fd.left = new FormAttachment(0,0); + nameLabel.setLayoutData(fd); + + listControl= fEditableList.getListControl(composite); + fEditableList.getTableViewer().getTable().addKeyListener(new KeyListener(){ + public void keyPressed(KeyEvent e){ + if(e.keyCode == SWT.DEL) + handleCustomButtonPressed(IDX_BUTTON_DELETE); + } + + public void keyReleased(KeyEvent e){ + + } + }); + + buttonsControl= fEditableList.getButtonBox(composite); + + fd = new FormData(); + fd.top = new FormAttachment(nameLabel,0); + fd.right = new FormAttachment(100,0); + buttonsControl.setLayoutData(fd); + + fd = new FormData(); + fd.top = new FormAttachment(nameLabel,0); + fd.left = new FormAttachment(0,0); + fd.right = new FormAttachment(buttonsControl,-5); + fd.bottom = new FormAttachment(50,-15); + listControl.setLayoutData(fd); + + } + + Label nameLabel = new Label(composite, SWT.LEFT); + nameLabel.setFont(composite.getFont()); + nameLabel.setText(ManagedBuilderUIMessages.getResourceString(SYSTEM_MACROS)); + fd = new FormData(); + if(fEditableList != null) + fd.top = new FormAttachment(listControl,2); + else + fd.top = new FormAttachment(0,2); + fd.left = new FormAttachment(0,0); + nameLabel.setLayoutData(fd); + + fStatusLabel = new Label(composite, SWT.LEFT); + fStatusLabel.setFont(composite.getFont()); + fStatusLabel.setForeground(JFaceResources.getColorRegistry().get(JFacePreferences.ERROR_COLOR)); + fd = new FormData(); + fd.bottom = new FormAttachment(100,-10); + fd.left = new FormAttachment(0,10); + fd.right = new FormAttachment(100,-10); + fStatusLabel.setLayoutData(fd); + + + if(fShowParentViewCheckBox){ + // Create a "show parent levels" button + fShowParentButton = new Button(composite, SWT.CHECK); + fShowParentButton.setFont(composite.getFont()); + fShowParentButton.setText(ManagedBuilderUIMessages.getResourceString(BUTTON_CHECK_SHOW_PARENT)); + fd = new FormData(); + fd.left = new FormAttachment(0,0); + fd.bottom = new FormAttachment(fStatusLabel,-10); + fShowParentButton.setLayoutData(fd); + fShowParentButton.setSelection(fShowParentMacros); + fShowParentButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + fShowParentMacros = fShowParentButton.getSelection(); + updateSystemMacros(); + } + }); + } + + listControl= fNonEditableList.getListControl(composite); + fd = new FormData(); + fd.top = new FormAttachment(nameLabel,0); + fd.left = new FormAttachment(0,0); + if(buttonsControl != null) + fd.right = new FormAttachment(buttonsControl,-5); + else + fd.right = new FormAttachment(100,0); + if(fShowParentButton != null) + fd.bottom = new FormAttachment(fShowParentButton,-2); + else + fd.bottom = new FormAttachment(fStatusLabel,-10); + + listControl.setLayoutData(fd); + + this.setControl(composite); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean) + */ + public void setVisible(boolean visible){ + fVisible = visible; + if(visible) + updateValues(); + super.setVisible(visible); + } + + /* + * return the context for which the macros are displayed + */ + public Object getContextData(){ + return fContextData; + } + + public int getContextType(){ + return fContextType; + } + + public void displayParentMacros(boolean display){ + fShowParentMacros = display; + if(fShowParentButton != null) + fShowParentButton.setSelection(fShowParentMacros); + updateSystemMacros(); + } + + /* + * answers whether the given macro should be displayed in UI or not + */ + protected boolean canDisplay(String name){ + return canCreate(name); + } + + /* + * answers whether the macro of a given name can be sreated + */ + public boolean canCreate(String name){ + if((name = EnvVarOperationProcessor.normalizeName(name)) == null) + return false; + + if(fHiddenMacros != null){ + for(int i = 0; i < fHiddenMacros.length; i++){ + if(name.equals(fHiddenMacros[i].toUpperCase())) + return false; + } + } + return true; + } + + /* + * filteres the macros to be displayed + */ + protected IBuildMacro[] filterDisplayedMacros(IBuildMacro macros[]){ + if(macros == null || macros.length == 0) + return macros; + + IBuildMacro filtered[] = new IBuildMacro[macros.length]; + int filteredNum = 0; + for(int i = 0; i < macros.length; i++){ + if(canDisplay(macros[i].getName())) + filtered[filteredNum++] = macros[i]; + } + + if(filteredNum != filtered.length){ + IBuildMacro tmp[] = new IBuildMacro[filteredNum]; + for(int i = 0; i < filteredNum; i++) + tmp[i] = filtered[i]; + filtered = tmp; + } + return filtered; + } + + protected IEnvironmentVariableProvider obtainEnvironmentVariableProvider(){ + ICOptionContainer container = getContainer(); + ManagedBuildOptionBlock optionBlock = null; + if(container instanceof BuildPropertyPage){ + BuildPropertyPage page = (BuildPropertyPage)container; + optionBlock = page.getOptionBlock(); + } else if(container instanceof BuildPreferencePage){ + BuildPreferencePage page = (BuildPreferencePage)container; + optionBlock = page.getOptionBlock(); + } + if(optionBlock != null){ + EnvironmentSetBlock block = optionBlock.getEnvironmentBlock(); + if(block != null) + return block.getEnvironmentVariableProvider(); + } + return null; + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/MacrosSetBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/MacrosSetBlock.java new file mode 100644 index 00000000000..e74cd4f100d --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/MacrosSetBlock.java @@ -0,0 +1,319 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.ui; + +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroContextInfo; +import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; +import org.eclipse.cdt.managedbuilder.ui.properties.BuildPropertyPage; +import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage; +import org.eclipse.cdt.ui.dialogs.ICOptionContainer; +import org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.SWT; +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.Group; + +/** + * Whe used in the BuildPropertyPage the displays the tab-folder that contains the following tabs: + * 1. a tab containing configuration-specific macros + * 2. a tab containing project-specific macros + * + * Otherwise displays a single MacrosBlock that contains + * the workspace-specific, CDT/Eclipse installation and eclipse process environment macros + * + */public class MacrosSetBlock extends AbstractCOptionPage { + /* + * String constants + */ + private static final String PREFIX = "MacrosSetBlock"; //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ + private static final String MACROS_LABEL = LABEL + ".macros"; //$NON-NLS-1$ + + private static final String MACROS_GROUP_LABEL = LABEL + ".macros.group"; //$NON-NLS-1$ + + private static final String TAB = LABEL + ".tab"; //$NON-NLS-1$ + private static final String TAB_CONFIGURATION = TAB + ".configuration"; //$NON-NLS-1$ + private static final String TAB_PROJECT = TAB + ".project"; //$NON-NLS-1$ + private static final String TAB_WORKSPACE = TAB + ".workspace"; //$NON-NLS-1$ + private static final String TAB_ECLIPSE = TAB + ".eclipse"; //$NON-NLS-1$ + + private MacrosTabFolder fEnvTabs; + private MacrosBlock fEnvBlock; + + private ICOptionContainer fParentContainer; + + private UIMacroProvider fMacroProvider; + + private class UIMacroContextInfo extends DefaultMacroContextInfo{ + public UIMacroContextInfo(int type, Object data){ + super(type,data); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo#getNext() + */ + public IMacroContextInfo getNext(){ + IMacroContextInfo info = super.getNext(); + if(info != null){ + MacrosBlock blocks[] = getAllBlocks(); + for(int i = 0; i < blocks.length; i++){ + if(blocks[i].getContextType() == info.getContextType() && + blocks[i].getContextData() == info.getContextData()) + return blocks[i].getContextInfo(); + } + return new UIMacroContextInfo(info.getContextType(),info.getContextData()); + } + return null; + } + } + + /* + * The BuildMacroProvider to be used in UI + * Unlike the default provider, this provider also contains + * the user-modified macros that are not applied yet + */ + private class UIMacroProvider extends BuildMacroProvider { + public IMacroContextInfo getMacroContextInfo(int contextType, Object contextData){ + MacrosBlock blocks[] = getAllBlocks(); + for(int i = 0; i < blocks.length; i++){ + if(blocks[i].getContextType() == contextType && + blocks[i].getContextData() == contextData) + return blocks[i].getContextInfo(); + } + return new UIMacroContextInfo(contextType,contextData); + } + } + + private class MacrosTabFolder extends TabFolderOptionBlock{ + private MacrosBlock fFolderTabs[]; + public MacrosTabFolder() { + super(fParentContainer, false); + } + + public MacrosBlock[] getTabs(){ + return fFolderTabs; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.TabFolderOptionBlock#addTabs() + */ + protected void addTabs(){ + if(fParentContainer instanceof BuildPropertyPage) { + // the EnvironmentSetBlock is used whithing the Build Property Page + // create the project and configuration tabs + fFolderTabs = new MacrosBlock[2]; + addTab(fFolderTabs[0] = new MacrosBlock(fParentContainer, + ManagedBuilderUIMessages.getResourceString(TAB_CONFIGURATION), + true, + true)); + addTab(fFolderTabs[1] = new MacrosBlock(fParentContainer, + ManagedBuilderUIMessages.getResourceString(TAB_PROJECT), + true, + true)); + } +/* else { + // the EnvironmentSetBlock is used whithing the Build Preference Page + // create the workspace and eclipse environment tabs + fFolderTabs = new MacrosBlock[2]; + addTab(fFolderTabs[0] = new MacrosBlock(fParentContainer, + ManagedBuilderUIMessages.getResourceString(TAB_WORKSPACE), + true, + true)); + addTab(fFolderTabs[1] = new MacrosBlock(fParentContainer, + ManagedBuilderUIMessages.getResourceString(TAB_ECLIPSE), + false, + false)); + } +*/ + } + + /* + * set the appropriate context data to the tabs + */ + public void updateContexts(){ + if(fFolderTabs == null) + return; + + if(fParentContainer instanceof BuildPropertyPage){ + BuildPropertyPage page = (BuildPropertyPage)fParentContainer; + if(page.getSelectedConfiguration() != null) + fFolderTabs[1].setContext(IBuildMacroProvider.CONTEXT_PROJECT,page.getSelectedConfiguration().getManagedProject()); + + fFolderTabs[0].setContext(IBuildMacroProvider.CONTEXT_CONFIGURATION,page.getSelectedConfiguration()); + fFolderTabs[0].setParentContextInfo(fFolderTabs[1].getContextInfo()); + } +/* else { + fFolderTabs[1].setContext(null); + + fFolderTabs[0].setContext(ResourcesPlugin.getWorkspace()); + fFolderTabs[0].setParentContextInfo(fFolderTabs[1].getContextInfo()); + } +*/ + } + + } + + + public MacrosSetBlock(ICOptionContainer parent){ + super(ManagedBuilderUIMessages.getResourceString(MACROS_LABEL)); + super.setContainer(parent); + fParentContainer = parent; +// fOptionBlock = optionBlock; + + if(fParentContainer instanceof BuildPropertyPage) + fEnvTabs = new MacrosTabFolder(); + else { + fEnvBlock = new MacrosBlock(fParentContainer, + ManagedBuilderUIMessages.getResourceString(TAB_WORKSPACE), + true, + false); + fEnvBlock.displayParentMacros(true); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + public void performApply(IProgressMonitor monitor) throws CoreException { + MacrosBlock tabs[] = getAllBlocks(); + if(tabs != null){ + for(int i = 0; i < tabs.length; i++) + tabs[i].performApply(monitor); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults() + */ + public void performDefaults() { + MacrosBlock tab = getSelectedBlock(); + if(tab != null) + tab.performDefaults(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean) + */ + public void setVisible(boolean visible){ + if(visible) + updateValues(); + super.setVisible(visible); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Control ctrl = null; + if(fEnvTabs != null){ + Group group = new Group(parent, SWT.NONE); + group.setFont(parent.getFont()); + group.setText(ManagedBuilderUIMessages.getResourceString(MACROS_GROUP_LABEL)); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + GridLayout gl = new GridLayout(); + gl.marginHeight = 0; + gl.marginWidth = 0; + group.setLayout(gl); + Control tabs = fEnvTabs.createContents(group); + GridData gd = new GridData(GridData.FILL_BOTH); + tabs.setLayoutData(gd); + ctrl = group; + } + else if(fEnvBlock != null){ + fEnvBlock.createControl(parent); + ctrl = fEnvBlock.getControl(); + ctrl.setLayoutData(new GridData(GridData.FILL_BOTH)); + } + + setControl(ctrl); + } + + public void updateValues(){ + MacrosBlock tab = getSelectedBlock(); + + updateContexts(); + if(tab != null) + tab.updateValues(); + } + + public boolean isConfigSelectionAllowed(){ + MacrosBlock block = getSelectedBlock(); + if(block != null) + return block.getContextData() instanceof IConfiguration; + return false; + } + + public boolean isModified(){ + MacrosBlock tabs[] = getAllBlocks(); + for(int i = 0; i < tabs.length; i++){ + if(tabs[i].isModified()) + return true; + } + return false; + } + + public void setModified(boolean modified){ + MacrosBlock tabs[] = getAllBlocks(); + for(int i = 0; i < tabs.length; i++){ + tabs[i].setModified(modified); + } + } + + /* + * returns the selected environment block + */ + protected MacrosBlock getSelectedBlock(){ + if(fEnvTabs != null) + return (MacrosBlock)fEnvTabs.getCurrentPage(); + return fEnvBlock; + } + + /* + * returns all available environment blocks + */ + protected MacrosBlock[] getAllBlocks(){ + if(fEnvTabs != null) + return fEnvTabs.getTabs(); + else if(fEnvBlock != null) + return new MacrosBlock[]{fEnvBlock}; + return new MacrosBlock[0]; + } + + /* + * updates the context of each EnvironmentBlock + */ + protected void updateContexts(){ + if(fEnvTabs != null) + fEnvTabs.updateContexts(); + else if(fEnvBlock != null) + fEnvBlock.setContext(IBuildMacroProvider.CONTEXT_WORKSPACE,ResourcesPlugin.getWorkspace()); + } + + /* + * returns the BuildMacroProvider to be used in UI + * Unlike the default provider, the returned provider also contains + * the user-modified macros that are not applied yet + */ + public BuildMacroProvider getBuildMacroProvider(){ + if(fMacroProvider == null) + fMacroProvider = new UIMacroProvider(); + return fMacroProvider; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ManagedBuildOptionBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ManagedBuildOptionBlock.java index 30256324edc..8d96890f359 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ManagedBuildOptionBlock.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ManagedBuildOptionBlock.java @@ -36,6 +36,7 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { private ErrorParserBlock errParserBlock; private BinaryParserBlock binaryParserBlock; private EnvironmentSetBlock environmentBlock; + private MacrosSetBlock macrosBlock; private Object element; /** @@ -77,10 +78,12 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { addTab(errParserBlock = new ErrorParserBlock()); addTab(binaryParserBlock = new BinaryParserBlock()); addTab(environmentBlock = new EnvironmentSetBlock((BuildPropertyPage) fParent)); + addTab(macrosBlock = new MacrosSetBlock((BuildPropertyPage) fParent)); } else if (element instanceof IFile) { addTab(toolsSettingsBlock = new ToolsSettingsBlock((ResourceBuildPropertyPage) fParent, element)); } else if (element instanceof IWorkspace) { addTab(environmentBlock = new EnvironmentSetBlock((BuildPreferencePage) fParent)); + addTab(macrosBlock = new MacrosSetBlock((BuildPreferencePage) fParent)); } } @@ -108,6 +111,10 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { return environmentBlock; } + public MacrosSetBlock getMacrosBlock() { + return macrosBlock; + } + public Control createContents(Composite parent, Object element) { this.element = element; Control control = super.createContents( parent ); @@ -144,6 +151,8 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { } if(getEnvironmentBlock()!= null) { } + if(getMacrosBlock()!= null) { + } } public void updateValues() { @@ -166,14 +175,18 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { } if(getCurrentPage() instanceof EnvironmentSetBlock) { ((EnvironmentSetBlock)getCurrentPage()).updateValues(); + }else if(getCurrentPage() instanceof MacrosSetBlock) { + ((MacrosSetBlock)getCurrentPage()).updateValues(); } } else if( element instanceof IFile) { if (getToolsSettingsBlock() != null) { getToolsSettingsBlock().updateValues(); } } else if(element instanceof IWorkspace) { - if(getEnvironmentBlock() != null) { - getEnvironmentBlock().updateValues(); + if(getCurrentPage() instanceof EnvironmentSetBlock) { + ((EnvironmentSetBlock)getCurrentPage()).updateValues(); + }else if(getCurrentPage() instanceof MacrosSetBlock) { + ((MacrosSetBlock)getCurrentPage()).updateValues(); } } } @@ -197,16 +210,21 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { // TODO //getBinaryParserBlock().setValues(); } - if(getEnvironmentBlock() != null) { - getEnvironmentBlock().updateValues(); + + if(getCurrentPage() instanceof EnvironmentSetBlock) { + ((EnvironmentSetBlock)getCurrentPage()).updateValues(); + }else if(getCurrentPage() instanceof MacrosSetBlock) { + ((MacrosSetBlock)getCurrentPage()).updateValues(); } } else if (element instanceof IFile) { if (getToolsSettingsBlock() != null) { getToolsSettingsBlock().updateValues(); } } else if (element instanceof IWorkspace) { - if(getEnvironmentBlock() != null) { - getEnvironmentBlock().updateValues(); + if(getCurrentPage() instanceof EnvironmentSetBlock) { + ((EnvironmentSetBlock)getCurrentPage()).updateValues(); + }else if(getCurrentPage() instanceof MacrosSetBlock) { + ((MacrosSetBlock)getCurrentPage()).updateValues(); } } } @@ -232,6 +250,9 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { } if(getEnvironmentBlock()!= null) { } + if(getMacrosBlock()!= null) { + } + } else if (element instanceof IFile) { if (getToolsSettingsBlock()!= null) { getToolsSettingsBlock().removeValues(id); @@ -239,6 +260,8 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { } else if (element instanceof IWorkspace) { if(getEnvironmentBlock()!= null) { } + if(getMacrosBlock()!= null) { + } } } @@ -263,12 +286,18 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { if(getCurrentPage() instanceof EnvironmentSetBlock) { return null; } + if(getCurrentPage() instanceof MacrosSetBlock) { + return null; + } } else if( element instanceof IFile) { if (getCurrentPage() instanceof ToolsSettingsBlock) { return toolsSettingsBlock.getPreferenceStore(); } } else if (element instanceof IWorkspace) { - if(getEnvironmentBlock()!= null) { + if(getCurrentPage() instanceof EnvironmentSetBlock) { + return null; + } + if(getCurrentPage() instanceof MacrosSetBlock) { return null; } } @@ -293,6 +322,10 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { ((BuildPropertyPage)fParent).enableConfigSelection( ((EnvironmentSetBlock)tab).isConfigSelectionAllowed()); } + else if(tab instanceof MacrosSetBlock){ + ((BuildPropertyPage)fParent).enableConfigSelection( + ((MacrosSetBlock)tab).isConfigSelectionAllowed()); + } else ((BuildPropertyPage)fParent).enableConfigSelection(true); } else if ( element instanceof IFile) { @@ -321,6 +354,8 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { //TODO ManagedBuildSystem needs its own binary parser block } else if(tab instanceof EnvironmentSetBlock) { ((EnvironmentSetBlock)tab).setModified(b); + } else if(tab instanceof MacrosSetBlock) { + ((MacrosSetBlock)tab).setModified(b); } } } @@ -344,7 +379,9 @@ public class ManagedBuildOptionBlock extends TabFolderOptionBlock { } else if (tab instanceof BinaryParserBlock) { //TODO ManagedBuildSystem needs its own binary parser block } else if(tab instanceof EnvironmentSetBlock) { - return ((EnvironmentSetBlock)tab).isModified(); + if (((EnvironmentSetBlock)tab).isModified()) return true; + } else if(tab instanceof MacrosSetBlock) { + if (((MacrosSetBlock)tab).isModified()) return true; } } diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/NewBuildMacroDialog.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/NewBuildMacroDialog.java new file mode 100644 index 00000000000..bd018de83c1 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/NewBuildMacroDialog.java @@ -0,0 +1,606 @@ +/********************************************************************** + * Copyright (c) 2005 Intel 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: + * Intel Corporation - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.ui; + +import java.text.Collator; +import java.util.Arrays; +import java.util.Comparator; + +import org.eclipse.cdt.internal.ui.dialogs.StatusDialog; +import org.eclipse.cdt.internal.ui.dialogs.StatusInfo; +import org.eclipse.cdt.managedbuilder.core.IOption; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacro; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.ui.properties.FileListControl; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +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.Point; +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.Control; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/* + * the dialog used to create or edit the build macro + */ +public class NewBuildMacroDialog extends StatusDialog { + // String constants + private static final String PREFIX = "NewBuildMacroDialog"; //$NON-NLS-1$ + private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$ + private static final String NAME = LABEL + ".name"; //$NON-NLS-1$ + private static final String VALUE = LABEL + ".value"; //$NON-NLS-1$ + + private static final String TYPE = LABEL + ".type"; //$NON-NLS-1$ + private static final String TYPE_TEXT = TYPE + ".text"; //$NON-NLS-1$ + private static final String TYPE_TEXT_LIST = TYPE + ".text.list"; //$NON-NLS-1$ + private static final String TYPE_PATH_FILE = TYPE + ".path.file"; //$NON-NLS-1$ + private static final String TYPE_PATH_FILE_LIST = TYPE + ".path.file.list"; //$NON-NLS-1$ + private static final String TYPE_PATH_DIR = TYPE + ".path.dir"; //$NON-NLS-1$ + private static final String TYPE_PATH_DIR_LIST = TYPE + ".path.dir.list"; //$NON-NLS-1$ + private static final String TYPE_PATH_ANY = TYPE + ".path.any"; //$NON-NLS-1$ + private static final String TYPE_PATH_ANY_LIST = TYPE + ".path.any.list"; //$NON-NLS-1$ + + + private static final String BROWSE = LABEL + ".browse"; //$NON-NLS-1$ + private static final String LIST_TITLE = LABEL + ".list.title"; //$NON-NLS-1$ + + private static final String TITLE_NEW = LABEL + ".title.new"; //$NON-NLS-1$ + private static final String TITLE_EDIT = LABEL + ".title.edit"; //$NON-NLS-1$ + + private static final String STATUS = LABEL + ".status"; //$NON-NLS-1$ + private static final String STATUS_CANNOT_CTREATE = STATUS + ".cannot.create"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = new String(); + + // The title of the dialog. + private String fTitle; + // hold the macro being edited(in the case of the "edit" mode) + private IBuildMacro fEditedMacro; + //the macros block block from which the dialog was called + private MacrosBlock fMacrosBlock; + //the resulting macro. Can be accessed only when the dialog is closed + private IBuildMacro fResultingMacro; + //the string that holds the value is used in the "replace" operation + private String fReplaceValue = null; + //the string that holds the value is used in the "append/prepend" operations + private String fAppPrepValue = null; + //specifies whether the fAppPrepValue holds the prepended or appended value + private boolean fAppPrepPrepend = true; + + private boolean fTotalSizeCalculated; + + private String fTypedName; + private int fTypedType = -1; + + // Widgets +// protected Text fMacroNameEdit; + private Composite fContainer; + private Combo fMacroNameEdit; + private Label fMacroValueLabel; + private Text fMacroValueEdit; + private Button fBrowseButton; + private Combo fTypeSelector; + private Composite fListEditorContainier; + + private FileListControl fListEditor; + + + public NewBuildMacroDialog(Shell parentShell, MacrosBlock macrosBlock, IBuildMacro editedMacro) { + super(parentShell); + if(editedMacro != null) + fTitle = ManagedBuilderUIMessages.getResourceString(TITLE_EDIT); + else + fTitle = ManagedBuilderUIMessages.getResourceString(TITLE_NEW); + fEditedMacro = editedMacro; + fMacrosBlock = macrosBlock; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell) + */ + protected void configureShell(Shell shell) { + super.configureShell(shell); + if (fTitle != null) + shell.setText(fTitle); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) + */ + protected Control createDialogArea(Composite parent) { + Composite comp = new Composite(parent, SWT.NULL); + comp.setFont(parent.getFont()); + comp.setLayout(new GridLayout(3, false)); + GridData gd = new GridData(GridData.FILL_BOTH); + comp.setLayoutData(gd); + + fContainer = comp; + + Label nameLabel = new Label(comp, SWT.LEFT); + nameLabel.setFont(comp.getFont()); + nameLabel.setText(ManagedBuilderUIMessages.getResourceString(NAME)); + nameLabel.setLayoutData(new GridData()); + +// fMacroNameEdit = new Text(comp, SWT.SINGLE | SWT.BORDER); + fMacroNameEdit = new Combo(comp, SWT.SINGLE | SWT.DROP_DOWN); + fMacroNameEdit.setItems(getMacroNames()); + fMacroNameEdit.setFont(comp.getFont()); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + 50; + fMacroNameEdit.setLayoutData(gd); + fMacroNameEdit.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + handleMacroNameModified(); + } + }); + fMacroNameEdit.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + handleMacroNameSelection(); + } + }); + + Label typeLabel = new Label(comp, SWT.LEFT); + typeLabel.setFont(comp.getFont()); + typeLabel.setText(ManagedBuilderUIMessages.getResourceString(TYPE)); + gd = new GridData(); + gd.horizontalSpan = 1; + typeLabel.setLayoutData(gd); + + fTypeSelector = new Combo(comp, SWT.READ_ONLY|SWT.DROP_DOWN); + gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + gd.horizontalSpan = 2; +// gd.widthHint = 100; + fTypeSelector.setLayoutData(gd); + fTypeSelector.setItems(new String[]{ + ManagedBuilderUIMessages.getResourceString(TYPE_TEXT), + ManagedBuilderUIMessages.getResourceString(TYPE_TEXT_LIST), + ManagedBuilderUIMessages.getResourceString(TYPE_PATH_FILE), + ManagedBuilderUIMessages.getResourceString(TYPE_PATH_FILE_LIST), + ManagedBuilderUIMessages.getResourceString(TYPE_PATH_DIR), + ManagedBuilderUIMessages.getResourceString(TYPE_PATH_DIR_LIST), + ManagedBuilderUIMessages.getResourceString(TYPE_PATH_ANY), + ManagedBuilderUIMessages.getResourceString(TYPE_PATH_ANY_LIST) + }); + setSelectedType(IBuildMacro.VALUE_TEXT); + + fTypeSelector.addListener(SWT.Selection, new Listener () { + public void handleEvent(Event e) { + handleTypeModified(); + } + }); + + fMacroValueLabel = new Label(comp, SWT.LEFT); + fMacroValueLabel.setFont(comp.getFont()); + fMacroValueLabel.setText(ManagedBuilderUIMessages.getResourceString(VALUE)); + gd = new GridData(); + gd.horizontalSpan = 1; + fMacroValueLabel.setLayoutData(gd); + + fMacroValueEdit = new Text(comp, SWT.SINGLE | SWT.BORDER); + fMacroValueEdit.setFont(comp.getFont()); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH + 100; + gd.horizontalSpan = 1; + fMacroValueEdit.setLayoutData(gd); + fMacroValueEdit.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + handleMacroValueModified(); + } + }); + + fBrowseButton = new Button(comp,SWT.PUSH); + fBrowseButton.setFont(comp.getFont()); + fBrowseButton.setText(ManagedBuilderUIMessages.getResourceString(BROWSE)); + fBrowseButton.addSelectionListener(new SelectionAdapter(){ + public void widgetSelected(SelectionEvent e){ + handleBrowseButtonPressed(); + } + }); + + gd = new GridData(); + gd.widthHint = IDialogConstants.BUTTON_WIDTH; + gd.horizontalSpan = 1; + fBrowseButton.setLayoutData(gd); + + fListEditorContainier = new Composite(comp,0); + gd = new GridData(GridData.FILL_BOTH); + gd.horizontalSpan = 3; + fListEditorContainier.setLayoutData(gd); + fListEditorContainier.setLayout(new GridLayout()); + + fListEditor = new FileListControl(fListEditorContainier, ManagedBuilderUIMessages.getResourceString(LIST_TITLE), IOption.BROWSE_NONE); + + if(fEditedMacro != null){ + loadMacroSettings(fEditedMacro,true); + fMacroNameEdit.setEnabled(false); + } + + return comp; + } + + /* + * get the names to be displayed in the var Name combo. + */ + private String[] getMacroNames(){ + IBuildMacro macros[] = fMacrosBlock.getSystemMacros(true); + String names[] = null; + if(macros == null || macros.length == 0) + names = new String[0]; + else{ + names = new String[macros.length]; + for(int i = 0; i < macros.length; i++){ + names[i] = macros[i].getName(); + } + + final Collator collator = Collator.getInstance(); + Arrays.sort(names, new Comparator() { + public int compare(Object a, Object b) { + String strA = ((String)a).toUpperCase(); + String strB = ((String)b).toUpperCase(); + return collator.compare(strA,strB); + } + }); + } + + return names; + } + + private void handleBrowseButtonPressed(){ + switch(getBrowseType(getSelectedType())){ + case IOption.BROWSE_FILE: + FileDialog fileDlg = new FileDialog(fBrowseButton.getShell()); + String file = fileDlg.open(); + if(file != null) + fMacroValueEdit.setText(file); + break; + case IOption.BROWSE_DIR: + DirectoryDialog dirDlg = new DirectoryDialog(fBrowseButton.getShell()); + String dir = dirDlg.open(); + if(dir != null) + fMacroValueEdit.setText(dir); + break; + } + } + + private int getBrowseType(int type){ + int browseType = IOption.BROWSE_NONE; + switch(type){ + case IBuildMacro.VALUE_PATH_FILE: + case IBuildMacro.VALUE_PATH_FILE_LIST: + browseType = IOption.BROWSE_FILE; + break; + case IBuildMacro.VALUE_PATH_DIR: + case IBuildMacro.VALUE_PATH_DIR_LIST: + browseType = IOption.BROWSE_DIR; + break; + case IBuildMacro.VALUE_PATH_ANY: + case IBuildMacro.VALUE_PATH_ANY_LIST: + break; + case IBuildMacro.VALUE_TEXT: + case IBuildMacro.VALUE_TEXT_LIST: + default: + } + return browseType; + + } + + /* + * called when the variable name is selected, loads all the dialog fields with the variable settings + */ + private void handleMacroNameSelection(){ + int index = fMacroNameEdit.getSelectionIndex(); + if(index == -1) + loadMacroSettings(null); + else + loadMacroSettings(fMacroNameEdit.getItem(index)); + } + + private void loadMacroSettings(String name){ + IBuildMacro macro = fMacrosBlock.getSystemMacro(name,true); + if(macro != null) + loadMacroSettings(macro,false); + else + loadMacroSettings(name,IBuildMacro.VALUE_TEXT,EMPTY_STRING); + } + + private void loadMacroSettings(String name, + int type, + String value[]){ + setSelectedType(type); + setSelectedMacroName(notNull(name)); + fListEditor.setList(value); + + updateWidgetState(); + } + + private void loadMacroSettings(String name, + int type, + String value){ + + setSelectedType(type); + setSelectedMacroName(notNull(name)); + fMacroValueEdit.setText(notNull(value)); + + updateWidgetState(); + + } + + /* + * loads all the dialog fields with the variable settings + */ + private void loadMacroSettings(IBuildMacro macro, boolean isUser){ + try{ + if(MacroResolver.isStringListMacro(macro.getMacroValueType())) + loadMacroSettings(macro.getName(),macro.getMacroValueType(),macro.getStringListValue()); + else + loadMacroSettings(macro.getName(),macro.getMacroValueType(),macro.getStringValue()); + }catch(BuildMacroException e){ + } + } + + /* + * returns an empty string in the case the string passed is null. + * otherwise returns the string passed + */ + private String notNull(String str){ + return str == null ? EMPTY_STRING : str; + } + + /* + * returns the name typed in the dialog var name edit triming spaces + */ + private String getSelectedVarName(){ + return fMacroNameEdit.getText().trim(); + } + + /* + * sets the variable name to the dialog "variable name" edit control + */ + private void setSelectedMacroName(String name){ + if(!macroNamesEqual(fMacroNameEdit.getText(),name)){ + fTypedName = name; + fMacroNameEdit.setText(notNull(name).trim()); + } + } + + private boolean macroNamesEqual(String name1, String name2){ + name1 = name1.trim(); + name2 = name2.trim(); + return name1.equalsIgnoreCase(name2); + } + + /* + * returns the selected type + */ + private int getSelectedType(){ + switch(fTypeSelector.getSelectionIndex()){ + case 1: + return IBuildMacro.VALUE_TEXT_LIST; + case 2: + return IBuildMacro.VALUE_PATH_FILE; + case 3: + return IBuildMacro.VALUE_PATH_FILE_LIST; + case 4: + return IBuildMacro.VALUE_PATH_DIR; + case 5: + return IBuildMacro.VALUE_PATH_DIR_LIST; + case 6: + return IBuildMacro.VALUE_PATH_ANY; + case 7: + return IBuildMacro.VALUE_PATH_ANY_LIST; + case 0: + default: + return IBuildMacro.VALUE_TEXT; + } + } + + /* + * sets the selected type + */ + private void setSelectedType(int type){ + switch(type){ + case IBuildMacro.VALUE_TEXT_LIST: + fTypeSelector.select(1); + break; + case IBuildMacro.VALUE_PATH_FILE: + fTypeSelector.select(2); + break; + case IBuildMacro.VALUE_PATH_FILE_LIST: + fTypeSelector.select(3); + break; + case IBuildMacro.VALUE_PATH_DIR: + fTypeSelector.select(4); + break; + case IBuildMacro.VALUE_PATH_DIR_LIST: + fTypeSelector.select(5); + break; + case IBuildMacro.VALUE_PATH_ANY: + fTypeSelector.select(6); + break; + case IBuildMacro.VALUE_PATH_ANY_LIST: + fTypeSelector.select(7); + break; + case IBuildMacro.VALUE_TEXT: + default: + fTypeSelector.select(0); + break; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#okPressed() + */ + protected void okPressed(){ + String name = getSelectedVarName(); + if(name != null || !EMPTY_STRING.equals(name)){ + int type = getSelectedType(); + if(MacroResolver.isStringListMacro(type)) + fResultingMacro = new BuildMacro(name,type,getSelectedStringListValue()); + else + fResultingMacro = new BuildMacro(name,type,getSelectedStringValue()); + } + + super.okPressed(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.window.Window#open() + */ + public int open(){ + fResultingMacro = null; + return super.open(); + } + + /* + * returns the macro value that should be stored in the resulting variable + */ + private String getSelectedStringValue(){ + return fMacroValueEdit.getText(); + } + + private String[] getSelectedStringListValue(){ + return fListEditor.getItems(); + } + + /* + * this method should be called after the dialog is closed + * to obtain the created variable. + * if the variable was not created, e.g. because a user has pressed + * the cancel button this method returns null + */ + public IBuildMacro getDefinedMacro(){ + return fResultingMacro; + } + + /* + * called when the variable name is modified + */ + private void handleMacroNameModified(){ + String name = getSelectedVarName(); + if(fTypedName == null || !fTypedName.equals(name)){ + loadMacroSettings(name); + } + } + + /* + * called when the macro value is modified + */ + private void handleMacroValueModified(){ + + } + + /* + * called when the operation is modified + */ + private void handleTypeModified(){ + int type = getSelectedType(); + if(fTypedType != -1 && fTypedType == type) + return; + + fTypedType = type; + + adjustLayout(type); + } + + private void adjustLayout(int type){ + GridData listGd = (GridData)fListEditorContainier.getLayoutData(); + GridData labelGd = (GridData)fMacroValueLabel.getLayoutData(); + GridData editGd = (GridData)fMacroValueEdit.getLayoutData(); + GridData browseGd = (GridData)fBrowseButton.getLayoutData(); + + if(MacroResolver.isStringListMacro(type)){ + listGd.exclude = false; + labelGd.exclude = true; + editGd.exclude = true; + browseGd.exclude = true; + fListEditorContainier.setVisible(true); + fListEditor.setType(getBrowseType(type)); + fMacroValueLabel.setVisible(false); + fMacroValueEdit.setVisible(false); + fBrowseButton.setVisible(false); + } else { + listGd.exclude = true; + labelGd.exclude = false; + editGd.exclude = false; + int editSpan; + fListEditorContainier.setVisible(false); + fMacroValueLabel.setVisible(true); + fMacroValueEdit.setVisible(true); + if(getBrowseType(type) != IOption.BROWSE_NONE){ + browseGd.exclude = false; + editSpan = 1; + fBrowseButton.setVisible(true); + } else { + browseGd.exclude = true; + editSpan = 2; + fBrowseButton.setVisible(false); + } + editGd.horizontalSpan = editSpan; + } + fContainer.layout(true,true); + } + + /* + * updates the state of the dialog controls + */ + private void updateWidgetState(){ + if(!fTotalSizeCalculated) + return; + handleTypeModified(); + validateState(); + } + + protected Point getInitialSize() { + Point size = super.getInitialSize(); + fTotalSizeCalculated = true; + updateWidgetState(); + return size; + } + + + /* (non-Javadoc) + * Update the status message and button state based on the variable name + * + */ + private void validateState() { + StatusInfo status= new StatusInfo(); + String name = getSelectedVarName(); + + if(EMPTY_STRING.equals(name)){ + // Not an error + status.setError(""); //$NON-NLS-1$ + } + else if(!fMacrosBlock.canCreate(name)){ + status.setError(ManagedBuilderUIMessages.getFormattedString(STATUS_CANNOT_CTREATE, name)); + } + + + updateStatus(status); + return; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/PluginResources.properties index ea0ba152205..0b461c16d23 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/PluginResources.properties @@ -89,6 +89,8 @@ BuildSettingsBlock.label.output.name=Artifact name: BuildSettingsBlock.label.output.extension=Artifact extension: BuildSettingsBlock.defaults.title=Reset Build Settings BuildSettingsBlock.defaults.message=This action will reset the build settings to their default settings.\n\nDo you want to proceed? +BuildSettingsBlock.label.macros.group=Build Macros usage +BuildSettingsBlock.label.macros.expand=Expand Build Environment Macros # ----------- Build Steps Block ----------- BuildStepSettingsBlock.label.Settings=Build Steps @@ -141,6 +143,56 @@ NewEnvVarDialog.label.title.new=Define a new variable NewEnvVarDialog.label.title.edit=Edit existing variable NewEnvVarDialog.label.status.cannot.create=The "{0}" Variable can not be created by user +# ----------- Macros Set Block ----------- +MacrosSetBlock.label.macros=Macros +MacrosSetBlock.label.macros.group=Macros +MacrosSetBlock.label.tab.configuration=Configuration +MacrosSetBlock.label.tab.project=Project +MacrosSetBlock.label.tab.workspace=Workspace + +# ----------- Macros Block ----------- +MacrosBlock.label.header.name=Name +MacrosBlock.label.header.type=Type +MacrosBlock.label.header.value=Value +MacrosBlock.label.button.new=New +MacrosBlock.label.button.edit=Edit +MacrosBlock.label.button.delete=Delete +MacrosBlock.label.button.check.chow.parent=Show parent context macros +MacrosBlock.label.user.macros=User Macros +MacrosBlock.label.system.macros=System Macros +MacrosBlock.label.delete.confirm.title=Macro deletion confirmation +MacrosBlock.label.delete.confirm.message=Are you sure you want to delete the selected user Macro(s)? +MacrosBlock.label.delete.all.confirm.title=Macro deletion confirmation +MacrosBlock.label.delete.all.confirm.message=Are you sure you want to delete all user macros? +MacrosBlock.label.value.eclipse.dynamic= +MacrosBlock.label.type.text=String +MacrosBlock.label.type.text.list=StringList +MacrosBlock.label.type.path.file=File +MacrosBlock.label.type.path.dir=Dir +MacrosBlock.label.type.path.file.list=FileList +MacrosBlock.label.type.path.dir.list=DirList +MacrosBlock.label.type.path.any=Path +MacrosBlock.label.type.path.any.list=PathList + + +# ----------- New Build Macro Dialog ----------- +NewBuildMacroDialog.label.name=Name +NewBuildMacroDialog.label.value=Value +NewBuildMacroDialog.label.type=Type +NewBuildMacroDialog.label.type.text=String +NewBuildMacroDialog.label.type.text.list=List of Strings +NewBuildMacroDialog.label.type.path.file=File +NewBuildMacroDialog.label.type.path.dir=Directory +NewBuildMacroDialog.label.type.path.file.list=List of Files +NewBuildMacroDialog.label.type.path.dir.list=List of Directories +NewBuildMacroDialog.label.type.path.any=File or Directory +NewBuildMacroDialog.label.type.path.any.list=List of Files or Directories +NewBuildMacroDialog.label.browse=Browse +NewBuildMacroDialog.label.title.new=Define a new macro +NewBuildMacroDialog.label.title.edit=Edit existing macro +NewBuildMacroDialog.label.list.title=Macro Value +NewBuildMacroDialog.label.status.cannot.create=The "{0}" Macro can not be created by user + # ------------Resource Configuration Selection Page ResourceBuildPropertyPage.label.ActiveResource=Active Resource configuration ResourceBuildPropertyPage.label.ResourceSettings=Resource Configuration settings diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ToolsSettingsBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ToolsSettingsBlock.java index e8e8daf0b9e..e6d32b608a3 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ToolsSettingsBlock.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/ToolsSettingsBlock.java @@ -18,12 +18,14 @@ import java.util.ListIterator; import java.util.Map; import org.eclipse.cdt.managedbuilder.core.IBuildObject; -import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; import org.eclipse.cdt.managedbuilder.ui.properties.BuildOptionSettingsPage; +import org.eclipse.cdt.managedbuilder.ui.properties.BuildPreferencePage; import org.eclipse.cdt.managedbuilder.ui.properties.BuildPropertyPage; import org.eclipse.cdt.managedbuilder.ui.properties.BuildSettingsPage; import org.eclipse.cdt.managedbuilder.ui.properties.BuildToolSettingsPage; @@ -290,11 +292,11 @@ public class ToolsSettingsBlock extends AbstractCOptionPage { } if (currentSettingsPage == null) { if ( this.element instanceof IProject) { - currentSettingsPage = new BuildToolSettingsPage(parent.getSelectedConfiguration(), tool); + currentSettingsPage = new BuildToolSettingsPage(parent.getSelectedConfiguration(), tool, obtainMacroProvider()); pages.add(currentSettingsPage); currentSettingsPage.setContainer(parent); } else if(this.element instanceof IFile) { - currentSettingsPage = new BuildToolSettingsPage(resParent.getCurrentResourceConfig(), tool); + currentSettingsPage = new BuildToolSettingsPage(resParent.getCurrentResourceConfig(), tool, obtainMacroProvider()); pages.add(currentSettingsPage); currentSettingsPage.setContainer(resParent); } @@ -368,6 +370,12 @@ public class ToolsSettingsBlock extends AbstractCOptionPage { setValues(); } + public void setVisible(boolean visible){ + // Update the field editor that displays all the build options + if(visible && currentSettingsPage instanceof BuildToolSettingsPage) + ((BuildToolSettingsPage)currentSettingsPage).updateAllOptionField(); + } + protected void setValues() { IConfiguration config = null; @@ -695,4 +703,31 @@ public class ToolsSettingsBlock extends AbstractCOptionPage { } return false; } + + /** + * Returns the build macro provider to be used for macro resolution + * In case the "Build Macros" tab is available, returns the BuildMacroProvider + * supplied by that tab. + * Unlike the default provider, that provider also contains + * the user-modified macros that are not applied yet + * If the "Build Macros" tab is not available, returns the default BuildMacroProvider + */ + protected BuildMacroProvider obtainMacroProvider(){ + ICOptionContainer container = getContainer(); + ManagedBuildOptionBlock optionBlock = null; + if(container instanceof BuildPropertyPage){ + BuildPropertyPage page = (BuildPropertyPage)container; + optionBlock = page.getOptionBlock(); + } else if(container instanceof BuildPreferencePage){ + BuildPreferencePage page = (BuildPreferencePage)container; + optionBlock = page.getOptionBlock(); + } + if(optionBlock != null){ + MacrosSetBlock block = optionBlock.getMacrosBlock(); + if(block != null) + return block.getBuildMacroProvider(); } + return (BuildMacroProvider)ManagedBuildManager.getBuildMacroProvider(); + } +} + diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPreferencePage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPreferencePage.java index 27e2acfa81e..bf22e9a7a56 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPreferencePage.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPreferencePage.java @@ -138,6 +138,10 @@ public class BuildPreferencePage extends PreferencePage super.performDefaults(); } + public ManagedBuildOptionBlock getOptionBlock(){ + return fOptionBlock; + } + /* * apply settings diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPropertyPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPropertyPage.java index c91b8e395d4..01587d90935 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPropertyPage.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildPropertyPage.java @@ -113,6 +113,11 @@ public class BuildPropertyPage extends PropertyPage implements IWorkbenchPropert } } + public ManagedBuildOptionBlock getOptionBlock(){ + return fOptionBlock; + } + + protected Control createContents(Composite parent) { // Create the container we return to the property page editor Composite composite = new Composite(parent, SWT.NULL); @@ -542,4 +547,4 @@ public class BuildPropertyPage extends PropertyPage implements IWorkbenchPropert // Update the contents of the configuration widget populateConfigurations(); } -} \ No newline at end of file +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingsPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingsPage.java index a4cfabcea1c..3212cd0c2f6 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingsPage.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/properties/BuildToolSettingsPage.java @@ -19,6 +19,7 @@ import java.util.Set; import java.util.Vector; import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator; import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo; @@ -27,7 +28,17 @@ import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.IResourceConfiguration; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.macros.BuildMacroProvider; +import org.eclipse.cdt.managedbuilder.internal.macros.DefaultMacroSubstitutor; +import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData; +import org.eclipse.cdt.managedbuilder.internal.macros.IMacroContextInfo; +import org.eclipse.cdt.managedbuilder.internal.macros.IMacroSubstitutor; +import org.eclipse.cdt.managedbuilder.internal.macros.MacroResolver; +import org.eclipse.cdt.managedbuilder.internal.macros.MbsMacroSupplier; import org.eclipse.cdt.managedbuilder.internal.ui.ManagedBuilderUIMessages; +import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacro; +import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.swt.graphics.Point; @@ -40,6 +51,8 @@ public class BuildToolSettingsPage extends BuildSettingsPage { private static final String DEFAULT_SEPERATOR = ";"; //$NON-NLS-1$ // Whitespace character private static final String WHITESPACE = " "; //$NON-NLS-1$ + // Empty String + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ // field editor that displays all the build options for a particular tool private MultiLineTextFieldEditor allOptionFieldEditor; // all build options preference store id @@ -55,7 +68,48 @@ public class BuildToolSettingsPage extends BuildSettingsPage { private boolean isItResourceConfigPage; - public BuildToolSettingsPage(IConfiguration configuration, ITool tool) { + //the build macro provider to be used for macro resolution + private BuildMacroProvider fProvider; + + //macro substitutor used in the macro resolution in UI + //resolves all macros except for the option-specific macros + //and the explicit file macros + public class UIMacroSubstitutor extends DefaultMacroSubstitutor { + private BuildMacroProvider fProvider; + + public UIMacroSubstitutor(int contextType, Object contextData, String inexistentMacroValue, String listDelimiter, BuildMacroProvider provider){ + super(contextType,contextData,inexistentMacroValue,listDelimiter); + fProvider = provider; + } + + public UIMacroSubstitutor(IMacroContextInfo contextInfo, String inexistentMacroValue, String listDelimiter){ + super(contextInfo,inexistentMacroValue,listDelimiter); + } + + protected IMacroContextInfo getMacroContextInfo(int contextType, Object contextData){ + if(fProvider != null) + return fProvider.getMacroContextInfo(contextType,contextData); + return super.getMacroContextInfo(); + } + + + protected ResolvedMacro resolveMacro(IBuildMacro macro) throws BuildMacroException{ + if(macro instanceof MbsMacroSupplier.FileContextMacro){ + MbsMacroSupplier.FileContextMacro fileMacro = (MbsMacroSupplier.FileContextMacro)macro; + if(fileMacro.isExplicit()){ + String name = macro.getName(); + return new ResolvedMacro(name,MacroResolver.createMacroReference(name)); + } + } else if (macro instanceof MbsMacroSupplier.OptionMacro) { + String name = macro.getName(); + return new ResolvedMacro(name,MacroResolver.createMacroReference(name)); + } + return super.resolveMacro(macro); + } + + } + + public BuildToolSettingsPage(IConfiguration configuration, ITool tool, BuildMacroProvider provider) { // Cache the configuration and tool this page is for super(configuration); this.tool = tool; @@ -63,8 +117,9 @@ public class BuildToolSettingsPage extends BuildSettingsPage { stringOptionsMap = new HashMap(); userObjsMap = new HashMap(); isItResourceConfigPage = false; + fProvider = provider; } - public BuildToolSettingsPage(IResourceConfiguration resConfig, ITool tool) { + public BuildToolSettingsPage(IResourceConfiguration resConfig, ITool tool, BuildMacroProvider provider) { // Cache the configuration and tool this page is for super(resConfig); this.tool = tool; @@ -72,6 +127,7 @@ public class BuildToolSettingsPage extends BuildSettingsPage { stringOptionsMap = new HashMap(); userObjsMap = new HashMap(); isItResourceConfigPage = true; + fProvider = provider; } /* (non-Javadoc) * @see org.eclipse.jface.preference.IPreferencePage#computeSize() @@ -199,9 +255,12 @@ public class BuildToolSettingsPage extends BuildSettingsPage { IOption[] options = tool.getOptions(); String listStr = ""; //$NON-NLS-1$ String[] listVal = null; + IBuildObject parent = configuration != null ? (IBuildObject)configuration.getToolChain() : (IBuildObject)resConfig; + IMacroSubstitutor macroSubstitutor = new UIMacroSubstitutor(0,null,EMPTY_STRING,WHITESPACE,fProvider); for (int k = 0; k < options.length; k++) { IOption option = options[k]; buf.setLength( 0 ); + try{ switch (option.getValueType()) { case IOption.BOOLEAN : String boolCmd; @@ -230,7 +289,8 @@ public class BuildToolSettingsPage extends BuildSettingsPage { String val = getToolSettingsPreferenceStore().getString(option.getId()); // add this string option value to the list stringOptionsMap.put(option, val); - if (val.length() > 0) { + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(null,null,option,parent)); + if (val.length() > 0 && (val = MacroResolver.resolveToString(val,macroSubstitutor)).length() > 0) { buf.append(evaluateCommand( strCmd, val )); } break; @@ -243,9 +303,11 @@ public class BuildToolSettingsPage extends BuildSettingsPage { listStr = getToolSettingsPreferenceStore().getString(option.getId()); if (cmd == null) userObjsMap.put(option, listStr); - listVal = BuildToolsSettingsStore.parseString(listStr); + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(null,null,option,parent)); + listVal = MacroResolver.resolveStringListValues(BuildToolsSettingsStore.parseString(listStr),macroSubstitutor,true); for (int j = 0; j < listVal.length; j++) { String temp = listVal[j]; + if(temp.length() > 0) buf.append( evaluateCommand( cmd, temp ) + ITool.WHITE_SPACE); } break; @@ -253,6 +315,9 @@ public class BuildToolSettingsPage extends BuildSettingsPage { break; } if( buf.toString().trim().length() > 0 ) flags.add( buf.toString().trim() ); + } catch (BuildMacroException e) { + + } } String outputName = "temp"; //$NON-NLS-1$ @@ -260,8 +325,16 @@ public class BuildToolSettingsPage extends BuildSettingsPage { outputName += tool.getDefaultInputExtension(); } String[] f = new String[ flags.size() ]; + String cmd = tool.getToolCommand(); + try{ + macroSubstitutor.setMacroContextInfo(IBuildMacroProvider.CONTEXT_FILE,new FileContextData(null,null,null,parent)); + String resolved = MacroResolver.resolveToString(cmd,macroSubstitutor); + if ((resolved = resolved.trim()).length() > 0) + cmd = resolved; + } catch (BuildMacroException e) { + } IManagedCommandLineGenerator gen = tool.getCommandLineGenerator(); - IManagedCommandLineInfo info = gen.generateCommandLineInfo( tool, tool.getToolCommand(), (String[])flags.toArray( f ), + IManagedCommandLineInfo info = gen.generateCommandLineInfo( tool, cmd, (String[])flags.toArray( f ), tool.getOutputFlag(), tool.getOutputPrefix(), outputName, new String[0], tool.getCommandLinePattern() ); return info.getFlags(); } @@ -575,8 +648,9 @@ public class BuildToolSettingsPage extends BuildSettingsPage { */ public void updateAllOptionField() { try { - if (getToolFlags() != null) { - getToolSettingsPreferenceStore().setValue(allOptionsId, getToolFlags()); + String flags = getToolFlags(); + if (flags != null) { + getToolSettingsPreferenceStore().setValue(allOptionsId, flags); allOptionFieldEditor.load(); } } catch (BuildException e) {