SGEC update, part 1

This is still an "experimental" feature, but it's getting expanded
a bit.  The implementation now lives in its own class.  An "export"
feature that generates SGEC data has been added.  The file extension
has been changed from ".sgec" to ".txt" to make it simpler to edit
under Windows.
This commit is contained in:
Andy McFadden 2020-07-15 16:18:02 -07:00
parent 0f415ffaf3
commit c5d764d11f
6 changed files with 157 additions and 48 deletions

View File

@ -4375,6 +4375,25 @@ namespace SourceGen {
showTextDlg.ShowDialog();
}
public void Debug_ExportEditCommands() {
SaveFileDialog fileDlg = new SaveFileDialog() {
Filter = Res.Strings.FILE_FILTER_SGEC + "|" + Res.Strings.FILE_FILTER_ALL,
FilterIndex = 1,
ValidateNames = true,
AddExtension = true,
FileName = Path.GetFileName(mDataPathName) + Sgec.SGEC_EXT
};
if (fileDlg.ShowDialog() != true) {
return;
}
string sgecPathName = Path.GetFullPath(fileDlg.FileName);
if (!Sgec.ExportToFile(sgecPathName, mProject, out string detailMsg)) {
MessageBox.Show("Failed: " + detailMsg);
} else {
MessageBox.Show("Success: " + detailMsg);
}
}
public void Debug_ApplyEditCommands() {
OpenFileDialog fileDlg = new OpenFileDialog() {
Filter = Res.Strings.FILE_FILTER_SGEC + "|" + Res.Strings.FILE_FILTER_ALL,
@ -4385,54 +4404,14 @@ namespace SourceGen {
}
string sgecPathName = Path.GetFullPath(fileDlg.FileName);
string[] lines;
try {
lines = File.ReadAllLines(sgecPathName);
} catch (IOException ex) {
// not expecting this to happen
MessageBox.Show(ex.Message);
return;
}
ChangeSet cs = new ChangeSet(1);
List<int> changed = new List<int>(lines.Length);
string setComment = "set-comment +";
foreach (string line in lines) {
if (!line.StartsWith(setComment)) {
Debug.WriteLine("Ignoring " + line);
continue;
}
int offset;
try {
offset = Convert.ToInt32(line.Substring(setComment.Length, 6), 16);
} catch (Exception ex) {
Debug.WriteLine("Failed on " + line);
MessageBox.Show(ex.Message);
return;
}
if (changed.Contains(offset)) {
Debug.WriteLine("Skipping repeated entry +" + offset.ToString("X6"));
continue;
}
string oldComment = mProject.Comments[offset];
string newComment = line.Substring(setComment.Length + 7);
if (!string.IsNullOrEmpty(oldComment)) {
Debug.WriteLine("Replacing comment +" + offset.ToString("x6") +
" '" + oldComment + "'");
}
UndoableChange uc = UndoableChange.CreateCommentChange(offset,
oldComment, newComment);
cs.Add(uc);
changed.Add(offset);
if (!Sgec.ImportFromFile(sgecPathName, mProject, cs, out string detailMsg)) {
MessageBox.Show("Failed: " + detailMsg);
} else {
ApplyUndoableChanges(cs);
MessageBox.Show("Success: " + detailMsg);
}
ApplyUndoableChanges(cs);
}
// Disable "analyze uncategorized data" for best results.

View File

@ -94,7 +94,7 @@ limitations under the License.
<system:String x:Key="str_FileFilterDis65">SourceGen projects (*.dis65)|*.dis65</system:String>
<system:String x:Key="str_FileFilterGif">GIF images (*.gif)|*.gif</system:String>
<system:String x:Key="str_FileFilterHtml">HTML files (*.html)|*.html</system:String>
<system:String x:Key="str_FileFilterSgec">SGEC files (*.sgec)|*.sgec</system:String>
<system:String x:Key="str_FileFilterSgec">SGEC files (*.txt)|*.txt</system:String>
<system:String x:Key="str_FileFilterSym65">SourceGen symbols (*.sym65)|*.sym65</system:String>
<system:String x:Key="str_FileFilterText">Text files (*.txt)|*.txt</system:String>
<system:String x:Key="str_FileInfoFmt">File is {0:N1} KB of raw data.</system:String>

120
SourceGen/Sgec.cs Normal file
View File

@ -0,0 +1,120 @@
/*
* Copyright 2020 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.Diagnostics;
using System.IO;
using System.Text;
namespace SourceGen {
/// <summary>
/// SourceGen Edit Commands implementation.
/// </summary>
/// <remarks>
/// This is an "experimental feature", meaning it's not in its final form and may be
/// lacking in features or error checking.
/// </remarks>
public static class Sgec {
public const string SGEC_EXT = "_sgec.txt";
/// <summary>
/// Exports comments in SGEC format.
/// </summary>
/// <param name="pathName">File to write to.</param>
/// <param name="proj">Project object.</param>
/// <param name="detailMsg">Details on failure or success.</param>
/// <returns>True on success.</returns>
public static bool ExportToFile(string pathName, DisasmProject proj, out string detailMsg) {
int numComments = 0;
using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) {
for (int offset = 0; offset < proj.FileDataLength; offset++) {
if (!string.IsNullOrEmpty(proj.Comments[offset])) {
sw.WriteLine("set-comment +" + offset.ToString("x6") + ':' +
proj.Comments[offset]);
numComments++;
}
}
}
detailMsg = "Exported " + numComments + " comments.";
return true;
}
/// <summary>
/// Import comments in SGEC format.
/// </summary>
/// <param name="pathName">File to read from.</param>
/// <param name="proj">Project object.</param>
/// <param name="cs">Change set that will hold changes.</param>
/// <param name="detailMsg">Failure detail, or null on success.</param>
/// <returns>True on success.</returns>
public static bool ImportFromFile(string pathName, DisasmProject proj, ChangeSet cs,
out string detailMsg) {
string[] lines;
try {
lines = File.ReadAllLines(pathName);
} catch (IOException ex) {
// not expecting this to happen
detailMsg = ex.Message;
return false;
}
List<int> changed = new List<int>(lines.Length);
string setComment = "set-comment +";
foreach (string line in lines) {
if (!line.StartsWith(setComment)) {
Debug.WriteLine("Ignoring " + line);
continue;
}
int offset;
try {
offset = Convert.ToInt32(line.Substring(setComment.Length, 6), 16);
} catch (Exception ex) {
Debug.WriteLine("Failed on " + line);
detailMsg = ex.Message;
return false;
}
if (changed.Contains(offset)) {
Debug.WriteLine("Skipping repeated entry +" + offset.ToString("X6"));
continue;
}
string oldComment = proj.Comments[offset];
string newComment = line.Substring(setComment.Length + 7);
if (oldComment == newComment) {
// no change
continue;
}
if (!string.IsNullOrEmpty(oldComment)) {
// overwriting existing entry
Debug.WriteLine("Replacing comment +" + offset.ToString("x6") +
" '" + oldComment + "'");
}
UndoableChange uc = UndoableChange.CreateCommentChange(offset,
oldComment, newComment);
cs.Add(uc);
changed.Add(offset);
}
detailMsg = "applied " + cs.Count + " changes.";
return true;
}
}
}

View File

@ -79,6 +79,7 @@
<Compile Include="FormattedOperandCache.cs" />
<Compile Include="LocalVariableLookup.cs" />
<Compile Include="MessageList.cs" />
<Compile Include="Sgec.cs" />
<Compile Include="Tests\GenTest.cs" />
<Compile Include="Tests\ProgressMessage.cs" />
<Compile Include="Tests\WpfGui\GenTestRunner.xaml.cs">

View File

@ -201,6 +201,7 @@ limitations under the License.
<RoutedUICommand x:Key="Debug_ApplesoftToHtmlCmd" Text="Applesoft to HTML..."/>
<RoutedUICommand x:Key="Debug_ApplyEditCommandsCmd" Text="Apply Edit Commands..."/>
<RoutedUICommand x:Key="Debug_ApplyPlatformSymbolsCmd" Text="Apply Platform Symbols"/>
<RoutedUICommand x:Key="Debug_ExportEditCommandsCmd" Text="Export Edit Commands..."/>
<RoutedUICommand x:Key="Debug_ExtensionScriptInfoCmd" Text="Extension Script Info..."/>
<RoutedUICommand x:Key="Debug_ShowAnalysisTimersCmd" Text="Show Analysis Timers"/>
<RoutedUICommand x:Key="Debug_ShowAnalyzerOutputCmd" Text="Show Analyzer Output"/>
@ -335,10 +336,12 @@ limitations under the License.
CanExecute="IsProjectOpen" Executed="Debug_RefreshCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ApplesoftToHtmlCmd}"
Executed="Debug_ApplesoftToHtmlCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ApplyPlatformSymbolsCmd}"
CanExecute="IsProjectOpen" Executed="Debug_ApplyPlatformSymbolsCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ApplyEditCommandsCmd}"
CanExecute="IsProjectOpen" Executed="Debug_ApplyEditCommandsCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ApplyPlatformSymbolsCmd}"
CanExecute="IsProjectOpen" Executed="Debug_ApplyPlatformSymbolsCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ExportEditCommandsCmd}"
CanExecute="IsProjectOpen" Executed="Debug_ExportEditCommandsCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ExtensionScriptInfoCmd}"
CanExecute="IsProjectOpen" Executed="Debug_ExtensionScriptInfoCmd_Executed"/>
<CommandBinding Command="{StaticResource Debug_ShowAnalysisTimersCmd}"
@ -458,6 +461,7 @@ limitations under the License.
Command="{StaticResource Debug_ToggleKeepAliveHackCmd}" IsCheckable="True"/>
<Separator/>
<MenuItem Command="{StaticResource Debug_ApplesoftToHtmlCmd}"/>
<MenuItem Command="{StaticResource Debug_ExportEditCommandsCmd}"/>
<MenuItem Command="{StaticResource Debug_ApplyEditCommandsCmd}"/>
<MenuItem Command="{StaticResource Debug_ApplyPlatformSymbolsCmd}"/>
</MenuItem>

View File

@ -1395,6 +1395,11 @@ namespace SourceGen.WpfGui {
mMainCtrl.Debug_ApplyPlatformSymbols();
}
private void Debug_ExportEditCommandsCmd_Executed(object sender,
ExecutedRoutedEventArgs e) {
mMainCtrl.Debug_ExportEditCommands();
}
private void Debug_ExtensionScriptInfoCmd_Executed(object sender,
ExecutedRoutedEventArgs e) {
mMainCtrl.Debug_ExtensionScriptInfo();