From 9aabd988a8742920c19239e17e028b2fed5bff02 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sat, 20 Oct 2018 21:24:28 -0700 Subject: [PATCH] Progress toward new assembler configuration Use configured column widths when generating output. The regression test always uses the assembler-preferred default widths. --- SourceGen/AsmGen/AsmCc65.cs | 41 ++++++++++++++++++++++----------- SourceGen/AsmGen/AsmMerlin32.cs | 40 +++++++++++++++++++++----------- SourceGen/AsmGen/IAssembler.cs | 3 ++- SourceGen/Tests/GenTest.cs | 19 +++++++++++---- 4 files changed, 70 insertions(+), 33 deletions(-) diff --git a/SourceGen/AsmGen/AsmCc65.cs b/SourceGen/AsmGen/AsmCc65.cs index ce72463..f8c89ef 100644 --- a/SourceGen/AsmGen/AsmCc65.cs +++ b/SourceGen/AsmGen/AsmCc65.cs @@ -58,6 +58,11 @@ namespace SourceGen.AsmGen { /// private bool mLongLabelNewLine; + /// + /// Output column widths. + /// + private int[] mColumnWidths; + /// /// Base filename. Typically the project file name without the ".dis65" extension. /// @@ -145,6 +150,10 @@ namespace SourceGen.AsmGen { Settings = settings; mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); + + AssemblerConfig config = AssemblerConfig.GetConfig(settings, + AssemblerInfo.Id.Cc65); + mColumnWidths = (int[])config.ColumnWidths.Clone(); } // IGenerator @@ -460,16 +469,17 @@ namespace SourceGen.AsmGen { StringComparison.InvariantCultureIgnoreCase)) { label += ':'; - if (mLongLabelNewLine && label.Length >= 9) { + if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) { mOutStream.WriteLine(label); label = string.Empty; } } mLineBuilder.Clear(); - TextUtil.AppendPaddedString(mLineBuilder, label, 9); - TextUtil.AppendPaddedString(mLineBuilder, opcode, 9 + 8); - TextUtil.AppendPaddedString(mLineBuilder, operand, 9 + 8 + 11); + TextUtil.AppendPaddedString(mLineBuilder, label, mColumnWidths[0]); + TextUtil.AppendPaddedString(mLineBuilder, opcode, mColumnWidths[0] + mColumnWidths[1]); + TextUtil.AppendPaddedString(mLineBuilder, operand, + mColumnWidths[0] + mColumnWidths[1] + mColumnWidths[2]); if (string.IsNullOrEmpty(comment)) { // Trim trailing spaces off of opcode or operand. If they want trailing // spaces at the end of a comment, that's fine. @@ -657,9 +667,12 @@ namespace SourceGen.AsmGen { /// Cross-assembler execution interface. /// public class AsmCc65 : IAssembler { - private List PathNames { get; set; } + // Paths from generator. + private List mPathNames; + + // Directory to make current before executing assembler. + private string mWorkDirectory; - private string WorkDirectory { get; set; } // IAssembler public void GetExeIdentifiers(out string humanName, out string exeName) { @@ -712,21 +725,21 @@ namespace SourceGen.AsmGen { // IAssembler public void Configure(List pathNames, string workDirectory) { // Clone pathNames, in case the caller decides to modify the original. - PathNames = new List(pathNames.Count); + mPathNames = new List(pathNames.Count); foreach (string str in pathNames) { - PathNames.Add(str); + mPathNames.Add(str); } - WorkDirectory = workDirectory; + mWorkDirectory = workDirectory; } // IAssembler public AssemblerResults RunAssembler(BackgroundWorker worker) { // Reduce input file to a partial path if possible. This is really just to make // what we display to the user a little easier to read. - string pathName = PathNames[0]; - if (pathName.StartsWith(WorkDirectory)) { - pathName = pathName.Remove(0, WorkDirectory.Length + 1); + string pathName = mPathNames[0]; + if (pathName.StartsWith(mWorkDirectory)) { + pathName = pathName.Remove(0, mWorkDirectory.Length + 1); } else { // Unexpected, but shouldn't be a problem. Debug.WriteLine("NOTE: source file is not in work directory"); @@ -742,14 +755,14 @@ namespace SourceGen.AsmGen { // Wrap pathname in quotes in case it has spaces. // (Do we need to shell-escape quotes in the pathName?) ShellCommand cmd = new ShellCommand(config.ExecutablePath, - "--target none \"" + pathName + "\"", WorkDirectory, null); + "--target none \"" + pathName + "\"", mWorkDirectory, null); cmd.Execute(); // Can't really do anything with a "cancel" request. // Output filename is the input filename without the ".S". Since the filename // was generated by us we can be confident in the format. - string outputFile = PathNames[0].Substring(0, PathNames[0].Length - 2); + string outputFile = mPathNames[0].Substring(0, mPathNames[0].Length - 2); return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout, cmd.Stderr, outputFile); diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs index 8da9e7e..ef12ba7 100644 --- a/SourceGen/AsmGen/AsmMerlin32.cs +++ b/SourceGen/AsmGen/AsmMerlin32.cs @@ -59,6 +59,11 @@ namespace SourceGen.AsmGen { /// private bool mLongLabelNewLine; + /// + /// Output column widths. + /// + private int[] mColumnWidths; + /// /// Base filename. Typically the project file name without the ".dis65" extension. /// @@ -134,6 +139,10 @@ namespace SourceGen.AsmGen { Settings = settings; mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); + + AssemblerConfig config = AssemblerConfig.GetConfig(settings, + AssemblerInfo.Id.Merlin32); + mColumnWidths = (int[])config.ColumnWidths.Clone(); } // IGenerator; executes on background thread @@ -343,7 +352,7 @@ namespace SourceGen.AsmGen { // IGenerator public void OutputLine(string label, string opcode, string operand, string comment) { // Split long label, but not on EQU directives (confuses the assembler). - if (mLongLabelNewLine && label.Length >= 9 && + if (mLongLabelNewLine && label.Length >= mColumnWidths[0] && !String.Equals(opcode, sDataOpNames.EquDirective, StringComparison.InvariantCultureIgnoreCase)) { mOutStream.WriteLine(label); @@ -351,9 +360,10 @@ namespace SourceGen.AsmGen { } mLineBuilder.Clear(); - TextUtil.AppendPaddedString(mLineBuilder, label, 9); - TextUtil.AppendPaddedString(mLineBuilder, opcode, 9 + 6); - TextUtil.AppendPaddedString(mLineBuilder, operand, 9 + 6 + 11); + TextUtil.AppendPaddedString(mLineBuilder, label, mColumnWidths[0]); + TextUtil.AppendPaddedString(mLineBuilder, opcode, mColumnWidths[0] + mColumnWidths[1]); + TextUtil.AppendPaddedString(mLineBuilder, operand, + mColumnWidths[0] + mColumnWidths[1] + mColumnWidths[2]); if (string.IsNullOrEmpty(comment)) { // Trim trailing spaces off of opcode or operand. If they want trailing // spaces at the end of a comment, that's fine. @@ -604,9 +614,11 @@ namespace SourceGen.AsmGen { /// Cross-assembler execution interface. /// public class AsmMerlin32 : IAssembler { - private List PathNames { get; set; } + // Paths from generator. + private List mPathNames; - private string WorkDirectory { get; set; } + // Directory to make current before executing assembler. + private string mWorkDirectory; // IAssembler @@ -659,21 +671,21 @@ namespace SourceGen.AsmGen { // IAssembler public void Configure(List pathNames, string workDirectory) { // Clone pathNames, in case the caller decides to modify the original. - PathNames = new List(pathNames.Count); + mPathNames = new List(pathNames.Count); foreach (string str in pathNames) { - PathNames.Add(str); + mPathNames.Add(str); } - WorkDirectory = workDirectory; + mWorkDirectory = workDirectory; } // IAssembler public AssemblerResults RunAssembler(BackgroundWorker worker) { // Reduce input file to a partial path if possible. This is really just to make // what we display to the user a little easier to read. - string pathName = PathNames[0]; - if (pathName.StartsWith(WorkDirectory)) { - pathName = pathName.Remove(0, WorkDirectory.Length + 1); + string pathName = mPathNames[0]; + if (pathName.StartsWith(mWorkDirectory)) { + pathName = pathName.Remove(0, mWorkDirectory.Length + 1); } else { // Unexpected, but shouldn't be a problem. Debug.WriteLine("NOTE: source file is not in work directory"); @@ -689,14 +701,14 @@ namespace SourceGen.AsmGen { // Wrap pathname in quotes in case it has spaces. // (Do we need to shell-escape quotes in the pathName?) ShellCommand cmd = new ShellCommand(config.ExecutablePath, ". \"" + pathName + "\"", - WorkDirectory, null); + mWorkDirectory, null); cmd.Execute(); // Can't really do anything with a "cancel" request. // Output filename is the input filename without the ".S". Since the filename // was generated by us we can be confident in the format. - string outputFile = PathNames[0].Substring(0, PathNames[0].Length - 2); + string outputFile = mPathNames[0].Substring(0, mPathNames[0].Length - 2); return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout, cmd.Stderr, outputFile); diff --git a/SourceGen/AsmGen/IAssembler.cs b/SourceGen/AsmGen/IAssembler.cs index 2de7a84..bbf7167 100644 --- a/SourceGen/AsmGen/IAssembler.cs +++ b/SourceGen/AsmGen/IAssembler.cs @@ -37,7 +37,8 @@ namespace SourceGen.AsmGen { AssemblerConfig GetDefaultConfig(); /// - /// Queries the assembler for its version. + /// Queries the assembler for its version. Assembler executable paths are queried from + /// the global settings object. /// /// Assembler version info, or null if query failed. AssemblerVersion QueryVersion(); diff --git a/SourceGen/Tests/GenTest.cs b/SourceGen/Tests/GenTest.cs index c8a2650..a13ea07 100644 --- a/SourceGen/Tests/GenTest.cs +++ b/SourceGen/Tests/GenTest.cs @@ -387,10 +387,21 @@ namespace SourceGen.Tests { // it for the localization test. settings.SetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, true); - // We will also want to define (or remove to get default behavior) any - // assembler-specific stuff that affects generated output, like column widths. - // We need to retain the assembler-specific configuration for things like - // where the assembler shell command lives. + IEnumerator iter = AssemblerInfo.GetInfoEnumerator(); + while (iter.MoveNext()) { + AssemblerInfo.Id asmId = iter.Current.AssemblerId; + AssemblerConfig curConfig = + AssemblerConfig.GetConfig(settings, asmId); + AssemblerConfig defConfig = + AssemblerInfo.GetAssembler(asmId).GetDefaultConfig(); + + // Merge the two together. We want the default assembler config for most + // things, but the executable path from the current config. + defConfig.ExecutablePath = curConfig.ExecutablePath; + + // Write it into the test settings. + AssemblerConfig.SetConfig(settings, asmId, defConfig); + } return settings; }