2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-02 23:17:26 +00:00

Import code from previous AssetBuilder version

This commit is contained in:
Jan
2019-09-24 10:45:09 +02:00
parent 5609557516
commit 0d8432d4f7
919 changed files with 154412 additions and 26 deletions

View File

@@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ZoneCodeGenerator.Interface.Arguments
{
class ArgumentParser
{
private readonly CommandLineOption[] options;
private readonly List<string> noOptionArgs;
private readonly Dictionary<CommandLineOption, List<string>> optionArgs;
public IReadOnlyList<string> Arguments => noOptionArgs.AsReadOnly();
public ArgumentParser(CommandLineOption[] options)
{
this.options = options;
noOptionArgs = new List<string>();
optionArgs = new Dictionary<CommandLineOption, List<string>>();
}
public bool ParseArguments(string[] args)
{
noOptionArgs.Clear();
optionArgs.Clear();
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
if (arg.StartsWith("-"))
{
CommandLineOption matchedOption;
if (arg.StartsWith("--"))
{
var longNameToFind = arg.Substring(2);
matchedOption = options.FirstOrDefault(option => longNameToFind.Equals(option.LongName));
}
else
{
var shortNameToFind = arg.Substring(1);
matchedOption = options.FirstOrDefault(option => shortNameToFind.Equals(option.ShortName));
}
if (matchedOption == null)
{
Console.WriteLine($"Unknown option '{arg}'.");
return false;
}
List<string> parameters;
if (optionArgs.ContainsKey(matchedOption))
{
if (!matchedOption.MultiUse)
{
Console.WriteLine($"Option '{arg}' already specified.");
return false;
}
parameters = optionArgs[matchedOption];
}
else
{
parameters = new List<string>();
optionArgs.Add(matchedOption, parameters);
}
if (i + matchedOption.ParameterCount >= args.Length)
{
Console.WriteLine($"Not enough parameters for option '{arg}'.");
return false;
}
for (var parameter = 0; parameter < matchedOption.ParameterCount; parameter++)
{
if (args[i + parameter + 1].StartsWith("-"))
{
Console.WriteLine($"Not enough parameters for option '{arg}'.");
return false;
}
parameters.Add(args[i + parameter + 1]);
}
i += matchedOption.ParameterCount;
}
else
{
noOptionArgs.Add(arg);
}
}
return true;
}
public bool IsOptionSpecified(CommandLineOption option)
{
return optionArgs.ContainsKey(option);
}
public string GetValueForOption(CommandLineOption option)
{
return IsOptionSpecified(option) ? string.Join(" ", optionArgs[option]) : null;
}
public IReadOnlyList<string> GetParametersForOption(CommandLineOption option)
{
return IsOptionSpecified(option) ? optionArgs[option].AsReadOnly() : null;
}
}
}

View File

@@ -0,0 +1,83 @@
using System.Collections.Generic;
namespace ZoneCodeGenerator.Interface.Arguments
{
class CommandLineOption
{
public string ShortName { get; private set; }
public string LongName { get; private set; }
public string Description { get; private set; }
public string Category { get; private set; }
public bool MultiUse { get; private set; }
private readonly List<string> parameters;
public IReadOnlyList<string> Parameters => parameters.AsReadOnly();
public int ParameterCount => parameters.Count;
private CommandLineOption()
{
ShortName = null;
LongName = null;
Description = "";
Category = "";
MultiUse = false;
parameters = new List<string>();
}
public class CommandLineOptionBuilder
{
private readonly CommandLineOption option;
private CommandLineOptionBuilder()
{
option = new CommandLineOption();
}
public static CommandLineOptionBuilder Create()
{
return new CommandLineOptionBuilder();
}
public CommandLineOptionBuilder WithShortName(string shortName)
{
option.ShortName = shortName;
return this;
}
public CommandLineOptionBuilder WithLongName(string longName)
{
option.LongName = longName;
return this;
}
public CommandLineOptionBuilder WithDescription(string description)
{
option.Description = description;
return this;
}
public CommandLineOptionBuilder WithCategory(string category)
{
option.Category = category;
return this;
}
public CommandLineOptionBuilder WithParameter(string argumentName)
{
option.parameters.Add(argumentName);
return this;
}
public CommandLineOptionBuilder Reusable()
{
option.MultiUse = true;
return this;
}
public CommandLineOption Build()
{
return option;
}
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Linq;
using System.Text;
namespace ZoneCodeGenerator.Interface.Arguments
{
static class UsageInformation
{
public static string FromCommandlineOptions(CommandLineOption[] options)
{
var usageInformation = new StringBuilder();
usageInformation.AppendLine("Usage:");
usageInformation.AppendLine();
var longestShortName = 0;
var longestLongName = 0;
var longestArgumentLength = 0;
foreach (var option in CommandLineOptions.ALL_OPTIONS)
{
if (option.ShortName != null && longestShortName < option.ShortName.Length)
longestShortName = option.ShortName.Length;
if (option.LongName != null && longestLongName < option.LongName.Length)
longestLongName = option.LongName.Length;
var argumentLength = GetOptionArgumentLength(option);
if (longestArgumentLength < argumentLength)
longestArgumentLength = argumentLength;
}
var categories = CommandLineOptions.ALL_OPTIONS
.Select(option => option.Category)
.Distinct();
var firstCategory = true;
foreach (var category in categories)
{
var optionsOfCategory = CommandLineOptions.ALL_OPTIONS
.Where(option => category.Equals(option.Category));
if(!firstCategory)
usageInformation.AppendLine();
if (!string.IsNullOrEmpty(category))
{
usageInformation.AppendLine($"== {category} ==");
}
foreach (var option in optionsOfCategory)
{
if (option.ShortName != null)
{
usageInformation.Append($"-{option.ShortName}");
usageInformation.Append(' ', longestShortName - option.ShortName.Length);
if (option.LongName != null)
usageInformation.Append(", ");
else
usageInformation.Append(' ', 2);
}
else
{
usageInformation.Append(' ', longestShortName + 1 + 2);
}
if (option.LongName != null)
{
usageInformation.Append($"--{option.LongName}");
usageInformation.Append(' ', longestLongName - option.LongName.Length);
}
else
{
usageInformation.Append(' ', longestLongName + 2);
}
usageInformation.Append(' ');
var argumentLength = GetOptionArgumentLength(option);
for(var i = 0; i < option.ParameterCount; i++)
{
if (i != 0)
usageInformation.Append(' ');
usageInformation.Append($"<{option.Parameters[i]}>");
}
usageInformation.Append(' ', longestArgumentLength - argumentLength + 1);
usageInformation.Append(option.Description);
usageInformation.AppendLine();
}
firstCategory = false;
}
return usageInformation.ToString();
}
private static int GetOptionArgumentLength(CommandLineOption option)
{
return option.ParameterCount * 2 // < and >
+ option.Parameters.Select(s => s.Length).Sum() // Length of the argument name
+ Math.Max(0, option.ParameterCount - 1); // One space between each argument
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Linq;
using ZoneCodeGenerator.Generating;
using ZoneCodeGenerator.Interface.Arguments;
using ZoneCodeGenerator.Parsing.C_Header;
using ZoneCodeGenerator.Parsing.CommandFile;
namespace ZoneCodeGenerator.Interface
{
class CUI
{
public bool Start(string[] args)
{
var argumentParser = new ArgumentParser(CommandLineOptions.ALL_OPTIONS);
if (args.Length == 0 || !argumentParser.ParseArguments(args))
{
PrintUsage();
return false;
}
if (argumentParser.IsOptionSpecified(CommandLineOptions.OPTION_HELP))
{
PrintUsage();
return true;
}
var session = new CUISession();
if (argumentParser.IsOptionSpecified(CommandLineOptions.OPTION_OUTPUT_FOLDER))
{
session.GeneratorOutputPath = argumentParser.GetValueForOption(CommandLineOptions.OPTION_OUTPUT_FOLDER);
}
if (argumentParser.IsOptionSpecified(CommandLineOptions.OPTION_CREATE))
{
session.SourceFilePath = argumentParser.GetValueForOption(CommandLineOptions.OPTION_CREATE);
session.Repository = HeaderReader.ReadFile(session.SourceFilePath);
if (session.Repository == null)
{
Console.WriteLine($"Creating a database from header file '{argumentParser.GetValueForOption(CommandLineOptions.OPTION_CREATE)}' failed.");
return false;
}
}
else
{
Console.WriteLine("Parsing a c header is needed to perform any other action.");
return false;
}
if (argumentParser.IsOptionSpecified(CommandLineOptions.OPTION_EDITING_COMMANDS))
{
if (!CommandFileReader.ReadFile(argumentParser.GetValueForOption(CommandLineOptions.OPTION_EDITING_COMMANDS), session))
{
return false;
}
}
if (argumentParser.IsOptionSpecified(CommandLineOptions.OPTION_PRINT))
{
var printer = new PrettyPrinter(session.Repository);
printer.PrintAll();
}
if (argumentParser.IsOptionSpecified(CommandLineOptions.OPTION_GENERATE))
{
var generationArgs = argumentParser.GetParametersForOption(CommandLineOptions.OPTION_GENERATE);
for (var i = 0; i < generationArgs.Count; i += CommandLineOptions.OPTION_GENERATE.ParameterCount)
{
var assetName = generationArgs[i];
var preset = generationArgs[i + 1];
var assets = session.Repository.GetAllStructureInformation()
.Where(inf => inf.IsAsset);
if (!assetName.Equals("*"))
assets = assets.Where(inf =>
inf.Type.FullName.Equals(assetName, StringComparison.CurrentCultureIgnoreCase));
if (!assets.Any())
{
Console.WriteLine($"Could not find asset '{assetName}'.");
continue;
}
foreach (var asset in assets)
{
if (CodeGenerator.GenerateCodeForPreset(preset, asset, session))
{
Console.WriteLine($"Successfully generated code for asset '{asset.Type.FullName}' with preset '{preset}'");
}
else
{
Console.WriteLine($"Could not generate code for asset '{asset.Type.FullName}' with preset '{preset}'");
}
}
}
}
return true;
}
private static void PrintUsage()
{
Console.WriteLine(UsageInformation.FromCommandlineOptions(CommandLineOptions.ALL_OPTIONS));
}
}
}

View File

@@ -0,0 +1,18 @@
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Interface
{
class CUISession
{
public string Game { get; set; }
public IDataRepository Repository { get; set; }
public string GeneratorOutputPath { get; set; }
public string SourceFilePath { get; set; }
public CUISession()
{
Repository = null;
GeneratorOutputPath = ".";
}
}
}

View File

@@ -0,0 +1,91 @@
using ZoneCodeGenerator.Generating;
using ZoneCodeGenerator.Interface.Arguments;
namespace ZoneCodeGenerator.Interface
{
static class CommandLineOptions
{
// ------
// GENERAL
// ------
public static readonly CommandLineOption OPTION_HELP = CommandLineOption.CommandLineOptionBuilder.Create()
.WithShortName("?")
.WithLongName("help")
.WithDescription("Show usage.")
.Build();
// ------
// INPUT
// ------
private const string CategoryInput = "Input";
public static readonly CommandLineOption OPTION_CREATE = CommandLineOption.CommandLineOptionBuilder.Create()
.WithShortName("h")
.WithLongName("header")
.WithDescription("Create a new database from the specified header file.")
.WithCategory(CategoryInput)
.WithParameter("headerFile")
.Build();
// ------
// EDITING
// ------
private const string CategoryEditing = "Editing";
public static readonly CommandLineOption OPTION_EDITING_COMMANDS = CommandLineOption.CommandLineOptionBuilder.Create()
.WithShortName("e")
.WithLongName("editing-commands")
.WithDescription("Specifies the editing command file. Defaults to stdin.")
.WithCategory(CategoryEditing)
.WithParameter("commandFile")
.Build();
// ------
// OUTPUT
// ------
private const string CategoryOutput = "Output";
public static readonly CommandLineOption OPTION_OUTPUT_FOLDER = CommandLineOption.CommandLineOptionBuilder.Create()
.WithShortName("o")
.WithLongName("output")
.WithDescription("Specify the folder to save the generate code files to. Defaults to the current directory.")
.WithCategory(CategoryOutput)
.WithParameter("outputPath")
.Build();
public static readonly CommandLineOption OPTION_PRINT = CommandLineOption.CommandLineOptionBuilder.Create()
.WithShortName("p")
.WithLongName("print")
.WithDescription("Print the loaded data.")
.WithCategory(CategoryOutput)
.Build();
public static readonly CommandLineOption OPTION_GENERATE = CommandLineOption.CommandLineOptionBuilder.Create()
.WithShortName("g")
.WithLongName("generate")
.WithDescription($"Generates a specified asset/preset combination. Can be used multiple times. Available presets: {string.Join(", ", CodeGenerator.Presets)}")
.WithCategory(CategoryOutput)
.WithParameter("assetName")
.WithParameter("preset")
.Reusable()
.Build();
public static readonly CommandLineOption[] ALL_OPTIONS =
{
// GENERAL
OPTION_HELP,
// INPUT
OPTION_CREATE,
// EDITING
OPTION_EDITING_COMMANDS,
// OUTPUT
OPTION_OUTPUT_FOLDER,
OPTION_PRINT,
OPTION_GENERATE,
};
}
}

View File

@@ -0,0 +1,315 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Interface
{
class PrettyPrinter
{
private readonly IDataRepository dataRepository;
public PrettyPrinter(IDataRepository dataRepository)
{
this.dataRepository = dataRepository;
}
public void PrintEnums()
{
var allEnums = dataRepository.GetAllEnums();
var dataTypeEnums = allEnums.ToList();
Console.WriteLine($"{dataTypeEnums.Count} enums:");
foreach(var _enum in dataTypeEnums)
{
Console.WriteLine($" Name: {_enum.FullName}");
Console.WriteLine($" Alignment: {_enum.Alignment}");
Console.WriteLine($" Size: {_enum.Size}");
foreach(var member in _enum.Members)
{
Console.WriteLine($" {member.Name} = {member.Value}");
}
Console.WriteLine();
}
}
private static void PrintVariablePointerToArray(Variable variable)
{
var arraySize = new List<int>();
var pointerDepth = 0;
var referenceOffset = 0;
for (; referenceOffset < variable.VariableType.References.Count; referenceOffset++)
{
if (!(variable.VariableType.References[referenceOffset] is ReferenceTypePointer))
break;
pointerDepth++;
}
for (; referenceOffset < variable.VariableType.References.Count; referenceOffset++)
{
if (!(variable.VariableType.References[referenceOffset] is ReferenceTypeArray array))
throw new Exception("Expected the rest of the references to be array references");
arraySize.Add(array.ArraySize);
}
var memberBuilder = new StringBuilder();
memberBuilder.Append(" ");
memberBuilder.Append(variable.VariableType.Type.FullName);
memberBuilder.Append('(');
memberBuilder.Append('*', pointerDepth);
memberBuilder.Append(variable.Name);
memberBuilder.Append(')');
foreach (var array in arraySize)
{
memberBuilder.Append('[');
memberBuilder.Append(array);
memberBuilder.Append(']');
}
Console.WriteLine(memberBuilder.ToString());
}
private static void PrintVariableArrayOfPointers(Variable variable)
{
var arraySize = new List<int>();
var pointerDepth = 0;
var referenceOffset = 0;
for (; referenceOffset < variable.VariableType.References.Count; referenceOffset++)
{
if (!(variable.VariableType.References[referenceOffset] is ReferenceTypeArray array))
break;
arraySize.Add(array.ArraySize);
}
for (; referenceOffset < variable.VariableType.References.Count; referenceOffset++)
{
if (!(variable.VariableType.References[referenceOffset] is ReferenceTypePointer))
throw new Exception("Expected the rest of the references to be pointer references");
pointerDepth++;
}
var memberBuilder = new StringBuilder();
memberBuilder.Append(" ");
memberBuilder.Append(variable.VariableType.Type.FullName);
memberBuilder.Append('*', pointerDepth);
memberBuilder.Append(" ");
memberBuilder.Append(variable.Name);
foreach (var array in arraySize)
{
memberBuilder.Append('[');
memberBuilder.Append(array);
memberBuilder.Append(']');
}
Console.WriteLine(memberBuilder.ToString());
}
private static void PrintVariable(Variable variable)
{
if (variable.VariableType.References.Count == 0)
{
Console.WriteLine($" {variable.VariableType.Type.FullName} {variable.Name}");
}
else
{
if (variable.VariableType.References[0] is ReferenceTypePointer &&
variable.VariableType.References.OfType<ReferenceTypeArray>().Any())
{
PrintVariablePointerToArray(variable);
}
else
{
PrintVariableArrayOfPointers(variable);
}
}
}
public void PrintStructs()
{
var allStructs = dataRepository.GetAllStructs();
var dataTypeStructs = allStructs.ToList();
Console.WriteLine($"{dataTypeStructs.Count} structs:");
foreach(var _struct in dataTypeStructs)
{
Console.WriteLine($" Name: {_struct.FullName}");
Console.WriteLine($" Alignment: {_struct.Alignment}");
Console.WriteLine($" Size: {_struct.Size}");
foreach(var member in _struct.Members)
PrintVariable(member);
Console.WriteLine();
}
}
public void PrintUnions()
{
var allUnions = dataRepository.GetAllUnions();
var dataTypeUnions = allUnions.ToList();
Console.WriteLine($"{dataTypeUnions.Count} unions:");
foreach(var union in dataTypeUnions)
{
Console.WriteLine($" Name: {union.FullName}");
Console.WriteLine($" Alignment: {union.Alignment}");
Console.WriteLine($" Size: {union.Size}");
foreach(var member in union.Members)
PrintVariable(member);
Console.WriteLine();
}
}
private static void PrintTypedefPointerToArray(DataTypeTypedef typedef)
{
var arraySize = new List<int>();
var pointerDepth = 0;
var referenceOffset = 0;
for (; referenceOffset < typedef.TypeDefinition.References.Count; referenceOffset++)
{
if (!(typedef.TypeDefinition.References[referenceOffset] is ReferenceTypePointer))
break;
pointerDepth++;
}
for (; referenceOffset < typedef.TypeDefinition.References.Count; referenceOffset++)
{
if (!(typedef.TypeDefinition.References[referenceOffset] is ReferenceTypeArray array))
throw new Exception("Expected the rest of the references to be array references");
arraySize.Add(array.ArraySize);
}
var memberBuilder = new StringBuilder();
memberBuilder.Append(" ");
memberBuilder.Append(typedef.TypeDefinition.Type.FullName);
memberBuilder.Append('(');
memberBuilder.Append('*', pointerDepth);
memberBuilder.Append(')');
foreach (var array in arraySize)
{
memberBuilder.Append('[');
memberBuilder.Append(array);
memberBuilder.Append(']');
}
Console.WriteLine(memberBuilder.ToString());
}
private static void PrintTypedefArrayOfPointers(DataTypeTypedef typedef)
{
var arraySize = new List<int>();
var pointerDepth = 0;
var referenceOffset = 0;
for (; referenceOffset < typedef.TypeDefinition.References.Count; referenceOffset++)
{
if (!(typedef.TypeDefinition.References[referenceOffset] is ReferenceTypeArray array))
break;
arraySize.Add(array.ArraySize);
}
for (; referenceOffset < typedef.TypeDefinition.References.Count; referenceOffset++)
{
if (!(typedef.TypeDefinition.References[referenceOffset] is ReferenceTypePointer))
throw new Exception("Expected the rest of the references to be pointer references");
pointerDepth++;
}
var memberBuilder = new StringBuilder();
memberBuilder.Append(" ");
memberBuilder.Append(typedef.TypeDefinition.Type.FullName);
memberBuilder.Append('*', pointerDepth);
foreach (var array in arraySize)
{
memberBuilder.Append('[');
memberBuilder.Append(array);
memberBuilder.Append(']');
}
Console.WriteLine(memberBuilder.ToString());
}
public void PrintTypedefs()
{
var allTypedefs = dataRepository.GetAllTypedefs();
var dataTypeTypedefs = allTypedefs.ToList();
Console.WriteLine($"{dataTypeTypedefs.Count} typedefs:");
foreach (var typeDef in dataTypeTypedefs)
{
Console.WriteLine($" Name: {typeDef.FullName}");
Console.WriteLine($" Alignment: {typeDef.Alignment}");
Console.WriteLine($" Size: {typeDef.Size}");
if (typeDef.TypeDefinition.References.Count == 0)
{
Console.WriteLine($" {typeDef.TypeDefinition.Type.FullName}");
}
else
{
if (typeDef.TypeDefinition.References[0] is ReferenceTypePointer &&
typeDef.TypeDefinition.References.OfType<ReferenceTypeArray>().Any())
{
PrintTypedefPointerToArray(typeDef);
}
else
{
PrintTypedefArrayOfPointers(typeDef);
}
}
Console.WriteLine();
}
}
public void PrintAll()
{
PrintEnums();
Console.WriteLine();
Console.WriteLine("==========================================================================================================");
Console.WriteLine();
PrintStructs();
Console.WriteLine();
Console.WriteLine("==========================================================================================================");
Console.WriteLine();
PrintUnions();
Console.WriteLine();
Console.WriteLine("==========================================================================================================");
Console.WriteLine();
PrintTypedefs();
}
}
}