1 --- driver.cs Tue Mar 19 19:15:50 2002
2 +++ ../mcs/driver.cs Sat Mar 16 13:22:44 2002
5 // driver.cs: The compiler command line driver.
\r
7 -// Author: Rafael Teixeira (rafaelteixeirabr@hotmail.com)
\r
8 -// Based on mcs by : Miguel de Icaza (miguel@gnu.org)
\r
9 +// Author: Miguel de Icaza (miguel@gnu.org)
\r
11 // Licensed under the terms of the GNU GPL
\r
13 -// (C) 2002 Rafael Teixeira
\r
14 +// (C) 2001 Ximian, Inc (http://www.ximian.com)
\r
17 -namespace Mono.Languages
\r
18 +namespace Mono.CSharp
\r
21 using System.Reflection;
\r
23 using System.Collections;
\r
25 using System.Globalization;
\r
26 - using Mono.CSharp;
\r
27 + using Mono.Languages;
\r
30 Library, Exe, Module, WinExe
\r
37 // Assemblies references to be linked. Initialized with
\r
38 - // mscorlib.dll elsewhere.
\r
39 + // mscorlib.dll here.
\r
40 static ArrayList references;
\r
43 static ArrayList link_paths;
\r
45 + // Whether we want Yacc to output its progress
\r
46 + static bool yacc_verbose = false;
\r
48 // Whether we want to only run the tokenizer
\r
49 static bool tokenize = false;
\r
52 static Hashtable source_files = new Hashtable ();
\r
55 - // An array of the defines from the command line
\r
56 + // A list of resource files
\r
58 - static ArrayList defines;
\r
59 + static ArrayList resources;
\r
62 - // A list of resource files
\r
63 + // An array of the defines from the command line
\r
65 - static ArrayList resources;
\r
66 + static ArrayList defines;
\r
69 // Last time we took the time
\r
71 span.Seconds, span.Milliseconds, msg);
\r
74 + static int tokenize_file (string input_file)
\r
79 + input = File.OpenRead (input_file);
\r
82 + Report.Error (2001, "Source file '" + input_file + "' could not be opened");
\r
87 + Tokenizer lexer = new Tokenizer (input, input_file, defines);
\r
88 + int token, tokens = 0, errors = 0;
\r
90 + while ((token = lexer.token ()) != Token.EOF){
\r
91 + Location l = lexer.Location;
\r
93 + if (token == Token.ERROR)
\r
96 + Console.WriteLine ("Tokenized: " + tokens + " found " + errors + " errors");
\r
102 + static int parse (string input_file)
\r
104 + CSharpParser parser;
\r
109 + input = File.OpenRead (input_file);
\r
111 + Report.Error (2001, "Source file '" + input_file + "' could not be opened");
\r
115 + parser = new CSharpParser (input_file, input, defines);
\r
116 + parser.yacc_verbose = yacc_verbose;
\r
118 + errors = parser.parse ();
\r
119 + } catch (Exception ex) {
\r
120 + Console.WriteLine (ex);
\r
121 + Console.WriteLine ("Compilation aborted");
\r
130 static void Usage (bool is_error)
\r
132 Console.WriteLine (
\r
133 - "MonoBASIC compiler, (C) 2001 Rafael Teixeira.\n" +
\r
134 + "Mono C# compiler, (C) 2001 Ximian, Inc.\n" +
\r
135 "mcs [options] source-files\n" +
\r
136 + " --about About the Mono C# compiler\n" +
\r
137 " --checked Set default context to checked\n" +
\r
138 " --define SYM Defines the symbol SYM\n" +
\r
139 " --fatal Makes errors fatal\n" +
\r
140 " -L PATH Adds PATH to the assembly link path\n" +
\r
141 " --nostdlib Does not load core libraries\n" +
\r
142 " --nowarn XXX Ignores warning number XXX\n" +
\r
143 + " -o FNAME Specifies output file\n" +
\r
144 " --optimize Optimizes\n" +
\r
145 " --parse Only parses the source file\n" +
\r
146 " --probe X Probes for the source to generate code X on line L\n" +
\r
147 @@ -109,13 +170,13 @@
148 static void About ()
\r
150 Console.WriteLine (
\r
151 - "The MonoBASIC compiler is (C) 2002 Rafael Teixeira\n\n" +
\r
152 + "The Mono C# compiler is (C) 2001 Ximian, Inc.\n\n" +
\r
153 "The compiler source code is released under the terms of the GNU GPL\n\n" +
\r
155 "For more information on Mono, visit the project Web site\n" +
\r
156 " http://www.go-mono.com\n\n" +
\r
158 - "The compiler was written by Rafael Teixeira and Miguel de Icaza and Ravi Pratap");
\r
159 + "The compiler was written by Miguel de Icaza and Ravi Pratap");
\r
162 static void error (string msg)
\r
163 @@ -128,11 +189,11 @@
164 Console.WriteLine (msg);
\r
167 - static int Main(string[] args)
\r
168 + public static int Main (string[] args)
\r
170 - MainDriver(args);
\r
171 + MainDriver (args);
\r
173 - return error_count;
\r
174 + return (error_count + Report.Errors) != 0 ? 1 : 0;
\r
177 static public int LoadAssembly (string assembly)
\r
178 @@ -183,19 +244,16 @@
182 - foreach (string r in references){
\r
183 + foreach (string r in references)
\r
184 errors += LoadAssembly (r);
\r
191 static void SetupDefaultDefines ()
\r
193 defines = new ArrayList ();
\r
194 defines.Add ("__MonoCS__");
\r
195 - defines.Add ("__MonoBASIC__");
\r
198 static string [] LoadArgs (string file)
\r
200 static string GetSystemDir ()
\r
202 Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
\r
203 - string s = assemblies [0].CodeBase;
\r
205 - return s.Substring (0, s.LastIndexOf ("/"));
\r
206 + foreach (Assembly a in assemblies){
\r
207 + string codebase = a.CodeBase;
\r
208 + if (codebase.EndsWith ("corlib.dll")){
\r
209 + return codebase.Substring (0, codebase.LastIndexOf ("/"));
\r
213 + Report.Error (-15, "Can not compute my system path");
\r
218 + // Given a path specification, splits the path from the file/pattern
\r
220 + static void SplitPathAndPattern (string spec, out string path, out string pattern)
\r
222 + int p = spec.LastIndexOf ("/");
\r
225 + // Windows does not like /file.cs, switch that to:
\r
226 + // "\", "file.cs"
\r
230 + pattern = spec.Substring (1);
\r
232 + path = spec.Substring (0, p);
\r
233 + pattern = spec.Substring (p + 1);
\r
238 + p = spec.LastIndexOf ("\\");
\r
240 + path = spec.Substring (0, p - 1);
\r
241 + pattern = spec.Substring (p);
\r
249 + static int ProcessFile (string f)
\r
251 + if (source_files.Contains (f)){
\r
254 + "Source file `" + f + "' specified multiple times");
\r
255 + Environment.Exit (1);
\r
257 + source_files.Add (f, f);
\r
260 + tokenize_file (f);
\r
262 + return parse (f);
\r
266 + static void RecurseOn (string pattern)
\r
268 + // FIXME: implement.
\r
272 @@ -246,20 +365,26 @@
275 string output_file = null;
\r
276 + bool parsing_options = true;
\r
278 references = new ArrayList ();
\r
279 link_paths = new ArrayList ();
\r
281 SetupDefaultDefines ();
\r
284 + // Setup defaults
\r
286 + // This is not required because Assembly.Load knows about this
\r
289 link_paths.Add (GetSystemDir ());
\r
291 int argc = args.Length;
\r
292 - for (i = 0; i < argc; i++)
\r
294 + for (i = 0; i < argc; i++){
\r
295 string arg = args [i];
\r
297 - if (arg.StartsWith ("@"))
\r
299 + if (arg.StartsWith ("@")){
\r
300 string [] new_args, extra_args;
\r
301 string response_file = arg.Substring (1);
\r
303 @@ -290,13 +415,18 @@
309 - if (arg.StartsWith ("-"))
\r
312 + // Prepare to recurse
\r
315 + if (parsing_options && (arg.StartsWith ("-") || arg.StartsWith ("/"))){
\r
318 - GenericParser.yacc_verbose_flag = true;
\r
319 + yacc_verbose = true;
\r
323 + parsing_options = false;
\r
327 @@ -319,13 +449,13 @@
328 RootContext.Optimize = true;
\r
331 + case "/?": case "/h": case "/help":
\r
337 - if ((i + 1) >= argc)
\r
339 + if ((i + 1) >= argc){
\r
349 code = Int32.Parse (
\r
350 args [++i], NumberStyles.AllowLeadingSign);
\r
351 @@ -349,12 +480,16 @@
355 - case "-o": case "--output":
\r
358 if ((i + 1) >= argc){
\r
362 output_file = args [++i];
\r
363 + string bname = CodeGen.Basename (output_file);
\r
364 + if (bname.IndexOf (".") == -1)
\r
365 + output_file += ".exe";
\r
370 Report.Stacktrace = true;
\r
373 + case "--resource":
\r
374 + if ((i + 1) >= argc){
\r
376 + Console.WriteLine("Missing argument to --resource");
\r
379 + if (resources == null)
\r
380 + resources = new ArrayList ();
\r
382 + resources.Add (args [++i]);
\r
386 if ((i + 1) >= argc){
\r
388 @@ -463,51 +610,39 @@
392 + case "--recurse":
\r
393 + if ((i + 1) >= argc){
\r
398 + RecurseOn (args [++i]);
\r
401 case "--timestamp":
\r
403 last_time = DateTime.Now;
\r
411 - } catch (System.IndexOutOfRangeException){
\r
415 - } catch (System.FormatException) {
\r
421 if (first_source == null)
\r
422 first_source = arg;
\r
424 - string [] files = Directory.GetFiles (".", arg);
\r
426 - foreach (string f in files)
\r
428 - if (source_files.Contains(f))
\r
432 - "Source file `" + f + "' specified multiple times");
\r
433 - Environment.Exit(1);
\r
434 + string path, pattern;
\r
435 + SplitPathAndPattern (arg, out path, out pattern);
\r
436 + string [] files = null;
\r
438 + files = Directory.GetFiles (path, pattern);
\r
439 + } catch (System.IO.DirectoryNotFoundException) {
\r
440 + Report.Error (2001, "Source file `" + arg + "' could not be found");
\r
444 - source_files.Add(f, f);
\r
447 - GenericParser.Tokenize(f);
\r
449 - errors += GenericParser.Parse(f);
\r
451 + foreach (string f in files)
\r
452 + errors += ProcessFile (f);
\r
461 RootContext.CodeGen = new CodeGen (output_file, output_file);
\r
463 + RootContext.TypeManager.AddModule (RootContext.CodeGen.ModuleBuilder);
\r
466 // Before emitting, we need to get the core
\r
467 // types emitted from the user defined types
\r
470 ShowTime (" Core Types done");
\r
472 - RootContext.TypeManager.AddModule (RootContext.CodeGen.ModuleBuilder);
\r
475 // The second pass of the compiler
\r
478 RootContext.ResolveTree ();
\r
480 ShowTime ("Populate tree");
\r
482 - if (Report.Errors > 0){
\r
483 - error ("Compilation failed");
\r
487 RootContext.PopulateTypes ();
\r
489 if (Report.Errors > 0){
\r
493 RootContext.CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
\r
497 + // Add the resources
\r
499 + if (resources != null){
\r
500 + foreach (string file in resources)
\r
501 + RootContext.CodeGen.AssemblyBuilder.AddResourceFile (file, file);
\r
504 RootContext.CodeGen.Save (output_file);
\r