1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-11-30 01:50:10 +00:00
6502bench/SourceGen/AsmGen/AsmCc65.cs
2018-09-28 10:05:11 -07:00

122 lines
4.7 KiB
C#

/*
* Copyright 2018 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using CommonUtil;
namespace SourceGen.AsmGen {
public class AsmCc65 : IAssembler {
private List<string> PathNames { get; set; }
private string WorkDirectory { get; set; }
// IAssembler
public AssemblerVersion QueryVersion() {
string exe = AppSettings.Global.GetString(AppSettings.ASM_CC65_EXECUTABLE, null);
if (string.IsNullOrEmpty(exe)) {
return null;
}
ShellCommand cmd = new ShellCommand(exe, "--version",
System.IO.Directory.GetCurrentDirectory(), null);
cmd.Execute();
if (string.IsNullOrEmpty(cmd.Stdout)) {
return null;
}
// Windows - Stderr: "cl65.exe V2.17\r\n"
// Linux - Stderr: "cl65 V2.17 - Git N/A\n"
// Other platforms may not have the ".exe". Find first occurrence of " V".
const string PREFIX = " V";
string str = cmd.Stderr;
int start = str.IndexOf(PREFIX);
int end = (start < 0) ? -1 : str.IndexOfAny(new char[] { ' ', '\r', '\n' }, start + 1);
if (start < 0 || end < 0 || start + PREFIX.Length >= end) {
Debug.WriteLine("Couldn't find version in " + str);
return null;
}
start += PREFIX.Length;
string versionStr = str.Substring(start, end - start);
CommonUtil.Version version = CommonUtil.Version.Parse(versionStr);
if (!version.IsValid) {
return null;
}
return new AssemblerVersion(versionStr, version);
}
// 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);
foreach (string str in pathNames) {
PathNames.Add(str);
}
WorkDirectory = 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);
} else {
// Unexpected, but shouldn't be a problem.
Debug.WriteLine("NOTE: source file is not in work directory");
}
//string home = AppSettings.Global.GetString(AppSettings.ASM_CC65_HOME, null);
//string cl65 = AppSettings.Global.GetString(AppSettings.ASM_CC65_EXECUTABLE, null);
//Debug.Assert(!string.IsNullOrEmpty(cl65));
//Debug.Assert(!string.IsNullOrEmpty(home));
//Dictionary<string, string> envVars = new Dictionary<string, string>(1);
//envVars.Add("CC65_HOME", home);
//string exePath = Path.Combine(home, cl65);
string cl65 = AppSettings.Global.GetString(AppSettings.ASM_CC65_EXECUTABLE, null);
if (string.IsNullOrEmpty(cl65)) {
Debug.WriteLine("Assembler not configured");
return null;
}
// Wrap pathname in quotes in case it has spaces.
// (Do we need to shell-escape quotes in the pathName?)
ShellCommand cmd = new ShellCommand(cl65,
"--target none \"" + pathName + "\"", WorkDirectory, 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);
return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout,
cmd.Stderr, outputFile);
}
}
}