~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/mcs/rootcontext.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
 
3
//
 
4
// Author: Miguel de Icaza (miguel@ximian.com)
 
5
//            Ravi Pratap  (ravi@ximian.com)
 
6
//            Marek Safar  (marek.safar@gmail.com)
 
7
//
 
8
//
 
9
// Dual licensed under the terms of the MIT X11 or GNU GPL
 
10
//
 
11
// Copyright 2001 Ximian, Inc (http://www.ximian.com)
 
12
// Copyright 2004-2008 Novell, Inc
 
13
 
 
14
using System.Collections.Generic;
 
15
using System.IO;
 
16
using System.Text;
 
17
using System.Globalization;
 
18
using System;
 
19
 
 
20
namespace Mono.CSharp {
 
21
 
 
22
        public enum LanguageVersion
 
23
        {
 
24
                ISO_1 = 1,
 
25
                ISO_2 = 2,
 
26
                V_3 = 3,
 
27
                V_4 = 4,
 
28
                Future = 100,
 
29
 
 
30
                Default = LanguageVersion.V_4,
 
31
        }
 
32
 
 
33
        public enum RuntimeVersion
 
34
        {
 
35
                v1,
 
36
                v2,
 
37
                v4
 
38
        }
 
39
 
 
40
        public enum Target
 
41
        {
 
42
                Library, Exe, Module, WinExe
 
43
        }
 
44
 
 
45
        public enum Platform
 
46
        {
 
47
                AnyCPU, X86, X64, IA64
 
48
        }
 
49
 
 
50
        public class CompilerSettings
 
51
        {
 
52
                public Target Target;
 
53
                public Platform Platform;
 
54
                public string TargetExt;
 
55
                public bool VerifyClsCompliance;
 
56
                public bool Optimize;
 
57
                public LanguageVersion Version;
 
58
                public bool EnhancedWarnings;
 
59
                public bool LoadDefaultReferences;
 
60
                public string SdkVersion;
 
61
 
 
62
                public string StrongNameKeyFile;
 
63
                public string StrongNameKeyContainer;
 
64
                public bool StrongNameDelaySign;
 
65
 
 
66
                //
 
67
                // Assemblies references to be loaded
 
68
                //
 
69
                public List<string> AssemblyReferences;
 
70
 
 
71
                // 
 
72
                // External aliases for assemblies
 
73
                //
 
74
                public List<Tuple<string, string>> AssemblyReferencesAliases;
 
75
 
 
76
                //
 
77
                // Modules to be embedded
 
78
                //
 
79
                public List<string> Modules;
 
80
 
 
81
                //
 
82
                // Lookup paths for referenced assemblies
 
83
                //
 
84
                public List<string> ReferencesLookupPaths;
 
85
 
 
86
                //
 
87
                // Encoding.
 
88
                //
 
89
                public Encoding Encoding;
 
90
 
 
91
                //
 
92
                // If set, enable XML documentation generation
 
93
                //
 
94
                public string DocumentationFile;
 
95
 
 
96
                public string MainClass;
 
97
 
 
98
                //
 
99
                // Output file
 
100
                //
 
101
                public string OutputFile;
 
102
 
 
103
                // 
 
104
                // The default compiler checked state
 
105
                //
 
106
                public bool Checked;
 
107
 
 
108
                //
 
109
                // If true, the compiler is operating in statement mode,
 
110
                // this currently turns local variable declaration into
 
111
                // static variables of a class
 
112
                //
 
113
                public bool StatementMode;      // TODO: SUPER UGLY
 
114
                
 
115
                //
 
116
                // Whether to allow Unsafe code
 
117
                //
 
118
                public bool Unsafe;
 
119
 
 
120
                public string Win32ResourceFile;
 
121
                public string Win32IconFile;
 
122
 
 
123
                //
 
124
                // A list of resource files for embedding
 
125
                //
 
126
                public List<AssemblyResource> Resources;
 
127
 
 
128
                public bool GenerateDebugInfo;
 
129
 
 
130
                // Compiler debug flags only
 
131
                public bool ParseOnly, TokenizeOnly, Timestamps;
 
132
                public int DebugFlags;
 
133
 
 
134
                //
 
135
                // Whether we are being linked against the standard libraries.
 
136
                // This is only used to tell whether `System.Object' should
 
137
                // have a base class or not.
 
138
                //
 
139
                public bool StdLib;
 
140
 
 
141
                public RuntimeVersion StdLibRuntimeVersion;
 
142
 
 
143
                readonly List<string> conditional_symbols;
 
144
 
 
145
                readonly List<CompilationSourceFile> source_files;
 
146
 
 
147
                public CompilerSettings ()
 
148
                {
 
149
                        StdLib = true;
 
150
                        Target = Target.Exe;
 
151
                        TargetExt = ".exe";
 
152
                        Platform = Platform.AnyCPU;
 
153
                        Version = LanguageVersion.Default;
 
154
                        VerifyClsCompliance = true;
 
155
                        Optimize = true;
 
156
                        Encoding = Encoding.UTF8;
 
157
                        LoadDefaultReferences = true;
 
158
                        StdLibRuntimeVersion = RuntimeVersion.v4;
 
159
 
 
160
                        AssemblyReferences = new List<string> ();
 
161
                        AssemblyReferencesAliases = new List<Tuple<string, string>> ();
 
162
                        Modules = new List<string> ();
 
163
                        ReferencesLookupPaths = new List<string> ();
 
164
 
 
165
                        conditional_symbols = new List<string> ();
 
166
                        //
 
167
                        // Add default mcs define
 
168
                        //
 
169
                        conditional_symbols.Add ("__MonoCS__");
 
170
 
 
171
                        source_files = new List<CompilationSourceFile> ();
 
172
                }
 
173
 
 
174
                #region Properties
 
175
 
 
176
                public CompilationSourceFile FirstSourceFile {
 
177
                        get {
 
178
                                return source_files.Count > 0 ? source_files [0] : null;
 
179
                        }
 
180
                }
 
181
 
 
182
                public bool HasKeyFileOrContainer {
 
183
                        get {
 
184
                                return StrongNameKeyFile != null || StrongNameKeyContainer != null;
 
185
                        }
 
186
                }
 
187
 
 
188
                public bool NeedsEntryPoint {
 
189
                        get {
 
190
                                return Target == Target.Exe || Target == Target.WinExe;
 
191
                        }
 
192
                }
 
193
 
 
194
                public List<CompilationSourceFile> SourceFiles {
 
195
                        get {
 
196
                                return source_files;
 
197
                        }
 
198
                }
 
199
 
 
200
                #endregion
 
201
 
 
202
                public void AddConditionalSymbol (string symbol)
 
203
                {
 
204
                        if (!conditional_symbols.Contains (symbol))
 
205
                                conditional_symbols.Add (symbol);
 
206
                }
 
207
 
 
208
                public bool IsConditionalSymbolDefined (string symbol)
 
209
                {
 
210
                        return conditional_symbols.Contains (symbol);
 
211
                }
 
212
        }
 
213
 
 
214
        public class CommandLineParser
 
215
        {
 
216
                enum ParseResult
 
217
                {
 
218
                        Success,
 
219
                        Error,
 
220
                        Stop,
 
221
                        UnknownOption
 
222
                }
 
223
 
 
224
                static readonly char[] argument_value_separator = new char[] { ';', ',' };
 
225
                static readonly char[] numeric_value_separator = new char[] { ';', ',', ' ' };
 
226
 
 
227
                readonly Report report;
 
228
                readonly TextWriter output;
 
229
                bool stop_argument;
 
230
 
 
231
                Dictionary<string, int> source_file_index;
 
232
 
 
233
                public event Func<string[], int, int> UnknownOptionHandler;
 
234
 
 
235
                public CommandLineParser (Report report)
 
236
                        : this (report, Console.Out)
 
237
                {
 
238
                }
 
239
 
 
240
                public CommandLineParser (Report report, TextWriter messagesOutput)
 
241
                {
 
242
                        this.report = report;
 
243
                        this.output = messagesOutput;
 
244
                }
 
245
 
 
246
                public bool HasBeenStopped {
 
247
                        get {
 
248
                                return stop_argument;
 
249
                        }
 
250
                }
 
251
 
 
252
                void About ()
 
253
                {
 
254
                        output.WriteLine (
 
255
                                "The Mono C# compiler is Copyright 2001-2011, Novell, Inc.\n\n" +
 
256
                                "The compiler source code is released under the terms of the \n" +
 
257
                                "MIT X11 or GNU GPL licenses\n\n" +
 
258
 
 
259
                                "For more information on Mono, visit the project Web site\n" +
 
260
                                "   http://www.mono-project.com\n\n" +
 
261
 
 
262
                                "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja R Harinath, Atushi Enomoto");
 
263
                }
 
264
 
 
265
                public CompilerSettings ParseArguments (string[] args)
 
266
                {
 
267
                        CompilerSettings settings = new CompilerSettings ();
 
268
                        List<string> response_file_list = null;
 
269
                        bool parsing_options = true;
 
270
                        stop_argument = false;
 
271
                        source_file_index = new Dictionary<string, int> ();
 
272
 
 
273
                        for (int i = 0; i < args.Length; i++) {
 
274
                                string arg = args[i];
 
275
                                if (arg.Length == 0)
 
276
                                        continue;
 
277
 
 
278
                                if (arg[0] == '@') {
 
279
                                        string[] extra_args;
 
280
                                        string response_file = arg.Substring (1);
 
281
 
 
282
                                        if (response_file_list == null)
 
283
                                                response_file_list = new List<string> ();
 
284
 
 
285
                                        if (response_file_list.Contains (response_file)) {
 
286
                                                report.Error (1515, "Response file `{0}' specified multiple times", response_file);
 
287
                                                return null;
 
288
                                        }
 
289
 
 
290
                                        response_file_list.Add (response_file);
 
291
 
 
292
                                        extra_args = LoadArgs (response_file);
 
293
                                        if (extra_args == null) {
 
294
                                                report.Error (2011, "Unable to open response file: " + response_file);
 
295
                                                return null;
 
296
                                        }
 
297
 
 
298
                                        args = AddArgs (args, extra_args);
 
299
                                        continue;
 
300
                                }
 
301
 
 
302
                                if (parsing_options) {
 
303
                                        if (arg == "--") {
 
304
                                                parsing_options = false;
 
305
                                                continue;
 
306
                                        }
 
307
 
 
308
                                        bool dash_opt = arg[0] == '-';
 
309
                                        bool slash_opt = arg[0] == '/';
 
310
                                        if (dash_opt) {
 
311
                                                switch (ParseOptionUnix (arg, ref args, ref i, settings)) {
 
312
                                                case ParseResult.Error:
 
313
                                                case ParseResult.Success:
 
314
                                                        continue;
 
315
                                                case ParseResult.Stop:
 
316
                                                        stop_argument = true;
 
317
                                                        return settings;
 
318
                                                case ParseResult.UnknownOption:
 
319
                                                        if (UnknownOptionHandler != null) {
 
320
                                                                var ret = UnknownOptionHandler (args, i);
 
321
                                                                if (ret != -1) {
 
322
                                                                        i = ret;
 
323
                                                                        continue;
 
324
                                                                }
 
325
                                                        }
 
326
                                                        break;
 
327
                                                }
 
328
                                        }
 
329
 
 
330
                                        if (dash_opt || slash_opt) {
 
331
                                                // Try a -CSCOPTION
 
332
                                                string csc_opt = dash_opt ? "/" + arg.Substring (1) : arg;
 
333
                                                switch (ParseOption (csc_opt, ref args, settings)) {
 
334
                                                case ParseResult.Error:
 
335
                                                case ParseResult.Success:
 
336
                                                        continue;
 
337
                                                case ParseResult.UnknownOption:
 
338
                                                        // Need to skip `/home/test.cs' however /test.cs is considered as error
 
339
                                                        if ((slash_opt && arg.Length > 3 && arg.IndexOf ('/', 2) > 0))
 
340
                                                                break;
 
341
 
 
342
                                                        if (UnknownOptionHandler != null) {
 
343
                                                                var ret = UnknownOptionHandler (args, i);
 
344
                                                                if (ret != -1) {
 
345
                                                                        i = ret;
 
346
                                                                        continue;
 
347
                                                                }
 
348
                                                        }
 
349
 
 
350
                                                        Error_WrongOption (arg);
 
351
                                                        return null;
 
352
 
 
353
                                                case ParseResult.Stop:
 
354
                                                        stop_argument = true;
 
355
                                                        return settings;
 
356
                                                }
 
357
                                        }
 
358
                                }
 
359
 
 
360
                                ProcessSourceFiles (arg, false, settings.SourceFiles);
 
361
                        }
 
362
 
 
363
                        return settings;
 
364
                }
 
365
 
 
366
                void ProcessSourceFiles (string spec, bool recurse, List<CompilationSourceFile> sourceFiles)
 
367
                {
 
368
                        string path, pattern;
 
369
 
 
370
                        SplitPathAndPattern (spec, out path, out pattern);
 
371
                        if (pattern.IndexOf ('*') == -1) {
 
372
                                AddSourceFile (spec, sourceFiles);
 
373
                                return;
 
374
                        }
 
375
 
 
376
                        string[] files = null;
 
377
                        try {
 
378
                                files = Directory.GetFiles (path, pattern);
 
379
                        } catch (System.IO.DirectoryNotFoundException) {
 
380
                                report.Error (2001, "Source file `" + spec + "' could not be found");
 
381
                                return;
 
382
                        } catch (System.IO.IOException) {
 
383
                                report.Error (2001, "Source file `" + spec + "' could not be found");
 
384
                                return;
 
385
                        }
 
386
                        foreach (string f in files) {
 
387
                                AddSourceFile (f, sourceFiles);
 
388
                        }
 
389
 
 
390
                        if (!recurse)
 
391
                                return;
 
392
 
 
393
                        string[] dirs = null;
 
394
 
 
395
                        try {
 
396
                                dirs = Directory.GetDirectories (path);
 
397
                        } catch {
 
398
                        }
 
399
 
 
400
                        foreach (string d in dirs) {
 
401
 
 
402
                                // Don't include path in this string, as each
 
403
                                // directory entry already does
 
404
                                ProcessSourceFiles (d + "/" + pattern, true, sourceFiles);
 
405
                        }
 
406
                }
 
407
 
 
408
                static string[] AddArgs (string[] args, string[] extra_args)
 
409
                {
 
410
                        string[] new_args;
 
411
                        new_args = new string[extra_args.Length + args.Length];
 
412
 
 
413
                        // if args contains '--' we have to take that into account
 
414
                        // split args into first half and second half based on '--'
 
415
                        // and add the extra_args before --
 
416
                        int split_position = Array.IndexOf (args, "--");
 
417
                        if (split_position != -1) {
 
418
                                Array.Copy (args, new_args, split_position);
 
419
                                extra_args.CopyTo (new_args, split_position);
 
420
                                Array.Copy (args, split_position, new_args, split_position + extra_args.Length, args.Length - split_position);
 
421
                        } else {
 
422
                                args.CopyTo (new_args, 0);
 
423
                                extra_args.CopyTo (new_args, args.Length);
 
424
                        }
 
425
 
 
426
                        return new_args;
 
427
                }
 
428
 
 
429
                void AddAssemblyReference (string alias, string assembly, CompilerSettings settings)
 
430
                {
 
431
                        if (assembly.Length == 0) {
 
432
                                report.Error (1680, "Invalid reference alias `{0}='. Missing filename", alias);
 
433
                                return;
 
434
                        }
 
435
 
 
436
                        if (!IsExternAliasValid (alias)) {
 
437
                                report.Error (1679, "Invalid extern alias for -reference. Alias `{0}' is not a valid identifier", alias);
 
438
                                return;
 
439
                        }
 
440
 
 
441
                        settings.AssemblyReferencesAliases.Add (Tuple.Create (alias, assembly));
 
442
                }
 
443
 
 
444
                void AddResource (AssemblyResource res, CompilerSettings settings)
 
445
                {
 
446
                        if (settings.Resources == null) {
 
447
                                settings.Resources = new List<AssemblyResource> ();
 
448
                                settings.Resources.Add (res);
 
449
                                return;
 
450
                        }
 
451
 
 
452
                        if (settings.Resources.Contains (res)) {
 
453
                                report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", res.Name);
 
454
                                return;
 
455
                        }
 
456
 
 
457
                        settings.Resources.Add (res);
 
458
                }
 
459
 
 
460
                void AddSourceFile (string fileName, List<CompilationSourceFile> sourceFiles)
 
461
                {
 
462
                        string path = Path.GetFullPath (fileName);
 
463
 
 
464
                        int index;
 
465
                        if (source_file_index.TryGetValue (path, out index)) {
 
466
                                string other_name = sourceFiles[index - 1].Name;
 
467
                                if (fileName.Equals (other_name))
 
468
                                        report.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name);
 
469
                                else
 
470
                                        report.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", fileName, other_name, path);
 
471
 
 
472
                                return;
 
473
                        }
 
474
 
 
475
                        var unit = new CompilationSourceFile (fileName, path, sourceFiles.Count + 1);
 
476
                        sourceFiles.Add (unit);
 
477
                        source_file_index.Add (path, unit.Index);
 
478
                }
 
479
 
 
480
                void Error_RequiresArgument (string option)
 
481
                {
 
482
                        report.Error (2006, "Missing argument for `{0}' option", option);
 
483
                }
 
484
 
 
485
                void Error_RequiresFileName (string option)
 
486
                {
 
487
                        report.Error (2005, "Missing file specification for `{0}' option", option);
 
488
                }
 
489
 
 
490
                void Error_WrongOption (string option)
 
491
                {
 
492
                        report.Error (2007, "Unrecognized command-line option: `{0}'", option);
 
493
                }
 
494
 
 
495
                static bool IsExternAliasValid (string identifier)
 
496
                {
 
497
                        if (identifier.Length == 0)
 
498
                                return false;
 
499
                        if (identifier[0] != '_' && !char.IsLetter (identifier[0]))
 
500
                                return false;
 
501
 
 
502
                        for (int i = 1; i < identifier.Length; i++) {
 
503
                                char c = identifier[i];
 
504
                                if (char.IsLetter (c) || char.IsDigit (c))
 
505
                                        continue;
 
506
 
 
507
                                UnicodeCategory category = char.GetUnicodeCategory (c);
 
508
                                if (category != UnicodeCategory.Format || category != UnicodeCategory.NonSpacingMark ||
 
509
                                                category != UnicodeCategory.SpacingCombiningMark ||
 
510
                                                category != UnicodeCategory.ConnectorPunctuation)
 
511
                                        return false;
 
512
                        }
 
513
 
 
514
                        return true;
 
515
                }
 
516
 
 
517
                static string[] LoadArgs (string file)
 
518
                {
 
519
                        StreamReader f;
 
520
                        var args = new List<string> ();
 
521
                        string line;
 
522
                        try {
 
523
                                f = new StreamReader (file);
 
524
                        } catch {
 
525
                                return null;
 
526
                        }
 
527
 
 
528
                        StringBuilder sb = new StringBuilder ();
 
529
 
 
530
                        while ((line = f.ReadLine ()) != null) {
 
531
                                int t = line.Length;
 
532
 
 
533
                                for (int i = 0; i < t; i++) {
 
534
                                        char c = line[i];
 
535
 
 
536
                                        if (c == '"' || c == '\'') {
 
537
                                                char end = c;
 
538
 
 
539
                                                for (i++; i < t; i++) {
 
540
                                                        c = line[i];
 
541
 
 
542
                                                        if (c == end)
 
543
                                                                break;
 
544
                                                        sb.Append (c);
 
545
                                                }
 
546
                                        } else if (c == ' ') {
 
547
                                                if (sb.Length > 0) {
 
548
                                                        args.Add (sb.ToString ());
 
549
                                                        sb.Length = 0;
 
550
                                                }
 
551
                                        } else
 
552
                                                sb.Append (c);
 
553
                                }
 
554
                                if (sb.Length > 0) {
 
555
                                        args.Add (sb.ToString ());
 
556
                                        sb.Length = 0;
 
557
                                }
 
558
                        }
 
559
 
 
560
                        return args.ToArray ();
 
561
                }
 
562
 
 
563
                void OtherFlags ()
 
564
                {
 
565
                        output.WriteLine (
 
566
                                "Other flags in the compiler\n" +
 
567
                                "   --fatal[=COUNT]    Makes errors after COUNT fatal\n" +
 
568
                                "   --lint             Enhanced warnings\n" +
 
569
                                "   --parse            Only parses the source file\n" +
 
570
                                "   --runtime:VERSION  Sets mscorlib.dll metadata version: v1, v2, v4\n" +
 
571
                                "   --stacktrace       Shows stack trace at error location\n" +
 
572
                                "   --timestamp        Displays time stamps of various compiler events\n" +
 
573
                                "   -v                 Verbose parsing (for debugging the parser)\n" +
 
574
                                "   --mcs-debug X      Sets MCS debugging level to X\n");
 
575
                }
 
576
 
 
577
                //
 
578
                // This parses the -arg and /arg options to the compiler, even if the strings
 
579
                // in the following text use "/arg" on the strings.
 
580
                //
 
581
                ParseResult ParseOption (string option, ref string[] args, CompilerSettings settings)
 
582
                {
 
583
                        int idx = option.IndexOf (':');
 
584
                        string arg, value;
 
585
 
 
586
                        if (idx == -1) {
 
587
                                arg = option;
 
588
                                value = "";
 
589
                        } else {
 
590
                                arg = option.Substring (0, idx);
 
591
 
 
592
                                value = option.Substring (idx + 1);
 
593
                        }
 
594
 
 
595
                        switch (arg.ToLowerInvariant ()) {
 
596
                        case "/nologo":
 
597
                                return ParseResult.Success;
 
598
 
 
599
                        case "/t":
 
600
                        case "/target":
 
601
                                switch (value) {
 
602
                                case "exe":
 
603
                                        settings.Target = Target.Exe;
 
604
                                        break;
 
605
 
 
606
                                case "winexe":
 
607
                                        settings.Target = Target.WinExe;
 
608
                                        break;
 
609
 
 
610
                                case "library":
 
611
                                        settings.Target = Target.Library;
 
612
                                        settings.TargetExt = ".dll";
 
613
                                        break;
 
614
 
 
615
                                case "module":
 
616
                                        settings.Target = Target.Module;
 
617
                                        settings.TargetExt = ".netmodule";
 
618
                                        break;
 
619
 
 
620
                                default:
 
621
                                        report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
 
622
                                        return ParseResult.Error;
 
623
                                }
 
624
                                return ParseResult.Success;
 
625
 
 
626
                        case "/out":
 
627
                                if (value.Length == 0) {
 
628
                                        Error_RequiresFileName (option);
 
629
                                        return ParseResult.Error;
 
630
                                }
 
631
                                settings.OutputFile = value;
 
632
                                return ParseResult.Success;
 
633
 
 
634
                        case "/o":
 
635
                        case "/o+":
 
636
                        case "/optimize":
 
637
                        case "/optimize+":
 
638
                                settings.Optimize = true;
 
639
                                return ParseResult.Success;
 
640
 
 
641
                        case "/o-":
 
642
                        case "/optimize-":
 
643
                                settings.Optimize = false;
 
644
                                return ParseResult.Success;
 
645
 
 
646
                        // TODO: Not supported by csc 3.5+
 
647
                        case "/incremental":
 
648
                        case "/incremental+":
 
649
                        case "/incremental-":
 
650
                                // nothing.
 
651
                                return ParseResult.Success;
 
652
 
 
653
                        case "/d":
 
654
                        case "/define": {
 
655
                                        if (value.Length == 0) {
 
656
                                                Error_RequiresArgument (option);
 
657
                                                return ParseResult.Error;
 
658
                                        }
 
659
 
 
660
                                        foreach (string d in value.Split (argument_value_separator)) {
 
661
                                                string conditional = d.Trim ();
 
662
                                                if (!Tokenizer.IsValidIdentifier (conditional)) {
 
663
                                                        report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional);
 
664
                                                        continue;
 
665
                                                }
 
666
 
 
667
                                                settings.AddConditionalSymbol (conditional);
 
668
                                        }
 
669
                                        return ParseResult.Success;
 
670
                                }
 
671
 
 
672
                        case "/bugreport":
 
673
                                //
 
674
                                // We should collect data, runtime, etc and store in the file specified
 
675
                                //
 
676
                                output.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
 
677
                                return ParseResult.Success;
 
678
 
 
679
                        case "/pkg": {
 
680
                                        string packages;
 
681
 
 
682
                                        if (value.Length == 0) {
 
683
                                                Error_RequiresArgument (option);
 
684
                                                return ParseResult.Error;
 
685
                                        }
 
686
                                        packages = String.Join (" ", value.Split (new Char[] { ';', ',', '\n', '\r' }));
 
687
                                        string pkgout = Driver.GetPackageFlags (packages, report);
 
688
 
 
689
                                        if (pkgout == null)
 
690
                                                return ParseResult.Error;
 
691
 
 
692
                                        string[] xargs = pkgout.Trim (new Char[] { ' ', '\n', '\r', '\t' }).Split (new Char[] { ' ', '\t' });
 
693
                                        args = AddArgs (args, xargs);
 
694
                                        return ParseResult.Success;
 
695
                                }
 
696
 
 
697
                        case "/linkres":
 
698
                        case "/linkresource":
 
699
                        case "/res":
 
700
                        case "/resource":
 
701
                                AssemblyResource res = null;
 
702
                                string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
 
703
                                switch (s.Length) {
 
704
                                case 1:
 
705
                                        if (s[0].Length == 0)
 
706
                                                goto default;
 
707
                                        res = new AssemblyResource (s[0], Path.GetFileName (s[0]));
 
708
                                        break;
 
709
                                case 2:
 
710
                                        res = new AssemblyResource (s[0], s[1]);
 
711
                                        break;
 
712
                                case 3:
 
713
                                        if (s[2] != "public" && s[2] != "private") {
 
714
                                                report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s[2]);
 
715
                                                return ParseResult.Error;
 
716
                                        }
 
717
                                        res = new AssemblyResource (s[0], s[1], s[2] == "private");
 
718
                                        break;
 
719
                                default:
 
720
                                        report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
 
721
                                        return ParseResult.Error;
 
722
                                }
 
723
 
 
724
                                if (res != null) {
 
725
                                        res.IsEmbeded = arg[1] == 'r' || arg[1] == 'R';
 
726
                                        AddResource (res, settings);
 
727
                                }
 
728
 
 
729
                                return ParseResult.Success;
 
730
 
 
731
                        case "/recurse":
 
732
                                if (value.Length == 0) {
 
733
                                        Error_RequiresFileName (option);
 
734
                                        return ParseResult.Error;
 
735
                                }
 
736
                                ProcessSourceFiles (value, true, settings.SourceFiles);
 
737
                                return ParseResult.Success;
 
738
 
 
739
                        case "/r":
 
740
                        case "/reference": {
 
741
                                        if (value.Length == 0) {
 
742
                                                Error_RequiresFileName (option);
 
743
                                                return ParseResult.Error;
 
744
                                        }
 
745
 
 
746
                                        string[] refs = value.Split (argument_value_separator);
 
747
                                        foreach (string r in refs) {
 
748
                                                if (r.Length == 0)
 
749
                                                        continue;
 
750
 
 
751
                                                string val = r;
 
752
                                                int index = val.IndexOf ('=');
 
753
                                                if (index > -1) {
 
754
                                                        string alias = r.Substring (0, index);
 
755
                                                        string assembly = r.Substring (index + 1);
 
756
                                                        AddAssemblyReference (alias, assembly, settings);
 
757
                                                        if (refs.Length != 1) {
 
758
                                                                report.Error (2034, "Cannot specify multiple aliases using single /reference option");
 
759
                                                                return ParseResult.Error;
 
760
                                                        }
 
761
                                                } else {
 
762
                                                        settings.AssemblyReferences.Add (val);
 
763
                                                }
 
764
                                        }
 
765
                                        return ParseResult.Success;
 
766
                                }
 
767
                        case "/addmodule": {
 
768
                                        if (value.Length == 0) {
 
769
                                                Error_RequiresFileName (option);
 
770
                                                return ParseResult.Error;
 
771
                                        }
 
772
 
 
773
                                        string[] refs = value.Split (argument_value_separator);
 
774
                                        foreach (string r in refs) {
 
775
                                                settings.Modules.Add (r);
 
776
                                        }
 
777
                                        return ParseResult.Success;
 
778
                                }
 
779
                        case "/win32res": {
 
780
                                        if (value.Length == 0) {
 
781
                                                Error_RequiresFileName (option);
 
782
                                                return ParseResult.Error;
 
783
                                        }
 
784
 
 
785
                                        if (settings.Win32IconFile != null)
 
786
                                                report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
787
 
 
788
                                        settings.Win32ResourceFile = value;
 
789
                                        return ParseResult.Success;
 
790
                                }
 
791
                        case "/win32icon": {
 
792
                                        if (value.Length == 0) {
 
793
                                                Error_RequiresFileName (option);
 
794
                                                return ParseResult.Error;
 
795
                                        }
 
796
 
 
797
                                        if (settings.Win32ResourceFile != null)
 
798
                                                report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
799
 
 
800
                                        settings.Win32IconFile = value;
 
801
                                        return ParseResult.Success;
 
802
                                }
 
803
                        case "/doc": {
 
804
                                        if (value.Length == 0) {
 
805
                                                Error_RequiresFileName (option);
 
806
                                                return ParseResult.Error;
 
807
                                        }
 
808
 
 
809
                                        settings.DocumentationFile = value;
 
810
                                        return ParseResult.Success;
 
811
                                }
 
812
                        case "/lib": {
 
813
                                        string[] libdirs;
 
814
 
 
815
                                        if (value.Length == 0) {
 
816
                                                return ParseResult.Error;
 
817
                                        }
 
818
 
 
819
                                        libdirs = value.Split (argument_value_separator);
 
820
                                        foreach (string dir in libdirs)
 
821
                                                settings.ReferencesLookupPaths.Add (dir);
 
822
                                        return ParseResult.Success;
 
823
                                }
 
824
 
 
825
                        case "/debug-":
 
826
                                settings.GenerateDebugInfo = false;
 
827
                                return ParseResult.Success;
 
828
 
 
829
                        case "/debug":
 
830
                                if (value == "full" || value == "")
 
831
                                        settings.GenerateDebugInfo = true;
 
832
 
 
833
                                return ParseResult.Success;
 
834
 
 
835
                        case "/debug+":
 
836
                                settings.GenerateDebugInfo = true;
 
837
                                return ParseResult.Success;
 
838
 
 
839
                        case "/checked":
 
840
                        case "/checked+":
 
841
                                settings.Checked = true;
 
842
                                return ParseResult.Success;
 
843
 
 
844
                        case "/checked-":
 
845
                                settings.Checked = false;
 
846
                                return ParseResult.Success;
 
847
 
 
848
                        case "/clscheck":
 
849
                        case "/clscheck+":
 
850
                                settings.VerifyClsCompliance = true;
 
851
                                return ParseResult.Success;
 
852
 
 
853
                        case "/clscheck-":
 
854
                                settings.VerifyClsCompliance = false;
 
855
                                return ParseResult.Success;
 
856
 
 
857
                        case "/unsafe":
 
858
                        case "/unsafe+":
 
859
                                settings.Unsafe = true;
 
860
                                return ParseResult.Success;
 
861
 
 
862
                        case "/unsafe-":
 
863
                                settings.Unsafe = false;
 
864
                                return ParseResult.Success;
 
865
 
 
866
                        case "/warnaserror":
 
867
                        case "/warnaserror+":
 
868
                                if (value.Length == 0) {
 
869
                                        report.WarningsAreErrors = true;
 
870
                                } else {
 
871
                                        foreach (string wid in value.Split (numeric_value_separator))
 
872
                                                report.AddWarningAsError (wid);
 
873
                                }
 
874
                                return ParseResult.Success;
 
875
 
 
876
                        case "/warnaserror-":
 
877
                                if (value.Length == 0) {
 
878
                                        report.WarningsAreErrors = false;
 
879
                                } else {
 
880
                                        foreach (string wid in value.Split (numeric_value_separator))
 
881
                                                report.RemoveWarningAsError (wid);
 
882
                                }
 
883
                                return ParseResult.Success;
 
884
 
 
885
                        case "/warn":
 
886
                                if (value.Length == 0) {
 
887
                                        Error_RequiresArgument (option);
 
888
                                        return ParseResult.Error;
 
889
                                }
 
890
 
 
891
                                SetWarningLevel (value);
 
892
                                return ParseResult.Success;
 
893
 
 
894
                        case "/nowarn":
 
895
                                        if (value.Length == 0) {
 
896
                                                Error_RequiresArgument (option);
 
897
                                                return ParseResult.Error;
 
898
                                        }
 
899
 
 
900
                                        var warns = value.Split (numeric_value_separator);
 
901
                                        foreach (string wc in warns) {
 
902
                                                try {
 
903
                                                        if (wc.Trim ().Length == 0)
 
904
                                                                continue;
 
905
 
 
906
                                                        int warn = Int32.Parse (wc);
 
907
                                                        if (warn < 1) {
 
908
                                                                throw new ArgumentOutOfRangeException ("warn");
 
909
                                                        }
 
910
                                                        report.SetIgnoreWarning (warn);
 
911
                                                } catch {
 
912
                                                        report.Error (1904, "`{0}' is not a valid warning number", wc);
 
913
                                                        return ParseResult.Error;
 
914
                                                }
 
915
                                        }
 
916
                                        return ParseResult.Success;
 
917
 
 
918
                        case "/noconfig":
 
919
                                settings.LoadDefaultReferences = false;
 
920
                                return ParseResult.Success;
 
921
 
 
922
                        case "/platform":
 
923
                                if (value.Length == 0) {
 
924
                                        Error_RequiresArgument (option);
 
925
                                        return ParseResult.Error;
 
926
                                }
 
927
 
 
928
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
 
929
                                case "anycpu":
 
930
                                        settings.Platform = Platform.AnyCPU;
 
931
                                        break;
 
932
                                case "x86":
 
933
                                        settings.Platform = Platform.X86;
 
934
                                        break;
 
935
                                case "x64":
 
936
                                        settings.Platform = Platform.X64;
 
937
                                        break;
 
938
                                case "itanium":
 
939
                                        settings.Platform = Platform.IA64;
 
940
                                        break;
 
941
                                default:
 
942
                                        report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'");
 
943
                                        return ParseResult.Error;
 
944
                                }
 
945
 
 
946
                                return ParseResult.Success;
 
947
 
 
948
                        case "/sdk":
 
949
                                if (value.Length == 0) {
 
950
                                        Error_RequiresArgument (option);
 
951
                                        return ParseResult.Error;
 
952
                                }
 
953
 
 
954
                                settings.SdkVersion = value;
 
955
                                return ParseResult.Success;
 
956
 
 
957
                        // We just ignore this.
 
958
                        case "/errorreport":
 
959
                        case "/filealign":
 
960
                                if (value.Length == 0) {
 
961
                                        Error_RequiresArgument (option);
 
962
                                        return ParseResult.Error;
 
963
                                }
 
964
 
 
965
                                return ParseResult.Success;
 
966
 
 
967
                        case "/helpinternal":
 
968
                                OtherFlags ();
 
969
                                return ParseResult.Stop;
 
970
 
 
971
                        case "/help":
 
972
                        case "/?":
 
973
                                Usage ();
 
974
                                return ParseResult.Stop;
 
975
 
 
976
                        case "/main":
 
977
                        case "/m":
 
978
                                if (value.Length == 0) {
 
979
                                        Error_RequiresArgument (option);
 
980
                                        return ParseResult.Error;
 
981
                                }
 
982
                                settings.MainClass = value;
 
983
                                return ParseResult.Success;
 
984
 
 
985
                        case "/nostdlib":
 
986
                        case "/nostdlib+":
 
987
                                settings.StdLib = false;
 
988
                                return ParseResult.Success;
 
989
 
 
990
                        case "/nostdlib-":
 
991
                                settings.StdLib = true;
 
992
                                return ParseResult.Success;
 
993
 
 
994
                        case "/fullpaths":
 
995
                                report.Printer.ShowFullPaths = true;
 
996
                                return ParseResult.Success;
 
997
 
 
998
                        case "/keyfile":
 
999
                                if (value.Length == 0) {
 
1000
                                        Error_RequiresFileName (option);
 
1001
                                        return ParseResult.Error;
 
1002
                                }
 
1003
 
 
1004
                                settings.StrongNameKeyFile = value;
 
1005
                                return ParseResult.Success;
 
1006
 
 
1007
                        case "/keycontainer":
 
1008
                                if (value.Length == 0) {
 
1009
                                        Error_RequiresArgument (option);
 
1010
                                        return ParseResult.Error;
 
1011
                                }
 
1012
 
 
1013
                                settings.StrongNameKeyContainer = value;
 
1014
                                return ParseResult.Success;
 
1015
 
 
1016
                        case "/delaysign+":
 
1017
                        case "/delaysign":
 
1018
                                settings.StrongNameDelaySign = true;
 
1019
                                return ParseResult.Success;
 
1020
 
 
1021
                        case "/delaysign-":
 
1022
                                settings.StrongNameDelaySign = false;
 
1023
                                return ParseResult.Success;
 
1024
 
 
1025
                        case "/langversion":
 
1026
                                if (value.Length == 0) {
 
1027
                                        Error_RequiresArgument (option);
 
1028
                                        return ParseResult.Error;
 
1029
                                }
 
1030
 
 
1031
                                switch (value.ToLowerInvariant ()) {
 
1032
                                case "iso-1":
 
1033
                                        settings.Version = LanguageVersion.ISO_1;
 
1034
                                        return ParseResult.Success;
 
1035
                                case "default":
 
1036
                                        settings.Version = LanguageVersion.Default;
 
1037
                                        return ParseResult.Success;
 
1038
                                case "iso-2":
 
1039
                                        settings.Version = LanguageVersion.ISO_2;
 
1040
                                        return ParseResult.Success;
 
1041
                                case "3":
 
1042
                                        settings.Version = LanguageVersion.V_3;
 
1043
                                        return ParseResult.Success;
 
1044
                                case "future":
 
1045
                                        settings.Version = LanguageVersion.Future;
 
1046
                                        return ParseResult.Success;
 
1047
                                }
 
1048
 
 
1049
                                report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value);
 
1050
                                return ParseResult.Error;
 
1051
 
 
1052
                        case "/codepage":
 
1053
                                if (value.Length == 0) {
 
1054
                                        Error_RequiresArgument (option);
 
1055
                                        return ParseResult.Error;
 
1056
                                }
 
1057
 
 
1058
                                switch (value) {
 
1059
                                case "utf8":
 
1060
                                        settings.Encoding = Encoding.UTF8;
 
1061
                                        break;
 
1062
                                case "reset":
 
1063
                                        settings.Encoding = Encoding.Default;
 
1064
                                        break;
 
1065
                                default:
 
1066
                                        try {
 
1067
                                                settings.Encoding = Encoding.GetEncoding (int.Parse (value));
 
1068
                                        } catch {
 
1069
                                                report.Error (2016, "Code page `{0}' is invalid or not installed", value);
 
1070
                                        }
 
1071
                                        return ParseResult.Error;
 
1072
                                }
 
1073
                                return ParseResult.Success;
 
1074
 
 
1075
                        default:
 
1076
                                return ParseResult.UnknownOption;
 
1077
                        }
 
1078
                }
 
1079
 
 
1080
                //
 
1081
                // Currently handles the Unix-like command line options, but will be
 
1082
                // deprecated in favor of the CSCParseOption, which will also handle the
 
1083
                // options that start with a dash in the future.
 
1084
                //
 
1085
                ParseResult ParseOptionUnix (string arg, ref string[] args, ref int i, CompilerSettings settings)
 
1086
                {
 
1087
                        switch (arg){
 
1088
                        case "-v":
 
1089
                                CSharpParser.yacc_verbose_flag++;
 
1090
                                return ParseResult.Success;
 
1091
 
 
1092
                        case "--version":
 
1093
                                Version ();
 
1094
                                return ParseResult.Stop;
 
1095
                                
 
1096
                        case "--parse":
 
1097
                                settings.ParseOnly = true;
 
1098
                                return ParseResult.Success;
 
1099
                                
 
1100
                        case "--main": case "-m":
 
1101
                                report.Warning (-29, 1, "Compatibility: Use -main:CLASS instead of --main CLASS or -m CLASS");
 
1102
                                if ((i + 1) >= args.Length){
 
1103
                                        Error_RequiresArgument (arg);
 
1104
                                        return ParseResult.Error;
 
1105
                                }
 
1106
                                settings.MainClass = args[++i];
 
1107
                                return ParseResult.Success;
 
1108
                                
 
1109
                        case "--unsafe":
 
1110
                                report.Warning (-29, 1, "Compatibility: Use -unsafe instead of --unsafe");
 
1111
                                settings.Unsafe = true;
 
1112
                                return ParseResult.Success;
 
1113
                                
 
1114
                        case "/?": case "/h": case "/help":
 
1115
                        case "--help":
 
1116
                                Usage ();
 
1117
                                return ParseResult.Stop;
 
1118
 
 
1119
                        case "--define":
 
1120
                                report.Warning (-29, 1, "Compatibility: Use -d:SYMBOL instead of --define SYMBOL");
 
1121
                                if ((i + 1) >= args.Length){
 
1122
                                        Error_RequiresArgument (arg);
 
1123
                                        return ParseResult.Error;
 
1124
                                }
 
1125
 
 
1126
                                settings.AddConditionalSymbol (args [++i]);
 
1127
                                return ParseResult.Success;
 
1128
 
 
1129
                        case "--tokenize":
 
1130
                                settings.TokenizeOnly = true;
 
1131
                                return ParseResult.Success;
 
1132
                                
 
1133
                        case "-o": 
 
1134
                        case "--output":
 
1135
                                report.Warning (-29, 1, "Compatibility: Use -out:FILE instead of --output FILE or -o FILE");
 
1136
                                if ((i + 1) >= args.Length){
 
1137
                                        Error_RequiresArgument (arg);
 
1138
                                        return ParseResult.Error;
 
1139
                                }
 
1140
                                settings.OutputFile = args[++i];
 
1141
                                return ParseResult.Success;
 
1142
 
 
1143
                        case "--checked":
 
1144
                                report.Warning (-29, 1, "Compatibility: Use -checked instead of --checked");
 
1145
                                settings.Checked = true;
 
1146
                                return ParseResult.Success;
 
1147
                                
 
1148
                        case "--stacktrace":
 
1149
                                report.Printer.Stacktrace = true;
 
1150
                                return ParseResult.Success;
 
1151
                                
 
1152
                        case "--linkresource":
 
1153
                        case "--linkres":
 
1154
                                report.Warning (-29, 1, "Compatibility: Use -linkres:VALUE instead of --linkres VALUE");
 
1155
                                if ((i + 1) >= args.Length){
 
1156
                                        Error_RequiresArgument (arg);
 
1157
                                        return ParseResult.Error;
 
1158
                                }
 
1159
 
 
1160
                                AddResource (new AssemblyResource (args[++i], args[i]), settings);
 
1161
                                return ParseResult.Success;
 
1162
                                
 
1163
                        case "--resource":
 
1164
                        case "--res":
 
1165
                                report.Warning (-29, 1, "Compatibility: Use -res:VALUE instead of --res VALUE");
 
1166
                                if ((i + 1) >= args.Length){
 
1167
                                        Error_RequiresArgument (arg);
 
1168
                                        return ParseResult.Error;
 
1169
                                }
 
1170
 
 
1171
                                AddResource (new AssemblyResource (args[++i], args[i], true), settings);
 
1172
                                return ParseResult.Success;
 
1173
                                
 
1174
                        case "--target":
 
1175
                                report.Warning (-29, 1, "Compatibility: Use -target:KIND instead of --target KIND");
 
1176
                                if ((i + 1) >= args.Length){
 
1177
                                        Error_RequiresArgument (arg);
 
1178
                                        return ParseResult.Error;
 
1179
                                }
 
1180
                                
 
1181
                                string type = args [++i];
 
1182
                                switch (type){
 
1183
                                case "library":
 
1184
                                        settings.Target = Target.Library;
 
1185
                                        settings.TargetExt = ".dll";
 
1186
                                        break;
 
1187
                                        
 
1188
                                case "exe":
 
1189
                                        settings.Target = Target.Exe;
 
1190
                                        break;
 
1191
                                        
 
1192
                                case "winexe":
 
1193
                                        settings.Target = Target.WinExe;
 
1194
                                        break;
 
1195
                                        
 
1196
                                case "module":
 
1197
                                        settings.Target = Target.Module;
 
1198
                                        settings.TargetExt = ".dll";
 
1199
                                        break;
 
1200
                                default:
 
1201
                                        report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
 
1202
                                        break;
 
1203
                                }
 
1204
                                return ParseResult.Success;
 
1205
                                
 
1206
                        case "-r":
 
1207
                                report.Warning (-29, 1, "Compatibility: Use -r:LIBRARY instead of -r library");
 
1208
                                if ((i + 1) >= args.Length){
 
1209
                                        Error_RequiresArgument (arg);
 
1210
                                        return ParseResult.Error;
 
1211
                                }
 
1212
                                
 
1213
                                string val = args [++i];
 
1214
                                int idx = val.IndexOf ('=');
 
1215
                                if (idx > -1) {
 
1216
                                        string alias = val.Substring (0, idx);
 
1217
                                        string assembly = val.Substring (idx + 1);
 
1218
                                        AddAssemblyReference (alias, assembly, settings);
 
1219
                                        return ParseResult.Success;
 
1220
                                }
 
1221
 
 
1222
                                settings.AssemblyReferences.Add (val);
 
1223
                                return ParseResult.Success;
 
1224
                                
 
1225
                        case "-L":
 
1226
                                report.Warning (-29, 1, "Compatibility: Use -lib:ARG instead of --L arg");
 
1227
                                if ((i + 1) >= args.Length){
 
1228
                                        Error_RequiresArgument (arg);
 
1229
                                        return ParseResult.Error;
 
1230
                                }
 
1231
                                settings.ReferencesLookupPaths.Add (args [++i]);
 
1232
                                return ParseResult.Success;
 
1233
 
 
1234
                        case "--lint":
 
1235
                                settings.EnhancedWarnings = true;
 
1236
                                return ParseResult.Success;
 
1237
                                
 
1238
                        case "--nostdlib":
 
1239
                                report.Warning (-29, 1, "Compatibility: Use -nostdlib instead of --nostdlib");
 
1240
                                settings.StdLib = false;
 
1241
                                return ParseResult.Success;
 
1242
                                
 
1243
                        case "--nowarn":
 
1244
                                report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn");
 
1245
                                if ((i + 1) >= args.Length){
 
1246
                                        Error_RequiresArgument (arg);
 
1247
                                        return ParseResult.Error;
 
1248
                                }
 
1249
                                int warn = 0;
 
1250
                                
 
1251
                                try {
 
1252
                                        warn = int.Parse (args [++i]);
 
1253
                                } catch {
 
1254
                                        Usage ();
 
1255
                                        Environment.Exit (1);
 
1256
                                }
 
1257
                                report.SetIgnoreWarning (warn);
 
1258
                                return ParseResult.Success;
 
1259
 
 
1260
                        case "--wlevel":
 
1261
                                report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
 
1262
                                if ((i + 1) >= args.Length){
 
1263
                                        Error_RequiresArgument (arg);
 
1264
                                        return ParseResult.Error;
 
1265
                                }
 
1266
 
 
1267
                                SetWarningLevel (args [++i]);
 
1268
                                return ParseResult.Success;
 
1269
 
 
1270
                        case "--mcs-debug":
 
1271
                                if ((i + 1) >= args.Length){
 
1272
                                        Error_RequiresArgument (arg);
 
1273
                                        return ParseResult.Error;
 
1274
                                }
 
1275
 
 
1276
                                try {
 
1277
                                        settings.DebugFlags = int.Parse (args [++i]);
 
1278
                                } catch {
 
1279
                                        Error_RequiresArgument (arg);
 
1280
                                        return ParseResult.Error;
 
1281
                                }
 
1282
 
 
1283
                                return ParseResult.Success;
 
1284
                                
 
1285
                        case "--about":
 
1286
                                About ();
 
1287
                                return ParseResult.Stop;
 
1288
                                
 
1289
                        case "--recurse":
 
1290
                                report.Warning (-29, 1, "Compatibility: Use -recurse:PATTERN option instead --recurse PATTERN");
 
1291
                                if ((i + 1) >= args.Length){
 
1292
                                        Error_RequiresArgument (arg);
 
1293
                                        return ParseResult.Error;
 
1294
                                }
 
1295
                                ProcessSourceFiles (args [++i], true, settings.SourceFiles);
 
1296
                                return ParseResult.Success;
 
1297
                                
 
1298
                        case "--timestamp":
 
1299
                                settings.Timestamps = true;
 
1300
                                return ParseResult.Success;
 
1301
 
 
1302
                        case "--debug": case "-g":
 
1303
                                report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
 
1304
                                settings.GenerateDebugInfo = true;
 
1305
                                return ParseResult.Success;
 
1306
                                
 
1307
                        case "--noconfig":
 
1308
                                report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
 
1309
                                settings.LoadDefaultReferences = false;
 
1310
                                return ParseResult.Success;
 
1311
 
 
1312
                        default:
 
1313
                                if (arg.StartsWith ("--fatal")){
 
1314
                                        int fatal = 1;
 
1315
                                        if (arg.StartsWith ("--fatal="))
 
1316
                                                int.TryParse (arg.Substring (8), out fatal);
 
1317
 
 
1318
                                        report.Printer.FatalCounter = fatal;
 
1319
                                        return ParseResult.Success;
 
1320
                                }
 
1321
                                if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
 
1322
                                        string version = arg.Substring (10);
 
1323
 
 
1324
                                        switch (version) {
 
1325
                                        case "v1":
 
1326
                                        case "V1":
 
1327
                                                settings.StdLibRuntimeVersion = RuntimeVersion.v1;
 
1328
                                                break;
 
1329
                                        case "v2":
 
1330
                                        case "V2":
 
1331
                                                settings.StdLibRuntimeVersion = RuntimeVersion.v2;
 
1332
                                                break;
 
1333
                                        case "v4":
 
1334
                                        case "V4":
 
1335
                                                settings.StdLibRuntimeVersion = RuntimeVersion.v4;
 
1336
                                                break;
 
1337
                                        }
 
1338
                                        return ParseResult.Success;
 
1339
                                }
 
1340
 
 
1341
                                return ParseResult.UnknownOption;
 
1342
                        }
 
1343
                }
 
1344
 
 
1345
                void SetWarningLevel (string s)
 
1346
                {
 
1347
                        int level = -1;
 
1348
 
 
1349
                        try {
 
1350
                                level = int.Parse (s);
 
1351
                        } catch {
 
1352
                        }
 
1353
                        if (level < 0 || level > 4) {
 
1354
                                report.Error (1900, "Warning level must be in the range 0-4");
 
1355
                                return;
 
1356
                        }
 
1357
                        report.WarningLevel = level;
 
1358
                }
 
1359
 
 
1360
                //
 
1361
                // Given a path specification, splits the path from the file/pattern
 
1362
                //
 
1363
                static void SplitPathAndPattern (string spec, out string path, out string pattern)
 
1364
                {
 
1365
                        int p = spec.LastIndexOf ('/');
 
1366
                        if (p != -1) {
 
1367
                                //
 
1368
                                // Windows does not like /file.cs, switch that to:
 
1369
                                // "\", "file.cs"
 
1370
                                //
 
1371
                                if (p == 0) {
 
1372
                                        path = "\\";
 
1373
                                        pattern = spec.Substring (1);
 
1374
                                } else {
 
1375
                                        path = spec.Substring (0, p);
 
1376
                                        pattern = spec.Substring (p + 1);
 
1377
                                }
 
1378
                                return;
 
1379
                        }
 
1380
 
 
1381
                        p = spec.LastIndexOf ('\\');
 
1382
                        if (p != -1) {
 
1383
                                path = spec.Substring (0, p);
 
1384
                                pattern = spec.Substring (p + 1);
 
1385
                                return;
 
1386
                        }
 
1387
 
 
1388
                        path = ".";
 
1389
                        pattern = spec;
 
1390
                }
 
1391
 
 
1392
                void Usage ()
 
1393
                {
 
1394
                        output.WriteLine (
 
1395
                                "Mono C# compiler, Copyright 2001 - 2011 Novell, Inc.\n" +
 
1396
                                "mcs [options] source-files\n" +
 
1397
                                "   --about              About the Mono C# compiler\n" +
 
1398
                                "   -addmodule:M1[,Mn]   Adds the module to the generated assembly\n" +
 
1399
                                "   -checked[+|-]        Sets default aritmetic overflow context\n" +
 
1400
                                "   -clscheck[+|-]       Disables CLS Compliance verifications\n" +
 
1401
                                "   -codepage:ID         Sets code page to the one in ID (number, utf8, reset)\n" +
 
1402
                                "   -define:S1[;S2]      Defines one or more conditional symbols (short: -d)\n" +
 
1403
                                "   -debug[+|-], -g      Generate debugging information\n" +
 
1404
                                "   -delaysign[+|-]      Only insert the public key into the assembly (no signing)\n" +
 
1405
                                "   -doc:FILE            Process documentation comments to XML file\n" +
 
1406
                                "   -fullpaths           Any issued error or warning uses absolute file path\n" +
 
1407
                                "   -help                Lists all compiler options (short: -?)\n" +
 
1408
                                "   -keycontainer:NAME   The key pair container used to sign the output assembly\n" +
 
1409
                                "   -keyfile:FILE        The key file used to strongname the ouput assembly\n" +
 
1410
                                "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, 3, Default or Future\n" +
 
1411
                                "   -lib:PATH1[,PATHn]   Specifies the location of referenced assemblies\n" +
 
1412
                                "   -main:CLASS          Specifies the class with the Main method (short: -m)\n" +
 
1413
                                "   -noconfig            Disables implicitly referenced assemblies\n" +
 
1414
                                "   -nostdlib[+|-]       Does not reference mscorlib.dll library\n" +
 
1415
                                "   -nowarn:W1[,Wn]      Suppress one or more compiler warnings\n" +
 
1416
                                "   -optimize[+|-]       Enables advanced compiler optimizations (short: -o)\n" +
 
1417
                                "   -out:FILE            Specifies output assembly name\n" +
 
1418
                                "   -pkg:P1[,Pn]         References packages P1..Pn\n" +
 
1419
                                "   -platform:ARCH       Specifies the target platform of the output assembly\n" +
 
1420
                                "                        ARCH can be one of: anycpu, x86, x64 or itanium\n" +
 
1421
                                "   -recurse:SPEC        Recursively compiles files according to SPEC pattern\n" +
 
1422
                                "   -reference:A1[,An]   Imports metadata from the specified assembly (short: -r)\n" +
 
1423
                                "   -reference:ALIAS=A   Imports metadata using specified extern alias (short: -r)\n" +
 
1424
                                "   -sdk:VERSION         Specifies SDK version of referenced assemblies\n" +
 
1425
                                "                        VERSION can be one of: 2, 4 (default) or custom value\n" +
 
1426
                                "   -target:KIND         Specifies the format of the output assembly (short: -t)\n" +
 
1427
                                "                        KIND can be one of: exe, winexe, library, module\n" +
 
1428
                                "   -unsafe[+|-]         Allows to compile code which uses unsafe keyword\n" +
 
1429
                                "   -warnaserror[+|-]    Treats all warnings as errors\n" +
 
1430
                                "   -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" +
 
1431
                                "   -warn:0-4            Sets warning level, the default is 4 (short -w:)\n" +
 
1432
                                "   -helpinternal        Shows internal and advanced compiler options\n" +
 
1433
                                "\n" +
 
1434
                                "Resources:\n" +
 
1435
                                "   -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
 
1436
                                "   -resource:FILE[,ID]     Embed FILE as a resource (short: -res)\n" +
 
1437
                                "   -win32res:FILE          Specifies Win32 resource file (.res)\n" +
 
1438
                                "   -win32icon:FILE         Use this icon for the output\n" +
 
1439
                                                                "   @file                   Read response file for more options\n\n" +
 
1440
                                "Options can be of the form -option or /option");
 
1441
                }
 
1442
 
 
1443
                void Version ()
 
1444
                {
 
1445
                        string version = System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType.Assembly.GetName ().Version.ToString ();
 
1446
                        output.WriteLine ("Mono C# compiler version {0}", version);
 
1447
                }
 
1448
        }
 
1449
 
 
1450
        public class RootContext
 
1451
        {
 
1452
                //
 
1453
                // Contains the parsed tree
 
1454
                //
 
1455
                static ModuleContainer root;
 
1456
 
 
1457
                static public ModuleContainer ToplevelTypes {
 
1458
                        get { return root; }
 
1459
                        set { root = value; }
 
1460
                }
 
1461
        }
 
1462
}