using System.Reflection.Emit;
using System.Collections;
using System.IO;
+ using System.Text;
using System.Globalization;
using Mono.Languages;
// A list of resource files
//
static ArrayList resources;
+ static ArrayList embedded_resources;
//
// An array of the defines from the command line
// Output file
//
static string output_file = null;
-
+
//
// Last time we took the time
//
- static DateTime last_time;
- static void ShowTime (string msg)
+ static DateTime last_time, first_time;
+
+ //
+ // Encoding: ISO-Latin1 is 28591
+ //
+ static Encoding encoding = Encoding.GetEncoding (28591);
+
+ //
+ // Whether the user has specified a different encoder manually
+ //
+ static bool using_default_encoder = true;
+
+ public static void ShowTime (string msg)
{
+ if (!timestamps)
+ return;
+
DateTime now = DateTime.Now;
TimeSpan span = now - last_time;
last_time = now;
"[{0:00}:{1:000}] {2}",
(int) span.TotalSeconds, span.Milliseconds, msg);
}
+
+ public static void ShowTotalTime (string msg)
+ {
+ if (!timestamps)
+ return;
+
+ DateTime now = DateTime.Now;
+ TimeSpan span = now - first_time;
+ last_time = now;
+
+ Console.WriteLine (
+ "[{0:00}:{1:000}] {2}",
+ (int) span.TotalSeconds, span.Milliseconds, msg);
+ }
static void tokenize_file (string input_file)
{
}
using (input){
- Tokenizer lexer = new Tokenizer (input, input_file, defines);
+ StreamReader reader = new StreamReader (input, encoding, using_default_encoder);
+ Tokenizer lexer = new Tokenizer (reader, input_file, defines);
int token, tokens = 0, errors = 0;
while ((token = lexer.token ()) != Token.EOF){
return;
}
- parser = new CSharpParser (input_file, input, defines);
+ StreamReader reader = new StreamReader (input, encoding, using_default_encoder);
+
+ parser = new CSharpParser (reader, input_file, defines);
parser.yacc_verbose = yacc_verbose;
try {
parser.parse ();
Console.WriteLine (
"Mono C# compiler, (C) 2001 Ximian, Inc.\n" +
"mcs [options] source-files\n" +
- " --about About the Mono C# compiler\n" +
- " --checked Set default context to checked\n" +
- " --define SYM Defines the symbol SYM\n" +
- " --debug Generate debugging information\n" +
- " -g Generate debugging information\n" +
- " --debug-args X Specify additional arguments for the\n" +
- " symbol writer.\n" +
- " --fatal Makes errors fatal\n" +
- " -L PATH Adds PATH to the assembly link path\n" +
- " --noconfig Disables implicit references to assemblies\n" +
- " --nostdlib Does not load core libraries\n" +
- " --nowarn XXX Ignores warning number XXX\n" +
- " -o FNAME Specifies output file\n" +
- " -g, --debug Write symbolic debugging information to FILE-debug.s\n" +
- " --parse Only parses the source file\n" +
- " --expect-error X Expect that error X will be encountered\n" +
- " --recurse SPEC Recursively compiles the files in SPEC ([dir]/file)\n" +
- " --resource FILE Addds FILE as a resource\n" +
- " --stacktrace Shows stack trace at error location\n" +
- " --target KIND Specifies the target (KIND is one of: exe, winexe, " +
- "library, module)\n" +
- " --timestamp Displays time stamps of various compiler events\n" +
- " --unsafe Allows unsafe code\n" +
- " --werror Treat warnings as errors\n" +
- " --wlevel LEVEL Sets warning level (the highest is 4, the default)\n" +
- " -r References an assembly\n" +
- " -v Verbose parsing (for debugging the parser)\n" +
- " @file Read response file for more options");
+ " --about About the Mono C# compiler\n" +
+ " -checked[+|-] Set default context to checked\n" +
+ " -codepage:ID Sets code page to the one in ID\n" +
+ " (number, `utf8' or `reset')" +
+ " -define:S1[;S2] Defines one or more symbols (short: /d:)\n" +
+ " -debug[+-] Generate debugging information\n" +
+ " -g Generate debugging information\n" +
+ " --debug-args X Specify additional arguments for the\n" +
+ " symbol writer.\n" +
+ " --fatal Makes errors fatal\n" +
+ " -lib:PATH1,PATH2 Adds the paths to the assembly link path\n" +
+ " -main:class Specified the class that contains the entry point\n" +
+ " -noconfig[+|-] Disables implicit references to assemblies\n" +
+ " -nostdlib[+|-] Does not load core libraries\n" +
+ " -nowarn:W1[,W2] Disables one or more warnings\n" +
+ " -out:FNAME Specifies output file\n" +
+ " --parse Only parses the source file\n" +
+ " --expect-error X Expect that error X will be encountered\n" +
+ " -recurse:SPEC Recursively compiles the files in SPEC ([dir]/file)\n" +
+ " -reference:ASS References the specified assembly (-r:ASS)\n" +
+ " --stacktrace Shows stack trace at error location\n" +
+ " -target:KIND Specifies the target (KIND is one of: exe, winexe, " +
+ "library, module), (short: /t:)\n" +
+ " --timestamp Displays time stamps of various compiler events\n" +
+ " -unsafe[+|-] Allows unsafe code\n" +
+ " -warnaserror[+|-] Treat warnings as errors\n" +
+ " -warn:LEVEL Sets warning level (the highest is 4, the default)\n" +
+ " -v Verbose parsing (for debugging the parser)\n" +
+ "\n" +
+ "Resources:" +
+ " -linkresource:FILE[,ID] Links FILE as a resource\n" +
+ " -resource:FILE[,ID] Embed FILE as a resource\n" +
+
+#if MCS_DEBUG
+ " --mcs-debug X Sets MCS debugging level to X\n" +
+#endif
+ " @file Read response file for more options\n\n" +
+ "Options can be of the form -option or /option");
}
static void About ()
{
Console.WriteLine (
- "The Mono C# compiler is (C) 2001 Ximian, Inc.\n\n" +
+ "The Mono C# compiler is (C) 2001, 2002 Ximian, Inc.\n\n" +
"The compiler source code is released under the terms of the GNU GPL\n\n" +
"For more information on Mono, visit the project Web site\n" +
" http://www.go-mono.com\n\n" +
- "The compiler was written by Miguel de Icaza and Ravi Pratap");
+ "The compiler was written by Miguel de Icaza, Ravi Pratap and Martin Baulig");
+ Environment.Exit (0);
}
public static int Main (string[] args)
return null;
}
+ StringBuilder sb = new StringBuilder ();
+
while ((line = f.ReadLine ()) != null){
- string [] line_args = line.Split (new char [] { ' ' });
+ int t = line.Length;
- foreach (string arg in line_args)
- args.Add (arg);
+ for (int i = 0; i < t; i++){
+ char c = line [i];
+
+ if (c == '"' || c == '\''){
+ char end = c;
+
+ for (i++; i < t; i++){
+ c = line [i];
+
+ if (c == end)
+ break;
+ sb.Append (c);
+ }
+ } else if (c == ' '){
+ if (sb.Length > 0){
+ args.Add (sb.ToString ());
+ sb.Length = 0;
+ }
+ } else
+ sb.Append (c);
+ }
+ if (sb.Length > 0){
+ args.Add (sb.ToString ());
+ sb.Length = 0;
+ }
}
string [] ret_value = new string [args.Count];
Report.Stacktrace = true;
return true;
- case "--resource":
+ case "--linkresource":
+ case "--linkres":
if ((i + 1) >= args.Length){
Usage ();
- Console.WriteLine("Missing argument to --resource");
+ Console.WriteLine("Missing argument to --linkres");
Environment.Exit (1);
}
if (resources == null)
resources.Add (args [++i]);
return true;
+ case "--resource":
+ case "--res":
+ if ((i + 1) >= args.Length){
+ Usage ();
+ Console.WriteLine("Missing argument to --resource");
+ Environment.Exit (1);
+ }
+ if (embedded_resources == null)
+ embedded_resources = new ArrayList ();
+
+ embedded_resources.Add (args [++i]);
+ return true;
+
case "--target":
if ((i + 1) >= args.Length){
Environment.Exit (1);
SetWarningLevel (args [++i]);
return true;
+
+#if MCS_DEBUG
+ case "--mcs-debug":
+ if ((i + 1) >= args.Length){
+ Console.WriteLine ("--mcs-debug requires an argument");
+ Environment.Exit (1);
+ }
+
+ try {
+ Report.DebugFlags = Int32.Parse (args [++i]);
+ } catch {
+ Console.WriteLine ("Invalid argument to --mcs-debug");
+ Environment.Exit (1);
+ }
+ return true;
+#endif
case "--about":
About ();
case "--timestamp":
timestamps = true;
- last_time = DateTime.Now;
+ last_time = first_time = DateTime.Now;
debug_arglist.Add ("timestamp");
return true;
case "--noconfig":
load_default_config = false;
return true;
-
- default:
- Report.Warning(666, "Unknown option: " + arg);
- return true;
}
+
+ return false;
}
//
}
return true;
- case "/out:":
+ case "/out":
if (value == ""){
Usage ();
Environment.Exit (1);
Usage ();
Environment.Exit (1);
}
-
- defs = value.Split (new Char [] {';'});
- foreach (string d in defs)
+
+ defs = value.Split (new Char [] {';', ','});
+ foreach (string d in defs){
defines.Add (d);
+ }
return true;
}
+ case "/linkres":
+ case "/linkresource":
+ if (value == ""){
+ Console.WriteLine ("{0} requires an argument", arg);
+ Environment.Exit (1);
+ }
+ if (resources == null)
+ resources = new ArrayList ();
+
+ resources.Add (value);
+ return true;
+
+ case "/res":
+ case "/resource":
+ if (value == ""){
+ Console.WriteLine ("{0} requires an argument", arg);
+ Environment.Exit (1);
+ }
+ if (embedded_resources == null)
+ embedded_resources = new ArrayList ();
+
+ embedded_resources.Add (value);
+ return true;
+
case "/recurse":
if (value == ""){
Console.WriteLine ("/recurse requires an argument");
case "/r":
case "/reference":
if (value == ""){
- Console.WriteLine ("/recurse requires an argument");
+ Console.WriteLine ("/reference requires an argument");
Environment.Exit (1);
}
references.Add (value);
case "/lib": {
string [] libdirs;
- if (value = ""){
- Usage ();
+ if (value == ""){
+ Console.WriteLine ("/lib requires an argument");
Environment.Exit (1);
}
string [] warns;
if (value == ""){
- Usage ();
+ Console.WriteLine ("/nowarn requires an argument");
Environment.Exit (1);
}
case "/main":
case "/m":
if (value == ""){
- Usage ();
+ Console.WriteLine ("/main requires an argument");
Environment.Exit (1);
}
RootContext.MainClass = value;
RootContext.StdLib = true;
return true;
+ case "/codepage":
+ int cp = -1;
+
+ if (value == "utf8")
+ cp = (new UTF8Encoding()).WindowsCodePage;
+ if (value == "reset"){
+ cp = 28591;
+ using_default_encoder = true;
+ }
+
+ try {
+ cp = Int32.Parse (value);
+ } catch { }
+
+ if (cp == -1){
+ Console.WriteLine ("Invalid code-page requested");
+ Usage ();
+ }
+
+ try {
+ encoding = Encoding.GetEncoding (cp);
+ using_default_encoder = false;
+ } catch {
+ Console.WriteLine ("Code page: {0} not supported", cp);
+ }
+ return true;
+
}
return false;
}
if (arg.StartsWith ("-")){
if (UnixParseOption (arg, ref args, ref i))
continue;
+
+ // Try a -CSCOPTION
+ string csc_opt = "/" + arg.Substring (1);
+ if (CSCParseOption (csc_opt, ref args, ref i))
+ continue;
} else {
- if (arg.StartsWith ("/"))
+ if (arg.StartsWith ("/")){
if (CSCParseOption (arg, ref args, ref i))
continue;
+ }
}
}
if (!RootContext.StdLib)
RootContext.BootCorlib_PopulateCoreTypes ();
RootContext.PopulateTypes ();
+ RootContext.DefineTypes ();
TypeManager.InitCodeHelpers ();
//
if (timestamps)
ShowTime ("Emitting code");
+ ShowTotalTime ("Total so far");
RootContext.EmitCode ();
if (timestamps)
ShowTime (" done");
if (timestamps)
ShowTime ("Closing types");
+
+ if (RootContext.WarningLevel >= 4)
+ if (!Namespace.VerifyUsing ())
+ return false;
RootContext.CloseTypes ();
MethodInfo ep = RootContext.EntryPoint;
if (ep == null){
- Report.Error (5001, "Program " + output_file +
+ if (Report.Errors == 0)
+ Report.Error (5001, "Program " + output_file +
" does not have an entry point defined");
return false;
}
// Add the resources
//
if (resources != null){
- foreach (string file in resources)
- CodeGen.AssemblyBuilder.AddResourceFile (file, file);
+ foreach (string spec in resources){
+ string file, res;
+ int cp;
+
+ cp = spec.IndexOf (',');
+ if (cp != -1){
+ file = spec.Substring (0, cp);
+ res = spec.Substring (cp + 1);
+ } else
+ file = res = spec;
+
+ CodeGen.AssemblyBuilder.AddResourceFile (res, file);
+ }
+ }
+
+ if (embedded_resources != null){
+ object[] margs = new object [2];
+ Type[] argst = new Type [2];
+ argst [0] = argst [1] = typeof (string);
+ MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", argst);
+ if (embed_res == null) {
+ Report.Warning (0, new Location (-1), "Cannot embed resources on this runtime: try the Mono runtime instead.");
+ } else {
+ foreach (string spec in embedded_resources) {
+ int cp;
+
+ cp = spec.IndexOf (',');
+ if (cp != -1){
+ margs [0] = spec.Substring (cp + 1);
+ margs [1] = spec.Substring (0, cp);
+ } else
+ margs [0] = margs [1] = spec;
+ embed_res.Invoke (CodeGen.AssemblyBuilder, margs);
+ }
+ }
}
CodeGen.Save (output_file);
- if (timestamps)
+ if (timestamps) {
ShowTime ("Saved output");
+ ShowTotalTime ("Total");
+ }
+ Timer.ShowTimers ();
+
if (want_debugging_support) {
CodeGen.SaveSymbols ();
if (timestamps)