diff options
Diffstat (limited to 'src/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java')
-rw-r--r-- | src/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/src/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java b/src/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java new file mode 100644 index 0000000..058ef12 --- /dev/null +++ b/src/net/sf/antcontrib/cpptasks/gcc/GccProcessor.java @@ -0,0 +1,299 @@ +/* + * + * Copyright 2002-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.gcc; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler; +/** + * A add-in class for Gcc processors + * + * + */ +public class GccProcessor { + // the results from gcc -dumpmachine + private static String machine; + private static String[] specs; + // the results from gcc -dumpversion + private static String version; + private static int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + /** + * Converts absolute Cygwin file or directory names to the corresponding + * Win32 name. + * + * @param names + * array of names, some elements may be null, will be changed in + * place. + */ + public static void convertCygwinFilenames(String[] names) { + if (names == null) { + throw new NullPointerException("names"); + } + File gccDir = CUtil.getExecutableLocation("gcc.exe"); + if (gccDir != null) { + String prefix = gccDir.getAbsolutePath() + "/.."; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + if (name != null && name.length() > 1 && name.charAt(0) == '/') { + buf.setLength(0); + buf.append(prefix); + buf.append(name); + names[i] = buf.toString(); + } + } + } + } + public static String[] getLibraryPatterns(String[] libnames) { + StringBuffer buf = new StringBuffer(); + String[] patterns = new String[libnames.length * 2]; + int offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + if (isHPUX()) { + offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns, + offset); + } else { + offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns, + offset); + } + return patterns; + } + public static String getMachine() { + if (machine == null) { + String[] args = new String[]{"gcc", "-dumpmachine"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + machine = "nomachine"; + } else { + machine = cmdout[0]; + } + } + return machine; + } + public static String[] getOutputFileSwitch(String letter, String outputFile) { + StringBuffer buf = new StringBuffer(); + if (outputFile.indexOf(' ') >= 0) { + buf.append('"'); + buf.append(outputFile.replace('\\', '/')); + buf.append('"'); + } else { + buf.append(outputFile.replace('\\', '/')); + } + String[] retval = new String[]{letter, buf.toString()}; + return retval; + } + /** + * Returns the contents of the gcc specs file. + * + * The implementation locates gcc.exe in the executable path and then + * builds a relative path name from the results of -dumpmachine and + * -dumpversion. Attempts to use gcc -dumpspecs to provide this information + * resulted in stalling on the Execute.run + * + * @returns contents of the specs file + */ + public static String[] getSpecs() { + if (specs == null) { + File gccParent = CUtil.getExecutableLocation("gcc.exe"); + if (gccParent != null) { + // + // build a relative path like + // ../lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs + // + StringBuffer buf = new StringBuffer("../lib/gcc-lib/"); + buf.append(getMachine()); + buf.append('/'); + buf.append(getVersion()); + buf.append("/specs"); + // + // resolve it relative to the location of gcc.exe + // + String relativePath = buf.toString(); + File specsFile = new File(gccParent, relativePath); + // + // found the specs file + // + try { + // + // read the lines in the file + // + BufferedReader reader = new BufferedReader(new FileReader( + specsFile)); + Vector lines = new Vector(100); + String line = reader.readLine(); + while (line != null) { + lines.addElement(line); + line = reader.readLine(); + } + specs = new String[lines.size()]; + lines.copyInto(specs); + } catch (IOException ex) { + } + } + } + if (specs == null) { + specs = new String[0]; + } + return specs; + } + public static String getVersion() { + if (version == null) { + String[] args = new String[]{"gcc", "-dumpversion"}; + String[] cmdout = CaptureStreamHandler.run(args); + if (cmdout.length == 0) { + version = "noversion"; + } else { + version = cmdout[0]; + } + } + return version; + } + public static boolean isCaseSensitive() { + return true; + } + /** + * Determines if task is running with cygwin + * + * @return true if cygwin was detected + */ + public static boolean isCygwin() { + return getMachine().indexOf("cygwin") > 0; + } + private static boolean isHPUX() { + String osname = System.getProperty("os.name").toLowerCase(); + if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) { + return true; + } + return false; + } + /** + * + * Parses the results of the specs file for a specific processor and + * options + * + * @param specsContent + * Contents of specs file as returned from getSpecs + * @param specSectionStart + * start of spec section, for example "*cpp:" + * @param options + * command line switches such as "-istart" + */ + public static String[][] parseSpecs(String[] specsContent, + String specSectionStart, String[] options) { + if (specsContent == null) { + throw new NullPointerException("specsContent"); + } + if (specSectionStart == null) { + throw new NullPointerException("specSectionStart"); + } + if (options == null) { + throw new NullPointerException("option"); + } + String[][] optionValues = new String[options.length][]; + StringBuffer optionValue = new StringBuffer(40); + for (int i = 0; i < specsContent.length; i++) { + String specLine = specsContent[i]; + // + // if start of section then start paying attention + // + if (specLine.startsWith(specSectionStart)) { + Vector[] optionVectors = new Vector[options.length]; + for (int j = 0; j < options.length; j++) { + optionVectors[j] = new Vector(10); + } + // + // go to next line and examine contents + // and repeat until end of file + // + for (i++; i < specsContent.length; i++) { + specLine = specsContent[i]; + for (int j = 0; j < options.length; j++) { + int optionStart = specLine.indexOf(options[j]); + while (optionStart >= 0) { + optionValue.setLength(0); + // + // walk rest of line looking for first non + // whitespace + // and then next space + boolean hasNonBlank = false; + int k = optionStart + options[j].length(); + for (; k < specLine.length(); k++) { + // + // either a blank or a "}" (close of + // conditional) + // section will end the path + // + if (specLine.charAt(k) == ' ' + || specLine.charAt(k) == '}') { + if (hasNonBlank) { + break; + } + } else { + hasNonBlank = true; + optionValue.append(specLine.charAt(k)); + } + } + // + // transition back to whitespace + // value is over, add it to vector + if (hasNonBlank) { + optionVectors[j].addElement(optionValue + .toString()); + } + // + // find next occurance on line + // + optionStart = specLine.indexOf(options[j], k); + } + } + } + // + // copy vectors over to option arrays + // + for (int j = 0; j < options.length; j++) { + optionValues[j] = new String[optionVectors[j].size()]; + optionVectors[j].copyInto(optionValues[j]); + } + } + } + // + // fill in any missing option values with + // a zero-length string array + for (int i = 0; i < optionValues.length; i++) { + String[] zeroLenArray = new String[0]; + if (optionValues[i] == null) { + optionValues[i] = zeroLenArray; + } + } + return optionValues; + } + private GccProcessor() { + } +} |