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