]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/CUtil.java
Changed spelling to manifest
[mirror_edk2.git] / Tools / Source / Cpptasks / net / sf / antcontrib / cpptasks / CUtil.java
1 /*
2 *
3 * Copyright 2001-2004 The Ant-Contrib project
4 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
17 package net.sf.antcontrib.cpptasks;
18 import java.io.File;
19 import java.io.IOException;
20 import java.util.Enumeration;
21 import java.util.Hashtable;
22 import java.util.StringTokenizer;
23 import java.util.Vector;
24
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.Project;
27 import org.apache.tools.ant.taskdefs.Execute;
28 import org.apache.tools.ant.taskdefs.LogStreamHandler;
29 import org.apache.tools.ant.types.Commandline;
30 import org.apache.tools.ant.types.Environment;
31 /**
32 * Some utilities used by the CC and Link tasks.
33 *
34 * @author Adam Murdoch
35 */
36 public class CUtil {
37 /**
38 * A class that splits a white-space, comma-separated list into a String
39 * array. Used for task attributes.
40 */
41 public static final class StringArrayBuilder {
42 private String[] _value;
43 public StringArrayBuilder(String value) {
44 // Split the defines up
45 StringTokenizer tokens = new StringTokenizer(value, ", ");
46 Vector vallist = new Vector();
47 while (tokens.hasMoreTokens()) {
48 String val = tokens.nextToken().trim();
49 if (val.length() == 0) {
50 continue;
51 }
52 vallist.addElement(val);
53 }
54 _value = new String[vallist.size()];
55 vallist.copyInto(_value);
56 }
57 public String[] getValue() {
58 return _value;
59 }
60 }
61 /**
62 * Adds the elements of the array to the given vector
63 */
64 public static void addAll(Vector dest, Object[] src) {
65 if (src == null) {
66 return;
67 }
68 for (int i = 0; i < src.length; i++) {
69 dest.addElement(src[i]);
70 }
71 }
72 /**
73 * Checks a array of names for non existent or non directory entries and
74 * nulls them out.
75 *
76 * @return Count of non-null elements
77 */
78 public static int checkDirectoryArray(String[] names) {
79 int count = 0;
80 for (int i = 0; i < names.length; i++) {
81 if (names[i] != null) {
82 File dir = new File(names[i]);
83 if (dir.exists() && dir.isDirectory()) {
84 count++;
85 } else {
86 names[i] = null;
87 }
88 }
89 }
90 return count;
91 }
92 /**
93 * Extracts the basename of a file, removing the extension, if present
94 */
95 public static String getBasename(File file) {
96 String path = file.getPath();
97 // Remove the extension
98 String basename = file.getName();
99 int pos = basename.lastIndexOf('.');
100 if (pos != -1) {
101 basename = basename.substring(0, pos);
102 }
103 return basename;
104 }
105 /**
106 * Gets the parent directory for the executable file name using the current
107 * directory and system executable path
108 *
109 * @param exeName
110 * Name of executable such as "cl.exe"
111 * @return parent directory or null if not located
112 */
113 public static File getExecutableLocation(String exeName) {
114 //
115 // must add current working directory to the
116 // from of the path from the "path" environment variable
117 File currentDir = new File(System.getProperty("user.dir"));
118 if (new File(currentDir, exeName).exists()) {
119 return currentDir;
120 }
121 File[] envPath = CUtil.getPathFromEnvironment("PATH",
122 File.pathSeparator);
123 for (int i = 0; i < envPath.length; i++) {
124 if (new File(envPath[i], exeName).exists()) {
125 return envPath[i];
126 }
127 }
128 return null;
129 }
130 /**
131 * Extracts the parent of a file
132 */
133 public static String getParentPath(String path) {
134 int pos = path.lastIndexOf(File.separator);
135 if (pos <= 0) {
136 return null;
137 }
138 return path.substring(0, pos);
139 }
140 /**
141 * Returns an array of File for each existing directory in the specified
142 * environment variable
143 *
144 * @param envVariable
145 * environment variable name such as "LIB" or "INCLUDE"
146 * @param delim
147 * delimitor used to separate parts of the path, typically ";"
148 * or ":"
149 * @return array of File's for each part that is an existing directory
150 */
151 public static File[] getPathFromEnvironment(String envVariable, String delim) {
152 // OS/4000 does not support the env command.
153 if (System.getProperty("os.name").equals("OS/400"))
154 return new File[]{};
155 Vector osEnv = Execute.getProcEnvironment();
156 String match = envVariable.concat("=");
157 for (Enumeration e = osEnv.elements(); e.hasMoreElements();) {
158 String entry = ((String) e.nextElement()).trim();
159 if (entry.length() > match.length()) {
160 String entryFrag = entry.substring(0, match.length());
161 if (entryFrag.equalsIgnoreCase(match)) {
162 String path = entry.substring(match.length());
163 return parsePath(path, delim);
164 }
165 }
166 }
167 File[] noPath = new File[0];
168 return noPath;
169 }
170 /**
171 * Returns a relative path for the targetFile relative to the base
172 * directory.
173 *
174 * @param canonicalBase
175 * base directory as returned by File.getCanonicalPath()
176 * @param targetFile
177 * target file
178 * @return relative path of target file. Returns targetFile if there were
179 * no commonalities between the base and the target
180 *
181 * @author Curt Arnold
182 */
183 public static String getRelativePath(String base, File targetFile) {
184 try {
185 //
186 // remove trailing file separator
187 //
188 String canonicalBase = base;
189 if (base.charAt(base.length() - 1) == File.separatorChar) {
190 canonicalBase = base.substring(0, base.length() - 1);
191 }
192 //
193 // get canonical name of target and remove trailing separator
194 //
195 String canonicalTarget;
196 if (System.getProperty("os.name").equals("OS/400"))
197 canonicalTarget = targetFile.getPath();
198 else
199 canonicalTarget = targetFile.getCanonicalPath();
200 if (canonicalTarget.charAt(canonicalTarget.length() - 1) == File.separatorChar) {
201 canonicalTarget = canonicalTarget.substring(0, canonicalTarget
202 .length() - 1);
203 }
204 if (canonicalTarget.equals(canonicalBase)) {
205 return ".";
206 }
207 //
208 // see if the prefixes are the same
209 //
210 if (canonicalBase.substring(0, 2).equals("\\\\")) {
211 //
212 // UNC file name, if target file doesn't also start with same
213 // server name, don't go there
214 int endPrefix = canonicalBase.indexOf('\\', 2);
215 String prefix1 = canonicalBase.substring(0, endPrefix);
216 String prefix2 = canonicalTarget.substring(0, endPrefix);
217 if (!prefix1.equals(prefix2)) {
218 return canonicalTarget;
219 }
220 } else {
221 if (canonicalBase.substring(1, 3).equals(":\\")) {
222 int endPrefix = 2;
223 String prefix1 = canonicalBase.substring(0, endPrefix);
224 String prefix2 = canonicalTarget.substring(0, endPrefix);
225 if (!prefix1.equals(prefix2)) {
226 return canonicalTarget;
227 }
228 } else {
229 if (canonicalBase.charAt(0) == '/') {
230 if (canonicalTarget.charAt(0) != '/') {
231 return canonicalTarget;
232 }
233 }
234 }
235 }
236 char separator = File.separatorChar;
237 int lastSeparator = -1;
238 int minLength = canonicalBase.length();
239 if (canonicalTarget.length() < minLength) {
240 minLength = canonicalTarget.length();
241 }
242 int firstDifference = minLength + 1;
243 //
244 // walk to the shorter of the two paths
245 // finding the last separator they have in common
246 for (int i = 0; i < minLength; i++) {
247 if (canonicalTarget.charAt(i) == canonicalBase.charAt(i)) {
248 if (canonicalTarget.charAt(i) == separator) {
249 lastSeparator = i;
250 }
251 } else {
252 firstDifference = lastSeparator + 1;
253 break;
254 }
255 }
256 StringBuffer relativePath = new StringBuffer(50);
257 //
258 // walk from the first difference to the end of the base
259 // adding "../" for each separator encountered
260 //
261 if (canonicalBase.length() > firstDifference) {
262 relativePath.append("..");
263 for (int i = firstDifference; i < canonicalBase.length(); i++) {
264 if (canonicalBase.charAt(i) == separator) {
265 relativePath.append(separator);
266 relativePath.append("..");
267 }
268 }
269 }
270 if (canonicalTarget.length() > firstDifference) {
271 //
272 // append the rest of the target
273 //
274 //
275 if (relativePath.length() > 0) {
276 relativePath.append(separator);
277 }
278 relativePath.append(canonicalTarget.substring(firstDifference));
279 }
280 return relativePath.toString();
281 } catch (IOException ex) {
282 }
283 return targetFile.toString();
284 }
285 public static boolean isActive(Project p, String ifCond, String unlessCond)
286 throws BuildException {
287 if (ifCond != null) {
288 String ifValue = p.getProperty(ifCond);
289 if (ifValue == null) {
290 return false;
291 } else {
292 if (ifValue.equals("false") || ifValue.equals("no")) {
293 throw new BuildException("if condition \"" + ifCond
294 + "\" has suspicious value \"" + ifValue);
295 }
296 }
297 }
298 if (unlessCond != null) {
299 String unlessValue = p.getProperty(unlessCond);
300 if (unlessValue != null) {
301 if (unlessValue.equals("false") || unlessValue.equals("no")) {
302 throw new BuildException("unless condition \"" + unlessCond
303 + "\" has suspicious value \"" + unlessValue);
304 }
305 return false;
306 }
307 }
308 return true;
309 }
310 /**
311 * Parse a string containing directories into an File[]
312 *
313 * @param path
314 * path string, for example ".;c:\something\include"
315 * @param delim
316 * delimiter, typically ; or :
317 */
318 public static File[] parsePath(String path, String delim) {
319 Vector libpaths = new Vector();
320 int delimPos = 0;
321 for (int startPos = 0; startPos < path.length(); startPos = delimPos
322 + delim.length()) {
323 delimPos = path.indexOf(delim, startPos);
324 if (delimPos < 0) {
325 delimPos = path.length();
326 }
327 //
328 // don't add an entry for zero-length paths
329 //
330 if (delimPos > startPos) {
331 String dirName = path.substring(startPos, delimPos);
332 File dir = new File(dirName);
333 if (dir.exists() && dir.isDirectory()) {
334 libpaths.addElement(dir);
335 }
336 }
337 }
338 File[] paths = new File[libpaths.size()];
339 libpaths.copyInto(paths);
340 return paths;
341 }
342 /**
343 * This method is exposed so test classes can overload and test the
344 * arguments without actually spawning the compiler
345 */
346 public static int runCommand(CCTask task, File workingDir,
347 String[] cmdline, boolean newEnvironment, Environment env)
348 throws BuildException {
349 try {
350 task.log(Commandline.toString(cmdline), Project.MSG_VERBOSE);
351 Execute exe = new Execute(new LogStreamHandler(task,
352 Project.MSG_INFO, Project.MSG_ERR));
353 if (System.getProperty("os.name").equals("OS/390"))
354 exe.setVMLauncher(false);
355 exe.setAntRun(task.getProject());
356 exe.setCommandline(cmdline);
357 exe.setWorkingDirectory(workingDir);
358 if (env != null) {
359 String[] environment = env.getVariables();
360 if (environment != null) {
361 for (int i = 0; i < environment.length; i++) {
362 task.log("Setting environment variable: "
363 + environment[i], Project.MSG_VERBOSE);
364 }
365 }
366 exe.setEnvironment(environment);
367 }
368 exe.setNewenvironment(newEnvironment);
369 return exe.execute();
370 } catch (java.io.IOException exc) {
371 throw new BuildException("Could not launch " + cmdline[0] + ": "
372 + exc, task.getLocation());
373 }
374 }
375 /**
376 * Compares the contents of 2 arrays for equaliy.
377 */
378 public static boolean sameList(Object[] a, Object[] b) {
379 if (a == null || b == null || a.length != b.length) {
380 return false;
381 }
382 for (int i = 0; i < a.length; i++) {
383 if (!a[i].equals(b[i])) {
384 return false;
385 }
386 }
387 return true;
388 }
389 /**
390 * Compares the contents of an array and a Vector for equality.
391 */
392 public static boolean sameList(Vector v, Object[] a) {
393 if (v == null || a == null || v.size() != a.length) {
394 return false;
395 }
396 for (int i = 0; i < a.length; i++) {
397 Object o = a[i];
398 if (!o.equals(v.elementAt(i))) {
399 return false;
400 }
401 }
402 return true;
403 }
404 /**
405 * Compares the contents of an array and a Vector for set equality. Assumes
406 * input array and vector are sets (i.e. no duplicate entries)
407 */
408 public static boolean sameSet(Object[] a, Vector b) {
409 if (a == null || b == null || a.length != b.size()) {
410 return false;
411 }
412 if (a.length == 0) {
413 return true;
414 }
415 // Convert the array into a set
416 Hashtable t = new Hashtable();
417 for (int i = 0; i < a.length; i++) {
418 t.put(a[i], a[i]);
419 }
420 for (int i = 0; i < b.size(); i++) {
421 Object o = b.elementAt(i);
422 if (t.remove(o) == null) {
423 return false;
424 }
425 }
426 return (t.size() == 0);
427 }
428 /**
429 * Converts a vector to a string array.
430 */
431 public static String[] toArray(Vector src) {
432 String[] retval = new String[src.size()];
433 src.copyInto(retval);
434 return retval;
435 }
436 /**
437 * Replaces any embedded quotes in the string so that the value can be
438 * placed in an attribute in an XML file
439 *
440 * @param attrValue
441 * value to be expressed
442 * @return equivalent attribute literal
443 *
444 */
445 public static String xmlAttribEncode(String attrValue) {
446 int quotePos = attrValue.indexOf('\"');
447 if (quotePos < 0) {
448 return attrValue;
449 }
450 int startPos = 0;
451 StringBuffer buf = new StringBuffer(attrValue.length() + 20);
452 while (quotePos >= 0) {
453 buf.append(attrValue.substring(startPos, quotePos));
454 buf.append("&quot;");
455 startPos = quotePos + 1;
456 quotePos = attrValue.indexOf('\"', startPos);
457 }
458 buf.append(attrValue.substring(startPos));
459 return buf.toString();
460 }
461 }