mirror of https://github.com/acidanthera/audk.git
462 lines
17 KiB
Java
462 lines
17 KiB
Java
|
/*
|
||
|
*
|
||
|
* 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;
|
||
|
import java.io.File;
|
||
|
import java.io.IOException;
|
||
|
import java.util.Enumeration;
|
||
|
import java.util.Hashtable;
|
||
|
import java.util.StringTokenizer;
|
||
|
import java.util.Vector;
|
||
|
|
||
|
import org.apache.tools.ant.BuildException;
|
||
|
import org.apache.tools.ant.Project;
|
||
|
import org.apache.tools.ant.taskdefs.Execute;
|
||
|
import org.apache.tools.ant.taskdefs.LogStreamHandler;
|
||
|
import org.apache.tools.ant.types.Commandline;
|
||
|
import org.apache.tools.ant.types.Environment;
|
||
|
/**
|
||
|
* Some utilities used by the CC and Link tasks.
|
||
|
*
|
||
|
* @author Adam Murdoch
|
||
|
*/
|
||
|
public class CUtil {
|
||
|
/**
|
||
|
* A class that splits a white-space, comma-separated list into a String
|
||
|
* array. Used for task attributes.
|
||
|
*/
|
||
|
public static final class StringArrayBuilder {
|
||
|
private String[] _value;
|
||
|
public StringArrayBuilder(String value) {
|
||
|
// Split the defines up
|
||
|
StringTokenizer tokens = new StringTokenizer(value, ", ");
|
||
|
Vector vallist = new Vector();
|
||
|
while (tokens.hasMoreTokens()) {
|
||
|
String val = tokens.nextToken().trim();
|
||
|
if (val.length() == 0) {
|
||
|
continue;
|
||
|
}
|
||
|
vallist.addElement(val);
|
||
|
}
|
||
|
_value = new String[vallist.size()];
|
||
|
vallist.copyInto(_value);
|
||
|
}
|
||
|
public String[] getValue() {
|
||
|
return _value;
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Adds the elements of the array to the given vector
|
||
|
*/
|
||
|
public static void addAll(Vector dest, Object[] src) {
|
||
|
if (src == null) {
|
||
|
return;
|
||
|
}
|
||
|
for (int i = 0; i < src.length; i++) {
|
||
|
dest.addElement(src[i]);
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Checks a array of names for non existent or non directory entries and
|
||
|
* nulls them out.
|
||
|
*
|
||
|
* @return Count of non-null elements
|
||
|
*/
|
||
|
public static int checkDirectoryArray(String[] names) {
|
||
|
int count = 0;
|
||
|
for (int i = 0; i < names.length; i++) {
|
||
|
if (names[i] != null) {
|
||
|
File dir = new File(names[i]);
|
||
|
if (dir.exists() && dir.isDirectory()) {
|
||
|
count++;
|
||
|
} else {
|
||
|
names[i] = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
/**
|
||
|
* Extracts the basename of a file, removing the extension, if present
|
||
|
*/
|
||
|
public static String getBasename(File file) {
|
||
|
String path = file.getPath();
|
||
|
// Remove the extension
|
||
|
String basename = file.getName();
|
||
|
int pos = basename.lastIndexOf('.');
|
||
|
if (pos != -1) {
|
||
|
basename = basename.substring(0, pos);
|
||
|
}
|
||
|
return basename;
|
||
|
}
|
||
|
/**
|
||
|
* Gets the parent directory for the executable file name using the current
|
||
|
* directory and system executable path
|
||
|
*
|
||
|
* @param exeName
|
||
|
* Name of executable such as "cl.exe"
|
||
|
* @return parent directory or null if not located
|
||
|
*/
|
||
|
public static File getExecutableLocation(String exeName) {
|
||
|
//
|
||
|
// must add current working directory to the
|
||
|
// from of the path from the "path" environment variable
|
||
|
File currentDir = new File(System.getProperty("user.dir"));
|
||
|
if (new File(currentDir, exeName).exists()) {
|
||
|
return currentDir;
|
||
|
}
|
||
|
File[] envPath = CUtil.getPathFromEnvironment("PATH",
|
||
|
File.pathSeparator);
|
||
|
for (int i = 0; i < envPath.length; i++) {
|
||
|
if (new File(envPath[i], exeName).exists()) {
|
||
|
return envPath[i];
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
/**
|
||
|
* Extracts the parent of a file
|
||
|
*/
|
||
|
public static String getParentPath(String path) {
|
||
|
int pos = path.lastIndexOf(File.separator);
|
||
|
if (pos <= 0) {
|
||
|
return null;
|
||
|
}
|
||
|
return path.substring(0, pos);
|
||
|
}
|
||
|
/**
|
||
|
* Returns an array of File for each existing directory in the specified
|
||
|
* environment variable
|
||
|
*
|
||
|
* @param envVariable
|
||
|
* environment variable name such as "LIB" or "INCLUDE"
|
||
|
* @param delim
|
||
|
* delimitor used to separate parts of the path, typically ";"
|
||
|
* or ":"
|
||
|
* @return array of File's for each part that is an existing directory
|
||
|
*/
|
||
|
public static File[] getPathFromEnvironment(String envVariable, String delim) {
|
||
|
// OS/4000 does not support the env command.
|
||
|
if (System.getProperty("os.name").equals("OS/400"))
|
||
|
return new File[]{};
|
||
|
Vector osEnv = Execute.getProcEnvironment();
|
||
|
String match = envVariable.concat("=");
|
||
|
for (Enumeration e = osEnv.elements(); e.hasMoreElements();) {
|
||
|
String entry = ((String) e.nextElement()).trim();
|
||
|
if (entry.length() > match.length()) {
|
||
|
String entryFrag = entry.substring(0, match.length());
|
||
|
if (entryFrag.equalsIgnoreCase(match)) {
|
||
|
String path = entry.substring(match.length());
|
||
|
return parsePath(path, delim);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
File[] noPath = new File[0];
|
||
|
return noPath;
|
||
|
}
|
||
|
/**
|
||
|
* Returns a relative path for the targetFile relative to the base
|
||
|
* directory.
|
||
|
*
|
||
|
* @param canonicalBase
|
||
|
* base directory as returned by File.getCanonicalPath()
|
||
|
* @param targetFile
|
||
|
* target file
|
||
|
* @return relative path of target file. Returns targetFile if there were
|
||
|
* no commonalities between the base and the target
|
||
|
*
|
||
|
* @author Curt Arnold
|
||
|
*/
|
||
|
public static String getRelativePath(String base, File targetFile) {
|
||
|
try {
|
||
|
//
|
||
|
// remove trailing file separator
|
||
|
//
|
||
|
String canonicalBase = base;
|
||
|
if (base.charAt(base.length() - 1) == File.separatorChar) {
|
||
|
canonicalBase = base.substring(0, base.length() - 1);
|
||
|
}
|
||
|
//
|
||
|
// get canonical name of target and remove trailing separator
|
||
|
//
|
||
|
String canonicalTarget;
|
||
|
if (System.getProperty("os.name").equals("OS/400"))
|
||
|
canonicalTarget = targetFile.getPath();
|
||
|
else
|
||
|
canonicalTarget = targetFile.getCanonicalPath();
|
||
|
if (canonicalTarget.charAt(canonicalTarget.length() - 1) == File.separatorChar) {
|
||
|
canonicalTarget = canonicalTarget.substring(0, canonicalTarget
|
||
|
.length() - 1);
|
||
|
}
|
||
|
if (canonicalTarget.equals(canonicalBase)) {
|
||
|
return ".";
|
||
|
}
|
||
|
//
|
||
|
// see if the prefixes are the same
|
||
|
//
|
||
|
if (canonicalBase.substring(0, 2).equals("\\\\")) {
|
||
|
//
|
||
|
// UNC file name, if target file doesn't also start with same
|
||
|
// server name, don't go there
|
||
|
int endPrefix = canonicalBase.indexOf('\\', 2);
|
||
|
String prefix1 = canonicalBase.substring(0, endPrefix);
|
||
|
String prefix2 = canonicalTarget.substring(0, endPrefix);
|
||
|
if (!prefix1.equals(prefix2)) {
|
||
|
return canonicalTarget;
|
||
|
}
|
||
|
} else {
|
||
|
if (canonicalBase.substring(1, 3).equals(":\\")) {
|
||
|
int endPrefix = 2;
|
||
|
String prefix1 = canonicalBase.substring(0, endPrefix);
|
||
|
String prefix2 = canonicalTarget.substring(0, endPrefix);
|
||
|
if (!prefix1.equals(prefix2)) {
|
||
|
return canonicalTarget;
|
||
|
}
|
||
|
} else {
|
||
|
if (canonicalBase.charAt(0) == '/') {
|
||
|
if (canonicalTarget.charAt(0) != '/') {
|
||
|
return canonicalTarget;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
char separator = File.separatorChar;
|
||
|
int lastSeparator = -1;
|
||
|
int minLength = canonicalBase.length();
|
||
|
if (canonicalTarget.length() < minLength) {
|
||
|
minLength = canonicalTarget.length();
|
||
|
}
|
||
|
int firstDifference = minLength + 1;
|
||
|
//
|
||
|
// walk to the shorter of the two paths
|
||
|
// finding the last separator they have in common
|
||
|
for (int i = 0; i < minLength; i++) {
|
||
|
if (canonicalTarget.charAt(i) == canonicalBase.charAt(i)) {
|
||
|
if (canonicalTarget.charAt(i) == separator) {
|
||
|
lastSeparator = i;
|
||
|
}
|
||
|
} else {
|
||
|
firstDifference = lastSeparator + 1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
StringBuffer relativePath = new StringBuffer(50);
|
||
|
//
|
||
|
// walk from the first difference to the end of the base
|
||
|
// adding "../" for each separator encountered
|
||
|
//
|
||
|
if (canonicalBase.length() > firstDifference) {
|
||
|
relativePath.append("..");
|
||
|
for (int i = firstDifference; i < canonicalBase.length(); i++) {
|
||
|
if (canonicalBase.charAt(i) == separator) {
|
||
|
relativePath.append(separator);
|
||
|
relativePath.append("..");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (canonicalTarget.length() > firstDifference) {
|
||
|
//
|
||
|
// append the rest of the target
|
||
|
//
|
||
|
//
|
||
|
if (relativePath.length() > 0) {
|
||
|
relativePath.append(separator);
|
||
|
}
|
||
|
relativePath.append(canonicalTarget.substring(firstDifference));
|
||
|
}
|
||
|
return relativePath.toString();
|
||
|
} catch (IOException ex) {
|
||
|
}
|
||
|
return targetFile.toString();
|
||
|
}
|
||
|
public static boolean isActive(Project p, String ifCond, String unlessCond)
|
||
|
throws BuildException {
|
||
|
if (ifCond != null) {
|
||
|
String ifValue = p.getProperty(ifCond);
|
||
|
if (ifValue == null) {
|
||
|
return false;
|
||
|
} else {
|
||
|
if (ifValue.equals("false") || ifValue.equals("no")) {
|
||
|
throw new BuildException("if condition \"" + ifCond
|
||
|
+ "\" has suspicious value \"" + ifValue);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (unlessCond != null) {
|
||
|
String unlessValue = p.getProperty(unlessCond);
|
||
|
if (unlessValue != null) {
|
||
|
if (unlessValue.equals("false") || unlessValue.equals("no")) {
|
||
|
throw new BuildException("unless condition \"" + unlessCond
|
||
|
+ "\" has suspicious value \"" + unlessValue);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
/**
|
||
|
* Parse a string containing directories into an File[]
|
||
|
*
|
||
|
* @param path
|
||
|
* path string, for example ".;c:\something\include"
|
||
|
* @param delim
|
||
|
* delimiter, typically ; or :
|
||
|
*/
|
||
|
public static File[] parsePath(String path, String delim) {
|
||
|
Vector libpaths = new Vector();
|
||
|
int delimPos = 0;
|
||
|
for (int startPos = 0; startPos < path.length(); startPos = delimPos
|
||
|
+ delim.length()) {
|
||
|
delimPos = path.indexOf(delim, startPos);
|
||
|
if (delimPos < 0) {
|
||
|
delimPos = path.length();
|
||
|
}
|
||
|
//
|
||
|
// don't add an entry for zero-length paths
|
||
|
//
|
||
|
if (delimPos > startPos) {
|
||
|
String dirName = path.substring(startPos, delimPos);
|
||
|
File dir = new File(dirName);
|
||
|
if (dir.exists() && dir.isDirectory()) {
|
||
|
libpaths.addElement(dir);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
File[] paths = new File[libpaths.size()];
|
||
|
libpaths.copyInto(paths);
|
||
|
return paths;
|
||
|
}
|
||
|
/**
|
||
|
* This method is exposed so test classes can overload and test the
|
||
|
* arguments without actually spawning the compiler
|
||
|
*/
|
||
|
public static int runCommand(CCTask task, File workingDir,
|
||
|
String[] cmdline, boolean newEnvironment, Environment env)
|
||
|
throws BuildException {
|
||
|
try {
|
||
|
task.log(Commandline.toString(cmdline), Project.MSG_VERBOSE);
|
||
|
Execute exe = new Execute(new LogStreamHandler(task,
|
||
|
Project.MSG_INFO, Project.MSG_ERR));
|
||
|
if (System.getProperty("os.name").equals("OS/390"))
|
||
|
exe.setVMLauncher(false);
|
||
|
exe.setAntRun(task.getProject());
|
||
|
exe.setCommandline(cmdline);
|
||
|
exe.setWorkingDirectory(workingDir);
|
||
|
if (env != null) {
|
||
|
String[] environment = env.getVariables();
|
||
|
if (environment != null) {
|
||
|
for (int i = 0; i < environment.length; i++) {
|
||
|
task.log("Setting environment variable: "
|
||
|
+ environment[i], Project.MSG_VERBOSE);
|
||
|
}
|
||
|
}
|
||
|
exe.setEnvironment(environment);
|
||
|
}
|
||
|
exe.setNewenvironment(newEnvironment);
|
||
|
return exe.execute();
|
||
|
} catch (java.io.IOException exc) {
|
||
|
throw new BuildException("Could not launch " + cmdline[0] + ": "
|
||
|
+ exc, task.getLocation());
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Compares the contents of 2 arrays for equaliy.
|
||
|
*/
|
||
|
public static boolean sameList(Object[] a, Object[] b) {
|
||
|
if (a == null || b == null || a.length != b.length) {
|
||
|
return false;
|
||
|
}
|
||
|
for (int i = 0; i < a.length; i++) {
|
||
|
if (!a[i].equals(b[i])) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
/**
|
||
|
* Compares the contents of an array and a Vector for equality.
|
||
|
*/
|
||
|
public static boolean sameList(Vector v, Object[] a) {
|
||
|
if (v == null || a == null || v.size() != a.length) {
|
||
|
return false;
|
||
|
}
|
||
|
for (int i = 0; i < a.length; i++) {
|
||
|
Object o = a[i];
|
||
|
if (!o.equals(v.elementAt(i))) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
/**
|
||
|
* Compares the contents of an array and a Vector for set equality. Assumes
|
||
|
* input array and vector are sets (i.e. no duplicate entries)
|
||
|
*/
|
||
|
public static boolean sameSet(Object[] a, Vector b) {
|
||
|
if (a == null || b == null || a.length != b.size()) {
|
||
|
return false;
|
||
|
}
|
||
|
if (a.length == 0) {
|
||
|
return true;
|
||
|
}
|
||
|
// Convert the array into a set
|
||
|
Hashtable t = new Hashtable();
|
||
|
for (int i = 0; i < a.length; i++) {
|
||
|
t.put(a[i], a[i]);
|
||
|
}
|
||
|
for (int i = 0; i < b.size(); i++) {
|
||
|
Object o = b.elementAt(i);
|
||
|
if (t.remove(o) == null) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return (t.size() == 0);
|
||
|
}
|
||
|
/**
|
||
|
* Converts a vector to a string array.
|
||
|
*/
|
||
|
public static String[] toArray(Vector src) {
|
||
|
String[] retval = new String[src.size()];
|
||
|
src.copyInto(retval);
|
||
|
return retval;
|
||
|
}
|
||
|
/**
|
||
|
* Replaces any embedded quotes in the string so that the value can be
|
||
|
* placed in an attribute in an XML file
|
||
|
*
|
||
|
* @param attrValue
|
||
|
* value to be expressed
|
||
|
* @return equivalent attribute literal
|
||
|
*
|
||
|
*/
|
||
|
public static String xmlAttribEncode(String attrValue) {
|
||
|
int quotePos = attrValue.indexOf('\"');
|
||
|
if (quotePos < 0) {
|
||
|
return attrValue;
|
||
|
}
|
||
|
int startPos = 0;
|
||
|
StringBuffer buf = new StringBuffer(attrValue.length() + 20);
|
||
|
while (quotePos >= 0) {
|
||
|
buf.append(attrValue.substring(startPos, quotePos));
|
||
|
buf.append(""");
|
||
|
startPos = quotePos + 1;
|
||
|
quotePos = attrValue.indexOf('\"', startPos);
|
||
|
}
|
||
|
buf.append(attrValue.substring(startPos));
|
||
|
return buf.toString();
|
||
|
}
|
||
|
}
|