**** Merged from MCS ****
[mono.git] / mcs / gmcs / driver.cs
1 //
2 // driver.cs: The compiler command line driver.
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //
6 // Licensed under the terms of the GNU GPL
7 //
8 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
9 //
10
11 namespace Mono.CSharp
12 {
13         using System;
14         using System.Reflection;
15         using System.Reflection.Emit;
16         using System.Collections;
17         using System.IO;
18         using System.Text;
19         using System.Globalization;
20
21         public enum Target {
22                 Library, Exe, Module, WinExe
23         };
24         
25         /// <summary>
26         ///    The compiler driver.
27         /// </summary>
28         public class Driver
29         {
30                 
31                 //
32                 // Assemblies references to be linked.   Initialized with
33                 // mscorlib.dll here.
34                 static ArrayList references;
35
36                 //
37                 // If any of these fail, we ignore the problem.  This is so
38                 // that we can list all the assemblies in Windows and not fail
39                 // if they are missing on Linux.
40                 //
41                 static ArrayList soft_references;
42
43                 //
44                 // Modules to be linked
45                 //
46                 static ArrayList modules;
47
48                 // Lookup paths
49                 static ArrayList link_paths;
50
51                 // Whether we want Yacc to output its progress
52                 static bool yacc_verbose = false;
53
54                 // Whether we want to only run the tokenizer
55                 static bool tokenize = false;
56                 
57                 static string first_source;
58
59                 static bool want_debugging_support = false;
60
61                 static bool parse_only = false;
62                 static bool timestamps = false;
63                 static bool pause = false;
64                 static bool show_counters = false;
65                 public static bool parser_verbose = false;
66                 
67                 //
68                 // Whether to load the initial config file (what CSC.RSP has by default)
69                 // 
70                 static bool load_default_config = true;
71
72                 static Hashtable response_file_list;
73
74                 //
75                 // A list of resource files
76                 //
77                 static ArrayList resources;
78                 static ArrayList embedded_resources;
79                 static string win32ResourceFile;
80                 static string win32IconFile;
81                 
82                 //
83                 // An array of the defines from the command line
84                 //
85                 static ArrayList defines;
86
87                 //
88                 // Output file
89                 //
90                 static string output_file = null;
91
92                 //
93                 // Last time we took the time
94                 //
95                 static DateTime last_time, first_time;
96
97                 //
98                 // Encoding: ISO-Latin1 is 28591
99                 //
100                 static Encoding encoding;
101
102                 //
103                 // Whether the user has specified a different encoder manually
104                 //
105                 static bool using_default_encoder = true;
106                 
107                 public static void ShowTime (string msg)
108                 {
109                         if (!timestamps)
110                                 return;
111
112                         DateTime now = DateTime.Now;
113                         TimeSpan span = now - last_time;
114                         last_time = now;
115
116                         Console.WriteLine (
117                                 "[{0:00}:{1:000}] {2}",
118                                 (int) span.TotalSeconds, span.Milliseconds, msg);
119                 }
120
121                 public static void ShowTotalTime (string msg)
122                 {
123                         if (!timestamps)
124                                 return;
125
126                         DateTime now = DateTime.Now;
127                         TimeSpan span = now - first_time;
128                         last_time = now;
129
130                         Console.WriteLine (
131                                 "[{0:00}:{1:000}] {2}",
132                                 (int) span.TotalSeconds, span.Milliseconds, msg);
133                 }              
134                
135                 static void tokenize_file (SourceFile file)
136                 {
137                         Stream input;
138
139                         try {
140                                 input = File.OpenRead (file.Name);
141                         } catch {
142                                 Report.Error (2001, "Source file '" + file.Name + "' could not be opened");
143                                 return;
144                         }
145
146                         using (input){
147                                 SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
148                                 Tokenizer lexer = new Tokenizer (reader, file, defines);
149                                 int token, tokens = 0, errors = 0;
150
151                                 while ((token = lexer.token ()) != Token.EOF){
152                                         tokens++;
153                                         if (token == Token.ERROR)
154                                                 errors++;
155                                 }
156                                 Console.WriteLine ("Tokenized: " + tokens + " found " + errors + " errors");
157                         }
158                         
159                         return;
160                 }
161
162                 // MonoTODO("Change error code for aborted compilation to something reasonable")]               
163                 static void parse (SourceFile file)
164                 {
165                         CSharpParser parser;
166                         Stream input;
167
168                         try {
169                                 input = File.OpenRead (file.Name);
170                         } catch {
171                                 Report.Error (2001, "Source file '" + file.Name + "' could not be opened");
172                                 return;
173                         }
174
175                         SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
176                                 
177                         parser = new CSharpParser (reader, file, defines);
178                         parser.yacc_verbose_flag = yacc_verbose;
179                         try {
180                                 parser.parse ();
181                         } catch (Exception ex) {
182                                 Report.Error(666, "Compilation aborted: " + ex);
183                         } finally {
184                                 input.Close ();
185                         }
186                 }
187                 
188                 static void Usage ()
189                 {
190                         Console.WriteLine (
191                                 "Mono C# compiler, (C) 2001 - 2003 Ximian, Inc.\n" +
192                                 "mcs [options] source-files\n" +
193                                 "   --about            About the Mono C# compiler\n" +
194                                 "   -checked[+|-]      Set default context to checked\n" +
195                                 "   -codepage:ID       Sets code page to the one in ID\n" +
196                                 "                      (number, `utf8' or `reset')\n" +
197                                 "   -define:S1[;S2]    Defines one or more symbols (short: /d:)\n" +
198                                 "   -debug[+-]         Generate debugging information\n" + 
199                                 "   -doc:FILE          XML Documentation file to generate\n" + 
200                                 "   -g                 Generate debugging information\n" +
201                                 "   --fatal            Makes errors fatal\n" +
202                                 "   -lib:PATH1,PATH2   Adds the paths to the assembly link path\n" +
203                                 "   -main:class        Specified the class that contains the entry point\n" +
204                                 "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
205                                 "   -nostdlib[+|-]     Does not load core libraries\n" +
206                                 "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
207                                 "   -out:FNAME         Specifies output file\n" +
208                                 "   --parse            Only parses the source file\n" +
209                                 "   --expect-error X   Expect that error X will be encountered\n" +
210                                 "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
211                                 "   -reference:ASS     References the specified assembly (-r:ASS)\n" +
212                                 "   --stacktrace       Shows stack trace at error location\n" +
213                                 "   -target:KIND       Specifies the target (KIND is one of: exe, winexe,\n" +
214                                 "                      library, module), (short: /t:)\n" +
215                                 "   --timestamp        Displays time stamps of various compiler events\n" +
216                                 "   -unsafe[+|-]       Allows unsafe code\n" +
217                                 "   -warnaserror[+|-]  Treat warnings as errors\n" +
218                                 "   -warn:LEVEL        Sets warning level (the highest is 4, the default is 2)\n" +
219                                 "   -v                 Verbose parsing (for debugging the parser)\n" +
220                                 "   -2                 Enables experimental C# features\n" +
221                                 "\n" +
222                                 "Resources:\n" +
223                                 "   -linkresource:FILE[,ID] Links FILE as a resource\n" +
224                                 "   -resource:FILE[,ID]     Embed FILE as a resource\n" +
225                                 "   -win32res:FILE          Specifies Win32 resource file (.res)\n" +
226                                 "   -win32icon:FILE         Use this icon for the output\n" +
227                                 "   --mcs-debug X      Sets MCS debugging level to X\n" +
228                                 "   @file              Read response file for more options\n\n" +
229                                 "Options can be of the form -option or /option");
230                 }
231
232                 static void TargetUsage ()
233                 {
234                         Report.Error (2019, "Valid options for -target: are exe, winexe, library or module");
235                 }
236                 
237                 static void About ()
238                 {
239                         Console.WriteLine (
240                                 "The Mono C# compiler is (C) 2001, 2002, 2003 Ximian, Inc.\n\n" +
241                                 "The compiler source code is released under the terms of the GNU GPL\n\n" +
242
243                                 "For more information on Mono, visit the project Web site\n" +
244                                 "   http://www.go-mono.com\n\n" +
245
246                                 "The compiler was written by Miguel de Icaza, Ravi Pratap and Martin Baulig");
247                         Environment.Exit (0);
248                 }
249
250                 public static int counter1, counter2;
251                 
252                 public static int Main (string[] args)
253                 {
254                         RootContext.V2 = true;
255                         bool ok = MainDriver (args);
256                         
257                         if (ok && Report.Errors == 0) {
258                                 Console.Write("Compilation succeeded");
259                                 if (Report.Warnings > 0) {
260                                         Console.Write(" - {0} warning(s)", Report.Warnings);
261                                 }
262                                 Console.WriteLine();
263                                 if (show_counters){
264                                         Console.WriteLine ("Counter1: " + counter1);
265                                         Console.WriteLine ("Counter2: " + counter2);
266                                 }
267                                 if (pause)
268                                         Console.ReadLine ();
269                                 return 0;
270                         } else {
271                                 Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
272                                         Report.Errors, Report.Warnings);
273                                 return 1;
274                         }
275                 }
276
277                 static public void LoadAssembly (string assembly, bool soft)
278                 {
279                         Assembly a;
280                         string total_log = "";
281
282                         try {
283                                 char[] path_chars = { '/', '\\', '.' };
284
285                                 if (assembly.IndexOfAny (path_chars) != -1) {
286                                         a = Assembly.LoadFrom (assembly);
287                                 } else {
288                                         a = Assembly.Load (assembly);
289                                 }
290                                 TypeManager.AddAssembly (a);
291
292                         } catch (FileNotFoundException){
293                                 foreach (string dir in link_paths){
294                                         string full_path = Path.Combine (dir, assembly);
295                                         if (!assembly.EndsWith (".dll"))
296                                                 full_path += ".dll";
297
298                                         try {
299                                                 a = Assembly.LoadFrom (full_path);
300                                                 TypeManager.AddAssembly (a);
301                                                 return;
302                                         } catch (FileNotFoundException ff) {
303                                                 total_log += ff.FusionLog;
304                                                 continue;
305                                         }
306                                 }
307                                 if (!soft) {
308                                         Report.Error (6, "Cannot find assembly `" + assembly + "'" );
309                                         Console.WriteLine ("Log: \n" + total_log);
310                                 }
311                         } catch (BadImageFormatException f) {
312                                 Report.Error(6, "Cannot load assembly (bad file format)" + f.FusionLog);
313                         } catch (FileLoadException f){
314                                 Report.Error(6, "Cannot load assembly " + f.FusionLog);
315                         } catch (ArgumentNullException){
316                                 Report.Error(6, "Cannot load assembly (null argument)");
317                         }
318                 }
319
320                 static public void LoadModule (MethodInfo adder_method, string module)
321                 {
322                         Module m;
323                         string total_log = "";
324
325                         try {
326                                 try {
327                                         m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { module });
328                                 }
329                                 catch (TargetInvocationException ex) {
330                                         throw ex.InnerException;
331                                 }
332                                 TypeManager.AddModule (m);
333
334                         } 
335                         catch (FileNotFoundException){
336                                 foreach (string dir in link_paths){
337                                         string full_path = Path.Combine (dir, module);
338                                         if (!module.EndsWith (".netmodule"))
339                                                 full_path += ".netmodule";
340
341                                         try {
342                                                 try {
343                                                         m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { full_path });
344                                                 }
345                                                 catch (TargetInvocationException ex) {
346                                                         throw ex.InnerException;
347                                                 }
348                                                 TypeManager.AddModule (m);
349                                                 return;
350                                         } catch (FileNotFoundException ff) {
351                                                 total_log += ff.FusionLog;
352                                                 continue;
353                                         }
354                                 }
355                                 Report.Error (6, "Cannot find module `" + module + "'" );
356                                 Console.WriteLine ("Log: \n" + total_log);
357                         } catch (BadImageFormatException f) {
358                                 Report.Error(6, "Cannot load module (bad file format)" + f.FusionLog);
359                         } catch (FileLoadException f){
360                                 Report.Error(6, "Cannot load module " + f.FusionLog);
361                         } catch (ArgumentNullException){
362                                 Report.Error(6, "Cannot load module (null argument)");
363                         }
364                 }
365
366                 /// <summary>
367                 ///   Loads all assemblies referenced on the command line
368                 /// </summary>
369                 static public void LoadReferences ()
370                 {
371                         foreach (string r in references)
372                                 LoadAssembly (r, false);
373
374                         foreach (string r in soft_references)
375                                 LoadAssembly (r, true);
376                         
377                         return;
378                 }
379
380                 static void SetupDefaultDefines ()
381                 {
382                         defines = new ArrayList ();
383                         defines.Add ("__MonoCS__");
384                 }
385
386                 static string [] LoadArgs (string file)
387                 {
388                         StreamReader f;
389                         ArrayList args = new ArrayList ();
390                         string line;
391                         try {
392                                 f = new StreamReader (file);
393                         } catch {
394                                 return null;
395                         }
396
397                         StringBuilder sb = new StringBuilder ();
398                         
399                         while ((line = f.ReadLine ()) != null){
400                                 int t = line.Length;
401
402                                 for (int i = 0; i < t; i++){
403                                         char c = line [i];
404                                         
405                                         if (c == '"' || c == '\''){
406                                                 char end = c;
407                                                 
408                                                 for (i++; i < t; i++){
409                                                         c = line [i];
410
411                                                         if (c == end)
412                                                                 break;
413                                                         sb.Append (c);
414                                                 }
415                                         } else if (c == ' '){
416                                                 if (sb.Length > 0){
417                                                         args.Add (sb.ToString ());
418                                                         sb.Length = 0;
419                                                 }
420                                         } else
421                                                 sb.Append (c);
422                                 }
423                                 if (sb.Length > 0){
424                                         args.Add (sb.ToString ());
425                                         sb.Length = 0;
426                                 }
427                         }
428
429                         string [] ret_value = new string [args.Count];
430                         args.CopyTo (ret_value, 0);
431
432                         return ret_value;
433                 }
434
435                 //
436                 // Returns the directory where the system assemblies are installed
437                 //
438                 static string GetSystemDir ()
439                 {
440                         Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
441
442                         foreach (Assembly a in assemblies){
443                                 string codebase = a.Location;
444                                 string fn = System.IO.Path.GetFileName (codebase);
445                                 if (fn == "corlib.dll" || fn == "mscorlib.dll"){
446                                         return codebase.Substring (0, codebase.LastIndexOf (System.IO.Path.DirectorySeparatorChar));
447                                 }
448                         }
449
450                         Report.Error (-15, "Can not compute my system path");
451                         return "";
452                 }
453
454                 //
455                 // Given a path specification, splits the path from the file/pattern
456                 //
457                 static void SplitPathAndPattern (string spec, out string path, out string pattern)
458                 {
459                         int p = spec.LastIndexOf ('/');
460                         if (p != -1){
461                                 //
462                                 // Windows does not like /file.cs, switch that to:
463                                 // "\", "file.cs"
464                                 //
465                                 if (p == 0){
466                                         path = "\\";
467                                         pattern = spec.Substring (1);
468                                 } else {
469                                         path = spec.Substring (0, p);
470                                         pattern = spec.Substring (p + 1);
471                                 }
472                                 return;
473                         }
474
475                         p = spec.LastIndexOf ('\\');
476                         if (p != -1){
477                                 path = spec.Substring (0, p);
478                                 pattern = spec.Substring (p + 1);
479                                 return;
480                         }
481
482                         path = ".";
483                         pattern = spec;
484                 }
485
486                 static void ProcessFile (string f)
487                 {
488                         if (first_source == null)
489                                 first_source = f;
490
491                         Location.AddFile (f);
492                 }
493
494                 static void ProcessFiles ()
495                 {
496                         Location.Initialize ();
497
498                         foreach (SourceFile file in Location.SourceFiles) {
499                                 if (tokenize) {
500                                         tokenize_file (file);
501                                 } else {
502                                         parse (file);
503                                 }
504                         }
505                 }
506
507                 static void CompileFiles (string spec, bool recurse)
508                 {
509                         string path, pattern;
510
511                         SplitPathAndPattern (spec, out path, out pattern);
512                         if (pattern.IndexOf ('*') == -1){
513                                 ProcessFile (spec);
514                                 return;
515                         }
516
517                         string [] files = null;
518                         try {
519                                 files = Directory.GetFiles (path, pattern);
520                         } catch (System.IO.DirectoryNotFoundException) {
521                                 Report.Error (2001, "Source file `" + spec + "' could not be found");
522                                 return;
523                         } catch (System.IO.IOException){
524                                 Report.Error (2001, "Source file `" + spec + "' could not be found");
525                                 return;
526                         }
527                         foreach (string f in files) {
528                                 ProcessFile (f);
529                         }
530
531                         if (!recurse)
532                                 return;
533                         
534                         string [] dirs = null;
535
536                         try {
537                                 dirs = Directory.GetDirectories (path);
538                         } catch {
539                         }
540                         
541                         foreach (string d in dirs) {
542                                         
543                                 // Don't include path in this string, as each
544                                 // directory entry already does
545                                 CompileFiles (d + "/" + pattern, true);
546                         }
547                 }
548
549                 static void DefineDefaultConfig ()
550                 {
551                         //
552                         // For now the "default config" is harcoded into the compiler
553                         // we can move this outside later
554                         //
555                         string [] default_config = {
556                                 "System",
557                                 "System.Xml",
558 #if false
559                                 //
560                                 // Is it worth pre-loading all this stuff?
561                                 //
562                                 "Accessibility",
563                                 "System.Configuration.Install",
564                                 "System.Data",
565                                 "System.Design",
566                                 "System.DirectoryServices",
567                                 "System.Drawing.Design",
568                                 "System.Drawing",
569                                 "System.EnterpriseServices",
570                                 "System.Management",
571                                 "System.Messaging",
572                                 "System.Runtime.Remoting",
573                                 "System.Runtime.Serialization.Formatters.Soap",
574                                 "System.Security",
575                                 "System.ServiceProcess",
576                                 "System.Web",
577                                 "System.Web.RegularExpressions",
578                                 "System.Web.Services",
579                                 "System.Windows.Forms"
580 #endif
581                         };
582                         
583                         int p = 0;
584                         foreach (string def in default_config)
585                                 soft_references.Insert (p++, def);
586                 }
587
588                 static void SetOutputFile (string name)
589                 {
590                         output_file = name;
591                 }
592
593                 static void SetWarningLevel (string s)
594                 {
595                         int level = 0;
596
597                         try {
598                                 level = Int32.Parse (s);
599                         } catch {
600                                 Report.Error (
601                                         1900,
602                                         "--wlevel requires a value from 0 to 4");
603                                 Environment.Exit (1);
604                         }
605                         if (level < 0 || level > 4){
606                                 Report.Error (1900, "Warning level must be 0 to 4");
607                                 Environment.Exit (1);
608                         }
609                         RootContext.WarningLevel = level;
610                         TestWarningConflict ();
611                 }
612
613                 static void TestWarningConflict ()
614                 {
615                         if (RootContext.WarningLevel == 0 && Report.WarningsAreErrors) {
616                                 Report.Error (1901, "Conflicting options specified: Warning level 0; Treat warnings as errors");
617                                 Environment.Exit (1);
618                         }
619                 }
620
621                 static void SetupV2 ()
622                 {
623                         RootContext.V2 = true;
624                         defines.Add ("__V2__");
625                 }
626                 
627                 static void Version ()
628                 {
629                         string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
630                         Console.WriteLine ("Mono C# compiler version {0}", version);
631                         Environment.Exit (0);
632                 }
633                 
634                 //
635                 // Currently handles the Unix-like command line options, but will be
636                 // deprecated in favor of the CSCParseOption, which will also handle the
637                 // options that start with a dash in the future.
638                 //
639                 static bool UnixParseOption (string arg, ref string [] args, ref int i)
640                 {
641                         switch (arg){
642                         case "-vv":
643                                 parser_verbose = true;
644                                 return true;
645                                 
646                         case "-v":
647                                 yacc_verbose = true;
648                                 return true;
649
650                         case "--version":
651                                 Version ();
652                                 return true;
653                                 
654                         case "--parse":
655                                 parse_only = true;
656                                 return true;
657                                 
658                         case "--main": case "-m":
659                                 if ((i + 1) >= args.Length){
660                                         Usage ();
661                                         Environment.Exit (1);
662                                 }
663                                 RootContext.MainClass = args [++i];
664                                 return true;
665                                 
666                         case "--unsafe":
667                                 RootContext.Unsafe = true;
668                                 return true;
669                                 
670                         case "/?": case "/h": case "/help":
671                         case "--help":
672                                 Usage ();
673                                 Environment.Exit (0);
674                                 return true;
675                                 
676                         case "--define":
677                                 if ((i + 1) >= args.Length){
678                                         Usage ();
679                                         Environment.Exit (1);
680                                 }
681                                 defines.Add (args [++i]);
682                                 return true;
683
684                         case "--show-counters":
685                                 show_counters = true;
686                                 return true;
687                                 
688                         case "--expect-error": {
689                                 int code = 0;
690                                 
691                                 try {
692                                         code = Int32.Parse (
693                                                 args [++i], NumberStyles.AllowLeadingSign);
694                                         Report.ExpectedError = code;
695                                 } catch {
696                                         Report.Error (-14, "Invalid number specified");
697                                 } 
698                                 return true;
699                         }
700                                 
701                         case "--tokenize": 
702                                 tokenize = true;
703                                 return true;
704                                 
705                         case "-o": 
706                         case "--output":
707                                 if ((i + 1) >= args.Length){
708                                         Usage ();
709                                         Environment.Exit (1);
710                                 }
711                                 SetOutputFile (args [++i]);
712                                 return true;
713                                 
714                         case "--checked":
715                                 RootContext.Checked = true;
716                                 return true;
717                                 
718                         case "--stacktrace":
719                                 Report.Stacktrace = true;
720                                 return true;
721                                 
722                         case "--linkresource":
723                         case "--linkres":
724                                 if ((i + 1) >= args.Length){
725                                         Usage ();
726                                         Report.Error (5, "Missing argument to --linkres"); 
727                                         Environment.Exit (1);
728                                 }
729                                 if (resources == null)
730                                         resources = new ArrayList ();
731                                 
732                                 resources.Add (args [++i]);
733                                 return true;
734                                 
735                         case "--resource":
736                         case "--res":
737                                 if ((i + 1) >= args.Length){
738                                         Usage ();
739                                         Report.Error (5, "Missing argument to --resource"); 
740                                         Environment.Exit (1);
741                                 }
742                                 if (embedded_resources == null)
743                                         embedded_resources = new ArrayList ();
744                                 
745                                 embedded_resources.Add (args [++i]);
746                                 return true;
747                                 
748                         case "--target":
749                                 if ((i + 1) >= args.Length){
750                                         Environment.Exit (1);
751                                         return true;
752                                 }
753                                 
754                                 string type = args [++i];
755                                 switch (type){
756                                 case "library":
757                                         RootContext.Target = Target.Library;
758                                         RootContext.TargetExt = ".dll";
759                                         break;
760                                         
761                                 case "exe":
762                                         RootContext.Target = Target.Exe;
763                                         break;
764                                         
765                                 case "winexe":
766                                         RootContext.Target = Target.WinExe;
767                                         break;
768                                         
769                                 case "module":
770                                         RootContext.Target = Target.Module;
771                                         RootContext.TargetExt = ".dll";
772                                         break;
773                                 default:
774                                         TargetUsage ();
775                                         Environment.Exit (1);
776                                         break;
777                                 }
778                                 return true;
779                                 
780                         case "-r":
781                                 if ((i + 1) >= args.Length){
782                                         Usage ();
783                                         Environment.Exit (1);
784                                 }
785                                 
786                                 references.Add (args [++i]);
787                                 return true;
788                                 
789                         case "-L":
790                                 if ((i + 1) >= args.Length){
791                                         Usage ();       
792                                         Environment.Exit (1);
793                                 }
794                                 link_paths.Add (args [++i]);
795                                 return true;
796                                 
797                         case "--nostdlib":
798                                 RootContext.StdLib = false;
799                                 return true;
800                                 
801                         case "--fatal":
802                                 Report.Fatal = true;
803                                 return true;
804                                 
805                         case "--werror":
806                                 Report.WarningsAreErrors = true;
807                                 TestWarningConflict();
808                                 return true;
809                                 
810                         case "--nowarn":
811                                 if ((i + 1) >= args.Length){
812                                         Usage ();
813                                         Environment.Exit (1);
814                                 }
815                                 int warn = 0;
816                                 
817                                 try {
818                                         warn = Int32.Parse (args [++i]);
819                                 } catch {
820                                         Usage ();
821                                         Environment.Exit (1);
822                                 }
823                                 Report.SetIgnoreWarning (warn);
824                                 return true;
825                                 
826                         case "--wlevel":
827                                 if ((i + 1) >= args.Length){
828                                         Report.Error (
829                                                 1900,
830                                                 "--wlevel requires a value from 0 to 4");
831                                         Environment.Exit (1);
832                                 }
833
834                                 SetWarningLevel (args [++i]);
835                                 return true;
836
837                         case "--mcs-debug":
838                                 if ((i + 1) >= args.Length){
839                                         Report.Error (5, "--mcs-debug requires an argument");
840                                         Environment.Exit (1);
841                                 }
842
843                                 try {
844                                         Report.DebugFlags = Int32.Parse (args [++i]);
845                                 } catch {
846                                         Report.Error (5, "Invalid argument to --mcs-debug");
847                                         Environment.Exit (1);
848                                 }
849                                 return true;
850                                 
851                         case "--about":
852                                 About ();
853                                 return true;
854                                 
855                         case "--recurse":
856                                 if ((i + 1) >= args.Length){
857                                         Report.Error (5, "--recurse requires an argument");
858                                         Environment.Exit (1);
859                                 }
860                                 CompileFiles (args [++i], true); 
861                                 return true;
862                                 
863                         case "--timestamp":
864                                 timestamps = true;
865                                 last_time = first_time = DateTime.Now;
866                                 return true;
867
868                         case "--pause":
869                                 pause = true;
870                                 return true;
871                                 
872                         case "--debug": case "-g":
873                                 want_debugging_support = true;
874                                 return true;
875                                 
876                         case "--noconfig":
877                                 load_default_config = false;
878                                 return true;
879                         }
880
881                         return false;
882                 }
883
884                 //
885                 // Currently it is very basic option parsing, but eventually, this will
886                 // be the complete option parser
887                 //
888                 static bool CSCParseOption (string option, ref string [] args, ref int i)
889                 {
890                         int idx = option.IndexOf (':');
891                         string arg, value;
892
893                         if (idx == -1){
894                                 arg = option;
895                                 value = "";
896                         } else {
897                                 arg = option.Substring (0, idx);
898
899                                 value = option.Substring (idx + 1);
900                         }
901
902                         switch (arg){
903                         case "/nologo":
904                                 return true;
905
906                         case "/t":
907                         case "/target":
908                                 switch (value){
909                                 case "exe":
910                                         RootContext.Target = Target.Exe;
911                                         break;
912
913                                 case "winexe":
914                                         RootContext.Target = Target.WinExe;
915                                         break;
916
917                                 case "library":
918                                         RootContext.Target = Target.Library;
919                                         RootContext.TargetExt = ".dll";
920                                         break;
921
922                                 case "module":
923                                         RootContext.Target = Target.Module;
924                                         RootContext.TargetExt = ".netmodule";
925                                         break;
926
927                                 default:
928                                         TargetUsage ();
929                                         Environment.Exit (1);
930                                         break;
931                                 }
932                                 return true;
933
934                         case "/out":
935                                 if (value == ""){
936                                         Usage ();
937                                         Environment.Exit (1);
938                                 }
939                                 SetOutputFile (value);
940                                 return true;
941
942                         case "/optimize":
943                         case "/optimize+":
944                         case "/optimize-":
945                         case "/incremental":
946                         case "/incremental+":
947                         case "/incremental-":
948                                 // nothing.
949                                 return true;
950
951                         case "/d":
952                         case "/define": {
953                                 string [] defs;
954
955                                 if (value == ""){
956                                         Usage ();
957                                         Environment.Exit (1);
958                                 }
959
960                                 defs = value.Split (new Char [] {';', ','});
961                                 foreach (string d in defs){
962                                         defines.Add (d);
963                                 }
964                                 return true;
965                         }
966
967                         case "/linkres":
968                         case "/linkresource":
969                                 if (value == ""){
970                                         Report.Error (5, arg + " requires an argument");
971                                         Environment.Exit (1);
972                                 }
973                                 if (resources == null)
974                                         resources = new ArrayList ();
975                                 
976                                 resources.Add (value);
977                                 return true;
978                                 
979                         case "/res":
980                         case "/resource":
981                                 if (value == ""){
982                                         Report.Error (5, arg + " requires an argument");
983                                         Environment.Exit (1);
984                                 }
985                                 if (embedded_resources == null)
986                                         embedded_resources = new ArrayList ();
987                                 
988                                 embedded_resources.Add (value);
989                                 return true;
990                                 
991                         case "/recurse":
992                                 if (value == ""){
993                                         Report.Error (5, "/recurse requires an argument");
994                                         Environment.Exit (1);
995                                 }
996                                 CompileFiles (value, true); 
997                                 return true;
998
999                         case "/r":
1000                         case "/reference": {
1001                                 if (value == ""){
1002                                         Report.Error (5, arg + " requires an argument");
1003                                         Environment.Exit (1);
1004                                 }
1005
1006                                 string [] refs = value.Split (new char [] { ';', ',' });
1007                                 foreach (string r in refs){
1008                                         references.Add (r);
1009                                 }
1010                                 return true;
1011                         }
1012                         case "/addmodule": {
1013                                 if (value == ""){
1014                                         Report.Error (5, arg + " requires an argument");
1015                                         Environment.Exit (1);
1016                                 }
1017
1018                                 string [] refs = value.Split (new char [] { ';', ',' });
1019                                 foreach (string r in refs){
1020                                         modules.Add (r);
1021                                 }
1022                                 return true;
1023                         }
1024                         case "/win32res": {
1025                                 if (value == "") {
1026                                         Report.Error (5, arg + " requires an argument");
1027                                         Environment.Exit (1);
1028                                 }
1029
1030                                 win32ResourceFile = value;
1031                                 return true;
1032                         }
1033                         case "/win32icon": {
1034                                 if (value == "") {
1035                                         Report.Error (5, arg + " requires an argument");
1036                                         Environment.Exit (1);
1037                                 }
1038
1039                                 win32IconFile = value;
1040                                 return true;
1041                         }
1042                         case "/doc": {
1043                                 if (value == ""){
1044                                         Report.Error (5, arg + " requires an argument");
1045                                         Environment.Exit (1);
1046                                 }
1047                                 // TODO handle the /doc argument to generate xml doc
1048                                 return true;
1049                         }
1050                         case "/lib": {
1051                                 string [] libdirs;
1052                                 
1053                                 if (value == ""){
1054                                         Report.Error (5, "/lib requires an argument");
1055                                         Environment.Exit (1);
1056                                 }
1057
1058                                 libdirs = value.Split (new Char [] { ',' });
1059                                 foreach (string dir in libdirs)
1060                                         link_paths.Add (dir);
1061                                 return true;
1062                         }
1063                                 
1064                         case "/debug":
1065                         case "/debug+":
1066                                 want_debugging_support = true;
1067                                 return true;
1068
1069                         case "/checked":
1070                         case "/checked+":
1071                                 RootContext.Checked = true;
1072                                 return true;
1073
1074                         case "/checked-":
1075                                 RootContext.Checked = false;
1076                                 return true;
1077
1078                         case "/unsafe":
1079                         case "/unsafe+":
1080                                 RootContext.Unsafe = true;
1081                                 return true;
1082
1083                         case "/unsafe-":
1084                                 RootContext.Unsafe = false;
1085                                 return true;
1086
1087                         case "/warnaserror":
1088                         case "/warnaserror+":
1089                                 Report.WarningsAreErrors = true;
1090                                 TestWarningConflict();
1091                                 return true;
1092
1093                         case "/warnaserror-":
1094                                 Report.WarningsAreErrors = false;
1095                                 return true;
1096
1097                         case "/warn":
1098                                 SetWarningLevel (value);
1099                                 return true;
1100
1101                         case "/nowarn": {
1102                                 string [] warns;
1103
1104                                 if (value == ""){
1105                                         Report.Error (5, "/nowarn requires an argument");
1106                                         Environment.Exit (1);
1107                                 }
1108                                 
1109                                 warns = value.Split (new Char [] {','});
1110                                 foreach (string wc in warns){
1111                                         try {
1112                                                 int warn = Int32.Parse (wc);
1113                                                 if (warn < 1) {
1114                                                         throw new ArgumentOutOfRangeException("warn");
1115                                                 }
1116                                                 Report.SetIgnoreWarning (warn);
1117                                         } catch {
1118                                                 Report.Error (1904, String.Format("'{0}' is not a valid warning number", wc));
1119                                                 Environment.Exit (1);
1120                                         }
1121                                 }
1122                                 return true;
1123                         }
1124
1125                         case "/noconfig-":
1126                                 load_default_config = true;
1127                                 return true;
1128                                 
1129                         case "/noconfig":
1130                         case "/noconfig+":
1131                                 load_default_config = false;
1132                                 return true;
1133
1134                         case "/help":
1135                         case "/?":
1136                                 Usage ();
1137                                 Environment.Exit (0);
1138                                 return true;
1139
1140                         case "/main":
1141                         case "/m":
1142                                 if (value == ""){
1143                                         Report.Error (5, arg + " requires an argument");                                        
1144                                         Environment.Exit (1);
1145                                 }
1146                                 RootContext.MainClass = value;
1147                                 return true;
1148
1149                         case "/nostdlib":
1150                         case "/nostdlib+":
1151                                 RootContext.StdLib = false;
1152                                 return true;
1153
1154                         case "/nostdlib-":
1155                                 RootContext.StdLib = true;
1156                                 return true;
1157
1158                         case "/fullpaths":
1159                                 return true;
1160
1161                         case "/v2":
1162                         case "/2":
1163                                 SetupV2 ();
1164                                 return true;
1165                                 
1166                         case "/codepage":
1167                                 int cp = -1;
1168
1169                                 if (value == "utf8"){
1170                                         encoding = new UTF8Encoding();
1171                                         using_default_encoder = false;
1172                                         return true;
1173                                 }
1174                                 if (value == "reset"){
1175                                         //
1176                                         // 28591 is the code page for ISO-8859-1 encoding.
1177                                         //
1178                                         cp = 28591;
1179                                         using_default_encoder = true;
1180                                 }
1181                                 
1182                                 try {
1183                                         cp = Int32.Parse (value);
1184                                         encoding = Encoding.GetEncoding (cp);
1185                                         using_default_encoder = false;
1186                                 } catch {
1187                                         Report.Error (2016, String.Format("Code page '{0}' is invalid or not installed", cp));
1188                                         Environment.Exit (1);
1189                                 }
1190                                 return true;
1191                         }
1192                         //Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
1193                         //Environment.Exit (1);
1194                         return false;
1195                 }
1196                 
1197                 /// <summary>
1198                 ///    Parses the arguments, and drives the compilation
1199                 ///    process.
1200                 /// </summary>
1201                 ///
1202                 /// <remarks>
1203                 ///    TODO: Mostly structured to debug the compiler
1204                 ///    now, needs to be turned into a real driver soon.
1205                 /// </remarks>
1206                 // [MonoTODO("Change error code for unknown argument to something reasonable")]
1207                 internal static bool MainDriver (string [] args)
1208                 {
1209                         int i;
1210                         bool parsing_options = true;
1211
1212                         Console.WriteLine ("Mono C# Compiler {0} for Generics",
1213                                            Assembly.GetExecutingAssembly ().GetName ().Version.ToString ());
1214                         try {
1215                                 encoding = Encoding.GetEncoding (28591);
1216                         } catch {
1217                                 Console.WriteLine ("Error: could not load encoding 28591, trying 1252");
1218                                 encoding = Encoding.GetEncoding (1252);
1219                         }
1220                         
1221                         references = new ArrayList ();
1222                         soft_references = new ArrayList ();
1223                         modules = new ArrayList ();
1224                         link_paths = new ArrayList ();
1225
1226                         SetupDefaultDefines ();
1227                         
1228                         //
1229                         // Setup defaults
1230                         //
1231                         // This is not required because Assembly.Load knows about this
1232                         // path.
1233                         //
1234
1235                         int argc = args.Length;
1236                         for (i = 0; i < argc; i++){
1237                                 string arg = args [i];
1238
1239                                 if (arg.StartsWith ("@")){
1240                                         string [] new_args, extra_args;
1241                                         string response_file = arg.Substring (1);
1242
1243                                         if (response_file_list == null)
1244                                                 response_file_list = new Hashtable ();
1245                                         
1246                                         if (response_file_list.Contains (response_file)){
1247                                                 Report.Error (
1248                                                         1515, "Response file `" + response_file +
1249                                                         "' specified multiple times");
1250                                                 Environment.Exit (1);
1251                                         }
1252                                         
1253                                         response_file_list.Add (response_file, response_file);
1254                                                     
1255                                         extra_args = LoadArgs (response_file);
1256                                         if (extra_args == null){
1257                                                 Report.Error (2011, "Unable to open response file: " +
1258                                                               response_file);
1259                                                 return false;
1260                                         }
1261
1262                                         new_args = new string [extra_args.Length + argc];
1263                                         args.CopyTo (new_args, 0);
1264                                         extra_args.CopyTo (new_args, argc);
1265                                         args = new_args;
1266                                         argc = new_args.Length;
1267                                         continue;
1268                                 }
1269
1270                                 if (parsing_options){
1271                                         if (arg == "--"){
1272                                                 parsing_options = false;
1273                                                 continue;
1274                                         }
1275                                         
1276                                         if (arg.StartsWith ("-")){
1277                                                 if (UnixParseOption (arg, ref args, ref i))
1278                                                         continue;
1279
1280                                                 // Try a -CSCOPTION
1281                                                 string csc_opt = "/" + arg.Substring (1);
1282                                                 if (CSCParseOption (csc_opt, ref args, ref i))
1283                                                         continue;
1284                                         } else {
1285                                                 if (arg.StartsWith ("/")){
1286                                                         if (CSCParseOption (arg, ref args, ref i))
1287                                                                 continue;
1288                                                 }
1289                                         }
1290                                 }
1291
1292                                 CompileFiles (arg, false); 
1293                         }
1294
1295                         ProcessFiles ();
1296
1297                         if (tokenize)
1298                                 return true;
1299                         
1300                         //
1301                         // If we are an exe, require a source file for the entry point
1302                         //
1303                         if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe){
1304                         if (first_source == null){
1305                                 Report.Error (2008, "No files to compile were specified");
1306                                 return false;
1307                         }
1308
1309                         }
1310
1311                         //
1312                         // If there is nothing to put in the assembly, and we are not a library
1313                         //
1314                         if (first_source == null && embedded_resources == null && resources == null){
1315                                         Report.Error (2008, "No files to compile were specified");
1316                                         return false;
1317                         }
1318
1319                         if (Report.Errors > 0)
1320                                 return false;
1321                         
1322                         if (parse_only)
1323                                 return true;
1324                         
1325                         Tokenizer.Cleanup ();
1326                         
1327                         //
1328                         // Load Core Library for default compilation
1329                         //
1330                         if (RootContext.StdLib)
1331                                 references.Insert (0, "mscorlib");
1332
1333                         if (load_default_config)
1334                                 DefineDefaultConfig ();
1335
1336                         if (Report.Errors > 0){
1337                                 return false;
1338                         }
1339
1340                         //
1341                         // Load assemblies required
1342                         //
1343                         if (timestamps)
1344                                 ShowTime ("Loading references");
1345                         link_paths.Add (GetSystemDir ());
1346                         LoadReferences ();
1347                         
1348                         if (timestamps)
1349                                 ShowTime ("   References loaded");
1350                         
1351                         if (Report.Errors > 0){
1352                                 return false;
1353                         }
1354
1355                         //
1356                         // Quick hack
1357                         //
1358                         if (output_file == null){
1359                                 int pos = first_source.LastIndexOf ('.');
1360
1361                                 if (pos > 0)
1362                                         output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
1363                                 else
1364                                         output_file = first_source + RootContext.TargetExt;
1365                         }
1366
1367                         CodeGen.Init (output_file, output_file, want_debugging_support);
1368
1369                         if (RootContext.Target == Target.Module) {
1370                                 PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
1371                                 if (module_only == null) {
1372                                         Report.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
1373                                         Environment.Exit (1);
1374                                 }
1375
1376                                 module_only.SetValue (CodeGen.Assembly.Builder, true, null);
1377                         }
1378
1379                         TypeManager.AddModule (CodeGen.Module.Builder);
1380
1381                         if (modules.Count > 0) {
1382                                 MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
1383                                 if (adder_method == null) {
1384                                         Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
1385                                         Environment.Exit (1);
1386                                 }
1387
1388                                 foreach (string module in modules)
1389                                         LoadModule (adder_method, module);
1390                         }
1391
1392                         TypeManager.ComputeNamespaces ();
1393                         
1394                         //
1395                         // Before emitting, we need to get the core
1396                         // types emitted from the user defined types
1397                         // or from the system ones.
1398                         //
1399                         if (timestamps)
1400                                 ShowTime ("Initializing Core Types");
1401                         if (!RootContext.StdLib){
1402                                 RootContext.ResolveCore ();
1403                                 if (Report.Errors > 0)
1404                                         return false;
1405                         }
1406                         
1407                         TypeManager.InitCoreTypes ();
1408                         if (timestamps)
1409                                 ShowTime ("   Core Types done");
1410
1411                         //
1412                         // The second pass of the compiler
1413                         //
1414                         if (timestamps)
1415                                 ShowTime ("Resolving tree");
1416                         RootContext.ResolveTree ();
1417                         if (Report.Errors > 0)
1418                                 return false;
1419                         if (timestamps)
1420                                 ShowTime ("Populate tree");
1421                         if (!RootContext.StdLib)
1422                                 RootContext.BootCorlib_PopulateCoreTypes ();
1423                         RootContext.PopulateTypes ();
1424                         RootContext.DefineTypes ();
1425                         
1426                         TypeManager.InitCodeHelpers ();
1427
1428                         //
1429                         // Verify using aliases now
1430                         //
1431                         Namespace.VerifyUsing ();
1432                         
1433                         if (Report.Errors > 0){
1434                                 return false;
1435                         }
1436                         
1437                         //
1438                         // The code generator
1439                         //
1440                         if (timestamps)
1441                                 ShowTime ("Emitting code");
1442                         ShowTotalTime ("Total so far");
1443                         RootContext.EmitCode ();
1444                         if (timestamps)
1445                                 ShowTime ("   done");
1446
1447                         if (Report.Errors > 0){
1448                                 return false;
1449                         }
1450
1451                         if (timestamps)
1452                                 ShowTime ("Closing types");
1453
1454                         RootContext.CloseTypes ();
1455
1456                         PEFileKinds k = PEFileKinds.ConsoleApplication;
1457                                 
1458                         switch (RootContext.Target) {
1459                         case Target.Library:
1460                         case Target.Module:
1461                                 k = PEFileKinds.Dll; break;
1462                         case Target.Exe:
1463                                 k = PEFileKinds.ConsoleApplication; break;
1464                         case Target.WinExe:
1465                                 k = PEFileKinds.WindowApplication; break;
1466                         }
1467
1468                         if (RootContext.NeedsEntryPoint) {
1469                                 MethodInfo ep = RootContext.EntryPoint;
1470
1471                                 if (ep == null) {
1472                                         if (Report.Errors == 0)
1473                                                 Report.Error (5001, "Program " + output_file +
1474                                                               " does not have an entry point defined");
1475                                         return false;
1476                                 }
1477                                 
1478                                 CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
1479                         } else if (RootContext.MainClass != null) {
1480                                 Report.Error (2017, "Can not specify -main: when building module or library");
1481                         }
1482
1483                         //
1484                         // Add the resources
1485                         //
1486                         if (resources != null){
1487                                 foreach (string spec in resources){
1488                                         string file, res;
1489                                         int cp;
1490                                         
1491                                         cp = spec.IndexOf (',');
1492                                         if (cp != -1){
1493                                                 file = spec.Substring (0, cp);
1494                                                 res = spec.Substring (cp + 1);
1495                                         } else
1496                                                 file = res = spec;
1497
1498                                         CodeGen.Assembly.Builder.AddResourceFile (res, file);
1499                                 }
1500                         }
1501                         
1502                         if (embedded_resources != null){
1503                                 object[] margs = new object [2];
1504                                 Type[] argst = new Type [2];
1505                                 argst [0] = argst [1] = typeof (string);
1506
1507                                 MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, CallingConventions.Any, argst, null);
1508                                 if (embed_res == null) {
1509                                         Report.Warning (0, new Location (-1), "Cannot embed resources on this runtime: try the Mono runtime instead.");
1510                                 } else {
1511                                         foreach (string spec in embedded_resources) {
1512                                                 int cp;
1513
1514                                                 cp = spec.IndexOf (',');
1515                                                 if (cp != -1){
1516                                                         margs [0] = spec.Substring (cp + 1);
1517                                                         margs [1] = spec.Substring (0, cp);
1518                                                 } else
1519                                                         margs [0] = margs [1] = spec;
1520
1521                                                 if (File.Exists ((string) margs [1]))
1522                                                         embed_res.Invoke (CodeGen.Assembly.Builder, margs);
1523                                                 else {
1524                                                         Report.Error (1566, "Can not find the resource " + margs [1]);
1525                                                 }
1526                                         }
1527                                 }
1528                         }
1529
1530                         //
1531                         // Add Win32 resources
1532                         //
1533
1534                         CodeGen.Assembly.Builder.DefineVersionInfoResource ();
1535
1536                         if (win32ResourceFile != null) {
1537                                 try {
1538                                         CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
1539                                 }
1540                                 catch (ArgumentException) {
1541                                         Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
1542                                 }
1543                         }
1544
1545                         if (win32IconFile != null) {
1546                                 MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
1547                                 if (define_icon == null) {
1548                                         Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
1549                                 }
1550                                 define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
1551                         }
1552
1553                         if (Report.Errors > 0)
1554                                 return false;
1555                         
1556                         CodeGen.Save (output_file);
1557                         if (timestamps) {
1558                                 ShowTime ("Saved output");
1559                                 ShowTotalTime ("Total");
1560                         }
1561
1562                         Timer.ShowTimers ();
1563                         
1564                         if (Report.ExpectedError != 0){
1565                                 Console.WriteLine("Failed to report expected error " + Report.ExpectedError);
1566                                 Environment.Exit (1);
1567                                 return false;
1568                         }
1569
1570 #if DEBUGME
1571                         Console.WriteLine ("Size of strings held: " + DeclSpace.length);
1572                         Console.WriteLine ("Size of strings short: " + DeclSpace.small);
1573 #endif
1574                         return (Report.Errors == 0);
1575                 }
1576
1577         }
1578
1579         //
1580         // This is the only public entry point
1581         //
1582         public class CompilerCallableEntryPoint : MarshalByRefObject {
1583                 static bool used = false;
1584                 
1585                 public bool InvokeCompiler (string [] args)
1586                 {
1587                         if (used)
1588                                 Reset ();
1589                         bool ok = Driver.MainDriver (args);
1590                         return ok && Report.Errors == 0;
1591                 }
1592
1593                 public void Reset ()
1594                 {
1595                 }
1596         }
1597 }