* platforms/linux.make: Tell users to read INSTALL.txt not the
[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);
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                                                 output_file = command_arg;
157                                                 break;
158                                         case "exe":
159                                                 target = Target.Exe;
160                                                 target_string = "exe";
161                                                 break;
162                                         case "dll":
163                                                 target = Target.Dll;
164                                                 target_string = "dll";
165                                                 break;
166                                         case "quiet":
167                                                 quiet = true;
168                                                 break;
169                                         // Stubs to stay commandline compatible with MS 
170                                         case "listing":
171                                         case "nologo":
172                                         case "debug":
173                                         case "clock":
174                                         case "error":
175                                         case "subsystem":
176                                         case "flags":
177                                         case "alignment":
178                                         case "base":
179                                         case "key":
180                                         case "resource":
181                                                 break;
182                                         case "scan_only":
183                                                 scan_only = true;
184                                                 break;
185                                         case "show_tokens":
186                                                 show_tokens = true;
187                                                 break;
188                                         case "show_method_def":
189                                                 show_method_def = true;
190                                                 break;
191                                         case "show_method_ref":
192                                                 show_method_ref = true;
193                                                 break;
194                                         case "show_parser":
195                                                 show_parser = true;
196                                                 break;
197                                         case "-about":
198                                                 if (str[0] != '-')
199                                                         break;
200                                                 About ();
201                                                 break;
202                                         case "-version":
203                                                 if (str[0] != '-')
204                                                         break;
205                                                 Version ();
206                                                 break;
207                                         }
208                                 }
209                         }
210
211                         private string GetCommand (string str, out string command_arg)
212                         {
213                                 int end_index = str.IndexOfAny (new char[] {':', '='}, 1);
214                                 string command = str.Substring (1,
215                                         end_index == -1 ? str.Length - 1 : end_index - 1);
216
217                                 if (end_index != -1) {
218                                         command_arg = str.Substring (end_index+1);
219                                 } else {
220                                         command_arg = null;
221                                 }
222
223                                 return command.ToLower ();
224                         }
225
226                         /// <summary>
227                         ///   Get the first file name and makes it into an output file name
228                         /// </summary>
229                         private string CreateOutputFile ()
230                         {
231                                 string file_name = (string)il_file_list[0];
232                                 int ext_index = file_name.LastIndexOf ('.');
233
234                                 if (ext_index == -1)
235                                         ext_index = file_name.Length;
236
237                                 return String.Format ("{0}.{1}", file_name.Substring (0, ext_index),
238                                         target_string);
239                         }
240
241                         private void Usage ()
242                         {
243                                 Console.WriteLine ("Mono ILasm compiler\n" +
244                                         "ilasm [options] source-files\n" +
245                                         "   --about            About the Mono ILasm compiler\n" +
246                                         "   --version          Print the version number of the Mono ILasm compiler\n" +
247                                         "   /out:file_name     Specifies output file.\n" +
248                                         "   /exe               Compile to executable.\n" +
249                                         "   /dll               Compile to library.\n" +
250                                         "Options can be of the form -option or /option\n");
251                                 Environment.Exit (1);
252                         }
253
254                         private void About ()
255                         {
256                                 Console.WriteLine (
257                                         "For more information on Mono, visit the project Web site\n" +
258                                         "   http://www.go-mono.com\n\n");
259                                 Environment.Exit (0);
260                         }
261
262                         private void Version ()
263                         {
264                                 string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
265                                 Console.WriteLine ("Mono ILasm compiler version {0}", version);
266                                 Environment.Exit (0);
267                         }
268
269                 }
270         }
271 }
272