mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
213 lines
No EOL
7 KiB
C#
213 lines
No EOL
7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Indy.IL2CPU;
|
|
using Indy.IL2CPU.IL.X86;
|
|
|
|
namespace IL2CPU {
|
|
public class Program {
|
|
public static string InputFile;
|
|
public static string OutputFile;
|
|
public static string AsmFile;
|
|
public static string BCLDir;
|
|
public static List<string> Plugs = new List<string>();
|
|
public static bool MetalMode;
|
|
public static string DebugFile;
|
|
public static TargetPlatformEnum TargetPlatform = TargetPlatformEnum.X86;
|
|
public const string FAsmParamsTemplate_Win32 = "\"{1}\" \"{0}\"";
|
|
|
|
private Type nativeType = typeof(X86OpCodeMap);
|
|
|
|
private static bool ParseArguments(IEnumerable<string> aArgs) {
|
|
Console.WriteLine("Initializing IL2CPU... This may take a minute so please wait for further status...");
|
|
Console.WriteLine();
|
|
foreach (string x in aArgs) {
|
|
// MtW: Slash added for powershell compatibility
|
|
if (x[0] != '-' && x[0] != '/') {
|
|
Console.WriteLine("Error parsing arguments. Arguments should start with a dash ('{0}')", x);
|
|
return false;
|
|
}
|
|
string xArg = x.Substring(1);
|
|
string[] xArgParts = new string[] { xArg, "" };
|
|
if (xArg.IndexOfAny(new char[] { '=', ':' }) > -1) {
|
|
xArgParts[0] = xArg.Substring(0, xArg.IndexOfAny(new char[] { '=', ':' }));
|
|
xArgParts[1] = xArg.Substring(xArg.IndexOfAny(new char[] { '=', ':' }) + 1);
|
|
}
|
|
switch (xArgParts[0].ToLower()) {
|
|
case "in": {
|
|
InputFile = xArgParts[1];
|
|
if (InputFile.StartsWith("\"") && InputFile.EndsWith("\"")) {
|
|
InputFile = InputFile.Substring(1, InputFile.Length - 2);
|
|
}
|
|
break;
|
|
}
|
|
case "out": {
|
|
OutputFile = xArgParts[1];
|
|
if (OutputFile.StartsWith("\"") && OutputFile.EndsWith("\"")) {
|
|
OutputFile = OutputFile.Substring(1, OutputFile.Length - 2);
|
|
}
|
|
break;
|
|
}
|
|
case "asm": {
|
|
AsmFile = xArgParts[1];
|
|
break;
|
|
}
|
|
case "plug": {
|
|
if (!File.Exists(xArgParts[1])) {
|
|
Console.WriteLine("Plug assembly '{0}' not found!", xArgParts[1]);
|
|
return false;
|
|
}
|
|
Plugs.Add(xArgParts[1]);
|
|
break;
|
|
}
|
|
case "metal": {
|
|
if (String.IsNullOrEmpty(xArgParts[1])) {
|
|
MetalMode = true;
|
|
} else {
|
|
if (!Boolean.TryParse(xArgParts[1], out MetalMode)) {
|
|
Console.WriteLine("Error parsing MetalMode argument. Invalid value. Valid values are '" + Boolean.TrueString + "' and '" + Boolean.FalseString + "', or use -metal/-metalmode, which is equal to -metal:true");
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case "platform": {
|
|
try {
|
|
TargetPlatform = (TargetPlatformEnum)Enum.Parse(typeof(TargetPlatformEnum), xArgParts[1], true);
|
|
} catch {
|
|
Console.WriteLine("Error parsing TargetPlatform argument. Invalid value '" + xArgParts[1] + "'");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case "debug": {
|
|
if (String.IsNullOrEmpty(xArgParts[1])) {
|
|
throw new Exception("When using the debug switch, you need to specify an output path!");
|
|
}
|
|
DebugFile = xArgParts[1];
|
|
break;
|
|
}
|
|
case "bcldir": {
|
|
if (String.IsNullOrEmpty(xArgParts[1])) {
|
|
throw new Exception("When using the bcldir switch, you need to specify a valid path!");
|
|
}
|
|
BCLDir = xArgParts[1];
|
|
break;
|
|
}
|
|
default: {
|
|
Console.WriteLine("Error parsing arguments. Arguments not recognized ('{0}')", xArgParts[0]);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
DebugFile = null;
|
|
if (String.IsNullOrEmpty(InputFile)) {
|
|
Console.WriteLine("Error: No InputFile specified!");
|
|
return false;
|
|
}
|
|
if (!File.Exists(InputFile)) {
|
|
Console.WriteLine("Error: InputFile '" + InputFile + "' not found!");
|
|
return false;
|
|
}
|
|
if (String.IsNullOrEmpty(AsmFile)) {
|
|
Console.WriteLine("Error: No assembler output directory specified");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static string NasmFileName {
|
|
get {
|
|
return Path.Combine(Path.Combine(ToolsDir, "nasm"), "nasm.exe");
|
|
}
|
|
}
|
|
|
|
private static string ElfLDFileName {
|
|
get {
|
|
return Path.Combine(Path.Combine(ToolsDir, "Binutils-X86"), "ld.exe");
|
|
}
|
|
}
|
|
|
|
private static string FAsmFileName {
|
|
get {
|
|
return Path.Combine(Path.Combine(ToolsDir, "fasm"), "fasm.exe");
|
|
}
|
|
}
|
|
|
|
private static string ToolsDir {
|
|
get {
|
|
return Path.Combine(Directory.GetParent(typeof(Program).Assembly.Location).Parent.Parent.Parent.Parent.FullName, "Tools");
|
|
}
|
|
}
|
|
|
|
public static int Main(string[] args) {
|
|
try {
|
|
if (ParseArguments(args)) {
|
|
Engine e = new Engine();
|
|
e.DebugLog += delegate(LogSeverityEnum aSeverity, string aMessage) {
|
|
switch (aSeverity) {
|
|
case LogSeverityEnum.Informational: {
|
|
if (String.IsNullOrEmpty(DebugFile)) {
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case LogSeverityEnum.Warning: {
|
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
|
break;
|
|
}
|
|
case LogSeverityEnum.Error: {
|
|
Console.ForegroundColor = ConsoleColor.Red;
|
|
break;
|
|
}
|
|
}
|
|
Console.WriteLine(aMessage);
|
|
Console.ResetColor();
|
|
};
|
|
string xTestOutput = Path.GetTempFileName();
|
|
Func<string, string> xGetFileNameForGroup = xGroup => Path.Combine(AsmFile, xGroup + ".asm");
|
|
e.Execute(InputFile, TargetPlatform, xGetFileNameForGroup, MetalMode, Plugs, DebugModeEnum.Source, 2, AsmFile);
|
|
ProcessStartInfo xFasmStartInfo = new ProcessStartInfo();
|
|
if (TargetPlatform != TargetPlatformEnum.X86) {
|
|
xFasmStartInfo.FileName = FAsmFileName;
|
|
xFasmStartInfo.Arguments = String.Format(FAsmParamsTemplate_Win32, xTestOutput, xGetFileNameForGroup("main"));
|
|
xFasmStartInfo.UseShellExecute = false;
|
|
xFasmStartInfo.RedirectStandardError = false;
|
|
xFasmStartInfo.RedirectStandardOutput = false;
|
|
Process xFasm = Process.Start(xFasmStartInfo);
|
|
if (!xFasm.WaitForExit(60 * 1000) || xFasm.ExitCode != 0) {
|
|
Console.WriteLine("Error while running NASM!");
|
|
Console.Write(xFasm.StandardOutput.ReadToEnd());
|
|
Console.Write(xFasm.StandardError.ReadToEnd());
|
|
return 3;
|
|
}
|
|
}
|
|
} else {
|
|
return 1;
|
|
}
|
|
} catch (ReflectionTypeLoadException E) {
|
|
Console.ForegroundColor = ConsoleColor.Red;
|
|
Console.WriteLine(E.ToString());
|
|
for (int i = 0; i < E.LoaderExceptions.Length; i++) {
|
|
Console.WriteLine("[{0}] {1}", i + 1, E.LoaderExceptions[i]);
|
|
Console.WriteLine();
|
|
}
|
|
Console.ResetColor();
|
|
return 2;
|
|
} catch (Exception E) {
|
|
Console.ForegroundColor = ConsoleColor.Red;
|
|
Console.WriteLine(E.ToString());
|
|
Console.ResetColor();
|
|
return 2;
|
|
}
|
|
Console.WriteLine("");
|
|
Console.ForegroundColor = ConsoleColor.Green;
|
|
Console.WriteLine("Completed");
|
|
Console.ResetColor();
|
|
return 0;
|
|
}
|
|
}
|
|
} |