main.java revision d166b746b91c114cd8d8fe4b054069083c33170b
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.jf.baksmali;
18
19import org.apache.commons.cli.*;
20
21/**
22 * Main class for baksmali. It recognizes enough options to be able to dispatch
23 * to the right "actual" main.
24 */
25public class main {
26
27    public static final String VERSION = "0.91";
28
29
30    /**
31     * This class is uninstantiable.
32     */
33    private main() {
34        // This space intentionally left blank.
35    }
36
37    /**
38     * Run!
39     */
40    public static void main(String[] args) {
41        Options options = new Options();
42
43
44        Option versionOption = OptionBuilder.withLongOpt("version")
45                                            .withDescription("prints the version")
46                                            .create("v");
47
48        Option helpOption = OptionBuilder.withLongOpt("help")
49                                         .withDescription("prints the help message")
50                                         .create("?");
51
52        Option disassembleOption = OptionBuilder.withLongOpt("disassemble")
53                                                .withDescription("disassembles a dex file into individual files for each class that are placed into a folder structure that matches the package structure of the classes.")
54                                                .create("dis");
55
56        Option dumpOption = OptionBuilder.withLongOpt("dump")
57                                         .withDescription("Dumps a dex file into a single annotated dump file named FILE")
58                                         .create("dump");
59
60        OptionGroup mainCommand = new OptionGroup();
61        mainCommand.addOption(versionOption);
62        mainCommand.addOption(helpOption);
63        mainCommand.addOption(disassembleOption);
64        mainCommand.addOption(dumpOption);
65        mainCommand.setRequired(true);
66
67        options.addOptionGroup(mainCommand);
68
69        CommandLineParser parser = new PosixParser();
70
71        try {
72            parser.parse(options, new String[]{args[0]});
73        } catch (ParseException ex) {
74            printHelp(options);
75            return;
76        }
77
78        try
79        {
80
81            String command = mainCommand.getSelected();
82            if (command.equals("?")) {
83                printHelp(options);
84                return;
85            }
86
87            if (command.equals("v")) {
88                version();
89                return;
90            }
91
92            if (command.equals("dis")) {
93                baksmali.main(without(args, 0));
94                return;
95            }
96
97            if (command.equals("dump")) {
98                dump.main(without(args, 0));
99            }
100        } catch (RuntimeException ex) {
101            System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
102            ex.printStackTrace();
103            System.exit(1);
104        } catch (Throwable ex) {
105            System.err.println("\nUNEXPECTED TOP-LEVEL ERROR:");
106            ex.printStackTrace();
107            System.exit(2);
108        }
109    }
110
111    /**
112     * Prints the usage message.
113     */
114    private static void printHelp(Options options) {
115        HelpFormatter formatter = new HelpFormatter();
116        formatter.printHelp("java -jar baksmali.jar <command> [command-args]",
117                "use <command> --help to see the options each command accepts", options, "");
118    }
119
120    /**
121     * Prints the version message.
122     */
123    private static void version() {
124        System.err.println("baksmali v" + VERSION);
125        System.exit(0);
126    }
127
128    /**
129     * Returns a copy of the given args array, but without the indicated
130     * element.
131     *
132     * @param orig non-null; original array
133     * @param n which element to omit
134     * @return non-null; new array
135     */
136    private static String[] without(String[] orig, int n) {
137        int len = orig.length - 1;
138        String[] newa = new String[len];
139        System.arraycopy(orig, 0, newa, 0, n);
140        System.arraycopy(orig, n + 1, newa, n, len - n);
141        return newa;
142    }
143}