using System.Reflection;
using System.Reflection.Emit;
using System.Collections;
+ using System.Diagnostics;
using System.IO;
using System.Text;
using System.Globalization;
- enum Target {
+ public enum Target {
Library, Exe, Module, WinExe
};
//
static ArrayList soft_references;
+ //
+ // Modules to be linked
+ //
+ static ArrayList modules;
+
// Lookup paths
static ArrayList link_paths;
static string first_source;
- static Target target = Target.Exe;
- static string target_ext = ".exe";
-
static bool want_debugging_support = false;
static bool parse_only = false;
static bool timestamps = false;
static bool pause = false;
static bool show_counters = false;
+ public static bool parser_verbose = false;
//
// Whether to load the initial config file (what CSC.RSP has by default)
//
static ArrayList resources;
static ArrayList embedded_resources;
+ static string win32ResourceFile;
+ static string win32IconFile;
//
// An array of the defines from the command line
// Whether the user has specified a different encoder manually
//
static bool using_default_encoder = true;
-
+
+ //
+ // The system version we are using, if not specified on the commandline we
+ // will use the same version as corlib for looking for libraries in the GAC.
+ //
+ static string sys_version;
+
public static void ShowTime (string msg)
{
if (!timestamps)
Console.WriteLine (
"[{0:00}:{1:000}] {2}",
(int) span.TotalSeconds, span.Milliseconds, msg);
-
- if (pause)
- Console.ReadLine ();
}
public static void ShowTotalTime (string msg)
}
using (input){
- StreamReader reader = new StreamReader (input, encoding, using_default_encoder);
+ SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
Tokenizer lexer = new Tokenizer (reader, file, defines);
int token, tokens = 0, errors = 0;
while ((token = lexer.token ()) != Token.EOF){
- Location l = lexer.Location;
tokens++;
if (token == Token.ERROR)
errors++;
return;
}
- StreamReader reader = new StreamReader (input, encoding, using_default_encoder);
+ SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
parser = new CSharpParser (reader, file, defines);
parser.yacc_verbose_flag = yacc_verbose;
}
}
+ static void OtherFlags ()
+ {
+ Console.WriteLine (
+ "Other flags in the compiler\n" +
+ " --fatal Makes errors fatal\n" +
+ " --parse Only parses the source file\n" +
+ " --stacktrace Shows stack trace at error location\n" +
+ " --timestamp Displays time stamps of various compiler events\n" +
+ " -2 Enables experimental C# features\n" +
+ " -v Verbose parsing (for debugging the parser)\n" +
+ " --mcs-debug X Sets MCS debugging level to X\n");
+ }
+
static void Usage ()
{
Console.WriteLine (
" -checked[+|-] Set default context to checked\n" +
" -codepage:ID Sets code page to the one in ID\n" +
" (number, `utf8' or `reset')\n" +
+ " -clscheck[+|-] Disables CLS Compliance verifications" + Environment.NewLine +
" -define:S1[;S2] Defines one or more symbols (short: /d:)\n" +
- " -debug[+-] Generate debugging information\n" +
+ " -debug[+|-] Generate debugging information\n" +
+ " -delaysign[+|-] Only insert the public key into the assembly (no signing)\n" +
" -doc:FILE XML Documentation file to generate\n" +
" -g Generate debugging information\n" +
- " --fatal Makes errors fatal\n" +
+ " -keycontainer:NAME The key pair container used to strongname the assembly\n" +
+ " -keyfile:FILE The strongname key file used to strongname the assembly\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" +
+ " -pkg:P1[,Pn] References packages P1..Pn\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,\n" +
" 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" +
+ " -warn:LEVEL Sets warning level (the highest is 4, the default is 2)\n" +
+ " -help2 Show other help flags\n" +
"\n" +
"Resources:\n" +
" -linkresource:FILE[,ID] Links FILE as a resource\n" +
" -resource:FILE[,ID] Embed FILE as a resource\n" +
- " --mcs-debug X Sets MCS debugging level to X\n" +
+ " -win32res:FILE Specifies Win32 resource file (.res)\n" +
+ " -win32icon:FILE Use this icon for the output\n" +
" @file Read response file for more options\n\n" +
"Options can be of the form -option or /option");
}
public static int Main (string[] args)
{
+ RootContext.V2 = true;
bool ok = MainDriver (args);
if (ok && Report.Errors == 0) {
Console.WriteLine ("Counter1: " + counter1);
Console.WriteLine ("Counter2: " + counter2);
}
+ if (pause)
+ Console.ReadLine ();
return 0;
} else {
Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
string total_log = "";
try {
- char[] path_chars = { '/', '\\', '.' };
+ char[] path_chars = { '/', '\\' };
if (assembly.IndexOfAny (path_chars) != -1) {
a = Assembly.LoadFrom (assembly);
} else {
- a = Assembly.Load (assembly);
+ string ass = assembly;
+ if (ass.EndsWith (".dll"))
+ ass = assembly.Substring (0, assembly.Length - 4);
+ a = Assembly.Load (ass);
}
TypeManager.AddAssembly (a);
}
}
+ static public void LoadModule (MethodInfo adder_method, string module)
+ {
+ Module m;
+ string total_log = "";
+
+ try {
+ try {
+ m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { module });
+ }
+ catch (TargetInvocationException ex) {
+ throw ex.InnerException;
+ }
+ TypeManager.AddModule (m);
+
+ }
+ catch (FileNotFoundException){
+ foreach (string dir in link_paths){
+ string full_path = Path.Combine (dir, module);
+ if (!module.EndsWith (".netmodule"))
+ full_path += ".netmodule";
+
+ try {
+ try {
+ m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { full_path });
+ }
+ catch (TargetInvocationException ex) {
+ throw ex.InnerException;
+ }
+ TypeManager.AddModule (m);
+ return;
+ } catch (FileNotFoundException ff) {
+ total_log += ff.FusionLog;
+ continue;
+ }
+ }
+ Report.Error (6, "Cannot find module `" + module + "'" );
+ Console.WriteLine ("Log: \n" + total_log);
+ } catch (BadImageFormatException f) {
+ Report.Error(6, "Cannot load module (bad file format)" + f.FusionLog);
+ } catch (FileLoadException f){
+ Report.Error(6, "Cannot load module " + f.FusionLog);
+ } catch (ArgumentNullException){
+ Report.Error(6, "Cannot load module (null argument)");
+ }
+ }
+
/// <summary>
/// Loads all assemblies referenced on the command line
/// </summary>
foreach (Assembly a in assemblies){
string codebase = a.Location;
- if (codebase.EndsWith ("corlib.dll")){
+ string fn = System.IO.Path.GetFileName (codebase);
+ if (fn == "corlib.dll" || fn == "mscorlib.dll"){
return codebase.Substring (0, codebase.LastIndexOf (System.IO.Path.DirectorySeparatorChar));
}
}
//
static void SplitPathAndPattern (string spec, out string path, out string pattern)
{
- int p = spec.LastIndexOf ("/");
+ int p = spec.LastIndexOf ('/');
if (p != -1){
//
// Windows does not like /file.cs, switch that to:
return;
}
- p = spec.LastIndexOf ("\\");
+ p = spec.LastIndexOf ('\\');
if (p != -1){
path = spec.Substring (0, p);
pattern = spec.Substring (p + 1);
string path, pattern;
SplitPathAndPattern (spec, out path, out pattern);
- if (pattern.IndexOf ("*") == -1){
+ if (pattern.IndexOf ('*') == -1){
ProcessFile (spec);
return;
}
} catch {
Report.Error (
1900,
- "--wlevel requires an value from 0 to 4");
+ "--wlevel requires a value from 0 to 4");
Environment.Exit (1);
}
if (level < 0 || level > 4){
Report.Error (1900, "Warning level must be 0 to 4");
Environment.Exit (1);
- } else
- RootContext.WarningLevel = level;
+ }
+ RootContext.WarningLevel = level;
+ TestWarningConflict ();
+ }
+
+ static void TestWarningConflict ()
+ {
+ if (RootContext.WarningLevel == 0 && Report.WarningsAreErrors) {
+ Report.Error (1901, "Conflicting options specified: Warning level 0; Treat warnings as errors");
+ Environment.Exit (1);
+ }
}
static void SetupV2 ()
static bool UnixParseOption (string arg, ref string [] args, ref int i)
{
switch (arg){
+ case "-vv":
+ parser_verbose = true;
+ return true;
+
case "-v":
yacc_verbose = true;
return true;
string type = args [++i];
switch (type){
case "library":
- target = Target.Library;
- target_ext = ".dll";
+ RootContext.Target = Target.Library;
+ RootContext.TargetExt = ".dll";
break;
case "exe":
- target = Target.Exe;
+ RootContext.Target = Target.Exe;
break;
case "winexe":
- target = Target.WinExe;
+ RootContext.Target = Target.WinExe;
break;
case "module":
- target = Target.Module;
- target_ext = ".dll";
+ RootContext.Target = Target.Module;
+ RootContext.TargetExt = ".dll";
break;
default:
TargetUsage ();
case "--werror":
Report.WarningsAreErrors = true;
+ TestWarningConflict();
return true;
case "--nowarn":
if ((i + 1) >= args.Length){
Report.Error (
1900,
- "--wlevel requires an value from 0 to 4");
+ "--wlevel requires a value from 0 to 4");
Environment.Exit (1);
}
//
static bool CSCParseOption (string option, ref string [] args, ref int i)
{
- int idx = option.IndexOf (":");
+ int idx = option.IndexOf (':');
string arg, value;
if (idx == -1){
case "/target":
switch (value){
case "exe":
- target = Target.Exe;
+ RootContext.Target = Target.Exe;
break;
case "winexe":
- target = Target.WinExe;
+ RootContext.Target = Target.WinExe;
break;
case "library":
- target = Target.Library;
- target_ext = ".dll";
+ RootContext.Target = Target.Library;
+ RootContext.TargetExt = ".dll";
break;
case "module":
- target = Target.Module;
- target_ext = ".netmodule";
+ RootContext.Target = Target.Module;
+ RootContext.TargetExt = ".netmodule";
break;
default:
resources.Add (value);
return true;
+ case "/pkg": {
+ string packages;
+
+ if (value == ""){
+ Usage ();
+ Environment.Exit (1);
+ }
+ packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
+
+ ProcessStartInfo pi = new ProcessStartInfo ();
+ pi.FileName = "pkg-config";
+ pi.RedirectStandardOutput = true;
+ pi.UseShellExecute = false;
+ pi.Arguments = "--libs " + packages;
+ Process p = null;
+ try {
+ p = Process.Start (pi);
+ } catch (Exception e) {
+ Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
+ Environment.Exit (1);
+ }
+
+ if (p.StandardOutput == null){
+ Report.Warning (-27, "Specified package did not return any information");
+ return true;
+ }
+ string pkgout = p.StandardOutput.ReadToEnd ();
+ p.WaitForExit ();
+ if (p.ExitCode != 0) {
+ Report.Error (-27, "Error running pkg-config. Check the above output.");
+ Environment.Exit (1);
+ }
+
+ if (pkgout != null){
+ string [] xargs = pkgout.Trim (new Char [] {' ', '\n', '\r', '\t'}).
+ Split (new Char [] { ' ', '\t'});
+ args = AddArgs (args, xargs);
+ }
+
+ p.Close ();
+ return true;
+ }
+
case "/res":
case "/resource":
if (value == ""){
}
return true;
}
+ case "/addmodule": {
+ if (value == ""){
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+
+ string [] refs = value.Split (new char [] { ';', ',' });
+ foreach (string r in refs){
+ modules.Add (r);
+ }
+ return true;
+ }
+ case "/win32res": {
+ if (value == "") {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+
+ win32ResourceFile = value;
+ return true;
+ }
+ case "/win32icon": {
+ if (value == "") {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+
+ win32IconFile = value;
+ return true;
+ }
case "/doc": {
if (value == ""){
Report.Error (5, arg + " requires an argument");
link_paths.Add (dir);
return true;
}
+
+ case "/debug-":
+ want_debugging_support = false;
+ return true;
case "/debug":
case "/debug+":
RootContext.Checked = false;
return true;
+ case "/clscheck":
+ case "/clscheck+":
+ return true;
+
+ case "/clscheck-":
+ RootContext.VerifyClsCompliance = false;
+ return true;
+
case "/unsafe":
case "/unsafe+":
RootContext.Unsafe = true;
case "/warnaserror":
case "/warnaserror+":
Report.WarningsAreErrors = true;
+ TestWarningConflict();
return true;
case "/warnaserror-":
warns = value.Split (new Char [] {','});
foreach (string wc in warns){
- int warn = 0;
-
try {
- warn = Int32.Parse (wc);
+ int warn = Int32.Parse (wc);
+ if (warn < 1) {
+ throw new ArgumentOutOfRangeException("warn");
+ }
+ Report.SetIgnoreWarning (warn);
} catch {
- Usage ();
+ Report.Error (1904, String.Format("'{0}' is not a valid warning number", wc));
Environment.Exit (1);
}
- Report.SetIgnoreWarning (warn);
}
return true;
}
load_default_config = false;
return true;
+ case "/help2":
+ OtherFlags ();
+ Environment.Exit(0);
+ return true;
+
case "/help":
case "/?":
Usage ();
case "/fullpaths":
return true;
- case "/win32icon":
- Report.Error (5, "/win32icon is currently not supported");
+ case "/keyfile":
+ if (value == String.Empty) {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+ RootContext.StrongNameKeyFile = value;
return true;
-
+ case "/keycontainer":
+ if (value == String.Empty) {
+ Report.Error (5, arg + " requires an argument");
+ Environment.Exit (1);
+ }
+ RootContext.StrongNameKeyContainer = value;
+ return true;
+ case "/delaysign+":
+ RootContext.StrongNameDelaySign = true;
+ return true;
+ case "/delaysign-":
+ RootContext.StrongNameDelaySign = false;
+ return true;
+
case "/v2":
+ case "/2":
SetupV2 ();
return 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);
+ Report.Error (2016, String.Format("Code page '{0}' is invalid or not installed", cp));
+ Environment.Exit (1);
}
return true;
-
}
+ //Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
+ //Environment.Exit (1);
return false;
}
+ static string [] AddArgs (string [] args, string [] extra_args)
+ {
+ string [] new_args;
+
+ new_args = new string [extra_args.Length + args.Length];
+ args.CopyTo (new_args, 0);
+ extra_args.CopyTo (new_args, args.Length);
+
+ return new_args;
+ }
+
/// <summary>
/// Parses the arguments, and drives the compilation
/// process.
/// now, needs to be turned into a real driver soon.
/// </remarks>
// [MonoTODO("Change error code for unknown argument to something reasonable")]
- static bool MainDriver (string [] args)
+ internal static bool MainDriver (string [] args)
{
int i;
bool parsing_options = true;
- Console.WriteLine ("Mono C# Compiler {0} for Generics",
+ Console.WriteLine ("ALPHA SOFTWARE: Mono C# Compiler {0} for Generics",
Assembly.GetExecutingAssembly ().GetName ().Version.ToString ());
try {
encoding = Encoding.GetEncoding (28591);
references = new ArrayList ();
soft_references = new ArrayList ();
+ modules = new ArrayList ();
link_paths = new ArrayList ();
SetupDefaultDefines ();
// path.
//
- int argc = args.Length;
- for (i = 0; i < argc; i++){
+ for (i = 0; i < args.Length; i++){
string arg = args [i];
+ if (arg == "")
+ continue;
if (arg.StartsWith ("@")){
- string [] new_args, extra_args;
+ string [] extra_args;
string response_file = arg.Substring (1);
if (response_file_list == null)
return false;
}
- new_args = new string [extra_args.Length + argc];
- args.CopyTo (new_args, 0);
- extra_args.CopyTo (new_args, argc);
- args = new_args;
- argc = new_args.Length;
+ args = AddArgs (args, extra_args);
continue;
}
if (tokenize)
return true;
+ //
+ // If we are an exe, require a source file for the entry point
+ //
+ if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe){
if (first_source == null){
Report.Error (2008, "No files to compile were specified");
return false;
}
+ }
+
+ //
+ // If there is nothing to put in the assembly, and we are not a library
+ //
+ if (first_source == null && embedded_resources == null && resources == null){
+ Report.Error (2008, "No files to compile were specified");
+ return false;
+ }
+
if (Report.Errors > 0)
return false;
if (parse_only)
return true;
+ Tokenizer.Cleanup ();
+
//
// Load Core Library for default compilation
//
if (timestamps)
ShowTime ("Loading references");
link_paths.Add (GetSystemDir ());
+ link_paths.Add (Directory.GetCurrentDirectory ());
LoadReferences ();
if (timestamps)
// Quick hack
//
if (output_file == null){
- int pos = first_source.LastIndexOf (".");
+ int pos = first_source.LastIndexOf ('.');
if (pos > 0)
- output_file = first_source.Substring (0, pos) + target_ext;
+ output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
else
- output_file = first_source + target_ext;
+ output_file = first_source + RootContext.TargetExt;
}
CodeGen.Init (output_file, output_file, want_debugging_support);
- TypeManager.AddModule (CodeGen.ModuleBuilder);
+ if (RootContext.Target == Target.Module) {
+ PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ if (module_only == null) {
+ Report.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
+ Environment.Exit (1);
+ }
+
+ MethodInfo set_method = module_only.GetSetMethod (true);
+ set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
+ }
+
+ TypeManager.AddModule (CodeGen.Module.Builder);
+
+ if (modules.Count > 0) {
+ MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
+ if (adder_method == null) {
+ Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
+ Environment.Exit (1);
+ }
+
+ foreach (string module in modules)
+ LoadModule (adder_method, module);
+ }
- DateTime start = DateTime.Now;
TypeManager.ComputeNamespaces ();
- DateTime end = DateTime.Now;
//
// Before emitting, we need to get the core
if (timestamps)
ShowTime ("Resolving tree");
RootContext.ResolveTree ();
+ if (Report.Errors > 0)
+ return false;
if (timestamps)
ShowTime ("Populate tree");
if (!RootContext.StdLib)
return false;
}
+ if (RootContext.VerifyClsCompliance) {
+ CodeGen.Assembly.ResolveClsCompliance ();
+ AttributeTester.VerifyModulesClsCompliance ();
+ TypeManager.LoadAllImportedTypes ();
+ }
+
//
// The code generator
//
PEFileKinds k = PEFileKinds.ConsoleApplication;
- if (target == Target.Library || target == Target.Module){
- k = PEFileKinds.Dll;
-
- if (RootContext.MainClass != null)
- Report.Error (2017, "Can not specify -main: when building module or library");
- } else if (target == Target.Exe)
- k = PEFileKinds.ConsoleApplication;
- else if (target == Target.WinExe)
- k = PEFileKinds.WindowApplication;
+ switch (RootContext.Target) {
+ case Target.Library:
+ case Target.Module:
+ k = PEFileKinds.Dll; break;
+ case Target.Exe:
+ k = PEFileKinds.ConsoleApplication; break;
+ case Target.WinExe:
+ k = PEFileKinds.WindowApplication; break;
+ }
- if (target == Target.Exe || target == Target.WinExe){
+ if (RootContext.NeedsEntryPoint) {
MethodInfo ep = RootContext.EntryPoint;
- if (ep == null){
+ if (ep == null) {
if (Report.Errors == 0)
Report.Error (5001, "Program " + output_file +
" does not have an entry point defined");
return false;
}
- CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
+ CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
+ } else if (RootContext.MainClass != null) {
+ Report.Error (2017, "Can not specify -main: when building module or library");
}
//
} else
file = res = spec;
- CodeGen.AssemblyBuilder.AddResourceFile (res, file);
+ CodeGen.Assembly.Builder.AddResourceFile (res, file);
}
}
object[] margs = new object [2];
Type[] argst = new Type [2];
argst [0] = argst [1] = typeof (string);
- MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", argst);
+
+ MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod (
+ "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
+ null, CallingConventions.Any, argst, null);
+
if (embed_res == null) {
- Report.Warning (0, new Location (-1), "Cannot embed resources on this runtime: try the Mono runtime instead.");
+ 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;
if (cp != -1){
margs [0] = spec.Substring (cp + 1);
margs [1] = spec.Substring (0, cp);
- } else
- margs [0] = margs [1] = spec;
+ } else {
+ margs [1] = spec;
+ margs [0] = spec.Replace ('/','.').Replace ('\\', '.');
+ }
if (File.Exists ((string) margs [1]))
- embed_res.Invoke (CodeGen.AssemblyBuilder, margs);
+ embed_res.Invoke (CodeGen.Assembly.Builder, margs);
else {
Report.Error (1566, "Can not find the resource " + margs [1]);
}
}
}
+ //
+ // Add Win32 resources
+ //
+
+ CodeGen.Assembly.Builder.DefineVersionInfoResource ();
+
+ if (win32ResourceFile != null) {
+ try {
+ CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
+ }
+ catch (ArgumentException) {
+ Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
+ }
+ }
+
+ if (win32IconFile != null) {
+ MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ if (define_icon == null) {
+ Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
+ }
+ define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
+ }
+
if (Report.Errors > 0)
return false;
Timer.ShowTimers ();
if (Report.ExpectedError != 0){
- Console.WriteLine("Failed to report expected error " + Report.ExpectedError);
+ if (Report.Errors == 0) {
+ Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
+ "No other errors reported.");
+
+ Environment.Exit (2);
+ } else {
+ Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
+ "However, other errors were reported.");
+
Environment.Exit (1);
+ }
+
+
return false;
}
}
}
+
+ //
+ // This is the only public entry point
+ //
+ public class CompilerCallableEntryPoint : MarshalByRefObject {
+ static bool used = false;
+
+ public bool InvokeCompiler (string [] args)
+ {
+ if (used)
+ Reset ();
+ bool ok = Driver.MainDriver (args);
+ return ok && Report.Errors == 0;
+ }
+
+ public void Reset ()
+ {
+ }
+ }
}