2004-05-27 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / ilasm / Driver.cs
1 //
2 // Mono.ILASM.Driver
3 //    Main Command line interface for Mono ILasm Compiler
4 //
5 // Author(s):
6 //  Jackson Harper (Jackson@LatitudeGeo.com)
7 //
8 // (C) 2003 Jackson Harper, All rights reserved
9 //
10
11 using System;
12 using System.IO;
13 using System.Reflection;
14 using System.Collections;
15
16 namespace Mono.ILASM {
17
18         public class Driver {
19
20                 enum Target {
21                         Dll,
22                         Exe
23                 }
24
25                 public static int Main (string[] args)
26                 {
27                         DriverMain driver = new DriverMain (args);
28                         try {
29                                 driver.Run ();
30                         } catch (Exception e) {
31                                 Console.WriteLine (e);
32                                 Console.WriteLine ("Error while compiling.");
33                                 return 1;
34                         }
35                         Console.WriteLine ("Compilation succeeded");
36                         return 0;
37                 }
38
39                 private class DriverMain {
40
41                         private ArrayList il_file_list;
42                         private Report report;
43                         private string output_file;
44                         private Target target = Target.Exe;
45                         private string target_string = "exe";
46                         private bool quiet = false;
47                         private bool show_tokens = false;
48                         private bool show_method_def = false;
49                         private bool show_method_ref = false;
50                         private bool show_parser = false;
51                         private bool scan_only = false;
52                         private CodeGen codegen;
53
54                         public DriverMain (string[] args)
55                         {
56                                 il_file_list = new ArrayList ();
57                                 ParseArgs (args);
58                                 report = new Report (quiet);
59                         }
60
61                         public void Run ()
62                         {
63                                 try {
64                                         if (il_file_list.Count == 0)
65                                                 Usage ();
66                                         if (output_file == null)
67                                                 output_file = CreateOutputFile ();
68                                         codegen = new CodeGen (output_file, target == Target.Dll, true, report);
69                                         foreach (string file_path in il_file_list)
70                                                 ProcessFile (file_path);
71                                         if (scan_only)
72                                                 return;
73
74                                         codegen.Write ();
75                                 } catch {
76                                         throw;
77                                 }
78                         }
79
80                         private void ProcessFile (string file_path)
81                         {
82                                 if (!File.Exists (file_path)) {
83                                         Console.WriteLine ("File does not exist: {0}",
84                                                 file_path);
85                                         Environment.Exit (2);
86                                 }
87                                 report.AssembleFile (file_path, null,
88                                                 target_string, output_file);
89                                 StreamReader reader = File.OpenText (file_path);
90                                 ILTokenizer scanner = new ILTokenizer (reader);
91
92                                 if (show_tokens)
93                                         scanner.NewTokenEvent += new NewTokenEvent (ShowToken);
94                                 //if (show_method_def)
95                                 //        MethodTable.MethodDefinedEvent += new MethodDefinedEvent (ShowMethodDef);
96                                 //if (show_method_ref)
97                                 //       MethodTable.MethodReferencedEvent += new MethodReferencedEvent (ShowMethodRef);
98
99                                 if (scan_only) {
100                                         ILToken tok;
101                                         while ((tok = scanner.NextToken) != ILToken.EOF) {
102                                                 Console.WriteLine (tok);
103                                         }
104                                         return;
105                                 }
106
107                                 ILParser parser = new ILParser (codegen, scanner);
108                                 try {
109                                         if (show_parser)
110                                                 parser.yyparse (new ScannerAdapter (scanner),
111                                                                 new yydebug.yyDebugSimple ());
112                                         else
113                                                 parser.yyparse (new ScannerAdapter (scanner),  null);
114                                 } catch {
115                                         Console.WriteLine ("Error at: " + scanner.Reader.Location);
116                                         throw;
117                                 }
118                         }
119
120                         public void ShowToken (object sender, NewTokenEventArgs args)
121                         {
122                                 Console.WriteLine ("token: '{0}'", args.Token);
123                         }
124                         /*
125                         public void ShowMethodDef (object sender, MethodDefinedEventArgs args)
126                         {
127                                 Console.WriteLine ("***** Method defined *****");
128                                 Console.WriteLine ("-- signature:   {0}", args.Signature);
129                                 Console.WriteLine ("-- name:        {0}", args.Name);
130                                 Console.WriteLine ("-- return type: {0}", args.ReturnType);
131                                 Console.WriteLine ("-- is in table: {0}", args.IsInTable);
132                                 Console.WriteLine ("-- method atts: {0}", args.MethodAttributes);
133                                 Console.WriteLine ("-- impl atts:   {0}", args.ImplAttributes);
134                                 Console.WriteLine ("-- call conv:   {0}", args.CallConv);
135                         }
136
137                         public void ShowMethodRef (object sender, MethodReferencedEventArgs args)
138                         {
139                                 Console.WriteLine ("***** Method referenced *****");
140                                 Console.WriteLine ("-- signature:   {0}", args.Signature);
141                                 Console.WriteLine ("-- name:        {0}", args.Name);
142                                 Console.WriteLine ("-- return type: {0}", args.ReturnType);
143                                 Console.WriteLine ("-- is in table: {0}", args.IsInTable);
144                         }
145                         */
146                         private void ParseArgs (string[] args)
147                         {
148                                 string command_arg;
149                                 foreach (string str in args) {
150                                         if ((str[0] != '-') && (str[0] != '/')) {
151                                                 il_file_list.Add (str);
152                                                 continue;
153                                         }
154                                         switch (GetCommand (str, out command_arg)) {
155                                         case "out":
156                                         case "output":
157                                                 output_file = command_arg;
158                                                 break;
159                                         case "exe":
160                                                 target = Target.Exe;
161                                                 target_string = "exe";
162                                                 break;
163                                         case "dll":
164                                                 target = Target.Dll;
165                                                 target_string = "dll";
166                                                 break;
167                                         case "quiet":
168                                                 quiet = true;
169                                                 break;
170                                         // Stubs to stay commandline compatible with MS 
171                                         case "listing":
172                                         case "nologo":
173                                         case "debug":
174                                         case "clock":
175                                         case "error":
176                                         case "subsystem":
177                                         case "flags":
178                                         case "alignment":
179                                         case "base":
180                                         case "key":
181                                         case "resource":
182                                                 break;
183                                         case "scan_only":
184                                                 scan_only = true;
185                                                 break;
186                                         case "show_tokens":
187                                                 show_tokens = true;
188                                                 break;
189                                         case "show_method_def":
190                                                 show_method_def = true;
191                                                 break;
192                                         case "show_method_ref":
193                                                 show_method_ref = true;
194                                                 break;
195                                         case "show_parser":
196                                                 show_parser = true;
197                                                 break;
198                                         case "-about":
199                                                 if (str[0] != '-')
200                                                         break;
201                                                 About ();
202                                                 break;
203                                         case "-version":
204                                                 if (str[0] != '-')
205                                                         break;
206                                                 Version ();
207                                                 break;
208                                         default:
209                                                 if (str [0] == '-')
210                                                         break;
211                                                 il_file_list.Add (str);
212                                                 break;
213                                         }
214                                 }
215                         }
216
217                         private string GetCommand (string str, out string command_arg)
218                         {
219                                 int end_index = str.IndexOfAny (new char[] {':', '='}, 1);
220                                 string command = str.Substring (1,
221                                         end_index == -1 ? str.Length - 1 : end_index - 1);
222
223                                 if (end_index != -1) {
224                                         command_arg = str.Substring (end_index+1);
225                                 } else {
226                                         command_arg = null;
227                                 }
228
229                                 return command.ToLower ();
230                         }
231
232                         /// <summary>
233                         ///   Get the first file name and makes it into an output file name
234                         /// </summary>
235                         private string CreateOutputFile ()
236                         {
237                                 string file_name = (string)il_file_list[0];
238                                 int ext_index = file_name.LastIndexOf ('.');
239
240                                 if (ext_index == -1)
241                                         ext_index = file_name.Length;
242
243                                 return String.Format ("{0}.{1}", file_name.Substring (0, ext_index),
244                                         target_string);
245                         }
246
247                         private void Usage ()
248                         {
249                                 Console.WriteLine ("Mono ILasm compiler\n" +
250                                         "ilasm [options] source-files\n" +
251                                         "   --about            About the Mono ILasm compiler\n" +
252                                         "   --version          Print the version number of the Mono ILasm compiler\n" +
253                                         "   /output:file_name  Specifies output file.\n" +
254                                         "   /exe               Compile to executable.\n" +
255                                         "   /dll               Compile to library.\n" +
256                                         "Options can be of the form -option or /option\n");
257                                 Environment.Exit (1);
258                         }
259
260                         private void About ()
261                         {
262                                 Console.WriteLine (
263                                         "For more information on Mono, visit the project Web site\n" +
264                                         "   http://www.go-mono.com\n\n");
265                                 Environment.Exit (0);
266                         }
267
268                         private void Version ()
269                         {
270                                 string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
271                                 Console.WriteLine ("Mono ILasm compiler version {0}", version);
272                                 Environment.Exit (0);
273                         }
274
275                 }
276         }
277 }
278