3 // Main Command line interface for Mono ILasm Compiler
6 // Jackson Harper (Jackson@LatitudeGeo.com)
8 // (C) 2003 Jackson Harper, All rights reserved
9 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 using System
.Reflection
;
15 using System
.Collections
;
16 using System
.Security
.Cryptography
;
21 namespace Mono
.ILASM
{
30 public static int Main (string[] args
)
32 // Do everything in Invariant
33 System
.Threading
.Thread
.CurrentThread
.CurrentCulture
= System
.Globalization
.CultureInfo
.InvariantCulture
;
35 DriverMain driver
= new DriverMain (args
);
38 Report
.Message ("Operation completed successfully");
42 private class DriverMain
{
44 private ArrayList il_file_list
;
45 private string output_file
;
46 private Target target
= Target
.Exe
;
47 private string target_string
= "exe";
48 private bool show_tokens
= false;
49 // private bool show_method_def = false;
50 // private bool show_method_ref = false;
51 private bool show_parser
= false;
52 private bool scan_only
= false;
53 private bool debugging_info
= false;
54 private CodeGen codegen
;
55 private bool keycontainer
= false;
56 private string keyname
;
58 private StrongName sn
;
62 public DriverMain (string[] args
)
64 il_file_list
= new ArrayList ();
70 if (il_file_list
.Count
== 0)
72 if (output_file
== null)
73 output_file
= CreateOutputFilename ();
75 codegen
= new CodeGen (output_file
, target
== Target
.Dll
, debugging_info
, noautoinherit
);
76 foreach (string file_path
in il_file_list
) {
77 Report
.FilePath
= file_path
;
78 ProcessFile (file_path
);
83 if (Report
.ErrorCount
> 0)
86 if (target
!= Target
.Dll
&& !codegen
.HasEntryPoint
)
87 Report
.Error ("No entry point found.");
89 // if we have a key and aren't assembling a netmodule
90 if ((keyname
!= null) && !codegen
.IsThisAssembly (null)) {
93 // this overrides any attribute or .publickey directive in the source
94 codegen
.ThisAssembly
.SetPublicKey (sn
.PublicKey
);
96 throw new NotSupportedException ();
103 File
.Delete (output_file
);
106 } catch (ILAsmException e
) {
107 Error (e
.ToString ());
109 } catch (PEAPI
.PEFileException pe
) {
110 Error ("Error : " + pe
.Message
);
114 #if HAS_MONO_SECURITY
117 Report
.Message ("Signing assembly with the specified strongname keypair");
118 return Sign (output_file
);
128 private void Error (string message
)
130 Console
.WriteLine (message
+ "\n");
131 Console
.WriteLine ("***** FAILURE *****\n");
134 #if HAS_MONO_SECURITY
135 private void LoadKey ()
138 CspParameters csp
= new CspParameters ();
139 csp
.KeyContainerName
= keyname
;
140 RSACryptoServiceProvider rsa
= new RSACryptoServiceProvider (csp
);
141 sn
= new StrongName (rsa
);
144 using (FileStream fs
= File
.OpenRead (keyname
)) {
145 data
= new byte [fs
.Length
];
146 fs
.Read (data
, 0, data
.Length
);
149 sn
= new StrongName (data
);
153 private bool Sign (string filename
)
155 // note: if the file cannot be signed (no public key in it) then
156 // we do not show an error, or a warning, if the key file doesn't
158 return sn
.Sign (filename
);
162 private void ProcessFile (string file_path
)
164 if (!File
.Exists (file_path
)) {
165 Console
.WriteLine ("File does not exist: {0}",
167 Environment
.Exit (2);
169 Report
.AssembleFile (file_path
, null,
170 target_string
, output_file
);
171 StreamReader reader
= File
.OpenText (file_path
);
172 ILTokenizer scanner
= new ILTokenizer (reader
);
175 scanner
.NewTokenEvent
+= new NewTokenEvent (ShowToken
);
176 //if (show_method_def)
177 // MethodTable.MethodDefinedEvent += new MethodDefinedEvent (ShowMethodDef);
178 //if (show_method_ref)
179 // MethodTable.MethodReferencedEvent += new MethodReferencedEvent (ShowMethodRef);
183 while ((tok
= scanner
.NextToken
) != ILToken
.EOF
) {
184 Console
.WriteLine (tok
);
189 ILParser parser
= new ILParser (codegen
, scanner
);
190 codegen
.BeginSourceFile (file_path
);
193 parser
.yyparse (new ScannerAdapter (scanner
),
194 new yydebug
.yyDebugSimple ());
196 parser
.yyparse (new ScannerAdapter (scanner
), null);
197 } catch (ILTokenizingException ilte
) {
198 Report
.Error (ilte
.Location
, "syntax error at token '" + ilte
.Token
+ "'");
199 } catch (Mono
.ILASM
.yyParser
.yyException ye
) {
200 Report
.Error (scanner
.Reader
.Location
, ye
.Message
);
201 } catch (ILAsmException ie
) {
202 ie
.FilePath
= file_path
;
203 ie
.Location
= scanner
.Reader
.Location
;
206 Console
.Write ("{0} ({1}, {2}): ",file_path
, scanner
.Reader
.Location
.line
, scanner
.Reader
.Location
.column
);
209 codegen
.EndSourceFile ();
213 public void ShowToken (object sender
, NewTokenEventArgs args
)
215 Console
.WriteLine ("token: '{0}'", args
.Token
);
218 public void ShowMethodDef (object sender, MethodDefinedEventArgs args)
220 Console.WriteLine ("***** Method defined *****");
221 Console.WriteLine ("-- signature: {0}", args.Signature);
222 Console.WriteLine ("-- name: {0}", args.Name);
223 Console.WriteLine ("-- return type: {0}", args.ReturnType);
224 Console.WriteLine ("-- is in table: {0}", args.IsInTable);
225 Console.WriteLine ("-- method atts: {0}", args.MethodAttributes);
226 Console.WriteLine ("-- impl atts: {0}", args.ImplAttributes);
227 Console.WriteLine ("-- call conv: {0}", args.CallConv);
230 public void ShowMethodRef (object sender, MethodReferencedEventArgs args)
232 Console.WriteLine ("***** Method referenced *****");
233 Console.WriteLine ("-- signature: {0}", args.Signature);
234 Console.WriteLine ("-- name: {0}", args.Name);
235 Console.WriteLine ("-- return type: {0}", args.ReturnType);
236 Console.WriteLine ("-- is in table: {0}", args.IsInTable);
239 private void ParseArgs (string[] args
)
242 foreach (string str
in args
) {
243 if ((str
[0] != '-') && (str
[0] != '/')) {
244 il_file_list
.Add (str
);
247 switch (GetCommand (str
, out command_arg
)) {
250 output_file
= command_arg
;
254 target_string
= "exe";
258 target_string
= "dll";
265 debugging_info
= true;
267 // Stubs to stay commandline compatible with MS
279 if (command_arg
.Length
> 0)
280 keycontainer
= (command_arg
[0] == '@');
282 keyname
= command_arg
.Substring (1);
284 keyname
= command_arg
;
286 case "noautoinherit":
287 noautoinherit
= true;
295 case "show_method_def":
296 // show_method_def = true;
298 case "show_method_ref":
299 // show_method_ref = true;
317 il_file_list
.Add (str
);
323 private string GetCommand (string str
, out string command_arg
)
325 int end_index
= str
.IndexOfAny (new char[] {':', '='}
, 1);
326 string command
= str
.Substring (1,
327 end_index
== -1 ? str
.Length
- 1 : end_index
- 1);
329 if (end_index
!= -1) {
330 command_arg
= str
.Substring (end_index
+1);
335 return command
.ToLower ();
339 /// Get the first file name and makes it into an output file name
341 private string CreateOutputFilename ()
343 string file_name
= (string)il_file_list
[0];
344 int ext_index
= file_name
.LastIndexOf ('.');
347 ext_index
= file_name
.Length
;
349 return String
.Format ("{0}.{1}", file_name
.Substring (0, ext_index
),
353 private void Usage ()
355 Console
.WriteLine ("Mono IL assembler compiler\n" +
356 "ilasm [options] source-files\n" +
357 " --about About the Mono IL assembler compiler\n" +
358 " --version Print the version number of the compiler\n" +
359 " /output:file_name Specifies output file.\n" +
360 " /exe Compile to executable.\n" +
361 " /dll Compile to library.\n" +
362 " /debug Include debug information.\n" +
363 " /key:keyfile Strongname using the specified key file\n" +
364 " /key:@container Strongname using the specified key container\n" +
365 " /noautoinherit Disable inheriting from System.Object by default\n" +
366 "Options can be of the form -option or /option\n");
367 Environment
.Exit (1);
370 private void About ()
373 "For more information on Mono, visit the project Web site\n" +
374 " http://www.go-mono.com\n\n");
375 Environment
.Exit (0);
378 private void Version ()
380 string version
= System
.Reflection
.Assembly
.GetExecutingAssembly ().GetName ().Version
.ToString ();
381 Console
.WriteLine ("Mono IL assembler compiler version {0}", version
);
382 Environment
.Exit (0);