3 * Copyright 2001-2005 The Ant-Contrib project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package net
.sf
.antcontrib
.cpptasks
.compiler
;
20 import java
.util
.Enumeration
;
21 import java
.util
.Vector
;
23 import net
.sf
.antcontrib
.cpptasks
.AslcompilerDef
;
24 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
25 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
26 import net
.sf
.antcontrib
.cpptasks
.ProcessorDef
;
27 import net
.sf
.antcontrib
.cpptasks
.TargetDef
;
28 import net
.sf
.antcontrib
.cpptasks
.types
.CommandLineArgument
;
30 import org
.apache
.tools
.ant
.BuildException
;
32 * An abstract ASL Compiler implementation which uses an external program to
33 * perform the ASL compile.
36 public abstract class CommandLineAslcompiler
extends AbstractAslcompiler
{
38 private String command
;
39 private String identifier
;
40 private String identifierArg
;
42 protected CommandLineAslcompiler(String command
, String identifierArg
,
43 String
[] sourceExtensions
, String
[] headerExtensions
,
44 String outputSuffix
) {
45 super(sourceExtensions
, headerExtensions
, outputSuffix
);
46 this.command
= command
;
47 this.identifierArg
= identifierArg
;
50 abstract protected void addImpliedArgs(Vector args
, boolean debug
,
54 * Compile a ACPI source file
57 public void aslcompiler(CCTask task
, File outputDir
, String
[] sourceFiles
,
58 String
[] args
, String
[] endArgs
) throws BuildException
{
59 String command
= getCommand();
60 int baseLength
= command
.length() + args
.length
+ endArgs
.length
;
61 for (int i
= 0; i
< args
.length
; i
++) {
62 baseLength
+= args
[i
].length();
64 for (int i
= 0; i
< endArgs
.length
; i
++) {
65 baseLength
+= endArgs
[i
].length();
67 if (baseLength
> getMaximumCommandLength()) {
68 throw new BuildException(
69 "Command line is over maximum length without sepcifying source file");
71 int maxInputFilesPerCommand
= getMaximumInputFilesPerCommand();
72 int argumentCountPerInputFile
= getArgumentCountPerInputFIle();
73 for (int sourceIndex
= 0; sourceIndex
< sourceFiles
.length
;) {
74 int cmdLength
= baseLength
;
75 int firstFileNextExec
;
76 for (firstFileNextExec
= sourceIndex
; firstFileNextExec
< sourceFiles
.length
77 && (firstFileNextExec
- sourceIndex
) < maxInputFilesPerCommand
; firstFileNextExec
++) {
78 cmdLength
+= getTotalArgumentLengthForInputFile(outputDir
,
79 sourceFiles
[firstFileNextExec
]);
80 if (cmdLength
>= getMaximumCommandLength())
83 if (firstFileNextExec
== sourceIndex
) {
84 throw new BuildException(
85 "Extremely long file name, can't fit on command line");
87 int argCount
= args
.length
+ 1 + endArgs
.length
88 + (firstFileNextExec
- sourceIndex
)
89 * argumentCountPerInputFile
;
90 String
[] commandline
= new String
[argCount
];
92 commandline
[index
++] = command
;
93 for (int j
= 0; j
< args
.length
; j
++) {
94 commandline
[index
++] = args
[j
];
96 for (int j
= sourceIndex
; j
< firstFileNextExec
; j
++) {
97 for (int k
= 0; k
< argumentCountPerInputFile
; k
++) {
98 commandline
[index
++] = getInputFileArgument(outputDir
,
102 for (int j
= 0; j
< endArgs
.length
; j
++) {
103 commandline
[index
++] = endArgs
[j
];
105 int retval
= runCommand(task
, outputDir
, commandline
);
106 // if with monitor, add more code
108 throw new BuildException(this.getCommand()
109 + " failed with return code " + retval
,
112 sourceIndex
= firstFileNextExec
;
116 protected AslcompilerConfiguration
createConfiguration(final CCTask task
,
117 final LinkType linkType
,
118 final ProcessorDef
[] baseDefs
,
119 final AslcompilerDef specificDef
,
120 final TargetDef targetPlatform
) {
121 Vector args
= new Vector();
122 AslcompilerDef
[] defaultProviders
= new AslcompilerDef
[baseDefs
.length
+1];
123 for (int i
= 0; i
< baseDefs
.length
; i
++) {
124 defaultProviders
[i
+ 1] = (AslcompilerDef
) baseDefs
[i
];
126 defaultProviders
[0] = specificDef
;
127 Vector cmdArgs
= new Vector();
129 // add command line arguments inherited from <cc> element
130 // any "extends" and finally and specific AslcompilerDef
132 CommandLineArgument
[] commandArgs
;
133 for (int i
= defaultProviders
.length
- 1; i
>=0; i
--){
134 commandArgs
= defaultProviders
[i
].getActiveProcessorArgs();
135 for (int j
= 0; j
< commandArgs
.length
; j
++) {
136 if (commandArgs
[j
].getLocation() == 0) {
137 args
.addElement(commandArgs
[j
].getValue());
140 cmdArgs
.addElement(commandArgs
[j
]);
145 boolean debug
= specificDef
.getDebug(baseDefs
, 0);
146 Boolean defaultflag
= specificDef
.getDefaultflag(defaultProviders
, 1);
147 this.addImpliedArgs(args
, debug
, defaultflag
);
148 Enumeration argEnum
= cmdArgs
.elements();
150 while( argEnum
.hasMoreElements()) {
151 CommandLineArgument arg
= (CommandLineArgument
) argEnum
.nextElement();
152 switch (arg
.getLocation()) {
154 args
.addElement(arg
.getValue());
161 String
[] endArgs
= new String
[endCount
];
162 argEnum
= cmdArgs
.elements();
164 while (argEnum
.hasMoreElements()) {
165 CommandLineArgument arg
= (CommandLineArgument
) argEnum
.nextElement();
166 if (arg
.getLocation() == 2) {
167 endArgs
[index
++] = arg
.getValue();
170 String
[] argArray
= new String
[args
.size()];
171 args
.copyInto(argArray
);
172 return new CommandLineAslcompilerConfiguration(this, argArray
, true, endArgs
);
175 protected int getArgumentCountPerInputFile() {
179 public String
getIdentifier() {
180 if (identifier
== null) {
181 if (identifierArg
== null) {
182 identifier
= getIdentifier(new String
[]{command
}, command
);
185 identifier
= getIdentifier(
186 new String
[]{command
, identifierArg
}, command
);
192 public final String
getCommand() {
195 abstract public int getMaximumCommandLength();
196 public void setCommand(String command
) {
197 this.command
= command
;
199 protected int getTotalArgumentLengthForInputFile(File outputDir
,
201 return inputFile
.length() + 1;
203 protected int runCommand(CCTask task
, File workingDir
, String
[] cmdline
)
204 throws BuildException
{
205 return CUtil
.runCommand(task
, workingDir
, cmdline
, false, null);
208 protected int getMaximumInputFilesPerCommand(){
211 protected int getArgumentCountPerInputFIle(){
214 protected String
getInputFileArgument(File outputDir
, String filename
, int index
) {
216 // if there is an embedded space,
217 // must enclose in quotes
218 if (filename
.indexOf(' ') >= 0) {
219 StringBuffer buf
= new StringBuffer("\"");
220 buf
.append(filename
);
222 return buf
.toString();