001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package util;
028:
029: /*
030: * Some things I find convenient for parsing strings and
031: * options containing signatures.
032: */
033: public class LinkerUtil {
034:
035: /*
036: * Read the named file.
037: * Tokenize the input.
038: * Returns an array of Strings which are the tokens.
039: * Propagates FileNotFound if the named file cannot be opened.
040: * In the input stream, the character '#' is understood
041: * to start a comment which continues to end-of-line.
042: */
043: public static String[] parseOptionFile(String fname)
044: throws java.io.IOException {
045: java.util.Vector v = new java.util.Vector();
046: java.io.StreamTokenizer in;
047: in = new java.io.StreamTokenizer(
048: new java.io.BufferedInputStream(
049: new java.io.FileInputStream(fname)));
050: in.resetSyntax();
051: in.eolIsSignificant(false);
052: in.whitespaceChars(0, 0x20);
053: in.wordChars('!', '~');
054: in.commentChar('#');
055:
056: while (in.nextToken() != java.io.StreamTokenizer.TT_EOF) {
057: v.addElement(in.sval);
058: }
059:
060: int n = v.size();
061: String olist[] = new String[n];
062: v.copyInto(olist);
063: return olist;
064: }
065:
066: /*
067: * A few constants we frequently use.
068: */
069: public final static String mainName = "main";
070: public final static String mainSig = "([Ljava/lang/String;)V";
071: public final static String constructorName = "<init>";
072: public final static String constructorSig = "()V";
073: public final static String staticInitializerName = "<clinit>";
074: public final static String staticInitializerSig = "()V";
075:
076: /*
077: * Classes are often written with . as component separator.
078: * But in classfiles, as internally in our programs, we use /.
079: * So we often want to find all instances of . and change them
080: * into /.
081: */
082: public static String sanitizeClassname(String classname) {
083: return classname.replace('.', '/').intern();
084: }
085:
086: /*
087: * When writing a fully-qualified method name,
088: * the type signature starts with (. Exploit this
089: * fact when looking for that signature.
090: */
091: public static int sigOff(String n) {
092: return n.indexOf('(');
093: }
094:
095: /*
096: * When writing a fully-qualified method name,
097: * the name of the method is separated from the name
098: * of the containing class by a ., or sometimes by a /
099: * find the offset of that character.
100: */
101: public static int methodOff(String n) {
102: int moff = n.lastIndexOf('.');
103: if (moff >= 0)
104: return moff;
105: // curses. Must work harder.
106: // Cannot just say lastIndexOf('/'), as that
107: // may get us into the signature.
108: int ending = n.indexOf('(');
109: if (ending < 0)
110: ending = n.length();
111: moff = n.lastIndexOf('/', ending);
112: return moff;
113: }
114:
115: }
|