Main.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
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 com.android.dx.command;
18
19import com.android.dx.Version;
20
21import junit.textui.TestRunner;
22
23/**
24 * Main class for dx. It recognizes enough options to be able to dispatch
25 * to the right "actual" main.
26 */
27public class Main {
28    private static String USAGE_MESSAGE =
29        "usage:\n" +
30        "  dx --dex [--debug] [--verbose] [--positions=<style>] " +
31        "[--no-locals]\n" +
32        "  [--no-optimize] [--statistics] [--[no-]optimize-list=<file>] " +
33        "[--no-strict]\n" +
34        "  [--keep-classes] [--output=<file>] [--dump-to=<file>] " +
35        "[--dump-width=<n>]\n" +
36        "  [--dump-method=<name>[*]] [--verbose-dump] [--no-files] " +
37        "[--core-library]\n" +
38        "  [<file>.class | <file>.{zip,jar,apk} | <directory>] ...\n" +
39        "    Convert a set of classfiles into a dex file, optionally " +
40        "embedded in a\n" +
41        "    jar/zip. Output name must end with one of: .dex .jar " +
42        ".zip .apk. Positions\n" +
43        "    options: none, important, lines.\n" +
44        "  dx --annotool --annotation=<class> [--element=<element types>]\n" +
45        "  [--print=<print types>]\n" +
46        "  dx --dump [--debug] [--strict] [--bytes] [--basic-blocks | " +
47        "--rop-blocks]\n" +
48        "  [--width=<n>] [<file>.class | <file>.txt] ...\n" +
49        "    Dump classfiles in a human-oriented format.\n" +
50        "  dx --junit [-wait] <TestClass>\n" +
51        "    Run the indicated unit test.\n" +
52        "  dx -J<option> ... <arguments, in one of the above " +
53        "forms>\n" +
54        "    Pass VM-specific options to the virtual machine that " +
55        "runs dx.\n" +
56        "  dx --version\n" +
57        "    Print the version of this tool (" + Version.VERSION +
58        ").\n" +
59        "  dx --help\n" +
60        "    Print this message.";
61
62    /**
63     * This class is uninstantiable.
64     */
65    private Main() {
66        // This space intentionally left blank.
67    }
68
69    /**
70     * Run!
71     */
72    public static void main(String[] args) {
73        boolean gotCmd = false;
74        boolean showUsage = false;
75
76        try {
77            for (int i = 0; i < args.length; i++) {
78                String arg = args[i];
79                if (arg.equals("--") || !arg.startsWith("--")) {
80                    gotCmd = false;
81                    showUsage = true;
82                    break;
83                }
84
85                gotCmd = true;
86                if (arg.equals("--dex")) {
87                    com.android.dx.command.dexer.Main.main(without(args, i));
88                    break;
89                } else if (arg.equals("--dump")) {
90                    com.android.dx.command.dump.Main.main(without(args, i));
91                    break;
92                } else if (arg.equals("--annotool")) {
93                    com.android.dx.command.annotool.Main.main(
94                            without(args, i));
95                    break;
96                } else if (arg.equals("--junit")) {
97                    TestRunner.main(without(args, i));
98                    break;
99                } else if (arg.equals("--version")) {
100                    version();
101                    break;
102                } else if (arg.equals("--help")) {
103                    showUsage = true;
104                    break;
105                } else {
106                    gotCmd = false;
107                }
108            }
109        } catch (UsageException ex) {
110            showUsage = true;
111        } catch (RuntimeException ex) {
112            System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
113            ex.printStackTrace();
114            System.exit(2);
115        } catch (Throwable ex) {
116            System.err.println("\nUNEXPECTED TOP-LEVEL ERROR:");
117            ex.printStackTrace();
118            if ((ex instanceof NoClassDefFoundError)
119                    || (ex instanceof NoSuchMethodError)) {
120                System.err.println(
121                        "Note: You may be using an incompatible " +
122                        "virtual machine or class library.\n" +
123                        "(This program is known to be incompatible " +
124                        "with recent releases of GCJ.)");
125            }
126            System.exit(3);
127        }
128
129        if (!gotCmd) {
130            System.err.println("error: no command specified");
131            showUsage = true;
132        }
133
134        if (showUsage) {
135            usage();
136            System.exit(1);
137        }
138    }
139
140    /**
141     * Prints the version message.
142     */
143    private static void version() {
144        System.err.println("dx version " + Version.VERSION);
145        System.exit(0);
146    }
147
148    /**
149     * Prints the usage message.
150     */
151    private static void usage() {
152        System.err.println(USAGE_MESSAGE);
153    }
154
155    /**
156     * Returns a copy of the given args array, but without the indicated
157     * element.
158     *
159     * @param orig non-null; original array
160     * @param n which element to omit
161     * @return non-null; new array
162     */
163    private static String[] without(String[] orig, int n) {
164        int len = orig.length - 1;
165        String[] newa = new String[len];
166        System.arraycopy(orig, 0, newa, 0, n);
167        System.arraycopy(orig, n + 1, newa, n, len - n);
168        return newa;
169    }
170}
171