--- /dev/null
+/*\r
+ * \r
+ * Copyright 2001-2005 The Ant-Contrib project\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package net.sf.antcontrib.cpptasks.compiler;\r
+\r
+import java.io.File;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+\r
+import net.sf.antcontrib.cpptasks.AslcompilerDef;\r
+import net.sf.antcontrib.cpptasks.CCTask;\r
+import net.sf.antcontrib.cpptasks.CUtil;\r
+import net.sf.antcontrib.cpptasks.ProcessorDef;\r
+import net.sf.antcontrib.cpptasks.TargetDef;\r
+import net.sf.antcontrib.cpptasks.types.CommandLineArgument;\r
+\r
+import org.apache.tools.ant.BuildException;\r
+/**\r
+ * An abstract ASL Compiler implementation which uses an external program to\r
+ * perform the ASL compile.\r
+ * \r
+ */\r
+public abstract class CommandLineAslcompiler extends AbstractAslcompiler{\r
+\r
+ private String command;\r
+ private String identifier;\r
+ private String identifierArg;\r
+ \r
+ protected CommandLineAslcompiler(String command, String identifierArg,\r
+ String[] sourceExtensions, String[] headerExtensions,\r
+ String outputSuffix) {\r
+ super(sourceExtensions, headerExtensions, outputSuffix);\r
+ this.command = command;\r
+ this.identifierArg = identifierArg;\r
+ }\r
+ \r
+ abstract protected void addImpliedArgs(Vector args, boolean debug,\r
+ Boolean defaultflag);\r
+ \r
+ /**\r
+ * Compile a ACPI source file\r
+ * \r
+ */\r
+ public void aslcompiler(CCTask task, File outputDir, String[] sourceFiles,\r
+ String[] args, String[] endArgs) throws BuildException{\r
+ String command = getCommand();\r
+ int baseLength = command.length() + args.length + endArgs.length; \r
+ for (int i = 0; i < args.length; i++) {\r
+ baseLength += args[i].length();\r
+ }\r
+ for (int i = 0; i < endArgs.length; i++) {\r
+ baseLength += endArgs[i].length();\r
+ }\r
+ if (baseLength > getMaximumCommandLength()) {\r
+ throw new BuildException(\r
+ "Command line is over maximum length without sepcifying source file");\r
+ }\r
+ int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();\r
+ int argumentCountPerInputFile = getArgumentCountPerInputFIle();\r
+ for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {\r
+ int cmdLength = baseLength;\r
+ int firstFileNextExec;\r
+ for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length\r
+ && (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {\r
+ cmdLength += getTotalArgumentLengthForInputFile(outputDir, \r
+ sourceFiles[firstFileNextExec]); \r
+ if (cmdLength >= getMaximumCommandLength()) \r
+ break;\r
+ }\r
+ if (firstFileNextExec == sourceIndex) {\r
+ throw new BuildException(\r
+ "Extremely long file name, can't fit on command line");\r
+ }\r
+ int argCount = args.length + 1 + endArgs.length\r
+ + (firstFileNextExec - sourceIndex)\r
+ * argumentCountPerInputFile;\r
+ String[] commandline = new String[argCount];\r
+ int index = 0;\r
+ commandline[index++] = command;\r
+ for (int j = 0; j < args.length; j++) {\r
+ commandline[index++] = args[j];\r
+ }\r
+ for (int j = sourceIndex; j < firstFileNextExec; j++) {\r
+ for (int k = 0; k < argumentCountPerInputFile; k++) {\r
+ commandline[index++] = getInputFileArgument(outputDir, \r
+ sourceFiles[j], k); \r
+ }\r
+ }\r
+ for (int j = 0; j < endArgs.length; j++) {\r
+ commandline[index++] = endArgs[j];\r
+ }\r
+ int retval = runCommand(task, outputDir, commandline);\r
+ // if with monitor, add more code\r
+ if (retval != 0) {\r
+ throw new BuildException(this.getCommand()\r
+ + " failed with return code " + retval,\r
+ task.getLocation());\r
+ }\r
+ sourceIndex = firstFileNextExec;\r
+ }\r
+ }\r
+ \r
+ protected AslcompilerConfiguration createConfiguration(final CCTask task,\r
+ final LinkType linkType, \r
+ final ProcessorDef[] baseDefs, \r
+ final AslcompilerDef specificDef,\r
+ final TargetDef targetPlatform) {\r
+ Vector args = new Vector();\r
+ AslcompilerDef[] defaultProviders = new AslcompilerDef[baseDefs.length +1];\r
+ for (int i = 0; i < baseDefs.length; i++) {\r
+ defaultProviders[i + 1] = (AslcompilerDef) baseDefs[i];\r
+ }\r
+ defaultProviders[0] = specificDef;\r
+ Vector cmdArgs = new Vector();\r
+ //\r
+ // add command line arguments inherited from <cc> element\r
+ // any "extends" and finally and specific AslcompilerDef\r
+ //\r
+ CommandLineArgument[] commandArgs;\r
+ for (int i = defaultProviders.length - 1; i >=0; i--){\r
+ commandArgs = defaultProviders[i].getActiveProcessorArgs();\r
+ for (int j = 0; j < commandArgs.length; j++) {\r
+ if (commandArgs[j].getLocation() == 0) {\r
+ args.addElement(commandArgs[j].getValue());\r
+ }\r
+ else {\r
+ cmdArgs.addElement(commandArgs[j]);\r
+ }\r
+ }\r
+ }\r
+ // omit param\r
+ boolean debug = specificDef.getDebug(baseDefs, 0);\r
+ Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);\r
+ this.addImpliedArgs(args, debug, defaultflag);\r
+ Enumeration argEnum = cmdArgs.elements();\r
+ int endCount = 0;\r
+ while( argEnum.hasMoreElements()) {\r
+ CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement();\r
+ switch (arg.getLocation()) {\r
+ case 1 :\r
+ args.addElement(arg.getValue());\r
+ break;\r
+ case 2 :\r
+ endCount++;\r
+ break;\r
+ }\r
+ }\r
+ String[] endArgs = new String[endCount];\r
+ argEnum = cmdArgs.elements();\r
+ int index = 0;\r
+ while (argEnum.hasMoreElements()) {\r
+ CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement();\r
+ if (arg.getLocation() == 2) {\r
+ endArgs[index++] = arg.getValue();\r
+ }\r
+ }\r
+ String[] argArray = new String[args.size()];\r
+ args.copyInto(argArray);\r
+ return new CommandLineAslcompilerConfiguration(this, argArray, true, endArgs);\r
+ }\r
+ \r
+ protected int getArgumentCountPerInputFile() {\r
+ return 1;\r
+ }\r
+ \r
+ public String getIdentifier() {\r
+ if (identifier == null) {\r
+ if (identifierArg == null) {\r
+ identifier = getIdentifier(new String[]{command}, command);\r
+ }\r
+ else {\r
+ identifier = getIdentifier(\r
+ new String[]{command, identifierArg}, command);\r
+ }\r
+ }\r
+ return identifier;\r
+ }\r
+ \r
+ public final String getCommand() {\r
+ return command;\r
+ }\r
+ abstract public int getMaximumCommandLength();\r
+ public void setCommand(String command) {\r
+ this.command = command;\r
+ }\r
+ protected int getTotalArgumentLengthForInputFile(File outputDir,\r
+ String inputFile) {\r
+ return inputFile.length() + 1;\r
+ }\r
+ protected int runCommand(CCTask task, File workingDir, String[] cmdline) \r
+ throws BuildException {\r
+ return CUtil.runCommand(task, workingDir, cmdline, false, null);\r
+ \r
+ }\r
+ protected int getMaximumInputFilesPerCommand(){\r
+ return 1;\r
+ }\r
+ protected int getArgumentCountPerInputFIle(){\r
+ return 1;\r
+ }\r
+ protected String getInputFileArgument(File outputDir, String filename, int index) {\r
+ //\r
+ // if there is an embedded space,\r
+ // must enclose in quotes\r
+ if (filename.indexOf(' ') >= 0) {\r
+ StringBuffer buf = new StringBuffer("\"");\r
+ buf.append(filename);\r
+ buf.append("\"");\r
+ return buf.toString();\r
+ }\r
+ return filename;\r
+ }\r
+}\r