示例#1
0
    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);
    }