//
// This parses the -arg and /arg options to the compiler, even if the strings
// in the following text use "/arg" on the strings.
//
ParseResult ParseOption (string option, ref string[] args, CompilerSettings settings)
{
int idx = option.IndexOf (':');
string arg, value;
if (idx == -1) {
arg = option;
value = "";
} else {
arg = option.Substring (0, idx);
value = option.Substring (idx + 1);
}
switch (arg.ToLowerInvariant ()) {
case "/nologo":
return ParseResult.Success;
case "/t":
case "/target":
switch (value) {
case "exe":
settings.Target = Target.Exe;
break;
case "winexe":
settings.Target = Target.WinExe;
break;
case "library":
settings.Target = Target.Library;
settings.TargetExt = ".dll";
break;
case "module":
settings.Target = Target.Module;
settings.TargetExt = ".netmodule";
break;
default:
report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
return ParseResult.Error;
}
return ParseResult.Success;
case "/out":
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
settings.OutputFile = value;
return ParseResult.Success;
case "/o":
case "/o+":
case "/optimize":
case "/optimize+":
settings.Optimize = true;
return ParseResult.Success;
case "/o-":
case "/optimize-":
settings.Optimize = false;
return ParseResult.Success;
// TODO: Not supported by csc 3.5+
case "/incremental":
case "/incremental+":
case "/incremental-":
// nothing.
return ParseResult.Success;
case "/d":
case "/define": {
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
foreach (string d in value.Split (argument_value_separator)) {
string conditional = d.Trim ();
if (!Tokenizer.IsValidIdentifier (conditional)) {
report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional);
continue;
}
RootContext.AddConditional (conditional);
}
return ParseResult.Success;
}
case "/bugreport":
//
// We should collect data, runtime, etc and store in the file specified
//
output.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
return ParseResult.Success;
case "/pkg": {
string packages;
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
packages = String.Join (" ", value.Split (new Char[] { ';', ',', '\n', '\r' }));
string pkgout = null;// Driver.GetPackageFlags(packages, report);
if (pkgout == null)
return ParseResult.Error;
string[] xargs = pkgout.Trim (new Char[] { ' ', '\n', '\r', '\t' }).Split (new Char[] { ' ', '\t' });
args = AddArgs (args, xargs);
return ParseResult.Success;
}
case "/linkres":
case "/linkresource":
case "/res":
case "/resource":
AssemblyResource res = null;
string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
switch (s.Length) {
case 1:
if (s[0].Length == 0)
goto default;
res = new AssemblyResource (s[0], Path.GetFileName (s[0]));
break;
case 2:
res = new AssemblyResource (s[0], s[1]);
break;
case 3:
if (s[2] != "public" && s[2] != "private") {
report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s[2]);
return ParseResult.Error;
}
res = new AssemblyResource (s[0], s[1], s[2] == "private");
break;
default:
report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
return ParseResult.Error;
}
if (res != null) {
res.IsEmbeded = arg[1] == 'r' || arg[1] == 'R';
AddResource (res, settings);
}
return ParseResult.Success;
case "/recurse":
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
ProcessSourceFiles (value, true);
return ParseResult.Success;
case "/r":
case "/reference": {
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
string[] refs = value.Split (argument_value_separator);
foreach (string r in refs) {
if (r.Length == 0)
continue;
string val = r;
int index = val.IndexOf ('=');
if (index > -1) {
string alias = r.Substring (0, index);
string assembly = r.Substring (index + 1);
AddAssemblyReference (alias, assembly, settings);
if (refs.Length != 1) {
report.Error (2034, "Cannot specify multiple aliases using single /reference option");
return ParseResult.Error;
}
} else {
settings.AssemblyReferences.Add (val);
}
}
return ParseResult.Success;
}
case "/addmodule": {
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
string[] refs = value.Split (argument_value_separator);
foreach (string r in refs) {
settings.Modules.Add (r);
}
return ParseResult.Success;
}
case "/win32res": {
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
if (settings.Win32IconFile != null)
report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
settings.Win32ResourceFile = value;
return ParseResult.Success;
}
case "/win32icon": {
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
if (settings.Win32ResourceFile != null)
report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
settings.Win32IconFile = value;
return ParseResult.Success;
}
case "/doc": {
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
//settings.Documentation = new Documentation (value);
return ParseResult.Error;
}
case "/lib": {
string[] libdirs;
if (value.Length == 0) {
return ParseResult.Error;
}
libdirs = value.Split (argument_value_separator);
foreach (string dir in libdirs)
settings.ReferencesLookupPaths.Add (dir);
return ParseResult.Success;
}
case "/debug-":
settings.GenerateDebugInfo = false;
return ParseResult.Success;
case "/debug":
if (value == "full" || value == "")
settings.GenerateDebugInfo = true;
return ParseResult.Success;
case "/debug+":
settings.GenerateDebugInfo = true;
return ParseResult.Success;
case "/checked":
case "/checked+":
settings.Checked = true;
return ParseResult.Success;
case "/checked-":
settings.Checked = false;
return ParseResult.Success;
case "/clscheck":
case "/clscheck+":
settings.VerifyClsCompliance = true;
return ParseResult.Success;
case "/clscheck-":
settings.VerifyClsCompliance = false;
return ParseResult.Success;
case "/unsafe":
case "/unsafe+":
settings.Unsafe = true;
return ParseResult.Success;
case "/unsafe-":
settings.Unsafe = false;
return ParseResult.Success;
case "/warnaserror":
case "/warnaserror+":
if (value.Length == 0) {
report.WarningsAreErrors = true;
} else {
foreach (string wid in value.Split (numeric_value_separator))
report.AddWarningAsError (wid);
}
return ParseResult.Success;
case "/warnaserror-":
if (value.Length == 0) {
report.WarningsAreErrors = false;
} else {
foreach (string wid in value.Split (numeric_value_separator))
report.RemoveWarningAsError (wid);
}
return ParseResult.Success;
case "/warn":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
SetWarningLevel (value);
return ParseResult.Success;
case "/nowarn":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
var warns = value.Split (numeric_value_separator);
foreach (string wc in warns) {
try {
if (wc.Trim ().Length == 0)
continue;
int warn = Int32.Parse (wc);
if (warn < 1) {
throw new ArgumentOutOfRangeException ("warn");
}
report.SetIgnoreWarning (warn);
} catch {
report.Error (1904, "`{0}' is not a valid warning number", wc);
return ParseResult.Error;
}
}
return ParseResult.Success;
case "/noconfig":
settings.LoadDefaultReferences = false;
return ParseResult.Success;
case "/platform":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
switch (value.ToLower (CultureInfo.InvariantCulture)) {
case "anycpu":
settings.Platform = Platform.AnyCPU;
break;
case "x86":
settings.Platform = Platform.X86;
break;
case "x64":
settings.Platform = Platform.X64;
break;
case "itanium":
settings.Platform = Platform.IA64;
break;
default:
report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'");
return ParseResult.Error;
}
return ParseResult.Success;
case "/sdk":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
settings.SdkVersion = value;
return ParseResult.Success;
// We just ignore this.
case "/errorreport":
case "/filealign":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
return ParseResult.Success;
case "/helpinternal":
OtherFlags ();
return ParseResult.Stop;
case "/help":
case "/?":
Usage ();
return ParseResult.Stop;
case "/main":
case "/m":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
settings.MainClass = value;
return ParseResult.Success;
case "/nostdlib":
case "/nostdlib+":
settings.StdLib = false;
return ParseResult.Success;
case "/nostdlib-":
settings.StdLib = true;
return ParseResult.Success;
case "/fullpaths":
report.Printer.ShowFullPaths = true;
return ParseResult.Success;
case "/keyfile":
if (value.Length == 0) {
Error_RequiresFileName (option);
return ParseResult.Error;
}
settings.StrongNameKeyFile = value;
return ParseResult.Success;
case "/keycontainer":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
settings.StrongNameKeyContainer = value;
return ParseResult.Success;
case "/delaysign+":
case "/delaysign":
settings.StrongNameDelaySign = true;
return ParseResult.Success;
case "/delaysign-":
settings.StrongNameDelaySign = false;
return ParseResult.Success;
case "/langversion":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
switch (value.ToLowerInvariant ()) {
case "iso-1":
settings.Version = LanguageVersion.ISO_1;
return ParseResult.Success;
case "default":
settings.Version = LanguageVersion.Default;
RootContext.AddConditional ("__V2__");
return ParseResult.Success;
case "iso-2":
settings.Version = LanguageVersion.ISO_2;
return ParseResult.Success;
case "3":
settings.Version = LanguageVersion.V_3;
return ParseResult.Success;
case "future":
settings.Version = LanguageVersion.Future;
return ParseResult.Success;
}
report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value);
return ParseResult.Error;
case "/codepage":
if (value.Length == 0) {
Error_RequiresArgument (option);
return ParseResult.Error;
}
switch (value) {
case "utf8":
settings.Encoding = new UTF8Encoding ();
break;
case "reset":
settings.Encoding = new UTF8Encoding ();//Encoding.Default;
break;
default:
try {
settings.Encoding = new UTF8Encoding(); //Encoding.GetEncoding(int.Parse(value));
} catch {
report.Error (2016, "Code page `{0}' is invalid or not installed", value);
}
return ParseResult.Error;
}
return ParseResult.Success;
default:
return ParseResult.UnknownOption;
}
}