/* | |
* | |
* Copyright 2001-2004 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.userdefine; | |
import java.io.File; | |
import java.util.Iterator; | |
import java.util.LinkedHashSet; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.StringTokenizer; | |
import java.util.Vector; | |
import net.sf.antcontrib.cpptasks.CCTask; | |
import net.sf.antcontrib.cpptasks.CUtil; | |
import net.sf.antcontrib.cpptasks.types.CommandLineArgument; | |
import net.sf.antcontrib.cpptasks.types.ConditionalFileSet; | |
import org.apache.tools.ant.BuildException; | |
import org.apache.tools.ant.DirectoryScanner; | |
import org.apache.tools.ant.Project; | |
import org.apache.tools.ant.types.Environment; | |
import org.apache.tools.ant.types.Path; | |
import org.apache.tools.ant.types.Environment.Variable; | |
/** | |
* | |
*/ | |
public class CommandLineUserDefine { | |
String includePathDelimiter = null; | |
String outputDelimiter = null; | |
public void command(CCTask cctask, UserDefineDef userdefine) { | |
boolean isGccCommand = userdefine.getFamily().equalsIgnoreCase("GCC"); | |
File workdir; | |
Project project = cctask.getProject(); | |
if (userdefine.getWorkdir() == null) { | |
workdir = new File("."); | |
} else { | |
workdir = userdefine.getWorkdir(); | |
} | |
// | |
// generate cmdline= command + args + includepath + endargs + outfile | |
// | |
Vector args = new Vector(); | |
Vector argsWithoutSpace = new Vector(); | |
Vector endargs = new Vector(); | |
Vector endargsWithoutSpace = new Vector(); | |
Vector includePath = new Vector(); | |
// | |
// get Args. | |
// | |
CommandLineArgument[] argument = userdefine.getActiveProcessorArgs(); | |
for (int j = 0; j < argument.length; j++) { | |
if (argument[j].getLocation() == 0) { | |
args.addElement(argument[j].getValue()); | |
} else { | |
endargs.addElement(argument[j].getValue()); | |
} | |
} | |
// | |
// get include path. | |
// | |
String[] incPath = userdefine.getActiveIncludePaths(); | |
for (int j = 0; j < incPath.length; j++) { | |
includePath.addElement(includePathDelimiter + incPath[j]); | |
} | |
// | |
// Remove space in args and endargs. | |
// | |
for (int i = 0; i < args.size(); i++) { | |
String str = (String) args.get(i); | |
StringTokenizer st = new StringTokenizer(str, " \t"); | |
while (st.hasMoreTokens()) { | |
argsWithoutSpace.addElement(st.nextToken()); | |
} | |
} | |
for (int i = 0; i < endargs.size(); i++) { | |
String str = (String) endargs.get(i); | |
StringTokenizer st = new StringTokenizer(str, " \t"); | |
while (st.hasMoreTokens()) { | |
endargsWithoutSpace.addElement(st.nextToken()); | |
} | |
} | |
int cmdLen = 0; | |
// | |
// command + args + endargs + includepath + sourcefile | |
// | |
cmdLen = 1 + argsWithoutSpace.size() + endargsWithoutSpace.size() | |
+ includePath.size() + 1; | |
String[] libSet = userdefine.getLibset(); | |
if (libSet != null && libSet.length > 0) { | |
cmdLen = cmdLen + libSet.length; | |
if (isGccCommand) { | |
cmdLen += 2; // we need -( and -) to group libs for GCC | |
} | |
} | |
// | |
// In gcc the "cr" flag should follow space then add outputfile name, | |
// otherwise | |
// it will pop error. | |
// TBD | |
if (outputDelimiter != null && userdefine.getOutputFile() != null | |
&& outputDelimiter.trim().length() > 0) { | |
if (outputDelimiter.trim().equalsIgnoreCase("-cr")) { | |
cmdLen = cmdLen + 2; | |
} else { | |
cmdLen++; | |
} | |
} | |
// | |
// for every source file | |
// if file is header file, just skip it (add later) | |
// | |
Vector srcSets = userdefine.getSrcSets(); | |
// | |
// if have source file append source file in command line. | |
// | |
Set allSrcFiles = new LinkedHashSet(); | |
for (int i = 0; i < srcSets.size(); i++) { | |
ConditionalFileSet srcSet = (ConditionalFileSet) srcSets | |
.elementAt(i); | |
if (srcSet.isActive()) { | |
// | |
// Find matching source files | |
// | |
DirectoryScanner scanner = srcSet.getDirectoryScanner(project); | |
// | |
// Check each source file - see if it needs compilation | |
// | |
String[] fileNames = scanner.getIncludedFiles(); | |
for (int j = 0; j < fileNames.length; j++) { | |
allSrcFiles.add(scanner.getBasedir() + "/" + fileNames[j]); | |
if (isGccCommand) { | |
System.out.println("[" + userdefine.getType() + "] " | |
+ fileNames[j]); | |
} | |
} | |
} | |
} | |
String[] fileNames = (String[]) allSrcFiles | |
.toArray(new String[allSrcFiles.size()]); | |
String[] cmd = new String[cmdLen - 1 + fileNames.length]; | |
int index = 0; | |
cmd[index++] = userdefine.getCmd(); | |
Iterator iter = argsWithoutSpace.iterator(); | |
while (iter.hasNext()) { | |
cmd[index++] = project.replaceProperties((String) iter.next()); | |
} | |
iter = endargsWithoutSpace.iterator(); | |
while (iter.hasNext()) { | |
cmd[index++] = project.replaceProperties((String) iter.next()); | |
} | |
// | |
// Add outputFileFlag and output file to cmd | |
// | |
if (outputDelimiter != null && userdefine.getOutputFile() != null | |
&& outputDelimiter.length() > 0) { | |
if (outputDelimiter.trim().equalsIgnoreCase("-cr")) { | |
cmd[index++] = outputDelimiter; | |
cmd[index++] = userdefine.getOutputFile(); | |
} else { | |
cmd[index++] = outputDelimiter + userdefine.getOutputFile(); | |
} | |
} | |
iter = includePath.iterator(); | |
while (iter.hasNext()) { | |
cmd[index++] = (String) iter.next(); | |
} | |
if (libSet != null && libSet.length > 0) { | |
if (isGccCommand) { | |
cmd[index++] = "-("; | |
} | |
for (int k = 0; k < libSet.length; k++) { | |
cmd[index++] = libSet[k]; | |
} | |
if (isGccCommand) { | |
cmd[index++] = "-)"; | |
} | |
} | |
for (int j = 0; j < fileNames.length; j++) { | |
cmd[index++] = fileNames[j]; | |
} | |
// StringBuffer logLine = new StringBuffer(); | |
// for(int i = 0; i < cmd.length; i++) { | |
// logLine.append(cmd[i] + " "); | |
// } | |
// project.log(logLine.toString(), Project.MSG_VERBOSE); | |
Environment newEnv = new Environment(); | |
// | |
// Prepare for environment variable PATH | |
// | |
if (userdefine.getDpath() != null && userdefine.getDpath().trim().length() != 0) { | |
String pathName = getPathName("PATH"); | |
String existPath = System.getenv(pathName); | |
Variable var = new Variable(); | |
var.setKey(pathName); | |
var.setPath(new Path(project, userdefine.getDpath() + ";" + existPath)); | |
newEnv.addVariable(var); | |
} | |
// | |
// Prepare for environment variable LIB | |
// | |
if (userdefine.getLibpath() != null && userdefine.getLibpath().trim().length() != 0) { | |
String pathName = getPathName("LIB"); | |
String existPath = System.getenv(pathName); | |
Variable var = new Variable(); | |
var.setKey(pathName); | |
if (existPath == null) { | |
var.setPath(new Path(project, userdefine.getLibpath())); | |
} else { | |
var.setPath(new Path(project, userdefine.getLibpath() + ";" + existPath)); | |
} | |
newEnv.addVariable(var); | |
} | |
// | |
// Prepare for environment variable INCLUDE | |
// | |
if (userdefine.getInclude() != null && userdefine.getInclude().trim().length() != 0) { | |
String pathName = getPathName("INCLUDE"); | |
String existPath = System.getenv(pathName); | |
Variable var = new Variable(); | |
var.setKey(pathName); | |
if (existPath == null) { | |
var.setPath(new Path(project, userdefine.getInclude())); | |
} else { | |
var.setPath(new Path(project, userdefine.getInclude() + ";" + existPath)); | |
} | |
newEnv.addVariable(var); | |
} | |
int retval = runCommand(cctask, workdir, cmd, newEnv); | |
if (retval != 0) { | |
throw new BuildException(userdefine.getCmd() | |
+ " failed with return code " + retval, cctask | |
.getLocation()); | |
} | |
} | |
private String getPathName(String variableName) { | |
Map allEnv = System.getenv(); | |
Iterator iter = allEnv.keySet().iterator(); | |
while (iter.hasNext()) { | |
String key = (String)iter.next(); | |
if(key.equalsIgnoreCase(variableName)) { | |
return key; | |
} | |
} | |
return variableName; | |
} | |
protected int runCommand(CCTask task, File workingDir, String[] cmdline, Environment env) | |
throws BuildException { | |
// | |
// Write command to File | |
// | |
return CUtil.runCommand(task, workingDir, cmdline, false, env); | |
} | |
} |