X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdriver.cs;h=7b5d86680eb3160bf5bce1f1471f8b004743b6d4;hb=168d424a84ed56998b15dd011e49291c581dd5a9;hp=0b8b540a6c07ce20ead692e1ae24924c7e1543bb;hpb=df4276338409c92fc7109acfaa82d12f83021f99;p=mono.git diff --git a/mcs/mcs/driver.cs b/mcs/mcs/driver.cs index 0b8b540a6c0..7b5d86680eb 100644 --- a/mcs/mcs/driver.cs +++ b/mcs/mcs/driver.cs @@ -1,12 +1,14 @@ // // driver.cs: The compiler command line driver. // -// Author: Miguel de Icaza (miguel@gnu.org) +// Authors: +// Miguel de Icaza (miguel@gnu.org) +// Marek Safar (marek.safar@gmail.com) // -// Licensed under the terms of the GNU GPL +// Dual licensed under the terms of the MIT X11 or GNU GPL // -// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) -// (C) 2004, 2005 Novell, Inc +// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) +// Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc // namespace Mono.CSharp @@ -28,9 +30,8 @@ namespace Mono.CSharp /// /// The compiler driver. /// - public class Driver + class Driver { - // // Assemblies references to be linked. Initialized with // mscorlib.dll here. @@ -57,21 +58,18 @@ namespace Mono.CSharp static ArrayList link_paths; // Whether we want to only run the tokenizer - static bool tokenize = false; + bool tokenize; - static string first_source; - - static bool want_debugging_support = false; + string first_source; - static bool parse_only = false; - static bool timestamps = false; - static bool pause = false; - static bool show_counters = false; + bool want_debugging_support; + bool parse_only; + bool timestamps; // // Whether to load the initial config file (what CSC.RSP has by default) // - static bool load_default_config = true; + bool load_default_config = true; // // A list of resource files @@ -83,40 +81,51 @@ namespace Mono.CSharp // // An array of the defines from the command line // - static ArrayList defines; + ArrayList defines; // // Output file // - static string output_file = null; + static string output_file; // // Last time we took the time // - static DateTime last_time, first_time; + DateTime last_time, first_time; // // Encoding. // - static Encoding encoding; + Encoding encoding; static public void Reset () { - want_debugging_support = false; - parse_only = false; - timestamps = false; - pause = false; - show_counters = false; - load_default_config = true; embedded_resources = null; win32ResourceFile = win32IconFile = null; - defines = null; output_file = null; - encoding = null; - first_source = null; } - public static void ShowTime (string msg) + public Driver () + { + encoding = Encoding.Default; + + // + // Setup default defines + // + defines = new ArrayList (); + defines.Add ("__MonoCS__"); + } + + public static Driver Create (string [] args) + { + Driver d = new Driver (); + if (!d.ParseArguments (args)) + return null; + + return d; + } + + void ShowTime (string msg) { if (!timestamps) return; @@ -130,7 +139,7 @@ namespace Mono.CSharp (int) span.TotalSeconds, span.Milliseconds, msg); } - public static void ShowTotalTime (string msg) + void ShowTotalTime (string msg) { if (!timestamps) return; @@ -144,7 +153,7 @@ namespace Mono.CSharp (int) span.TotalSeconds, span.Milliseconds, msg); } - static void tokenize_file (SourceFile file) + void tokenize_file (CompilationUnit file) { Stream input; @@ -171,16 +180,14 @@ namespace Mono.CSharp return; } - // MonoTODO("Change error code for aborted compilation to something reasonable")] - static void parse (SourceFile file) + void Parse (CompilationUnit file) { - CSharpParser parser; Stream input; try { input = File.OpenRead (file.Name); } catch { - Report.Error (2001, "Source file `" + file.Name + "' could not be found"); + Report.Error (2001, "Source file `{0}' could not be found", file.Name); return; } @@ -194,16 +201,19 @@ namespace Mono.CSharp } reader.Position = 0; - parser = new CSharpParser (reader, file, defines); + Parse (reader, file); + input.Close (); + } + + void Parse (SeekableStreamReader reader, CompilationUnit file) + { + CSharpParser parser = new CSharpParser (reader, file, defines); parser.ErrorOutput = Report.Stderr; try { parser.parse (); } catch (Exception ex) { - Report.Error( - 666, String.Format ("Compilation aborted in file {0}, parser at {1}: {2}", - file.Name, parser.Lexer.Location, ex)); - } finally { - input.Close (); + Report.Error(589, parser.Lexer.Location, + "Compilation aborted in file `{0}', {1}", file.Name, ex); } } @@ -224,7 +234,7 @@ namespace Mono.CSharp static void Usage () { Console.WriteLine ( - "Mono C# compiler, (C) 2001 - 2008 Novell, Inc.\n" + + "Mono C# compiler, Copyright 2001 - 2008 Novell, Inc.\n" + "mcs [options] source-files\n" + " --about About the Mono C# compiler\n" + " -addmodule:M1[,Mn] Adds the module to the generated assembly\n" + @@ -274,8 +284,9 @@ namespace Mono.CSharp static void About () { Console.WriteLine ( - "The Mono C# compiler is (C) 2001-2008, Novell, Inc.\n\n" + - "The compiler source code is released under the terms of the GNU GPL\n\n" + + "The Mono C# compiler is Copyright 2001-2008, Novell, Inc.\n\n" + + "The compiler source code is released under the terms of the \n"+ + "MIT X11 or GNU GPL licenses\n\n" + "For more information on Mono, visit the project Web site\n" + " http://www.mono-project.com\n\n" + @@ -284,26 +295,20 @@ namespace Mono.CSharp Environment.Exit (0); } - public static int counter1, counter2; - public static int Main (string[] args) { RootContext.Version = LanguageVersion.Default; Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t"; - bool ok = MainDriver (args); - - if (ok && Report.Errors == 0) { + Driver d = Driver.Create (args); + if (d == null) + return 1; + + if (d.Compile () && Report.Errors == 0) { if (Report.Warnings > 0) { Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings); } - if (show_counters){ - Console.WriteLine ("Counter1: " + counter1); - Console.WriteLine ("Counter2: " + counter2); - } - if (pause) - Console.ReadLine (); return 0; } else { Console.WriteLine("Compilation failed: {0} error(s), {1} warnings", @@ -479,12 +484,6 @@ namespace Mono.CSharp return; } - static void SetupDefaultDefines () - { - defines = new ArrayList (); - defines.Add ("__MonoCS__"); - } - static string [] LoadArgs (string file) { StreamReader f; @@ -574,7 +573,7 @@ namespace Mono.CSharp pattern = spec; } - static void ProcessFile (string f) + void AddSourceFile (string f) { if (first_source == null) first_source = f; @@ -582,26 +581,125 @@ namespace Mono.CSharp Location.AddFile (f); } - static void ProcessFiles () + bool ParseArguments (string[] args) + { + references = new ArrayList (); + external_aliases = new Hashtable (); + soft_references = new ArrayList (); + modules = new ArrayList (2); + link_paths = new ArrayList (); + + ArrayList response_file_list = null; + bool parsing_options = true; + + for (int i = 0; i < args.Length; i++) { + string arg = args [i]; + if (arg.Length == 0) + continue; + + if (arg.StartsWith ("@")) { + string [] extra_args; + string response_file = arg.Substring (1); + + if (response_file_list == null) + response_file_list = new ArrayList (); + + if (response_file_list.Contains (response_file)) { + Report.Error ( + 1515, "Response file `" + response_file + + "' specified multiple times"); + return false; + } + + response_file_list.Add (response_file); + + extra_args = LoadArgs (response_file); + if (extra_args == null) { + Report.Error (2011, "Unable to open response file: " + + response_file); + return false; + } + + args = AddArgs (args, extra_args); + continue; + } + + if (parsing_options) { + if (arg == "--") { + parsing_options = false; + continue; + } + + if (arg.StartsWith ("-")) { + if (UnixParseOption (arg, ref args, ref i)) + continue; + + // Try a -CSCOPTION + string csc_opt = "/" + arg.Substring (1); + if (CSCParseOption (csc_opt, ref args, ref i)) + continue; + + Error_WrongOption (arg); + return false; + } + if (arg [0] == '/') { + if (CSCParseOption (arg, ref args, ref i)) + continue; + + // Need to skip `/home/test.cs' however /test.cs is considered as error + if (arg.Length < 2 || arg.IndexOf ('/', 2) == -1) { + Error_WrongOption (arg); + return false; + } + } + } + + ProcessSourceFiles (arg, false); + } + + // + // If we are an exe, require a source file for the entry point + // + if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe || RootContext.Target == Target.Module) { + if (first_source == null) { + Report.Error (2008, "No files to compile were specified"); + return false; + } + + } + + // + // If there is nothing to put in the assembly, and we are not a library + // + if (first_source == null && embedded_resources == null) { + Report.Error (2008, "No files to compile were specified"); + return false; + } + + return true; + } + + public void Parse () { Location.Initialize (); - foreach (SourceFile file in Location.SourceFiles) { + int files_count = Location.SourceFiles.Length; + for (int i = 0; i < files_count; ++i) { if (tokenize) { - tokenize_file (file); + tokenize_file (Location.SourceFiles [i]); } else { - parse (file); + Parse (Location.SourceFiles [i]); } } } - static void CompileFiles (string spec, bool recurse) + void ProcessSourceFiles (string spec, bool recurse) { string path, pattern; SplitPathAndPattern (spec, out path, out pattern); if (pattern.IndexOf ('*') == -1){ - ProcessFile (spec); + AddSourceFile (spec); return; } @@ -616,7 +714,7 @@ namespace Mono.CSharp return; } foreach (string f in files) { - ProcessFile (f); + AddSourceFile (f); } if (!recurse) @@ -633,7 +731,7 @@ namespace Mono.CSharp // Don't include path in this string, as each // directory entry already does - CompileFiles (d + "/" + pattern, true); + ProcessSourceFiles (d + "/" + pattern, true); } } @@ -645,13 +743,12 @@ namespace Mono.CSharp // string [] default_config = { "System", + "System.Xml", #if NET_2_1 - "agclr", "System.Core", - "System.Silverlight", - "System.Xml.Core", -#else - "System.Xml" + "System.Net", + "System.Windows", + "System.Windows.Browser", #endif #if false // @@ -721,7 +818,7 @@ namespace Mono.CSharp // deprecated in favor of the CSCParseOption, which will also handle the // options that start with a dash in the future. // - static bool UnixParseOption (string arg, ref string [] args, ref int i) + bool UnixParseOption (string arg, ref string [] args, ref int i) { switch (arg){ case "-v": @@ -765,23 +862,6 @@ namespace Mono.CSharp defines.Add (args [++i]); return true; - case "--show-counters": - show_counters = true; - return true; - - case "--expect-error": { - int code = 0; - - try { - code = Int32.Parse ( - args [++i], NumberStyles.AllowLeadingSign); - Report.ExpectedError = code; - } catch { - Report.Error (-14, "Invalid number specified"); - } - return true; - } - case "--tokenize": tokenize = true; return true; @@ -960,7 +1040,7 @@ namespace Mono.CSharp Report.Error (5, "--recurse requires an argument"); Environment.Exit (1); } - CompileFiles (args [++i], true); + ProcessSourceFiles (args [++i], true); return true; case "--timestamp": @@ -968,10 +1048,6 @@ namespace Mono.CSharp last_time = first_time = DateTime.Now; return true; - case "--pause": - pause = true; - return true; - case "--debug": case "-g": Report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug"); want_debugging_support = true; @@ -990,7 +1066,7 @@ namespace Mono.CSharp // This parses the -arg and /arg options to the compiler, even if the strings // in the following text use "/arg" on the strings. // - static bool CSCParseOption (string option, ref string [] args, ref int i) + bool CSCParseOption (string option, ref string [] args, ref int i) { int idx = option.IndexOf (':'); string arg, value; @@ -1165,7 +1241,7 @@ namespace Mono.CSharp Report.Error (5, "-recurse requires an argument"); Environment.Exit (1); } - CompileFiles (value, true); + ProcessSourceFiles (value, true); return true; case "/r": @@ -1490,139 +1566,21 @@ namespace Mono.CSharp return true; } - /// - /// Parses the arguments, and drives the compilation - /// process. - /// - /// - /// - /// TODO: Mostly structured to debug the compiler - /// now, needs to be turned into a real driver soon. - /// - // [MonoTODO("Change error code for unknown argument to something reasonable")] - internal static bool MainDriver (string [] args) + // + // Main compilation method + // + public bool Compile () { - int i; - bool parsing_options = true; - - encoding = Encoding.Default; - - references = new ArrayList (); - external_aliases = new Hashtable (); - soft_references = new ArrayList (); - modules = new ArrayList (); - link_paths = new ArrayList (); - - SetupDefaultDefines (); - - // - // Setup defaults - // - // This is not required because Assembly.Load knows about this - // path. - // - - Hashtable response_file_list = null; - - for (i = 0; i < args.Length; i++){ - string arg = args [i]; - if (arg.Length == 0) - continue; - - if (arg.StartsWith ("@")){ - string [] extra_args; - string response_file = arg.Substring (1); - - if (response_file_list == null) - response_file_list = new Hashtable (); - - if (response_file_list.Contains (response_file)){ - Report.Error ( - 1515, "Response file `" + response_file + - "' specified multiple times"); - Environment.Exit (1); - } - - response_file_list.Add (response_file, response_file); - - extra_args = LoadArgs (response_file); - if (extra_args == null){ - Report.Error (2011, "Unable to open response file: " + - response_file); - return false; - } - - args = AddArgs (args, extra_args); - continue; - } - - if (parsing_options){ - if (arg == "--"){ - parsing_options = false; - continue; - } - - if (arg.StartsWith ("-")){ - if (UnixParseOption (arg, ref args, ref i)) - continue; - - // Try a -CSCOPTION - string csc_opt = "/" + arg.Substring (1); - if (CSCParseOption (csc_opt, ref args, ref i)) - continue; - - Error_WrongOption (arg); - return false; - } else { - if (arg [0] == '/'){ - if (CSCParseOption (arg, ref args, ref i)) - continue; - - // Need to skip `/home/test.cs' however /test.cs is considered as error - if (arg.Length < 2 || arg.IndexOf ('/', 2) == -1) { - Error_WrongOption (arg); - return false; - } - } - } - } - - CompileFiles (arg, false); - } - - ProcessFiles (); + Parse (); + if (Report.Errors > 0) + return false; - if (tokenize) + if (tokenize || parse_only) return true; if (RootContext.ToplevelTypes.NamespaceEntry != null) throw new InternalErrorException ("who set it?"); - // - // If we are an exe, require a source file for the entry point - // - if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe || RootContext.Target == Target.Module){ - if (first_source == null){ - Report.Error (2008, "No files to compile were specified"); - return false; - } - - } - - // - // If there is nothing to put in the assembly, and we are not a library - // - if (first_source == null && embedded_resources == null){ - Report.Error (2008, "No files to compile were specified"); - return false; - } - - if (Report.Errors > 0) - return false; - - if (parse_only) - return true; - if (load_default_config) DefineDefaultConfig (); @@ -1812,15 +1770,14 @@ namespace Mono.CSharp // Add Win32 resources // - CodeGen.Assembly.Builder.DefineVersionInfoResource (); - if (win32ResourceFile != null) { try { CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile); - } - catch (ArgumentException) { + } catch (ArgumentException) { Report.RuntimeMissingSupport (Location.Null, "resource embeding"); } + } else { + CodeGen.Assembly.Builder.DefineVersionInfoResource (); } if (win32IconFile != null) { @@ -1834,7 +1791,7 @@ namespace Mono.CSharp if (Report.Errors > 0) return false; - CodeGen.Save (output_file); + CodeGen.Save (output_file, want_debugging_support); if (timestamps) { ShowTime ("Saved output"); ShowTotalTime ("Total"); @@ -1982,7 +1939,11 @@ namespace Mono.CSharp { Report.Stderr = error; try { - return Driver.MainDriver (args) && Report.Errors == 0; + Driver d = Driver.Create (args); + if (d == null) + return false; + + return d.Compile () && Report.Errors == 0; } finally { Report.Stderr = Console.Error; @@ -2010,6 +1971,9 @@ namespace Mono.CSharp CodeGen.Reset (); Attribute.Reset (); AttributeTester.Reset (); + AnonymousTypeClass.Reset (); + AnonymousMethodBody.Reset (); + AnonymousMethodStorey.Reset (); } } }