summaryrefslogtreecommitdiffstats
path: root/src/net/sf/antcontrib/cpptasks/ProcessorDef.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/sf/antcontrib/cpptasks/ProcessorDef.java')
-rw-r--r--src/net/sf/antcontrib/cpptasks/ProcessorDef.java668
1 files changed, 668 insertions, 0 deletions
diff --git a/src/net/sf/antcontrib/cpptasks/ProcessorDef.java b/src/net/sf/antcontrib/cpptasks/ProcessorDef.java
new file mode 100644
index 0000000..24c1a1f
--- /dev/null
+++ b/src/net/sf/antcontrib/cpptasks/ProcessorDef.java
@@ -0,0 +1,668 @@
+/*
+ *
+ * Copyright 2002-2004 The Ant-Contrib project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.sf.antcontrib.cpptasks;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Vector;
+import net.sf.antcontrib.cpptasks.compiler.LinkType;
+import net.sf.antcontrib.cpptasks.compiler.Processor;
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;
+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
+import net.sf.antcontrib.cpptasks.types.ConditionalFileSet;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Reference;
+/**
+ * An abstract compiler/linker definition.
+ *
+ * @author Curt Arnold
+ */
+public abstract class ProcessorDef extends DataType {
+ /**
+ * Returns the equivalent Boolean object for the specified value
+ *
+ * Equivalent to Boolean.valueOf in JDK 1.4
+ *
+ * @param val
+ * boolean value
+ * @return Boolean.TRUE or Boolean.FALSE
+ */
+ protected static Boolean booleanValueOf(boolean val) {
+ if (val) {
+ return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ }
+ /**
+ * if true, targets will be built for debugging
+ */
+ private Boolean debug;
+ private Environment env = null;
+ /**
+ * Reference for "extends" processor definition
+ */
+ private Reference extendsRef = null;
+ /**
+ * Name of property that must be present or definition will be ignored. May
+ * be null.
+ */
+ private String ifProp;
+ /**
+ * if true, processor definition inherits values from containing <cc>
+ * element
+ */
+ private boolean inherit;
+ private Boolean libtool = null;
+ protected boolean newEnvironment = false;
+ /**
+ * Processor.
+ */
+ private Processor processor;
+ /**
+ * Collection of <compilerarg>or <linkerarg>contained by definition
+ */
+ private final Vector processorArgs = new Vector();
+ /**
+ * Collection of <compilerparam>or <linkerparam>contained by definition
+ */
+ private final Vector processorParams = new Vector();
+ /**
+ * if true, all targets will be unconditionally rebuilt
+ */
+ private Boolean rebuild;
+ /**
+ * Collection of <fileset>contained by definition
+ */
+ private final Vector srcSets = new Vector();
+ /**
+ * Name of property that if present will cause definition to be ignored.
+ * May be null.
+ */
+ private String unlessProp;
+ /**
+ * Constructor
+ *
+ */
+ protected ProcessorDef() throws NullPointerException {
+ inherit = true;
+ }
+ /**
+ * Adds a <compilerarg>or <linkerarg>
+ *
+ * @param arg
+ * command line argument, must not be null
+ * @throws NullPointerException
+ * if arg is null
+ * @throws BuildException
+ * if this definition is a reference
+ */
+ protected void addConfiguredProcessorArg(CommandLineArgument arg)
+ throws NullPointerException, BuildException {
+ if (arg == null) {
+ throw new NullPointerException("arg");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ processorArgs.addElement(arg);
+ }
+ /**
+ * Adds a <compilerarg>or <linkerarg>
+ *
+ * @param arg
+ * command line argument, must not be null
+ * @throws NullPointerException
+ * if arg is null
+ * @throws BuildException
+ * if this definition is a reference
+ */
+ protected void addConfiguredProcessorParam(ProcessorParam param)
+ throws NullPointerException, BuildException {
+ if (param == null) {
+ throw new NullPointerException("param");
+ }
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ processorParams.addElement(param);
+ }
+ /**
+ * Add an environment variable to the launched process.
+ */
+ public void addEnv(Environment.Variable var) {
+ if (env == null) {
+ env = new Environment();
+ }
+ env.addVariable(var);
+ }
+ /**
+ * Adds a source file set.
+ *
+ * Files in these set will be processed by this configuration and will not
+ * participate in the auction.
+ *
+ * @param srcSet
+ * Fileset identifying files that should be processed by this
+ * processor
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void addFileset(ConditionalFileSet srcSet) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ srcSet.setProject(getProject());
+ srcSets.addElement(srcSet);
+ }
+ /**
+ * Creates a configuration
+ *
+ * @param baseDef
+ * reference to def from containing <cc>element, may be null
+ * @return configuration
+ *
+ */
+ public ProcessorConfiguration createConfiguration(CCTask task,
+ LinkType linkType, ProcessorDef baseDef,
+ TargetDef targetPlatform, VersionInfo versionInfo) {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).createConfiguration(task, linkType,
+ baseDef, targetPlatform, versionInfo);
+ }
+ ProcessorDef[] defaultProviders = getDefaultProviders(baseDef);
+ Processor proc = getProcessor();
+ return proc.createConfiguration(task, linkType, defaultProviders, this, targetPlatform, versionInfo);
+ }
+ /**
+ * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that
+ * are active for the current project settings.
+ *
+ * @return active compiler arguments
+ */
+ public CommandLineArgument[] getActiveProcessorArgs() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getActiveProcessorArgs();
+ }
+ Vector activeArgs = new Vector(processorArgs.size());
+ for (int i = 0; i < processorArgs.size(); i++) {
+ CommandLineArgument arg = (CommandLineArgument) processorArgs
+ .elementAt(i);
+ if (arg.isActive(p)) {
+ activeArgs.addElement(arg);
+ }
+ }
+ CommandLineArgument[] array = new CommandLineArgument[activeArgs.size()];
+ activeArgs.copyInto(array);
+ return array;
+ }
+ /**
+ * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that
+ * are active for the current project settings.
+ *
+ * @return active compiler arguments
+ */
+ public ProcessorParam[] getActiveProcessorParams() {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException("project must be set");
+ }
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getActiveProcessorParams();
+ }
+ Vector activeParams = new Vector(processorParams.size());
+ for (int i = 0; i < processorParams.size(); i++) {
+ ProcessorParam param = (ProcessorParam) processorParams
+ .elementAt(i);
+ if (param.isActive(p)) {
+ activeParams.addElement(param);
+ }
+ }
+ ProcessorParam[] array = new ProcessorParam[activeParams.size()];
+ activeParams.copyInto(array);
+ return array;
+ }
+ /**
+ * Gets boolean indicating debug build
+ *
+ * @param defaultProviders
+ * array of ProcessorDef's in descending priority
+ * @param index
+ * index to first element in array that should be considered
+ * @return if true, built targets for debugging
+ */
+ public boolean getDebug(ProcessorDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getDebug(defaultProviders, index);
+ }
+ if (debug != null) {
+ return debug.booleanValue();
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getDebug(defaultProviders,
+ index + 1);
+ }
+ }
+ return false;
+ }
+ /**
+ * Creates an chain of objects which provide default values in descending
+ * order of significance.
+ *
+ * @param baseDef
+ * corresponding ProcessorDef from CCTask, will be last element
+ * in array unless inherit = false
+ * @return default provider array
+ *
+ */
+ protected final ProcessorDef[] getDefaultProviders(ProcessorDef baseDef) {
+ ProcessorDef extendsDef = getExtends();
+ Vector chain = new Vector();
+ while (extendsDef != null && !chain.contains(extendsDef)) {
+ chain.addElement(extendsDef);
+ extendsDef = extendsDef.getExtends();
+ }
+ if (baseDef != null && getInherit()) {
+ chain.addElement(baseDef);
+ }
+ ProcessorDef[] defaultProviders = new ProcessorDef[chain.size()];
+ chain.copyInto(defaultProviders);
+ return defaultProviders;
+ }
+ /**
+ * Gets the ProcessorDef specified by the extends attribute
+ *
+ * @return Base ProcessorDef, null if extends is not specified
+ * @throws BuildException
+ * if reference is not same type object
+ */
+ public ProcessorDef getExtends() throws BuildException {
+ if (extendsRef != null) {
+ Object obj = extendsRef.getReferencedObject(getProject());
+ if (!getClass().isInstance(obj)) {
+ throw new BuildException("Referenced object "
+ + extendsRef.getRefId() + " not correct type, is "
+ + obj.getClass().getName() + " should be "
+ + getClass().getName());
+ }
+ return (ProcessorDef) obj;
+ }
+ return null;
+ }
+ /**
+ * Gets the inherit attribute. If the inherit value is true, this processor
+ * definition will inherit default values from the containing <cc>element.
+ *
+ * @return if true then properties from the containing <cc>element are
+ * used.
+ */
+ public final boolean getInherit() {
+ return inherit;
+ }
+ public boolean getLibtool() {
+ if (libtool != null) {
+ return libtool.booleanValue();
+ }
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getLibtool();
+ }
+ ProcessorDef extendsDef = getExtends();
+ if (extendsDef != null) {
+ return extendsDef.getLibtool();
+ }
+ return false;
+ }
+ /**
+ * Obtains the appropriate processor (compiler, linker)
+ *
+ * @return processor
+ */
+ protected Processor getProcessor() {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getProcessor();
+ }
+ //
+ // if a processor has not been explicitly set
+ // then may be set by an extended definition
+ if (processor == null) {
+ ProcessorDef extendsDef = getExtends();
+ if (extendsDef != null) {
+ return extendsDef.getProcessor();
+ }
+ }
+ return processor;
+ }
+ /**
+ * Gets a boolean value indicating whether all targets must be rebuilt
+ * regardless of dependency analysis.
+ *
+ * @param defaultProviders
+ * array of ProcessorDef's in descending priority
+ * @param index
+ * index to first element in array that should be considered
+ * @return true if all targets should be rebuilt.
+ */
+ public boolean getRebuild(ProcessorDef[] defaultProviders, int index) {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).getRebuild(defaultProviders, index);
+ }
+ if (rebuild != null) {
+ return rebuild.booleanValue();
+ } else {
+ if (defaultProviders != null && index < defaultProviders.length) {
+ return defaultProviders[index].getRebuild(defaultProviders,
+ index + 1);
+ }
+ }
+ return false;
+ }
+ /**
+ * Returns true if the processor definition contains embedded file set
+ * definitions
+ *
+ * @return true if processor definition contains embedded filesets
+ */
+ public boolean hasFileSets() {
+ if (isReference()) {
+ return ((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).hasFileSets();
+ }
+ return srcSets.size() > 0;
+ }
+ /**
+ * Determine if this def should be used.
+ *
+ * Definition will be active if the "if" variable (if specified) is set and
+ * the "unless" variable (if specified) is not set and that all reference
+ * or extended definitions are active
+ *
+ * @return true if processor is active
+ * @throws IllegalStateException
+ * if not properly initialized
+ * @throws BuildException
+ * if "if" or "unless" variable contains suspicious values
+ * "false" or "no" which indicates possible confusion
+ */
+ public boolean isActive() throws BuildException, IllegalStateException {
+ Project project = getProject();
+ if (!CUtil.isActive(project, ifProp, unlessProp)) {
+ return false;
+ }
+ if (isReference()) {
+ if (!((ProcessorDef) getCheckedRef(ProcessorDef.class,
+ "ProcessorDef")).isActive()) {
+ return false;
+ }
+ }
+ //
+ // walk through any extended definitions
+ //
+ ProcessorDef[] defaultProviders = getDefaultProviders(null);
+ for (int i = 0; i < defaultProviders.length; i++) {
+ if (!defaultProviders[i].isActive()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ /**
+ * Sets the class name for the adapter. Use the "name" attribute when the
+ * tool is supported.
+ *
+ * @param className
+ * full class name
+ *
+ */
+ public void setClassname(String className) throws BuildException {
+ Object proc = null;
+ try {
+ Class implClass = ProcessorDef.class.getClassLoader().loadClass(
+ className);
+ try {
+ Method getInstance = implClass.getMethod("getInstance",
+ new Class[0]);
+ proc = getInstance.invoke(null, new Object[0]);
+ } catch (Exception ex) {
+ proc = implClass.newInstance();
+ }
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ setProcessor((Processor) proc);
+ }
+ /**
+ * If set true, all targets will be built for debugging.
+ *
+ * @param debug
+ * true if targets should be built for debugging
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void setDebug(boolean debug) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.debug = booleanValueOf(debug);
+ }
+ /**
+ * Sets a description of the current data type.
+ */
+ public void setDescription(String desc) {
+ super.setDescription(desc);
+ }
+ /**
+ * Specifies that this element extends the element with id attribute with a
+ * matching value. The configuration will be constructed from the settings
+ * of this element, element referenced by extends, and the containing cc
+ * element.
+ *
+ * @param extendsRef
+ * Reference to the extended processor definition.
+ * @throws BuildException
+ * if this processor definition is a reference
+ */
+ public void setExtends(Reference extendsRef) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.extendsRef = extendsRef;
+ }
+ /**
+ * Sets an id that can be used to reference this element.
+ *
+ * @param id
+ * id
+ */
+ public void setId(String id) {
+ //
+ // this is actually accomplished by a different
+ // mechanism, but we can document it
+ //
+ }
+ /**
+ * Sets the property name for the 'if' condition.
+ *
+ * The configuration will be ignored unless the property is defined.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") will throw an exception when
+ * evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setIf(String propName) {
+ ifProp = propName;
+ }
+ /**
+ * If inherit has the default value of true, defines, includes and other
+ * settings from the containing <cc>element will be inherited.
+ *
+ * @param inherit
+ * new value
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void setInherit(boolean inherit) throws BuildException {
+ if (isReference()) {
+ throw super.tooManyAttributes();
+ }
+ this.inherit = inherit;
+ }
+ /**
+ * Set use of libtool.
+ *
+ * If set to true, the "libtool " will be prepended to the command line
+ *
+ * @param libtool
+ * If true, use libtool.
+ */
+ public void setLibtool(boolean libtool) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.libtool = booleanValueOf(libtool);
+ }
+ /**
+ * Do not propagate old environment when new environment variables are
+ * specified.
+ */
+ public void setNewenvironment(boolean newenv) {
+ newEnvironment = newenv;
+ }
+ /**
+ * Sets the processor
+ *
+ * @param processor
+ * processor, may not be null.
+ * @throws BuildException
+ * if ProcessorDef is a reference
+ * @throws NullPointerException
+ * if processor is null
+ */
+ protected void setProcessor(Processor processor) throws BuildException,
+ NullPointerException {
+ if (processor == null) {
+ throw new NullPointerException("processor");
+ }
+ if (isReference()) {
+ throw super.tooManyAttributes();
+ }
+ if (env == null && !newEnvironment) {
+ this.processor = processor;
+ } else {
+ this.processor = processor.changeEnvironment(newEnvironment, env);
+ }
+ }
+ /**
+ * If set true, all targets will be unconditionally rebuilt.
+ *
+ * @param rebuild
+ * if true, rebuild all targets.
+ * @throws BuildException
+ * if processor definition is a reference
+ */
+ public void setRebuild(boolean rebuild) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.rebuild = booleanValueOf(rebuild);
+ }
+ /**
+ * Specifies that this element should behave as if the content of the
+ * element with the matching id attribute was inserted at this location. If
+ * specified, no other attributes or child content should be specified,
+ * other than "if", "unless" and "description".
+ *
+ * @param ref
+ * Reference to other element
+ *
+ */
+ public void setRefid(org.apache.tools.ant.types.Reference ref) {
+ super.setRefid(ref);
+ }
+ /**
+ * Set the property name for the 'unless' condition.
+ *
+ * If named property is set, the configuration will be ignored.
+ *
+ * The value of the property is insignificant, but values that would imply
+ * misinterpretation ("false", "no") of the behavior will throw an
+ * exception when evaluated.
+ *
+ * @param propName
+ * name of property
+ */
+ public void setUnless(String propName) {
+ unlessProp = propName;
+ }
+ /**
+ * This method calls the FileVistor's visit function for every file in the
+ * processors definition
+ *
+ * @param visitor
+ * object whose visit method is called for every file
+ */
+ public void visitFiles(FileVisitor visitor) {
+ Project p = getProject();
+ if (p == null) {
+ throw new java.lang.IllegalStateException(
+ "project must be set before this call");
+ }
+ if (isReference()) {
+ ((ProcessorDef) getCheckedRef(ProcessorDef.class, "ProcessorDef"))
+ .visitFiles(visitor);
+ }
+ //
+ // if this processor extends another,
+ // visit its files first
+ //
+ ProcessorDef extendsDef = getExtends();
+ if (extendsDef != null) {
+ extendsDef.visitFiles(visitor);
+ }
+
+ for (int i = 0; i < srcSets.size(); i++) {
+ ConditionalFileSet srcSet = (ConditionalFileSet) srcSets
+ .elementAt(i);
+ if (srcSet.isActive()) {
+ // Find matching source files
+ DirectoryScanner scanner = srcSet.getDirectoryScanner(p);
+ // Check each source file - see if it needs compilation
+ String[] fileNames = scanner.getIncludedFiles();
+ File parentDir = scanner.getBasedir();
+ for (int j = 0; j < fileNames.length; j++) {
+ String currentFile = fileNames[j];
+ visitor.visit(parentDir, currentFile);
+ }
+ }
+ }
+ }
+}