diff options
Diffstat (limited to 'mcs/ilasm/Driver.cs')
-rw-r--r-- | mcs/ilasm/Driver.cs | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/mcs/ilasm/Driver.cs b/mcs/ilasm/Driver.cs new file mode 100644 index 00000000000..d4315f4c640 --- /dev/null +++ b/mcs/ilasm/Driver.cs @@ -0,0 +1,357 @@ +// +// Mono.ILASM.Driver +// Main Command line interface for Mono ILasm Compiler +// +// Author(s): +// Jackson Harper (Jackson@LatitudeGeo.com) +// +// (C) 2003 Jackson Harper, All rights reserved +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// + +using System; +using System.IO; +using System.Reflection; +using System.Collections; +using System.Security.Cryptography; +using Mono.Security; + +namespace Mono.ILASM { + + public class Driver { + + enum Target { + Dll, + Exe + } + + public static int Main (string[] args) + { + // Do everything in Invariant + System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + + DriverMain driver = new DriverMain (args); + if (!driver.Run ()) + return 1; + Console.WriteLine ("Operation completed successfully"); + return 0; + } + + private class DriverMain { + + private ArrayList il_file_list; + private string output_file; + private Target target = Target.Exe; + private string target_string = "exe"; + private bool show_tokens = false; + private bool show_method_def = false; + private bool show_method_ref = false; + private bool show_parser = false; + private bool scan_only = false; + private bool debugging_info = false; + private CodeGen codegen; + private bool keycontainer = false; + private string keyname; + + public DriverMain (string[] args) + { + il_file_list = new ArrayList (); + ParseArgs (args); + } + + public bool Run () + { + if (il_file_list.Count == 0) + Usage (); + if (output_file == null) + output_file = CreateOutputFilename (); + try { + codegen = new CodeGen (output_file, target == Target.Dll, true, debugging_info); + foreach (string file_path in il_file_list) + ProcessFile (file_path); + if (scan_only) + return true; + + if (Report.ErrorCount > 0) + return false; + + if (target != Target.Dll && !codegen.HasEntryPoint) + Report.Error ("No entry point found."); + + try { + codegen.Write (); + } catch { + File.Delete (output_file); + throw; + } + } catch (ILAsmException e) { + Error (e.Message); + return false; + } catch (PEAPI.PEFileException pe) { + Error (pe.Message); + return false; + } + + try { + if (keyname != null) { + Console.WriteLine ("Signing assembly with the specified strongname keypair"); + return Sign (output_file); + } + } catch { + return false; + } + + return true; + } + + private void Error (string message) + { + Console.WriteLine ("Error : " + message + "\n"); + Console.WriteLine ("***** FAILURE *****\n"); + } + + private bool Sign (string filename) + { + // note: if the file cannot be signed (no public key in it) then + // we do not show an error, or a warning, if the key file doesn't + // exists + StrongName sn = null; + if (keycontainer) { + CspParameters csp = new CspParameters (); + csp.KeyContainerName = keyname; + RSACryptoServiceProvider rsa = new RSACryptoServiceProvider (csp); + sn = new StrongName (rsa); + } else { + byte[] data = null; + using (FileStream fs = File.OpenRead (keyname)) { + data = new byte [fs.Length]; + fs.Read (data, 0, data.Length); + fs.Close (); + } + sn = new StrongName (data); + } + return sn.Sign (filename); + } + + private void ProcessFile (string file_path) + { + if (!File.Exists (file_path)) { + Console.WriteLine ("File does not exist: {0}", + file_path); + Environment.Exit (2); + } + Report.AssembleFile (file_path, null, + target_string, output_file); + StreamReader reader = File.OpenText (file_path); + ILTokenizer scanner = new ILTokenizer (reader); + + if (show_tokens) + scanner.NewTokenEvent += new NewTokenEvent (ShowToken); + //if (show_method_def) + // MethodTable.MethodDefinedEvent += new MethodDefinedEvent (ShowMethodDef); + //if (show_method_ref) + // MethodTable.MethodReferencedEvent += new MethodReferencedEvent (ShowMethodRef); + + if (scan_only) { + ILToken tok; + while ((tok = scanner.NextToken) != ILToken.EOF) { + Console.WriteLine (tok); + } + return; + } + + ILParser parser = new ILParser (codegen, scanner); + codegen.BeginSourceFile (file_path); + try { + if (show_parser) + parser.yyparse (new ScannerAdapter (scanner), + new yydebug.yyDebugSimple ()); + else + parser.yyparse (new ScannerAdapter (scanner), null); + } catch (ILTokenizingException ilte) { + Report.Error (file_path + "(" + ilte.Location.line + ") : error : " + + "syntax error at token '" + ilte.Token + "'."); + } catch (Mono.ILASM.yyParser.yyException) { + Report.Error ("Error at: " + scanner.Reader.Location); + } catch { + Console.WriteLine ("Error at: " + scanner.Reader.Location); + throw; + } finally { + codegen.EndSourceFile (); + } + } + + public void ShowToken (object sender, NewTokenEventArgs args) + { + Console.WriteLine ("token: '{0}'", args.Token); + } + /* + public void ShowMethodDef (object sender, MethodDefinedEventArgs args) + { + Console.WriteLine ("***** Method defined *****"); + Console.WriteLine ("-- signature: {0}", args.Signature); + Console.WriteLine ("-- name: {0}", args.Name); + Console.WriteLine ("-- return type: {0}", args.ReturnType); + Console.WriteLine ("-- is in table: {0}", args.IsInTable); + Console.WriteLine ("-- method atts: {0}", args.MethodAttributes); + Console.WriteLine ("-- impl atts: {0}", args.ImplAttributes); + Console.WriteLine ("-- call conv: {0}", args.CallConv); + } + + public void ShowMethodRef (object sender, MethodReferencedEventArgs args) + { + Console.WriteLine ("***** Method referenced *****"); + Console.WriteLine ("-- signature: {0}", args.Signature); + Console.WriteLine ("-- name: {0}", args.Name); + Console.WriteLine ("-- return type: {0}", args.ReturnType); + Console.WriteLine ("-- is in table: {0}", args.IsInTable); + } + */ + private void ParseArgs (string[] args) + { + string command_arg; + foreach (string str in args) { + if ((str[0] != '-') && (str[0] != '/')) { + il_file_list.Add (str); + continue; + } + switch (GetCommand (str, out command_arg)) { + case "out": + case "output": + output_file = command_arg; + break; + case "exe": + target = Target.Exe; + target_string = "exe"; + break; + case "dll": + target = Target.Dll; + target_string = "dll"; + break; + case "quiet": + Report.Quiet = true; + break; + case "debug": + case "deb": + if (str[0] != '-') + break; + debugging_info = true; + break; + // Stubs to stay commandline compatible with MS + case "listing": + case "nologo": + case "clock": + case "error": + case "subsystem": + case "flags": + case "alignment": + case "base": + case "resource": + break; + case "key": + if (command_arg.Length > 0) + keycontainer = (command_arg [0] == '@'); + if (keycontainer) + keyname = command_arg.Substring (1); + else + keyname = command_arg; + break; + case "scan_only": + scan_only = true; + break; + case "show_tokens": + show_tokens = true; + break; + case "show_method_def": + show_method_def = true; + break; + case "show_method_ref": + show_method_ref = true; + break; + case "show_parser": + show_parser = true; + break; + case "-about": + if (str[0] != '-') + break; + About (); + break; + case "-version": + if (str[0] != '-') + break; + Version (); + break; + default: + if (str [0] == '-') + break; + il_file_list.Add (str); + break; + } + } + } + + private string GetCommand (string str, out string command_arg) + { + int end_index = str.IndexOfAny (new char[] {':', '='}, 1); + string command = str.Substring (1, + end_index == -1 ? str.Length - 1 : end_index - 1); + + if (end_index != -1) { + command_arg = str.Substring (end_index+1); + } else { + command_arg = null; + } + + return command.ToLower (); + } + + /// <summary> + /// Get the first file name and makes it into an output file name + /// </summary> + private string CreateOutputFilename () + { + string file_name = (string)il_file_list[0]; + int ext_index = file_name.LastIndexOf ('.'); + + if (ext_index == -1) + ext_index = file_name.Length; + + return String.Format ("{0}.{1}", file_name.Substring (0, ext_index), + target_string); + } + + private void Usage () + { + Console.WriteLine ("Mono ILasm compiler\n" + + "ilasm [options] source-files\n" + + " --about About the Mono ILasm compiler\n" + + " --version Print the version number of the Mono ILasm compiler\n" + + " /output:file_name Specifies output file.\n" + + " /exe Compile to executable.\n" + + " /dll Compile to library.\n" + + " /debug Include debug information.\n" + + " /key:keyfile Strongname using the specified key file\n" + + " /key:@container Strongname using the specified key container\n" + + "Options can be of the form -option or /option\n"); + Environment.Exit (1); + } + + private void About () + { + Console.WriteLine ( + "For more information on Mono, visit the project Web site\n" + + " http://www.go-mono.com\n\n"); + Environment.Exit (0); + } + + private void Version () + { + string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString (); + Console.WriteLine ("Mono ILasm compiler version {0}", version); + Environment.Exit (0); + } + + } + } +} + |