X Tutup
using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using IKVM.Reflection; using IKVM.Reflection.Emit; using System.Resources; using System.Reflection; using Microsoft.Scripting.Runtime; namespace IronPythonCompiler { public class Config { public Config() { Embed = false; Files = new List(); Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly; Machine = IKVM.Reflection.ImageFileMachine.AMD64; Standalone = false; Target = PEFileKinds.Dll; UseMta = false; MainName = Main = string.Empty; Output = string.Empty; OutputPath = string.Empty; Win32Icon = string.Empty; FileVersion = string.Empty; ProductName = string.Empty; Copyright = string.Empty; ProductVersion = string.Empty; ErrorMessageFormat = "Error occurred: {0}"; PythonOptions = new Dictionary(); DLLs = new List(); } public string ErrorMessageFormat { get; private set; } public string FileVersion { get; private set; } public string Win32Icon { get; private set; } public string ProductName { get; private set; } public string Copyright { get; private set; } public string ProductVersion { get; private set; } public string Output { get; private set; } public string OutputPath { get; private set; } public string Main { get; private set; } public string MainName { get; private set; } public PEFileKinds Target { get; private set; } public bool UseMta { get; private set; } public bool Standalone { get; private set; } public List Files { get; private set; } public List DLLs { get; private set; } public IDictionary PythonOptions { get; private set; } public bool Embed { get; internal set; } public IKVM.Reflection.ImageFileMachine Machine { get; private set; } public IKVM.Reflection.PortableExecutableKinds Platform { get; private set; } public void ParseArgs(IEnumerable args, List respFiles = null) { var helpStrings = new string[] { "/?", "-?", "/h", "-h" }; foreach (var a in args) { var arg = a.Trim(); if (arg.StartsWith("#")) { continue; } if (arg.StartsWith("/main:")) { MainName = Main = arg.Substring(6).Trim('"'); // only override the target kind if its currently a DLL if (Target == PEFileKinds.Dll) { Target = PEFileKinds.ConsoleApplication; } } else if (arg.StartsWith("/out:")) { Output = arg.Substring(5).Trim('"'); } else if (arg.StartsWith("/target:")) { string tgt = arg.Substring(8).Trim('"'); switch (tgt) { case "exe": Target = PEFileKinds.ConsoleApplication; break; case "winexe": Target = PEFileKinds.WindowApplication; break; default: Target = PEFileKinds.Dll; break; } } else if (arg.StartsWith("/platform:")) { string plat = arg.Substring(10).Trim('"'); switch (plat) { case "x86": Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.Required32Bit; Machine = IKVM.Reflection.ImageFileMachine.I386; break; case "x64": Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly | IKVM.Reflection.PortableExecutableKinds.PE32Plus; Machine = IKVM.Reflection.ImageFileMachine.AMD64; break; default: Platform = IKVM.Reflection.PortableExecutableKinds.ILOnly; Machine = IKVM.Reflection.ImageFileMachine.AMD64; break; } } else if (arg.StartsWith("/win32icon:")) { Win32Icon = arg.Substring(11).Trim('"'); } else if (arg.StartsWith("/fileversion:")) { FileVersion = arg.Substring(13).Trim('"'); } else if (arg.StartsWith("/productversion:")) { ProductVersion = arg.Substring(16).Trim('"'); } else if (arg.StartsWith("/productname:")) { ProductName = arg.Substring(13).Trim('"'); } else if (arg.StartsWith("/copyright:")) { Copyright = arg.Substring(11).Trim('"'); } else if (arg.StartsWith("/errfmt:")) { ErrorMessageFormat = arg.Substring(8); } else if (arg.StartsWith("/embed")) { Embed = true; } else if (arg.StartsWith("/standalone")) { Standalone = true; } else if (arg.StartsWith("/mta")) { UseMta = true; } else if (arg.StartsWith("/recurse:")) { string pattern = arg.Substring(9); if (string.IsNullOrWhiteSpace(pattern)) { ConsoleOps.Error(true, "Missing pattern for /recurse option"); } foreach (var f in Directory.EnumerateFiles(Environment.CurrentDirectory, pattern)) { Files.Add(Path.GetFullPath(f)); } } else if (Array.IndexOf(helpStrings, arg) >= 0) { ConsoleOps.Usage(true); } else if (arg.StartsWith("/py:")) { // if you add a parameter that takes a different type then // ScriptingRuntimeHelpers.True/False or int // you need ot also modify Program.cs for standalone generation. string[] pyargs = arg.Substring(4).Trim('"').Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (pyargs[0]) { case "-X:Frames": PythonOptions["Frames"] = ScriptingRuntimeHelpers.True; break; case "-X:FullFrames": PythonOptions["Frames"] = PythonOptions["FullFrames"] = ScriptingRuntimeHelpers.True; break; case "-X:Tracing": PythonOptions["Tracing"] = ScriptingRuntimeHelpers.True; break; case "-X:GCStress": int gcStress; if (!int.TryParse(pyargs[1], out gcStress) || (gcStress < 0 || gcStress > GC.MaxGeneration)) { ConsoleOps.Error(true, $"The argument for the {pyargs[1]} option must be between 0 and {GC.MaxGeneration}."); } PythonOptions["GCStress"] = gcStress; break; case "-X:MaxRecursion": // we need about 6 frames for starting up, so 10 is a nice round number. int limit; if (!int.TryParse(pyargs[1], out limit) || limit < 10) { ConsoleOps.Error(true, $"The argument for the {pyargs[1]} option must be an integer >= 10."); } PythonOptions["RecursionLimit"] = limit; break; case "-X:EnableProfiler": PythonOptions["EnableProfiler"] = ScriptingRuntimeHelpers.True; break; case "-X:LightweightScopes": PythonOptions["LightweightScopes"] = ScriptingRuntimeHelpers.True; break; case "-X:Debug": PythonOptions["Debug"] = ScriptingRuntimeHelpers.True; break; } } else { if (arg.StartsWith("@")) { var respFile = Path.GetFullPath(arg.Substring(1)); if (respFiles == null) { respFiles = new List(); } if (!respFiles.Contains(respFile)) { respFiles.Add(respFile); ParseArgs(File.ReadAllLines(respFile), respFiles); } else { ConsoleOps.Warning($"Already parsed response file '{arg.Substring(1)}'"); } } else { if (arg.ToLower().EndsWith(".dll")) { DLLs.Add(arg); } else { Files.Add(arg); } } } } } public bool Validate() { if (Files.Count == 1 && string.IsNullOrWhiteSpace(MainName)) { MainName = Files[0]; } if (Files.Count == 0 && !string.IsNullOrWhiteSpace(MainName)) { Files.Add(MainName); } if (Files == null || Files.Count == 0 || string.IsNullOrEmpty(MainName)) { ConsoleOps.Error("No files or main defined"); return false; } if (Target != PEFileKinds.Dll && string.IsNullOrEmpty(MainName)) { ConsoleOps.Error("EXEs require /main: to be specified"); return false; } if (DLLs.Count > 0 && !Standalone) { ConsoleOps.Error("DLLs can only be used in standalone mode"); return false; } if (string.IsNullOrWhiteSpace(Output) && !string.IsNullOrWhiteSpace(MainName)) { Output = Path.GetFileNameWithoutExtension(MainName); OutputPath = Path.GetDirectoryName(MainName); } else if (string.IsNullOrWhiteSpace(Output) && Files != null && Files.Count > 0) { Output = Path.GetFileNameWithoutExtension(Files[0]); OutputPath = Path.GetDirectoryName(Files[0]); } if (!string.IsNullOrWhiteSpace(Win32Icon) && Target == PEFileKinds.Dll) { ConsoleOps.Error("DLLs may not have a win32icon"); return false; } else if (!string.IsNullOrWhiteSpace(Win32Icon) && !File.Exists(Win32Icon)) { ConsoleOps.Error($"win32icon '{Win32Icon}' does not exist"); return false; } return true; } public override string ToString() { StringBuilder res = new StringBuilder("Input Files:\n"); foreach (var file in Files) { res.AppendLine($"\t{file}"); } res.AppendLine($"Output:\n\t{Output}"); res.AppendLine($"OutputPath:\n\t{OutputPath}"); res.AppendLine($"Target:\n\t{Target}"); res.AppendLine($"Platform:\n\t{Machine}"); if (Target == PEFileKinds.WindowApplication) { res.AppendLine("Threading:"); if (UseMta) { res.AppendLine("\tMTA"); } else { res.AppendLine("\tSTA"); } } if (PythonOptions.Count > 0) { res.AppendLine("\nIronPython Context Options:"); foreach (var option in PythonOptions) { res.AppendLine($"\t{option.Key} = {option.Value}"); } } return res.ToString(); } } }
X Tutup