112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden/* 212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Copyright (C) 2009 The Android Open Source Project 312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * 412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Licensed under the Apache License, Version 2.0 (the "License"); 512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * you may not use this file except in compliance with the License. 612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * You may obtain a copy of the License at 712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * 812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * http://www.apache.org/licenses/LICENSE-2.0 912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * 1012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Unless required by applicable law or agreed to in writing, software 1112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * distributed under the License is distributed on an "AS IS" BASIS, 1212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * See the License for the specific language governing permissions and 1412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * limitations under the License. 1512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 1612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 1712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenpackage com.android.dexdeps; 1812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 1912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.File; 2012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.FileNotFoundException; 2112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.IOException; 2212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.InputStream; 2312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.io.RandomAccessFile; 2412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipEntry; 2512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipException; 2612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipFile; 2712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenimport java.util.zip.ZipInputStream; 2838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstromimport java.util.ArrayList; 2938e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstromimport java.util.Collections; 3038e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstromimport java.util.List; 3112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 3212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFaddenpublic class Main { 3306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein private String[] mInputFileNames; 3400da1fe5d42693f2bcf5351a459db1fb32b9ca9cAndy McFadden private String mOutputFormat = "xml"; 3512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 3612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /** 3706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein * whether to only emit info about classes used; when {@code false}, 3806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein * info about fields and methods is also emitted 3906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein */ 4006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein private boolean mJustClasses = false; 4106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein 4206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein /** 4312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Entry point. 4412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 4512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden public static void main(String[] args) { 4612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden Main main = new Main(); 4712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden main.run(args); 4812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 4912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 5012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /** 5112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Start things up. 5212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 5312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden void run(String[] args) { 5412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden try { 5512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden parseArgs(args); 5606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein boolean first = true; 5706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein 5806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein for (String fileName : mInputFileNames) { 5906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein if (first) { 6006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein first = false; 6106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein Output.generateFirstHeader(fileName, mOutputFormat); 6206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein } else { 6306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein Output.generateHeader(fileName, mOutputFormat); 6406d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein } 6538e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom List<RandomAccessFile> rafs = openInputFiles(fileName); 6638e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom for (RandomAccessFile raf : rafs) { 6738e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom DexData dexData = new DexData(raf); 6838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom dexData.load(); 6938e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom Output.generate(dexData, mOutputFormat, mJustClasses); 7038e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom raf.close(); 7138e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom } 7206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein Output.generateFooter(mOutputFormat); 7306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein } 7412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } catch (UsageException ue) { 7512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden usage(); 7612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden System.exit(2); 7712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } catch (IOException ioe) { 7806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein if (ioe.getMessage() != null) { 79753f32ab1db6de174a1de68210f9f30a1e327612Andy McFadden System.err.println("Failed: " + ioe); 8006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein } 8112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden System.exit(1); 8212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } catch (DexDataException dde) { 8312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* a message was already reported, just bail quietly */ 8412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden System.exit(1); 8512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 8612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 8712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 8812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /** 8906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein * Opens an input file, which could be a .dex or a .jar/.apk with a 9012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * classes.dex inside. If the latter, we extract the contents to a 9112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * temporary file. 9206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein * 9306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein * @param fileName the name of the file to open 9412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 9538e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom List<RandomAccessFile> openInputFiles(String fileName) throws IOException { 9638e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom List<RandomAccessFile> rafs = openInputFileAsZip(fileName); 9712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 9838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom if (rafs == null) { 9906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein File inputFile = new File(fileName); 10038e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom RandomAccessFile raf = new RandomAccessFile(inputFile, "r"); 10138e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom rafs = Collections.singletonList(raf); 10212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 10312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 10438e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom return rafs; 10512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 10612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 10712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /** 10838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom * Tries to open an input file as a Zip archive (jar/apk) with dex files inside. 10912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * 11006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein * @param fileName the name of the file to open 11138e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom * @return a list of RandomAccessFile for classes.dex, 11238e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom * classes2.dex, etc., or null if the input file is not a 11338e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom * zip archive 11412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * @throws IOException if the file isn't found, or it's a zip and 11538e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom * no classes.dex isn't found inside 11612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 11738e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom List<RandomAccessFile> openInputFileAsZip(String fileName) throws IOException { 11812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* 11912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Try it as a zip file. 12012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 12138e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom ZipFile zipFile; 12212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden try { 12306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein zipFile = new ZipFile(fileName); 12412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } catch (FileNotFoundException fnfe) { 12512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* not found, no point in retrying as non-zip */ 12606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein System.err.println("Unable to open '" + fileName + "': " + 12712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden fnfe.getMessage()); 12812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden throw fnfe; 12912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } catch (ZipException ze) { 13012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* not a zip */ 13112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden return null; 13212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 13312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 13438e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom List<RandomAccessFile> result = new ArrayList<RandomAccessFile>(); 13538e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom try { 13638e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom int classesDexNumber = 1; 13738e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom while (true) { 13838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom result.add(openClassesDexZipFileEntry(zipFile, classesDexNumber)); 13938e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom classesDexNumber++; 14038e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom } 14138e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom } catch (IOException ioe) { 14238e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom // We didn't find any of the expected dex files in the zip. 14338e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom if (result.isEmpty()) { 14438e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom throw ioe; 14538e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom } 14638e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom return result; 14738e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom } 14838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom } 14938e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom 15038e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom RandomAccessFile openClassesDexZipFileEntry(ZipFile zipFile, int classesDexNumber) 15138e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom throws IOException { 15212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* 15312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * We know it's a zip; see if there's anything useful inside. A 15412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * failure here results in some type of IOException (of which 15512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * ZipException is a subclass). 15612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 15738e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom String zipEntryName = ("classes" + 15838e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom (classesDexNumber == 1 ? "" : classesDexNumber) + 15938e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom ".dex"); 16038e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom ZipEntry entry = zipFile.getEntry(zipEntryName); 16112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden if (entry == null) { 16212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden zipFile.close(); 16338e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom throw new ZipException("Unable to find '" + zipEntryName + 16438e91254a9c5bf51055fc36ac79f4d5dccccc855Brian Carlstrom "' in '" + zipFile.getName() + "'"); 16512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 16612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 16712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden InputStream zis = zipFile.getInputStream(entry); 16812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 16912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* 17012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Create a temp file to hold the DEX data, open it, and delete it 17112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * to ensure it doesn't hang around if we fail. 17212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 17312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden File tempFile = File.createTempFile("dexdeps", ".dex"); 174753f32ab1db6de174a1de68210f9f30a1e327612Andy McFadden //System.out.println("+++ using temp " + tempFile); 17512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden RandomAccessFile raf = new RandomAccessFile(tempFile, "rw"); 17612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden tempFile.delete(); 17712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 17812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /* 17912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Copy all data from input stream to output file. 18012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 18112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden byte copyBuf[] = new byte[32768]; 18212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden int actual; 18312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 18412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden while (true) { 18512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden actual = zis.read(copyBuf); 18612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden if (actual == -1) 18712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden break; 18812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 18912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden raf.write(copyBuf, 0, actual); 19012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 19112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 19212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden zis.close(); 19312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden raf.seek(0); 19412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 19512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden return raf; 19612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 19712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 19812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 19912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /** 20012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Parses command-line arguments. 20112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * 20212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * @throws UsageException if arguments are missing or poorly formed 20312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 20412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden void parseArgs(String[] args) { 20512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden int idx; 20612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 20712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden for (idx = 0; idx < args.length; idx++) { 20812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden String arg = args[idx]; 20912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 21012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden if (arg.equals("--") || !arg.startsWith("--")) { 21112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden break; 21212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } else if (arg.startsWith("--format=")) { 21312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden mOutputFormat = arg.substring(arg.indexOf('=') + 1); 21412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden if (!mOutputFormat.equals("brief") && 21512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden !mOutputFormat.equals("xml")) 21612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden { 21712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden System.err.println("Unknown format '" + mOutputFormat +"'"); 21812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden throw new UsageException(); 21912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 220753f32ab1db6de174a1de68210f9f30a1e327612Andy McFadden //System.out.println("+++ using format " + mOutputFormat); 22106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein } else if (arg.equals("--just-classes")) { 22206d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein mJustClasses = true; 22312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } else { 22412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden System.err.println("Unknown option '" + arg + "'"); 22512d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden throw new UsageException(); 22612d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 22712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 22812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 22906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein // We expect at least one more argument (file name). 23006d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein int fileCount = args.length - idx; 23106d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein if (fileCount == 0) { 23212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden throw new UsageException(); 23312d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 23412d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 23506d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein mInputFileNames = new String[fileCount]; 23606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein System.arraycopy(args, idx, mInputFileNames, 0, fileCount); 23712d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 23812d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden 23912d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden /** 24012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden * Prints command-line usage info. 24112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden */ 24212d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden void usage() { 24306d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein System.err.print( 24406d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein "DEX dependency scanner v1.2\n" + 24506d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein "Copyright (C) 2009 The Android Open Source Project\n\n" + 24606d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein "Usage: dexdeps [options] <file.{dex,apk,jar}> ...\n" + 24706d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein "Options:\n" + 24806d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein " --format={xml,brief}\n" + 24906d020698f7182ae17b933fa688ab9302a8674e2Dan Bornstein " --just-classes\n"); 25012d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden } 25112d6d4c0ea192b6a924df0df1e3b14ce1ed5793bAndy McFadden} 252