/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dasm; import java.io.BufferedReader; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; /** * DAsm entry point */ public class Main { /** * The Dasm version */ public static final String version = "v0.1"; public static final boolean DEBUG = !false; /** * destination path to place .dex file(s) */ private static String destPath = null; /** * generate human-readable files */ private static boolean humanHeadable = false; /** * input files codepage */ private static String encoding = null; /** * automatically generate line numbers */ private static boolean generateLineNumbers = false; private static void incompleteOption(String opt) { System.err.println("Command line option " + opt + " required argument missed"); System.exit(-1); } private static Reader createReader(String fname) throws IOException { FileInputStream fs = new FileInputStream(fname); InputStreamReader ir; if (encoding == null) ir = new InputStreamReader(fs); else ir = new InputStreamReader(fs, encoding); return new BufferedReader(ir); } /** * Called to assemble a single file. * * @param fname * is the name of the file containing the DAsm source code. */ public static void assemble(String fname) { DAsm dAsm = new DAsm(); // read and parse .d file Reader inp = null; try { inp = createReader(fname); dAsm.readD(inp, new File(fname).getName(), generateLineNumbers); close(inp); } catch (DasmError e) { if (DEBUG) e.printStackTrace(); System.err.println("DASM Error: " + e.getMessage()); } catch (Exception e) { if (DEBUG) e.printStackTrace(); System.err.println("Exception <" + e.getClass().getName() + ">" + e.getMessage() + " while reading and parsing " + fname); return; } finally { close(inp); } if (dAsm.errorCount() > 0) { System.err.println("Found " + dAsm.errorCount() + " errors " + " while reading and parsing " + fname); return; } String class_path[] = Utils .getClassFieldFromString(dAsm.getClassName()); String class_name = class_path[1]; // determine where to place .dex file String dest_dir = destPath; if (class_path[0] != null) { String class_dir = class_path[0].replaceAll("/|\\.", Character .toString(File.separatorChar)); if (dest_dir != null) { dest_dir = dest_dir + File.separator + class_dir; } else { dest_dir = class_dir; } } File out_file = null; File hr_file = null; if (dest_dir == null) { out_file = new File(class_name + ".dex"); hr_file = new File(class_name + ".dxt"); } else { out_file = new File(dest_dir, class_name + ".dex"); hr_file = new File(dest_dir, class_name + ".dxt"); // check that dest_dir exists File dest = new File(dest_dir); if (!dest.exists()) { dest.mkdirs(); } if (!dest.isDirectory()) { System.err.println("Cannot create directory " + dest_dir); return; } } // write output FileOutputStream outp = null; FileWriter hr_outp = null; try { outp = new FileOutputStream(out_file); if (humanHeadable) hr_outp = new FileWriter(hr_file); dAsm.write(outp, hr_outp); } catch (Exception e) { if (DEBUG) e.printStackTrace(); System.err.println("Exception <" + e.getClass().getName() + ">" + e.getMessage() + " while writing " + out_file.getPath()); close(hr_outp); close(outp); hr_file.delete(); out_file.delete(); return; } finally { close(hr_outp); close(outp); } System.out.println("Generated: " + out_file.getPath()); } private static void close(Closeable c) { if (c == null) return; try { c.close(); } catch (IOException e) { } } public static void main(String args[]) { int i; String files[] = new String[args.length]; int num_files = 0; if (args.length == 0) { printUsage(); System.exit(-1); } for (i = 0; i < args.length; i++) { if (args[i].equals("-help") || args[i].equals("-?")) { printUsage(); System.exit(0); } if (args[i].equals("-version")) { System.out.println("DAsm version: " + version); if (DEBUG) System.out.println("(compiled with DEBUG flag on)"); System.exit(0); } if (args[i].equals("-g")) { generateLineNumbers = true; } else if (args[i].equals("-d")) { if (++i >= args.length) incompleteOption("-d"); else destPath = args[i]; } else if (args[i].equals("-h")) { humanHeadable = true; } else if (args[i].equals("-e")) { if (++i >= args.length) incompleteOption("-e"); else encoding = args[i]; } else { files[num_files++] = args[i]; } } for (i = 0; i < num_files; i++) { assemble(files[i]); } } static void printUsage() { System.err .println("dasm [-d ] [-g] [-h] [-e ] " + "[ ...]\n\n" + " -g - autogenerate linenumbers\n" + " -e - codepage for inputfile encoding\n" + " -d - path for generated classfiles\n" + " -h - generate human-readable output\n" + " file - sourcefile\n" + "or: dasm -version\n" + "or: dasm -help"); } };