int ContinueParseCommandLine(IEnumerator <string> arglist, List <CompilerOptions> targets, CompilerOptions options) { while (arglist.MoveNext()) { string s = arglist.Current; if (s == "{") { nonleaf = true; IkvmcCompiler nestedLevel = new IkvmcCompiler(); nestedLevel.manifestMainClass = manifestMainClass; nestedLevel.classes = new Dictionary <string, byte[]>(classes); nestedLevel.resources = new Dictionary <string, byte[]>(resources); nestedLevel.defaultAssemblyName = defaultAssemblyName; nestedLevel.classesToExclude = new List <string>(classesToExclude); int rc = nestedLevel.ContinueParseCommandLine(arglist, targets, options.Copy()); if (rc != 0) { return(rc); } } else if (s == "}") { break; } else if (nonleaf) { Console.Error.WriteLine("Error: you can only specify options before any child levels"); return(1); } else if (s[0] == '-') { if (s.StartsWith("-out:")) { options.path = s.Substring(5); } else if (s.StartsWith("-Xtrace:")) { Tracer.SetTraceLevel(s.Substring(8)); } else if (s.StartsWith("-Xmethodtrace:")) { Tracer.HandleMethodTrace(s.Substring(14)); } else if (s.StartsWith("-assembly:")) { options.assembly = s.Substring(10); } else if (s.StartsWith("-target:")) { switch (s) { case "-target:exe": options.target = PEFileKinds.ConsoleApplication; options.guessFileKind = false; break; case "-target:winexe": options.target = PEFileKinds.WindowApplication; options.guessFileKind = false; break; case "-target:module": options.targetIsModule = true; options.target = PEFileKinds.Dll; options.guessFileKind = false; break; case "-target:library": options.target = PEFileKinds.Dll; options.guessFileKind = false; break; default: Console.Error.WriteLine("Warning: unrecognized option: {0}", s); break; } } else if (s.StartsWith("-platform:")) { switch (s) { case "-platform:x86": options.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Required32Bit; options.imageFileMachine = ImageFileMachine.I386; break; case "-platform:Itanium": options.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus; options.imageFileMachine = ImageFileMachine.IA64; break; case "-platform:x64": options.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus; options.imageFileMachine = ImageFileMachine.AMD64; break; case "-platform:anycpu": options.pekind = PortableExecutableKinds.ILOnly; options.imageFileMachine = ImageFileMachine.I386; break; default: Console.Error.WriteLine("Warning: unrecognized option: {0}", s); break; } } else if (s.StartsWith("-apartment:")) { switch (s) { case "-apartment:sta": options.apartment = ApartmentState.STA; break; case "-apartment:mta": options.apartment = ApartmentState.MTA; break; case "-apartment:none": options.apartment = ApartmentState.Unknown; break; default: Console.Error.WriteLine("Warning: unrecognized option: {0}", s); break; } } else if (s == "-noglobbing") { options.noglobbing = true; } else if (s.StartsWith("-D")) { string[] keyvalue = s.Substring(2).Split('='); if (keyvalue.Length != 2) { keyvalue = new string[] { keyvalue[0], "" }; } options.props[keyvalue[0]] = keyvalue[1]; } else if (s == "-ea" || s == "-enableassertions") { options.props["ikvm.assert.default"] = "true"; } else if (s == "-da" || s == "-disableassertions") { options.props["ikvm.assert.default"] = "false"; } else if (s.StartsWith("-ea:") || s.StartsWith("-enableassertions:")) { options.props["ikvm.assert.enable"] = s.Substring(s.IndexOf(':') + 1); } else if (s.StartsWith("-da:") || s.StartsWith("-disableassertions:")) { options.props["ikvm.assert.disable"] = s.Substring(s.IndexOf(':') + 1); } else if (s == "-removeassertions") { options.codegenoptions |= CodeGenOptions.RemoveAsserts; } else if (s.StartsWith("-main:")) { options.mainClass = s.Substring(6); } else if (s.StartsWith("-reference:") || s.StartsWith("-r:")) { string r = s.Substring(s.IndexOf(':') + 1); if (r == "") { Console.Error.WriteLine("Error: missing file specification for '{0}' option", s); return(1); } ArrayAppend(ref options.unresolvedReferences, r); } else if (s.StartsWith("-recurse:")) { string spec = s.Substring(9); bool exists = false; // MONOBUG On Mono 1.0.2, Directory.Exists throws an exception if we pass an invalid directory name try { exists = Directory.Exists(spec); } catch (IOException) { } if (exists) { DirectoryInfo dir = new DirectoryInfo(spec); Recurse(dir, dir, "*"); } else { try { DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(spec)); if (dir.Exists) { Recurse(dir, dir, Path.GetFileName(spec)); } else { RecurseJar(spec); } } catch (PathTooLongException) { Console.Error.WriteLine("Error: path too long: {0}", spec); return(1); } catch (DirectoryNotFoundException) { Console.Error.WriteLine("Error: path not found: {0}", spec); return(1); } catch (ArgumentException) { Console.Error.WriteLine("Error: invalid path: {0}", spec); return(1); } } } else if (s.StartsWith("-resource:")) { string[] spec = s.Substring(10).Split('='); try { using (FileStream fs = new FileStream(spec[1], FileMode.Open, FileAccess.Read)) { byte[] b = new byte[fs.Length]; fs.Read(b, 0, b.Length); string name = spec[0]; if (name.StartsWith("/")) { // a leading slash is not required, so strip it name = name.Substring(1); } AddResource(name, b); } } catch (Exception x) { Console.Error.WriteLine("Error: {0}: {1}", x.Message, spec[1]); return(1); } } else if (s.StartsWith("-externalresource:")) { string[] spec = s.Substring(18).Split('='); if (!File.Exists(spec[1])) { Console.Error.WriteLine("Error: external resource file does not exist: {0}", spec[1]); return(1); } if (Path.GetFileName(spec[1]) != spec[1]) { Console.Error.WriteLine("Error: external resource file may not include path specification: {0}", spec[1]); return(1); } if (options.externalResources == null) { options.externalResources = new Dictionary <string, string>(); } // TODO resource name clashes should be tested options.externalResources.Add(spec[0], spec[1]); } else if (s == "-nojni") { options.codegenoptions |= CodeGenOptions.NoJNI; } else if (s.StartsWith("-exclude:")) { ProcessExclusionFile(classesToExclude, s.Substring(9)); } else if (s.StartsWith("-version:")) { string str = s.Substring(9); if (!TryParseVersion(s.Substring(9), out options.version)) { Console.Error.WriteLine("Error: Invalid version specified: {0}", str); return(1); } } else if (s.StartsWith("-fileversion:")) { options.fileversion = s.Substring(13); } else if (s.StartsWith("-keyfile:")) { options.keyfile = s.Substring(9); } else if (s.StartsWith("-key:")) { options.keycontainer = s.Substring(5); } else if (s == "-delaysign") { options.delaysign = true; } else if (s == "-debug") { options.codegenoptions |= CodeGenOptions.Debug; } else if (s.StartsWith("-srcpath:")) { options.sourcepath = s.Substring(9); } else if (s.StartsWith("-remap:")) { options.remapfile = s.Substring(7); } else if (s == "-nostacktraceinfo") { options.codegenoptions |= CodeGenOptions.NoStackTraceInfo; } else if (s == "-opt:fields") { options.removeUnusedFields = true; } else if (s == "-compressresources") { options.compressedResources = true; } else if (s == "-strictfinalfieldsemantics") { options.codegenoptions |= CodeGenOptions.StrictFinalFieldSemantics; } else if (s.StartsWith("-privatepackage:")) { string prefix = s.Substring(16); ArrayAppend(ref options.privatePackages, prefix); } else if (s.StartsWith("-publicpackage:")) { string prefix = s.Substring(15); ArrayAppend(ref options.publicPackages, prefix); } else if (s.StartsWith("-nowarn:")) { foreach (string w in s.Substring(8).Split(',')) { string ws = w; // lame way to chop off the leading zeroes while (ws.StartsWith("0")) { ws = ws.Substring(1); } StaticCompiler.SuppressWarning(ws); } } else if (s.StartsWith("-warnaserror:")) { foreach (string w in s.Substring(13).Split(',')) { string ws = w; // lame way to chop off the leading zeroes while (ws.StartsWith("0")) { ws = ws.Substring(1); } StaticCompiler.WarnAsError(ws); } } else if (s.StartsWith("-runtime:")) { // NOTE this is an undocumented option runtimeAssembly = s.Substring(9); } else if (s == "-time") { time = true; } else if (s.StartsWith("-classloader:")) { options.classLoader = s.Substring(13); } else if (s == "-sharedclassloader") { if (options.sharedclassloader == null) { options.sharedclassloader = new List <CompilerClassLoader>(); } } else if (s.StartsWith("-baseaddress:")) { string baseAddress = s.Substring(13); ulong baseAddressParsed; if (baseAddress.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { baseAddressParsed = UInt64.Parse(baseAddress.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier); } else { // note that unlike CSC we don't support octal baseAddressParsed = UInt64.Parse(baseAddress); } options.baseAddress = (long)(baseAddressParsed & 0xFFFFFFFFFFFF0000UL); } else if (s == "-nopeercrossreference") { options.crossReferenceAllPeers = false; } else if (s == "-nostdlib") { // this is a global option nostdlib = true; } else if (s.StartsWith("-lib:")) { // this is a global option libpaths.Add(s.Substring(5)); } else if (s == "-noautoserialization") { options.codegenoptions |= CodeGenOptions.NoAutomagicSerialization; } else { Console.Error.WriteLine("Warning: unrecognized option: {0}", s); } } else { if (defaultAssemblyName == null) { try { defaultAssemblyName = new FileInfo(Path.GetFileName(s)).Name; } catch (ArgumentException) { // if the filename contains a wildcard (or any other invalid character), we ignore // it as a potential default assembly name } } string[] files; try { string path = Path.GetDirectoryName(s); files = Directory.GetFiles(path == "" ? "." : path, Path.GetFileName(s)); } catch (Exception) { Console.Error.WriteLine("Error: invalid filename: {0}", s); return(1); } if (files.Length == 0) { Console.Error.WriteLine("Error: file not found: {0}", s); return(1); } foreach (string f in files) { ProcessFile(null, f); } } if (options.targetIsModule && options.sharedclassloader != null) { Console.Error.WriteLine("Error: -target:module and -sharedclassloader options cannot be combined."); return(1); } } if (nonleaf) { return(0); } if (options.assembly == null) { string basename = options.path == null ? defaultAssemblyName : new FileInfo(options.path).Name; if (basename == null) { Console.Error.WriteLine("Error: no output file specified"); return(1); } int idx = basename.LastIndexOf('.'); if (idx > 0) { options.assembly = basename.Substring(0, idx); } else { options.assembly = basename; } } if (options.path != null && options.guessFileKind) { if (options.path.ToLower().EndsWith(".dll")) { options.target = PEFileKinds.Dll; } options.guessFileKind = false; } if (options.mainClass == null && manifestMainClass != null && (options.guessFileKind || options.target != PEFileKinds.Dll)) { StaticCompiler.IssueMessage(Message.MainMethodFromManifest, manifestMainClass); options.mainClass = manifestMainClass; } options.classes = classes; options.resources = resources; options.classesToExclude = classesToExclude.ToArray(); targets.Add(options); return(0); }