]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java
Changed spelling to manifest
[mirror_edk2.git] / Tools / Source / Cpptasks / net / sf / antcontrib / cpptasks / gcc / GccProcessor.java
1 /*
2 *
3 * Copyright 2002-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.gcc;
18 import java.io.BufferedReader;
19 import java.io.File;
20 import java.io.FileReader;
21 import java.io.IOException;
22 import java.util.Vector;
23
24 import net.sf.antcontrib.cpptasks.CUtil;
25 import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
26 /**
27 * A add-in class for Gcc processors
28 *
29 *
30 */
31 public class GccProcessor {
32 // the results from gcc -dumpmachine
33 private static String machine;
34 private static String[] specs;
35 // the results from gcc -dumpversion
36 private static String version;
37 private static int addLibraryPatterns(String[] libnames, StringBuffer buf,
38 String prefix, String extension, String[] patterns, int offset) {
39 for (int i = 0; i < libnames.length; i++) {
40 buf.setLength(0);
41 buf.append(prefix);
42 buf.append(libnames[i]);
43 buf.append(extension);
44 patterns[offset + i] = buf.toString();
45 }
46 return offset + libnames.length;
47 }
48 /**
49 * Converts absolute Cygwin file or directory names to the corresponding
50 * Win32 name.
51 *
52 * @param names
53 * array of names, some elements may be null, will be changed in
54 * place.
55 */
56 public static void convertCygwinFilenames(String[] names) {
57 if (names == null) {
58 throw new NullPointerException("names");
59 }
60 File gccDir = CUtil.getExecutableLocation("gcc.exe");
61 if (gccDir != null) {
62 String prefix = gccDir.getAbsolutePath() + "/..";
63 StringBuffer buf = new StringBuffer();
64 for (int i = 0; i < names.length; i++) {
65 String name = names[i];
66 if (name != null && name.length() > 1 && name.charAt(0) == '/') {
67 buf.setLength(0);
68 buf.append(prefix);
69 buf.append(name);
70 names[i] = buf.toString();
71 }
72 }
73 }
74 }
75 public static String[] getLibraryPatterns(String[] libnames) {
76 StringBuffer buf = new StringBuffer();
77 String[] patterns = new String[libnames.length * 2];
78 int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);
79 if (isHPUX()) {
80 offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,
81 offset);
82 } else {
83 offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,
84 offset);
85 }
86 return patterns;
87 }
88 public static String getMachine() {
89 if (machine == null) {
90 String[] args = new String[]{"gcc", "-dumpmachine"};
91 String[] cmdout = CaptureStreamHandler.run(args);
92 if (cmdout.length == 0) {
93 machine = "nomachine";
94 } else {
95 machine = cmdout[0];
96 }
97 }
98 return machine;
99 }
100 public static String[] getOutputFileSwitch(String letter, String outputFile) {
101 StringBuffer buf = new StringBuffer();
102 if (outputFile.indexOf(' ') >= 0) {
103 buf.append('"');
104 buf.append(outputFile.replace('\\', '/'));
105 buf.append('"');
106 } else {
107 buf.append(outputFile.replace('\\', '/'));
108 }
109 String[] retval = new String[]{letter, buf.toString()};
110 return retval;
111 }
112 /**
113 * Returns the contents of the gcc specs file.
114 *
115 * The implementation locates gcc.exe in the executable path and then
116 * builds a relative path name from the results of -dumpmachine and
117 * -dumpversion. Attempts to use gcc -dumpspecs to provide this information
118 * resulted in stalling on the Execute.run
119 *
120 * @returns contents of the specs file
121 */
122 public static String[] getSpecs() {
123 if (specs == null) {
124 File gccParent = CUtil.getExecutableLocation("gcc.exe");
125 if (gccParent != null) {
126 //
127 // build a relative path like
128 // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs
129 //
130 StringBuffer buf = new StringBuffer("../lib/gcc-lib/");
131 buf.append(getMachine());
132 buf.append('/');
133 buf.append(getVersion());
134 buf.append("/specs");
135 //
136 // resolve it relative to the location of gcc.exe
137 //
138 String relativePath = buf.toString();
139 File specsFile = new File(gccParent, relativePath);
140 //
141 // found the specs file
142 //
143 try {
144 //
145 // read the lines in the file
146 //
147 BufferedReader reader = new BufferedReader(new FileReader(
148 specsFile));
149 Vector lines = new Vector(100);
150 String line = reader.readLine();
151 while (line != null) {
152 lines.addElement(line);
153 line = reader.readLine();
154 }
155 specs = new String[lines.size()];
156 lines.copyInto(specs);
157 } catch (IOException ex) {
158 }
159 }
160 }
161 if (specs == null) {
162 specs = new String[0];
163 }
164 return specs;
165 }
166 public static String getVersion() {
167 if (version == null) {
168 String[] args = new String[]{"gcc", "-dumpversion"};
169 String[] cmdout = CaptureStreamHandler.run(args);
170 if (cmdout.length == 0) {
171 version = "noversion";
172 } else {
173 version = cmdout[0];
174 }
175 }
176 return version;
177 }
178 public static boolean isCaseSensitive() {
179 return true;
180 }
181 /**
182 * Determines if task is running with cygwin
183 *
184 * @return true if cygwin was detected
185 */
186 public static boolean isCygwin() {
187 return getMachine().indexOf("cygwin") > 0;
188 }
189 private static boolean isHPUX() {
190 String osname = System.getProperty("os.name").toLowerCase();
191 if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {
192 return true;
193 }
194 return false;
195 }
196 /**
197 *
198 * Parses the results of the specs file for a specific processor and
199 * options
200 *
201 * @param specsContent
202 * Contents of specs file as returned from getSpecs
203 * @param specSectionStart
204 * start of spec section, for example "*cpp:"
205 * @param options
206 * command line switches such as "-istart"
207 */
208 public static String[][] parseSpecs(String[] specsContent,
209 String specSectionStart, String[] options) {
210 if (specsContent == null) {
211 throw new NullPointerException("specsContent");
212 }
213 if (specSectionStart == null) {
214 throw new NullPointerException("specSectionStart");
215 }
216 if (options == null) {
217 throw new NullPointerException("option");
218 }
219 String[][] optionValues = new String[options.length][];
220 StringBuffer optionValue = new StringBuffer(40);
221 for (int i = 0; i < specsContent.length; i++) {
222 String specLine = specsContent[i];
223 //
224 // if start of section then start paying attention
225 //
226 if (specLine.startsWith(specSectionStart)) {
227 Vector[] optionVectors = new Vector[options.length];
228 for (int j = 0; j < options.length; j++) {
229 optionVectors[j] = new Vector(10);
230 }
231 //
232 // go to next line and examine contents
233 // and repeat until end of file
234 //
235 for (i++; i < specsContent.length; i++) {
236 specLine = specsContent[i];
237 for (int j = 0; j < options.length; j++) {
238 int optionStart = specLine.indexOf(options[j]);
239 while (optionStart >= 0) {
240 optionValue.setLength(0);
241 //
242 // walk rest of line looking for first non
243 // whitespace
244 // and then next space
245 boolean hasNonBlank = false;
246 int k = optionStart + options[j].length();
247 for (; k < specLine.length(); k++) {
248 //
249 // either a blank or a "}" (close of
250 // conditional)
251 // section will end the path
252 //
253 if (specLine.charAt(k) == ' '
254 || specLine.charAt(k) == '}') {
255 if (hasNonBlank) {
256 break;
257 }
258 } else {
259 hasNonBlank = true;
260 optionValue.append(specLine.charAt(k));
261 }
262 }
263 //
264 // transition back to whitespace
265 // value is over, add it to vector
266 if (hasNonBlank) {
267 optionVectors[j].addElement(optionValue
268 .toString());
269 }
270 //
271 // find next occurance on line
272 //
273 optionStart = specLine.indexOf(options[j], k);
274 }
275 }
276 }
277 //
278 // copy vectors over to option arrays
279 //
280 for (int j = 0; j < options.length; j++) {
281 optionValues[j] = new String[optionVectors[j].size()];
282 optionVectors[j].copyInto(optionValues[j]);
283 }
284 }
285 }
286 //
287 // fill in any missing option values with
288 // a zero-length string array
289 for (int i = 0; i < optionValues.length; i++) {
290 String[] zeroLenArray = new String[0];
291 if (optionValues[i] == null) {
292 optionValues[i] = zeroLenArray;
293 }
294 }
295 return optionValues;
296 }
297 private GccProcessor() {
298 }
299 }