1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-11-18 15:06:07 +00:00

Progress toward new assembler configuration

Use configured column widths when generating output.

The regression test always uses the assembler-preferred default
widths.
This commit is contained in:
Andy McFadden 2018-10-20 21:24:28 -07:00
parent 4f9af30455
commit 9aabd988a8
4 changed files with 70 additions and 33 deletions

View File

@ -58,6 +58,11 @@ namespace SourceGen.AsmGen {
/// </summary>
private bool mLongLabelNewLine;
/// <summary>
/// Output column widths.
/// </summary>
private int[] mColumnWidths;
/// <summary>
/// Base filename. Typically the project file name without the ".dis65" extension.
/// </summary>
@ -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.
/// </summary>
public class AsmCc65 : IAssembler {
private List<string> PathNames { get; set; }
// Paths from generator.
private List<string> 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<string> pathNames, string workDirectory) {
// Clone pathNames, in case the caller decides to modify the original.
PathNames = new List<string>(pathNames.Count);
mPathNames = new List<string>(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);

View File

@ -59,6 +59,11 @@ namespace SourceGen.AsmGen {
/// </summary>
private bool mLongLabelNewLine;
/// <summary>
/// Output column widths.
/// </summary>
private int[] mColumnWidths;
/// <summary>
/// Base filename. Typically the project file name without the ".dis65" extension.
/// </summary>
@ -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.
/// </summary>
public class AsmMerlin32 : IAssembler {
private List<string> PathNames { get; set; }
// Paths from generator.
private List<string> 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<string> pathNames, string workDirectory) {
// Clone pathNames, in case the caller decides to modify the original.
PathNames = new List<string>(pathNames.Count);
mPathNames = new List<string>(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);

View File

@ -37,7 +37,8 @@ namespace SourceGen.AsmGen {
AssemblerConfig GetDefaultConfig();
/// <summary>
/// Queries the assembler for its version.
/// Queries the assembler for its version. Assembler executable paths are queried from
/// the global settings object.
/// </summary>
/// <returns>Assembler version info, or null if query failed.</returns>
AssemblerVersion QueryVersion();

View File

@ -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<AssemblerInfo> 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;
}