001    /*
002     * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    
027    
028    package sun.tools.javap;
029    
030    import java.util.*;
031    import java.io.*;
032    
033    /**
034     * Entry point for javap, class file disassembler.
035     *
036     * @author  Sucheta Dambalkar (Adopted code from old javap)
037     */
038    public class Main {
039    
040        private Vector<String> classList = new Vector<String>();
041        private PrintWriter out;
042        JavapEnvironment env = new JavapEnvironment();
043        private static boolean errorOccurred = false;
044        private static final String progname = "javap";
045    
046    
047        public Main(PrintWriter out){
048            this.out = out;
049        }
050    
051        public static void main(String argv[]) {
052            // unless first arg is -Xold, use new javap
053            if (!(argv.length >= 1 && argv[0].equals("-Xold"))) {
054                com.sun.tools.javap.Main.main(argv);
055                return;
056            }
057    
058            entry(argv);
059            if (errorOccurred) {
060                System.exit(1);
061            }
062        }
063    
064    
065        /**
066         * Entry point for tool if you don't want System.exit() called.
067         */
068        public static void entry(String argv[]) {
069            PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
070            try {
071    
072                Main jpmain = new Main(out);
073                jpmain.perform(argv);
074    
075            } finally {
076                out.close();
077            }
078        }
079    
080        /**
081         * Process the arguments and perform the desired action
082         */
083        private void perform(String argv[]) {
084            if (parseArguments(argv)) {
085                displayResults();
086    
087            }
088        }
089    
090        private void error(String msg) {
091            errorOccurred = true;
092            System.err.println(msg);
093            System.err.flush();
094        }
095    
096        /**
097         * Print usage information
098         */
099        private void usage() {
100            java.io.PrintStream out = System.out;
101            out.println("Usage: " + progname + " <options> <classes>...");
102            out.println();
103            out.println("where options include:");
104            out.println("   -c                        Disassemble the code");
105            out.println("   -classpath <pathlist>     Specify where to find user class files");
106            out.println("   -extdirs <dirs>           Override location of installed extensions");
107            out.println("   -help                     Print this usage message");
108            out.println("   -J<flag>                  Pass <flag> directly to the runtime system");
109            out.println("   -l                        Print line number and local variable tables");
110            out.println("   -public                   Show only public classes and members");
111            out.println("   -protected                Show protected/public classes and members");
112            out.println("   -package                  Show package/protected/public classes");
113            out.println("                             and members (default)");
114            out.println("   -private                  Show all classes and members");
115            out.println("   -s                        Print internal type signatures");
116            out.println("   -bootclasspath <pathlist> Override location of class files loaded");
117            out.println("                             by the bootstrap class loader");
118            out.println("   -verbose                  Print stack size, number of locals and args for methods");
119            out.println("                             If verifying, print reasons for failure");
120            out.println();
121        }
122    
123        /**
124         * Parse the command line arguments.
125         * Set flags, construct the class list and create environment.
126         */
127        private boolean parseArguments(String argv[]) {
128            for (int i = 0 ; i < argv.length ; i++) {
129                String arg = argv[i];
130                if (arg.startsWith("-")) {
131                    if (arg.equals("-l")) {
132                        env.showLineAndLocal = true;
133                    } else if (arg.equals("-private") || arg.equals("-p")) {
134                        env.showAccess = env.PRIVATE;
135                    } else if (arg.equals("-package")) {
136                        env.showAccess = env.PACKAGE;
137                    } else if (arg.equals("-protected")) {
138                        env.showAccess = env.PROTECTED;
139                    } else if (arg.equals("-public")) {
140                        env.showAccess = env.PUBLIC;
141                    } else if (arg.equals("-c")) {
142                        env.showDisassembled = true;
143                    } else if (arg.equals("-s")) {
144                        env.showInternalSigs = true;
145                    } else if (arg.equals("-verbose"))  {
146                        env.showVerbose = true;
147                    } else if (arg.equals("-v")) {
148                        env.showVerbose = true;
149                    } else if (arg.equals("-h")) {
150                        error("-h is no longer available - use the 'javah' program");
151                        return false;
152                    } else if (arg.equals("-verify")) {
153                        error("-verify is no longer available - use 'java -verify'");
154                        return false;
155                    } else if (arg.equals("-verify-verbose")) {
156                        error("-verify is no longer available - use 'java -verify'");
157                        return false;
158                    } else if (arg.equals("-help")) {
159                        usage();
160                        return false;
161                    } else if (arg.equals("-classpath")) {
162                        if ((i + 1) < argv.length) {
163                            env.classPathString = argv[++i];
164                        } else {
165                            error("-classpath requires argument");
166                            usage();
167                            return false;
168                        }
169                    } else if (arg.equals("-bootclasspath")) {
170                        if ((i + 1) < argv.length) {
171                            env.bootClassPathString = argv[++i];
172                        } else {
173                            error("-bootclasspath requires argument");
174                            usage();
175                            return false;
176                        }
177                    } else if (arg.equals("-extdirs")) {
178                        if ((i + 1) < argv.length) {
179                            env.extDirsString = argv[++i];
180                        } else {
181                            error("-extdirs requires argument");
182                            usage();
183                            return false;
184                        }
185                    } else if (arg.equals("-all")) {
186                        env.showallAttr = true;
187                    } else if (arg.equals("-Xold")) {
188                        // ignore: this is old javap
189                    } else {
190                        error("invalid flag: " + arg);
191                        usage();
192                        return false;
193                    }
194                } else {
195                    classList.addElement(arg);
196                    env.nothingToDo = false;
197                }
198            }
199            if (env.nothingToDo) {
200                System.out.println("No classes were specified on the command line.  Try -help.");
201                errorOccurred = true;
202                return false;
203            }
204            return true;
205        }
206    
207        /**
208         * Display results
209         */
210        private void displayResults() {
211            for (int i = 0; i < classList.size() ; i++ ) {
212                String Name = classList.elementAt(i);
213                InputStream classin = env.getFileInputStream(Name);
214    
215                try {
216                    JavapPrinter printer = new JavapPrinter(classin, out, env);
217                    printer.print();                // actual do display
218    
219                } catch (IllegalArgumentException exc) {
220                    error(exc.getMessage());
221                }
222            }
223        }
224    }