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
;
24 import java
.util
.StringTokenizer
;
25 import java
.util
.Vector
;
27 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
28 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
29 import net
.sf
.antcontrib
.cpptasks
.types
.CommandLineArgument
;
30 import net
.sf
.antcontrib
.cpptasks
.types
.ConditionalFileSet
;
32 import org
.apache
.tools
.ant
.BuildException
;
33 import org
.apache
.tools
.ant
.DirectoryScanner
;
34 import org
.apache
.tools
.ant
.Project
;
35 import org
.apache
.tools
.ant
.types
.Environment
;
36 import org
.apache
.tools
.ant
.types
.Path
;
37 import org
.apache
.tools
.ant
.types
.Environment
.Variable
;
42 public class CommandLineUserDefine
{
44 String includePathDelimiter
= null;
46 String outputDelimiter
= null;
48 private static String pathName
= null;
50 public void command(CCTask cctask
, UserDefineDef userdefine
) {
51 boolean isGccCommand
= userdefine
.getFamily().equalsIgnoreCase("GCC");
53 Project project
= cctask
.getProject();
54 if (userdefine
.getWorkdir() == null) {
55 workdir
= new File(".");
57 workdir
= userdefine
.getWorkdir();
61 // generate cmdline= command + args + includepath + endargs + outfile
63 Vector args
= new Vector();
64 Vector argsWithoutSpace
= new Vector();
65 Vector endargs
= new Vector();
66 Vector endargsWithoutSpace
= new Vector();
67 Vector includePath
= new Vector();
72 CommandLineArgument
[] argument
= userdefine
.getActiveProcessorArgs();
73 for (int j
= 0; j
< argument
.length
; j
++) {
74 if (argument
[j
].getLocation() == 0) {
75 args
.addElement(argument
[j
].getValue());
77 endargs
.addElement(argument
[j
].getValue());
84 String
[] incPath
= userdefine
.getActiveIncludePaths();
85 for (int j
= 0; j
< incPath
.length
; j
++) {
86 includePath
.addElement(includePathDelimiter
+ incPath
[j
]);
90 // Remove space in args and endargs.
92 for (int i
= 0; i
< args
.size(); i
++) {
93 String str
= (String
) args
.get(i
);
94 StringTokenizer st
= new StringTokenizer(str
, " \t");
95 while (st
.hasMoreTokens()) {
96 argsWithoutSpace
.addElement(st
.nextToken());
99 for (int i
= 0; i
< endargs
.size(); i
++) {
100 String str
= (String
) endargs
.get(i
);
101 StringTokenizer st
= new StringTokenizer(str
, " \t");
102 while (st
.hasMoreTokens()) {
103 endargsWithoutSpace
.addElement(st
.nextToken());
109 // command + args + endargs + includepath + sourcefile
111 cmdLen
= 1 + argsWithoutSpace
.size() + endargsWithoutSpace
.size()
112 + includePath
.size() + 1;
113 String
[] libSet
= userdefine
.getLibset();
114 if (libSet
!= null && libSet
.length
> 0) {
115 cmdLen
= cmdLen
+ libSet
.length
;
117 cmdLen
+= 2; // we need -( and -) to group libs for GCC
122 // In gcc the "cr" flag should follow space then add outputfile name,
124 // it will pop error.
126 if (outputDelimiter
!= null && userdefine
.getOutputFile() != null
127 && outputDelimiter
.trim().length() > 0) {
128 if (outputDelimiter
.trim().equalsIgnoreCase("-cr")) {
136 // for every source file
137 // if file is header file, just skip it (add later)
139 Vector srcSets
= userdefine
.getSrcSets();
142 // if have source file append source file in command line.
144 Set allSrcFiles
= new LinkedHashSet();
146 for (int i
= 0; i
< srcSets
.size(); i
++) {
147 ConditionalFileSet srcSet
= (ConditionalFileSet
) srcSets
149 if (srcSet
.isActive()) {
151 // Find matching source files
153 DirectoryScanner scanner
= srcSet
.getDirectoryScanner(project
);
155 // Check each source file - see if it needs compilation
157 String
[] fileNames
= scanner
.getIncludedFiles();
158 for (int j
= 0; j
< fileNames
.length
; j
++) {
159 allSrcFiles
.add(scanner
.getBasedir() + "/" + fileNames
[j
]);
161 System
.out
.println("[" + userdefine
.getType() + "] "
168 String
[] fileNames
= (String
[]) allSrcFiles
169 .toArray(new String
[allSrcFiles
.size()]);
170 String
[] cmd
= new String
[cmdLen
- 1 + fileNames
.length
];
172 cmd
[index
++] = userdefine
.getCmd();
174 Iterator iter
= argsWithoutSpace
.iterator();
175 while (iter
.hasNext()) {
176 cmd
[index
++] = project
.replaceProperties((String
) iter
.next());
179 iter
= endargsWithoutSpace
.iterator();
180 while (iter
.hasNext()) {
181 cmd
[index
++] = project
.replaceProperties((String
) iter
.next());
185 // Add outputFileFlag and output file to cmd
187 if (outputDelimiter
!= null && userdefine
.getOutputFile() != null
188 && outputDelimiter
.length() > 0) {
189 if (outputDelimiter
.trim().equalsIgnoreCase("-cr")) {
190 cmd
[index
++] = outputDelimiter
;
191 cmd
[index
++] = userdefine
.getOutputFile();
193 cmd
[index
++] = outputDelimiter
+ userdefine
.getOutputFile();
197 iter
= includePath
.iterator();
198 while (iter
.hasNext()) {
199 cmd
[index
++] = (String
) iter
.next();
202 if (libSet
!= null && libSet
.length
> 0) {
206 for (int k
= 0; k
< libSet
.length
; k
++) {
207 cmd
[index
++] = libSet
[k
];
213 for (int j
= 0; j
< fileNames
.length
; j
++) {
214 cmd
[index
++] = fileNames
[j
];
217 // StringBuffer logLine = new StringBuffer();
218 // for(int i = 0; i < cmd.length; i++) {
219 // logLine.append(cmd[i] + " ");
221 // project.log(logLine.toString(), Project.MSG_VERBOSE);
225 if (userdefine
.getDpath() == null || userdefine
.getDpath().trim().length() == 0) {
226 retval
= runCommand(cctask
, workdir
, cmd
, null);
228 String existPath
= System
.getenv(getPathName());
229 Environment newEnv
= new Environment();
230 Variable var
= new Variable();
231 var
.setKey(getPathName());
232 var
.setPath(new Path(project
, userdefine
.getDpath() + ";" + existPath
));
233 newEnv
.addVariable(var
);
234 retval
= runCommand(cctask
, workdir
, cmd
, newEnv
);
239 throw new BuildException(userdefine
.getCmd()
240 + " failed with return code " + retval
, cctask
245 private String
getPathName() {
246 if (pathName
!= null) {
249 Map allEnv
= System
.getenv();
250 Iterator iter
= allEnv
.keySet().iterator();
251 while (iter
.hasNext()) {
252 String key
= (String
)iter
.next();
253 if(key
.equalsIgnoreCase("PATH")) {
261 protected int runCommand(CCTask task
, File workingDir
, String
[] cmdline
, Environment env
)
262 throws BuildException
{
264 // Write command to File
266 return CUtil
.runCommand(task
, workingDir
, cmdline
, false, env
);