1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.command;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.Version;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Main class for dx. It recognizes enough options to be able to dispatch
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the right "actual" main.
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Main {
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static String USAGE_MESSAGE =
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "usage:\n" +
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  dx --dex [--debug] [--verbose] [--positions=<style>] " +
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "[--no-locals]\n" +
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  [--no-optimize] [--statistics] [--[no-]optimize-list=<file>] " +
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "[--no-strict]\n" +
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  [--keep-classes] [--output=<file>] [--dump-to=<file>] " +
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "[--dump-width=<n>]\n" +
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  [--dump-method=<name>[*]] [--verbose-dump] [--no-files] " +
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "[--core-library]\n" +
36266f45ff7da18022faf5f77df76c69f8cdad313fjeffhao        "  [--num-threads=<n>] [--incremental] [--force-jumbo]\n" +
374c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "  [--multi-dex [--main-dex-list=<file> [--minimal-main-dex]]\n" +
38a7ab2182266fb9ea1e4e8d1347fc6d6da35760d4Elliott Hughes        "  [<file>.class | <file>.{zip,jar,apk} | <directory>] ...\n" +
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "    Convert a set of classfiles into a dex file, optionally " +
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "embedded in a\n" +
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "    jar/zip. Output name must end with one of: .dex .jar " +
424c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        ".zip .apk or be a directory.\n" +
434c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    Positions options: none, important, lines.\n" +
444c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    --multi-dex: allows to generate several dex files if needed. " +
454c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "This option is \n" +
464c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    exclusive with --incremental, causes --num-threads to be ignored " +
474c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "and only\n" +
484c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    supports folder or archive output.\n" +
494c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    --main-dex-list=<file>: <file> is a list of class file names, " +
504c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "classes defined by\n" +
514c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    those class files are put in classes.dex.\n" +
524c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    --minimal-main-dex: only classes selected by --main-dex-list are " +
534c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "to be put in\n" +
544c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche        "    the main dex.\n" +
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  dx --annotool --annotation=<class> [--element=<element types>]\n" +
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  [--print=<print types>]\n" +
5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        "  dx --dump [--debug] [--strict] [--bytes] [--optimize]\n" +
5899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        "  [--basic-blocks | --rop-blocks | --ssa-blocks | --dot] " +
5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        "[--ssa-step=<step>]\n" +
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  [--width=<n>] [<file>.class | <file>.txt] ...\n" +
6199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        "    Dump classfiles, or transformations thereof, in a " +
6299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        "human-oriented format.\n" +
63e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        "  dx --find-usages <file.dex> <declaring type> <member>\n" +
64e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        "    Find references and declarations to a field or method.\n" +
65e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        "    declaring type: a class name in internal form, like " +
66e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        "Ljava/lang/Object;\n" +
67e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        "    member: a field or method name, like hashCode\n" +
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  dx -J<option> ... <arguments, in one of the above " +
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "forms>\n" +
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "    Pass VM-specific options to the virtual machine that " +
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "runs dx.\n" +
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  dx --version\n" +
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "    Print the version of this tool (" + Version.VERSION +
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ").\n" +
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "  dx --help\n" +
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "    Print this message.";
77de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This class is uninstantiable.
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Main() {
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // This space intentionally left blank.
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Run!
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static void main(String[] args) {
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean gotCmd = false;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean showUsage = false;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < args.length; i++) {
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String arg = args[i];
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (arg.equals("--") || !arg.startsWith("--")) {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    gotCmd = false;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    showUsage = true;
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                gotCmd = true;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (arg.equals("--dex")) {
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    com.android.dx.command.dexer.Main.main(without(args, i));
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (arg.equals("--dump")) {
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    com.android.dx.command.dump.Main.main(without(args, i));
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (arg.equals("--annotool")) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    com.android.dx.command.annotool.Main.main(
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            without(args, i));
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
112e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson                } else if (arg.equals("--find-usages")) {
113e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson                    com.android.dx.command.findusages.Main.main(without(args, i));
114e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson                    break;
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (arg.equals("--version")) {
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    version();
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (arg.equals("--help")) {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    showUsage = true;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    gotCmd = false;
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (UsageException ex) {
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            showUsage = true;
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (RuntimeException ex) {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ex.printStackTrace();
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.exit(2);
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (Throwable ex) {
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("\nUNEXPECTED TOP-LEVEL ERROR:");
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ex.printStackTrace();
134de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro            if ((ex instanceof NoClassDefFoundError)
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    || (ex instanceof NoSuchMethodError)) {
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.err.println(
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "Note: You may be using an incompatible " +
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "virtual machine or class library.\n" +
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "(This program is known to be incompatible " +
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "with recent releases of GCJ.)");
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.exit(3);
143de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        }
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!gotCmd) {
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("error: no command specified");
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            showUsage = true;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (showUsage) {
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            usage();
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.exit(1);
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Prints the version message.
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static void version() {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.err.println("dx version " + Version.VERSION);
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.exit(0);
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Prints the usage message.
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static void usage() {
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.err.println(USAGE_MESSAGE);
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a copy of the given args array, but without the indicated
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * element.
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
17599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param orig {@code non-null;} original array
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param n which element to omit
17799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} new array
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static String[] without(String[] orig, int n) {
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = orig.length - 1;
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] newa = new String[len];
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(orig, 0, newa, 0, n);
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(orig, n + 1, newa, n, len - n);
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return newa;
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
187