3 * Copyright 2001-2004 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
.userdefine
;
20 import java
.util
.Iterator
;
21 import java
.util
.LinkedHashSet
;
23 import java
.util
.StringTokenizer
;
24 import java
.util
.Vector
;
26 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
27 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
28 import net
.sf
.antcontrib
.cpptasks
.types
.CommandLineArgument
;
29 import net
.sf
.antcontrib
.cpptasks
.types
.ConditionalFileSet
;
31 import org
.apache
.tools
.ant
.BuildException
;
32 import org
.apache
.tools
.ant
.DirectoryScanner
;
33 import org
.apache
.tools
.ant
.Project
;
38 public class CommandLineUserDefine
{
40 String includePathDelimiter
= null;
42 String outputDelimiter
= null;
44 public void command(CCTask cctask
, UserDefineDef userdefine
) {
45 boolean isGccCommand
= userdefine
.getFamily().equalsIgnoreCase("GCC");
47 Project project
= cctask
.getProject();
48 if (userdefine
.getWorkdir() == null) {
49 workdir
= new File(".");
51 workdir
= userdefine
.getWorkdir();
55 // generate cmdline= command + args + includepath + endargs + outfile
57 Vector args
= new Vector();
58 Vector argsWithoutSpace
= new Vector();
59 Vector endargs
= new Vector();
60 Vector endargsWithoutSpace
= new Vector();
61 Vector includePath
= new Vector();
66 CommandLineArgument
[] argument
= userdefine
.getActiveProcessorArgs();
67 for (int j
= 0; j
< argument
.length
; j
++) {
68 if (argument
[j
].getLocation() == 0) {
69 args
.addElement(argument
[j
].getValue());
71 endargs
.addElement(argument
[j
].getValue());
78 String
[] incPath
= userdefine
.getActiveIncludePaths();
79 for (int j
= 0; j
< incPath
.length
; j
++) {
80 includePath
.addElement(includePathDelimiter
+ incPath
[j
]);
84 // Remove space in args and endargs.
86 for (int i
= 0; i
< args
.size(); i
++) {
87 String str
= (String
) args
.get(i
);
88 StringTokenizer st
= new StringTokenizer(str
, " \t");
89 while (st
.hasMoreTokens()) {
90 argsWithoutSpace
.addElement(st
.nextToken());
93 for (int i
= 0; i
< endargs
.size(); i
++) {
94 String str
= (String
) endargs
.get(i
);
95 StringTokenizer st
= new StringTokenizer(str
, " \t");
96 while (st
.hasMoreTokens()) {
97 endargsWithoutSpace
.addElement(st
.nextToken());
103 // command + args + endargs + includepath + sourcefile
105 cmdLen
= 1 + argsWithoutSpace
.size() + endargsWithoutSpace
.size()
106 + includePath
.size() + 1;
107 String
[] libSet
= userdefine
.getLibset();
108 if (libSet
!= null && libSet
.length
> 0) {
109 cmdLen
= cmdLen
+ libSet
.length
;
111 cmdLen
+= 2; // we need -( and -) to group libs for GCC
116 // In gcc the "cr" flag should follow space then add outputfile name,
118 // it will pop error.
120 if (outputDelimiter
!= null && userdefine
.getOutputFile() != null
121 && outputDelimiter
.trim().length() > 0) {
122 if (outputDelimiter
.trim().equalsIgnoreCase("-cr")) {
130 // for every source file
131 // if file is header file, just skip it (add later)
133 Vector srcSets
= userdefine
.getSrcSets();
136 // if have source file append source file in command line.
138 Set allSrcFiles
= new LinkedHashSet();
139 for (int i
= 0; i
< srcSets
.size(); i
++) {
140 ConditionalFileSet srcSet
= (ConditionalFileSet
) srcSets
142 if (srcSet
.isActive()) {
144 // Find matching source files
146 DirectoryScanner scanner
= srcSet
.getDirectoryScanner(project
);
149 // Check each source file - see if it needs compilation
151 String
[] fileNames
= scanner
.getIncludedFiles();
152 for (int j
= 0; j
< fileNames
.length
; j
++) {
153 allSrcFiles
.add(scanner
.getBasedir() + "/" + fileNames
[j
]);
155 System
.out
.println("[" + userdefine
.getType() + "] "
162 String
[] fileNames
= (String
[]) allSrcFiles
163 .toArray(new String
[allSrcFiles
.size()]);
164 String
[] cmd
= new String
[cmdLen
- 1 + fileNames
.length
];
166 cmd
[index
++] = userdefine
.getCmd();
168 Iterator iter
= argsWithoutSpace
.iterator();
169 while (iter
.hasNext()) {
170 cmd
[index
++] = project
.replaceProperties((String
) iter
.next());
173 iter
= endargsWithoutSpace
.iterator();
174 while (iter
.hasNext()) {
175 cmd
[index
++] = project
.replaceProperties((String
) iter
.next());
179 // Add outputFileFlag and output file to cmd
181 if (outputDelimiter
!= null && userdefine
.getOutputFile() != null
182 && outputDelimiter
.length() > 0) {
183 if (outputDelimiter
.trim().equalsIgnoreCase("-cr")) {
184 cmd
[index
++] = outputDelimiter
;
185 cmd
[index
++] = userdefine
.getOutputFile();
187 cmd
[index
++] = outputDelimiter
+ userdefine
.getOutputFile();
191 iter
= includePath
.iterator();
192 while (iter
.hasNext()) {
193 cmd
[index
++] = (String
) iter
.next();
196 if (libSet
!= null && libSet
.length
> 0) {
200 for (int k
= 0; k
< libSet
.length
; k
++) {
201 cmd
[index
++] = libSet
[k
];
207 for (int j
= 0; j
< fileNames
.length
; j
++) {
208 cmd
[index
++] = fileNames
[j
];
211 int retval
= runCommand(cctask
, workdir
, cmd
);
214 throw new BuildException(userdefine
.getCmd()
215 + " failed with return code " + retval
, cctask
220 protected int runCommand(CCTask task
, File workingDir
, String
[] cmdline
)
221 throws BuildException
{
222 return CUtil
.runCommand(task
, workingDir
, cmdline
, false, null);