private void ParseCompilerOptions(VsaEngine engine, StringCollection args, TextWriter output, bool generateExe){
// Process compiler options and return command line fragment to complete the partial debug command line
// that was formed by examining the CompilerParameters structure only.
string libpath = System.Environment.GetEnvironmentVariable("LIB");
bool generateWinExe = false;
Hashtable defines = new Hashtable(10);
Hashtable resources = new Hashtable(10);
Hashtable resourceFiles = new Hashtable(10);
bool targetSpecified = false;
StringBuilder fullCmdLine = null;
if (this.debugCommandLine != null)
fullCmdLine = new StringBuilder(this.debugCommandLine);
// if '/' separates dir, use '-' as switch
string cmdLineSwitch = Path.DirectorySeparatorChar == '/' ? "-" : "/" ;
for (int i = 0, n = args.Count; i < n; i++){
object argument;
string option;
string arg = args[i];
if (arg == null || arg.Length == 0) continue;
if (arg[0] == '@')
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "@<filename>", engine.ErrorCultureInfo);
// slash ('/') character is a valid filename character on UNIX, so we can't use it as a switch
if ('-' != arg[0] && ('/' != arg[0] || Path.DirectorySeparatorChar == '/'))
break;
option = arg.Substring(1);
if (option.Length > 0){
switch (option[0]){
case '?':
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/?", engine.ErrorCultureInfo);
case 'a':
case 'A':
argument = CmdLineOptionParser.IsBooleanOption(option, "autoref");
if (argument != null){
engine.SetOption("autoref", argument);
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
break;
case 'c':
case 'C':
argument = CmdLineOptionParser.IsArgumentOption(option, "codepage");
if (argument != null)
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/codepage:<id>", engine.ErrorCultureInfo);
break;
case 'd':
case 'D':
argument = CmdLineOptionParser.IsBooleanOption(option, "debug");
if (argument != null){
engine.GenerateDebugInfo = (bool)argument;
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
argument = CmdLineOptionParser.IsArgumentOption(option, "d", "define");
if (argument != null){
this.GetAllDefines((string)argument, defines, engine);
if (fullCmdLine != null){
fullCmdLine.Append(cmdLineSwitch + "d:\"");
fullCmdLine.Append((string)argument);
fullCmdLine.Append("\" ");
}
continue;
}
break;
case 'f':
case 'F':
argument = CmdLineOptionParser.IsBooleanOption(option, "fast");
if (argument != null){
engine.SetOption("fast", argument);
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
break;
case 'l':
case 'L':
argument = CmdLineOptionParser.IsArgumentOption(option, "lcid");
if (argument != null){
if (((string)argument).Length == 0)
throw new CmdLineException(CmdLineError.NoLocaleID, arg, engine.ErrorCultureInfo);
try{
engine.LCID = Int32.Parse((string)argument, CultureInfo.InvariantCulture);
}catch{
throw new CmdLineException(CmdLineError.InvalidLocaleID, (string)argument, engine.ErrorCultureInfo);
}
continue;
}
argument = CmdLineOptionParser.IsArgumentOption(option, "lib");
if (argument != null){
string newPaths = (string)argument;
if (newPaths.Length == 0)
throw new CmdLineException(CmdLineError.MissingLibArgument, engine.ErrorCultureInfo);
newPaths = newPaths.Replace(',', Path.PathSeparator);
libpath = newPaths + Path.PathSeparator + libpath;
if (fullCmdLine != null){
fullCmdLine.Append(cmdLineSwitch + "lib:\"");
fullCmdLine.Append((string)argument);
fullCmdLine.Append("\" ");
}
continue;
}
argument = CmdLineOptionParser.IsArgumentOption(option, "linkres", "linkresource");
if (argument != null){
try{
ResInfo resinfo = new ResInfo((string)argument, true /* isLinked */);
this.AddResourceFile(resinfo, resources, resourceFiles, engine);
}catch(CmdLineException){
throw;
}catch{
throw new CmdLineException(CmdLineError.ManagedResourceNotFound, engine.ErrorCultureInfo);
}
continue;
}
break;
case 'n':
case 'N':
argument = CmdLineOptionParser.IsBooleanOption(option, "nologo");
if (argument != null)
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/nologo[+|-]", engine.ErrorCultureInfo);
argument = CmdLineOptionParser.IsBooleanOption(option, "nostdlib");
if (argument != null)
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/nostdlib[+|-]", engine.ErrorCultureInfo);
break;
case 'o':
case 'O':
argument = CmdLineOptionParser.IsArgumentOption(option, "out");
if (argument != null)
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/out:<filename>", engine.ErrorCultureInfo);
break;
case 'p':
case 'P':
argument = CmdLineOptionParser.IsBooleanOption(option, "print");
if (argument != null){
engine.SetOption("print", argument);
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
argument = CmdLineOptionParser.IsArgumentOption(option, "platform");
if (argument != null){
string platform = (string)argument;
PortableExecutableKinds PEKindFlags;
ImageFileMachine PEMachineArchitecture;
if (String.Compare(platform, "x86", StringComparison.OrdinalIgnoreCase) == 0) {
PEKindFlags = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Required32Bit;
PEMachineArchitecture = ImageFileMachine.I386;
} else if (String.Compare(platform, "Itanium", StringComparison.OrdinalIgnoreCase) == 0) {
PEKindFlags = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus;
PEMachineArchitecture = ImageFileMachine.IA64;
} else if (String.Compare(platform, "x64", StringComparison.OrdinalIgnoreCase) == 0) {
PEKindFlags = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus;
PEMachineArchitecture = ImageFileMachine.AMD64;
} else if (String.Compare(platform, "anycpu", StringComparison.OrdinalIgnoreCase) == 0) {
PEKindFlags = PortableExecutableKinds.ILOnly;
PEMachineArchitecture = ImageFileMachine.I386;
} else
throw new CmdLineException(CmdLineError.InvalidPlatform, (string)argument, engine.ErrorCultureInfo);
engine.SetOption("PortableExecutableKind", PEKindFlags);
engine.SetOption("ImageFileMachine", PEMachineArchitecture);
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
break;
case 'r':
case 'R':
argument = CmdLineOptionParser.IsArgumentOption(option, "r", "reference");
if (argument != null)
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/r[eference]:<file list>", engine.ErrorCultureInfo);
argument = CmdLineOptionParser.IsArgumentOption(option, "res", "resource");
if (argument != null){
try{
ResInfo resinfo = new ResInfo((string)argument, false /* isLinked */);
this.AddResourceFile(resinfo, resources, resourceFiles, engine);
}catch(CmdLineException){
throw;
}catch{
throw new CmdLineException(CmdLineError.ManagedResourceNotFound, engine.ErrorCultureInfo);
}
continue;
}
break;
case 't':
case 'T':
argument = CmdLineOptionParser.IsArgumentOption(option, "t", "target");
if (argument != null){
if (String.Compare((string)argument, "exe", StringComparison.OrdinalIgnoreCase) == 0){
if (!generateExe)
throw new CmdLineException(CmdLineError.IncompatibleTargets, arg, engine.ErrorCultureInfo);
if (targetSpecified)
throw new CmdLineException(CmdLineError.MultipleTargets, engine.ErrorCultureInfo);
// no change -- /t:exe is the default when GenerateExecutable is true
targetSpecified = true;
continue;
}
if (String.Compare((string)argument, "winexe", StringComparison.OrdinalIgnoreCase) == 0){
if (!generateExe)
throw new CmdLineException(CmdLineError.IncompatibleTargets, arg, engine.ErrorCultureInfo);
if (targetSpecified)
throw new CmdLineException(CmdLineError.MultipleTargets, engine.ErrorCultureInfo);
engine.SetOption("PEFileKind", PEFileKinds.WindowApplication);
generateWinExe = true;
targetSpecified = true;
continue;
}
if (String.Compare((string)argument, "library", StringComparison.OrdinalIgnoreCase) == 0){
if (generateExe)
throw new CmdLineException(CmdLineError.IncompatibleTargets, engine.ErrorCultureInfo);
if (targetSpecified)
throw new CmdLineException(CmdLineError.MultipleTargets, engine.ErrorCultureInfo);
// no change -- /t:library is the default when GenerateExecutable is false
targetSpecified = true;
continue;
}
throw new CmdLineException(CmdLineError.InvalidTarget, (string)argument, engine.ErrorCultureInfo);
}
break;
case 'u':
case 'U':
argument = CmdLineOptionParser.IsArgumentOption(option, "utf8output");
if (argument != null)
throw new CmdLineException(CmdLineError.InvalidForCompilerOptions, "/utf8output[+|-]", engine.ErrorCultureInfo);
break;
case 'v':
case 'V':
argument = CmdLineOptionParser.IsBooleanOption(option, "VersionSafe");
if (argument != null){
engine.SetOption("VersionSafe", argument);
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
break;
case 'w':
case 'W':
argument = CmdLineOptionParser.IsArgumentOption(option, "w", "warn");
if (argument != null){
if (((string)argument).Length == 0){
throw new CmdLineException(CmdLineError.NoWarningLevel, arg, engine.ErrorCultureInfo);
}
if (((string)argument).Length == 1){
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
switch (((string)argument)[0]){
case '0': engine.SetOption("WarningLevel", (object)0); continue;
case '1': engine.SetOption("WarningLevel", (object)1); continue;
case '2': engine.SetOption("WarningLevel", (object)2); continue;
case '3': engine.SetOption("WarningLevel", (object)3); continue;
case '4': engine.SetOption("WarningLevel", (object)4); continue;
}
}
throw new CmdLineException(CmdLineError.InvalidWarningLevel, arg, engine.ErrorCultureInfo);
}
argument = CmdLineOptionParser.IsBooleanOption(option, "warnaserror");
if (argument != null){
engine.SetOption("warnaserror", argument);
if (fullCmdLine != null){
fullCmdLine.Append(arg);
fullCmdLine.Append(" ");
}
continue;
}
break;
default:
break;
}
}
throw new CmdLineException(CmdLineError.UnknownOption, arg, engine.ErrorCultureInfo);
}
if (fullCmdLine != null){
// append target type to debug command line
if (generateExe){
if (generateWinExe)
fullCmdLine.Append(cmdLineSwitch + "t:winexe ");
else
fullCmdLine.Append(cmdLineSwitch + "t:exe ");
}else{
fullCmdLine.Append(cmdLineSwitch + "t:library ");
}
this.debugCommandLine = fullCmdLine.ToString();
}
// set options on engine that were possibly built from multiple arguments
engine.SetOption("libpath", libpath);
engine.SetOption("defines", defines);
}