• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 
17 package dasm;
18 
19 import java.io.BufferedReader;
20 import java.io.Closeable;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.FileWriter;
25 import java.io.IOException;
26 import java.io.InputStreamReader;
27 import java.io.Reader;
28 
29 /**
30  * DAsm entry point
31  */
32 public class Main {
33 
34     /**
35      * The Dasm version
36      */
37     public static final String version = "v0.1";
38     public static final boolean DEBUG = !false;
39 
40     /**
41      * destination path to place .dex file(s)
42      */
43     private static String destPath = null;
44 
45     /**
46      * generate human-readable files
47      */
48     private static boolean humanHeadable = false;
49 
50     /**
51      * input files codepage
52      */
53     private static String encoding = null;
54 
55     /**
56      * automatically generate line numbers
57      */
58     private static boolean generateLineNumbers = false;
59 
incompleteOption(String opt)60     private static void incompleteOption(String opt) {
61         System.err.println("Command line option " + opt
62                 + " required argument missed");
63         System.exit(-1);
64     }
65 
createReader(String fname)66     private static Reader createReader(String fname) throws IOException {
67         FileInputStream fs = new FileInputStream(fname);
68         InputStreamReader ir;
69         if (encoding == null)
70             ir = new InputStreamReader(fs);
71         else
72             ir = new InputStreamReader(fs, encoding);
73         return new BufferedReader(ir);
74     }
75 
76     /**
77      * Called to assemble a single file.
78      *
79      * @param fname
80      *            is the name of the file containing the DAsm source code.
81      */
assemble(String fname)82     public static void assemble(String fname) {
83         DAsm dAsm = new DAsm();
84 
85         // read and parse .d file
86         Reader inp = null;
87         try {
88             inp = createReader(fname);
89             dAsm.readD(inp, new File(fname).getName(), generateLineNumbers);
90             close(inp);
91         } catch (DasmError e) {
92             if (DEBUG) e.printStackTrace();
93             System.err.println("DASM Error: " + e.getMessage());
94         } catch (Exception e) {
95             if (DEBUG) e.printStackTrace();
96             System.err.println("Exception <" + e.getClass().getName() + ">"
97                     + e.getMessage() + " while reading and parsing " + fname);
98             return;
99 
100         } finally {
101             close(inp);
102         }
103 
104         if (dAsm.errorCount() > 0) {
105             System.err.println("Found " + dAsm.errorCount() + " errors "
106                     + " while reading and parsing " + fname);
107             return;
108         }
109 
110         String class_path[] = Utils
111                 .getClassFieldFromString(dAsm.getClassName());
112         String class_name = class_path[1];
113 
114         // determine where to place .dex file
115         String dest_dir = destPath;
116         if (class_path[0] != null) {
117             String class_dir = class_path[0].replaceAll("/|\\.", Character
118                     .toString(File.separatorChar));
119             if (dest_dir != null) {
120                 dest_dir = dest_dir + File.separator + class_dir;
121             } else {
122                 dest_dir = class_dir;
123             }
124         }
125 
126         File out_file = null;
127         File hr_file = null;
128 
129         if (dest_dir == null) {
130             out_file = new File(class_name + ".dex");
131             hr_file = new File(class_name + ".dxt");
132         } else {
133             out_file = new File(dest_dir, class_name + ".dex");
134             hr_file = new File(dest_dir, class_name + ".dxt");
135 
136             // check that dest_dir exists
137             File dest = new File(dest_dir);
138             if (!dest.exists()) {
139                 dest.mkdirs();
140             }
141 
142             if (!dest.isDirectory()) {
143                 System.err.println("Cannot create directory " + dest_dir);
144                 return;
145             }
146         }
147 
148         // write output
149         FileOutputStream outp = null;
150         FileWriter hr_outp = null;
151 
152         try {
153             outp = new FileOutputStream(out_file);
154             if (humanHeadable) hr_outp = new FileWriter(hr_file);
155             dAsm.write(outp, hr_outp);
156         } catch (Exception e) {
157             if (DEBUG) e.printStackTrace();
158             System.err.println("Exception <" + e.getClass().getName() + ">"
159                     + e.getMessage() + " while writing " + out_file.getPath());
160 
161             close(hr_outp);
162             close(outp);
163 
164             hr_file.delete();
165             out_file.delete();
166 
167             return;
168         } finally {
169             close(hr_outp);
170             close(outp);
171         }
172 
173         System.out.println("Generated: " + out_file.getPath());
174     }
175 
close(Closeable c)176     private static void close(Closeable c) {
177         if (c == null) return;
178         try {
179             c.close();
180         } catch (IOException e) {
181 
182         }
183     }
184 
main(String args[])185     public static void main(String args[]) {
186         int i;
187 
188         String files[] = new String[args.length];
189         int num_files = 0;
190 
191         if (args.length == 0) {
192             printUsage();
193             System.exit(-1);
194         }
195 
196         for (i = 0; i < args.length; i++) {
197             if (args[i].equals("-help") || args[i].equals("-?")) {
198                 printUsage();
199                 System.exit(0);
200             }
201             if (args[i].equals("-version")) {
202                 System.out.println("DAsm version: " + version);
203                 if (DEBUG) System.out.println("(compiled with DEBUG flag on)");
204                 System.exit(0);
205             }
206             if (args[i].equals("-g")) {
207                 generateLineNumbers = true;
208             } else if (args[i].equals("-d")) {
209                 if (++i >= args.length)
210                     incompleteOption("-d");
211                 else
212                     destPath = args[i];
213             } else if (args[i].equals("-h")) {
214                 humanHeadable = true;
215             } else if (args[i].equals("-e")) {
216                 if (++i >= args.length)
217                     incompleteOption("-e");
218                 else
219                     encoding = args[i];
220             } else {
221                 files[num_files++] = args[i];
222             }
223         }
224 
225         for (i = 0; i < num_files; i++) {
226             assemble(files[i]);
227         }
228     }
229 
printUsage()230     static void printUsage() {
231         System.err
232                 .println("dasm [-d <outpath>] [-g] [-h] [-e <encoding>] <file>"
233                         + "[<file> ...]\n\n"
234                         + "  -g - autogenerate linenumbers\n"
235                         + "  -e - codepage for inputfile encoding\n"
236                         + "  -d - path for generated classfiles\n"
237                         + "  -h - generate human-readable output\n"
238                         + "  file  - sourcefile\n"
239                         + "or: dasm -version\n"
240                         + "or: dasm -help");
241     }
242 };
243