/* * * Copyright 2001-2005 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.compiler; import java.io.File; import java.util.Enumeration; import java.util.Vector; import net.sf.antcontrib.cpptasks.AslcompilerDef; import net.sf.antcontrib.cpptasks.CCTask; import net.sf.antcontrib.cpptasks.CUtil; import net.sf.antcontrib.cpptasks.ProcessorDef; import net.sf.antcontrib.cpptasks.TargetDef; import net.sf.antcontrib.cpptasks.types.CommandLineArgument; import org.apache.tools.ant.BuildException; /** * An abstract ASL Compiler implementation which uses an external program to * perform the ASL compile. * */ public abstract class CommandLineAslcompiler extends AbstractAslcompiler{ private String command; private String identifier; private String identifierArg; protected CommandLineAslcompiler(String command, String identifierArg, String[] sourceExtensions, String[] headerExtensions, String outputSuffix) { super(sourceExtensions, headerExtensions, outputSuffix); this.command = command; this.identifierArg = identifierArg; } abstract protected void addImpliedArgs(Vector args, boolean debug, Boolean defaultflag); /** * Compile a ACPI source file * */ public void aslcompiler(CCTask task, File outputDir, String[] sourceFiles, String[] args, String[] endArgs) throws BuildException{ String command = getCommand(); int baseLength = command.length() + args.length + endArgs.length; for (int i = 0; i < args.length; i++) { baseLength += args[i].length(); } for (int i = 0; i < endArgs.length; i++) { baseLength += endArgs[i].length(); } if (baseLength > getMaximumCommandLength()) { throw new BuildException( "Command line is over maximum length without sepcifying source file"); } int maxInputFilesPerCommand = getMaximumInputFilesPerCommand(); int argumentCountPerInputFile = getArgumentCountPerInputFIle(); for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) { int cmdLength = baseLength; int firstFileNextExec; for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) { cmdLength += getTotalArgumentLengthForInputFile(outputDir, sourceFiles[firstFileNextExec]); if (cmdLength >= getMaximumCommandLength()) break; } if (firstFileNextExec == sourceIndex) { throw new BuildException( "Extremely long file name, can't fit on command line"); } int argCount = args.length + 1 + endArgs.length + (firstFileNextExec - sourceIndex) * argumentCountPerInputFile; String[] commandline = new String[argCount]; int index = 0; commandline[index++] = command; for (int j = 0; j < args.length; j++) { commandline[index++] = args[j]; } for (int j = sourceIndex; j < firstFileNextExec; j++) { for (int k = 0; k < argumentCountPerInputFile; k++) { commandline[index++] = getInputFileArgument(outputDir, sourceFiles[j], k); } } for (int j = 0; j < endArgs.length; j++) { commandline[index++] = endArgs[j]; } int retval = runCommand(task, outputDir, commandline); // if with monitor, add more code if (retval != 0) { throw new BuildException(this.getCommand() + " failed with return code " + retval, task.getLocation()); } sourceIndex = firstFileNextExec; } } protected AslcompilerConfiguration createConfiguration(final CCTask task, final LinkType linkType, final ProcessorDef[] baseDefs, final AslcompilerDef specificDef, final TargetDef targetPlatform) { Vector args = new Vector(); AslcompilerDef[] defaultProviders = new AslcompilerDef[baseDefs.length +1]; for (int i = 0; i < baseDefs.length; i++) { defaultProviders[i + 1] = (AslcompilerDef) baseDefs[i]; } defaultProviders[0] = specificDef; Vector cmdArgs = new Vector(); // // add command line arguments inherited from element // any "extends" and finally and specific AslcompilerDef // CommandLineArgument[] commandArgs; for (int i = defaultProviders.length - 1; i >=0; i--){ commandArgs = defaultProviders[i].getActiveProcessorArgs(); for (int j = 0; j < commandArgs.length; j++) { if (commandArgs[j].getLocation() == 0) { args.addElement(commandArgs[j].getValue()); } else { cmdArgs.addElement(commandArgs[j]); } } } // omit param boolean debug = specificDef.getDebug(baseDefs, 0); Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1); this.addImpliedArgs(args, debug, defaultflag); Enumeration argEnum = cmdArgs.elements(); int endCount = 0; while( argEnum.hasMoreElements()) { CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement(); switch (arg.getLocation()) { case 1 : args.addElement(arg.getValue()); break; case 2 : endCount++; break; } } String[] endArgs = new String[endCount]; argEnum = cmdArgs.elements(); int index = 0; while (argEnum.hasMoreElements()) { CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement(); if (arg.getLocation() == 2) { endArgs[index++] = arg.getValue(); } } String[] argArray = new String[args.size()]; args.copyInto(argArray); return new CommandLineAslcompilerConfiguration(this, argArray, true, endArgs); } protected int getArgumentCountPerInputFile() { return 1; } public String getIdentifier() { if (identifier == null) { if (identifierArg == null) { identifier = getIdentifier(new String[]{command}, command); } else { identifier = getIdentifier( new String[]{command, identifierArg}, command); } } return identifier; } public final String getCommand() { return command; } abstract public int getMaximumCommandLength(); public void setCommand(String command) { this.command = command; } protected int getTotalArgumentLengthForInputFile(File outputDir, String inputFile) { return inputFile.length() + 1; } protected int runCommand(CCTask task, File workingDir, String[] cmdline) throws BuildException { return CUtil.runCommand(task, workingDir, cmdline, false, null); } protected int getMaximumInputFilesPerCommand(){ return 1; } protected int getArgumentCountPerInputFIle(){ return 1; } protected String getInputFileArgument(File outputDir, String filename, int index) { // // if there is an embedded space, // must enclose in quotes if (filename.indexOf(' ') >= 0) { StringBuffer buf = new StringBuffer("\""); buf.append(filename); buf.append("\""); return buf.toString(); } return filename; } }