1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-05-31 22:41:37 +00:00

Add "remove formatting" action

This action removes operand formatting from all code and data in the
selected range.  In most cases this is equivalent to simply editing
the various items and clicking the "default" format radio button,
but the feature can be used to remove data formats that end up inside
multi-byte instructions.  Instructions with such formats cause warnings
and were tricky to fix.

Labels embedded in multi-byte items are also tricky to remove, so this
clears those as well.  It does not remove visible labels.  This is
done in a single pass, which means that labels that would become visible
after the formatting is cleared will still be removed.

Also, fix inclusion of address range end lines when restoring the
selection.  Their peculiar nature -- being associated with the offset
of the last byte of multi-byte items -- was interfering with the
selection save code.  This does not add them to the selection when
an address region deletion is undone, since technically they weren't
part of the selection.

Also, moved Edit Note higher in the Actions menu.
This commit is contained in:
Andy McFadden 2021-10-12 11:16:50 -07:00
parent 6df29e562f
commit 09eba228dd
6 changed files with 113 additions and 21 deletions

View File

@ -1099,6 +1099,9 @@ namespace CommonUtil {
/// We use inclusive Offset values for both start and end. If we don't do this, the
/// offset for end records will be outside the file bounds. It also gets a bit painful
/// when the display list tries to update [M,N] if the end is actually held at N+1.
/// The fundamental problem is that the "end region" directive is a separate physical
/// entity in the line list, not an abstract start+length value, which must be placed
/// inside the address region.
/// </remarks>
public class AddressChange {
// True if this is a region start, false if a region end.

View File

@ -307,7 +307,15 @@ namespace SourceGen {
if (lineType == Line.Type.Code || lineType == Line.Type.Data) {
lineType = Line.Type.CodeOrData;
}
if (line.FileOffset != curOffset) {
if (line.FileOffset == curOffset || lineType == Line.Type.ArEndDirective) {
// Another item at same offset. We special-case the arend directive
// because it's contained within the previous item, so we want it to be
// set on the existing [offset,offset+span) range tag.
tag.mSpan = Math.Max(tag.mSpan, line.OffsetSpan);
tag.mTypes |= lineType;
Debug.Assert(line.FileOffset >= tag.mOffset &&
line.FileOffset < tag.mOffset + tag.mSpan);
} else {
// advanced to new offset, flush previous
if (tag != null) {
savedSel.mSelectionTags.Add(tag);
@ -315,10 +323,6 @@ namespace SourceGen {
curOffset = line.FileOffset;
tag = new Tag(line.FileOffset, line.OffsetSpan, lineType);
} else {
// another item at same offset
tag.mSpan = Math.Max(tag.mSpan, line.OffsetSpan);
tag.mTypes |= lineType;
}
}
if (curOffset == -1) {
@ -344,6 +348,7 @@ namespace SourceGen {
/// that correspond to items in the SavedSelection tag list.
/// </summary>
/// <param name="dl">Display list, with list of Lines.</param>
/// <param name="topIndex">Index of line to place at top of list control.</param>
/// <returns>Set of selected lines.</returns>
public DisplayListSelection Restore(LineListGen dl, out int topIndex) {
List<Line> lineList = dl.mLineList;

View File

@ -2788,6 +2788,48 @@ namespace SourceGen {
}
}
public bool CanRemoveFormatting() {
// Want at least one line of code or data. No need to check for existing formatting.
EntityCounts counts = SelectionAnalysis.mEntityCounts;
return (counts.mDataLines > 0 || counts.mCodeLines > 0);
}
public void RemoveFormatting() {
RangeSet sel = OffsetSetFromSelected();
ChangeSet cs = new ChangeSet(16);
foreach (int offset in sel) {
if (offset < 0) {
// header comment
continue;
}
// Formatted?
if (mProject.OperandFormats.TryGetValue(offset, out FormatDescriptor oldFd)) {
Debug.WriteLine("Remove format from +" + offset.ToString("x6"));
UndoableChange uc = UndoableChange.CreateOperandFormatChange(offset,
oldFd, null);
cs.Add(uc);
}
// As an added bonus, check for mid-line labels. The tricky part with this is
// that the determination of visibility is made before the effects of removing
// the formatting are known. In general we try very hard to avoid embedding
// labels, so this is unlikely to be a problem.
Anattrib attr = mProject.GetAnattrib(offset);
if (attr.Symbol != null && !attr.IsStart) {
Debug.WriteLine("Remove label from +" + offset.ToString("x6"));
UndoableChange uc = UndoableChange.CreateLabelChange(offset, attr.Symbol, null);
cs.Add(uc);
}
}
if (cs.Count != 0) {
ApplyUndoableChanges(cs);
} else {
Debug.WriteLine("No formatting or embedded labels found");
}
}
public void ReloadExternalFiles() {
string messages = mProject.LoadExternalFiles();
if (messages.Length != 0) {
@ -3525,6 +3567,11 @@ namespace SourceGen {
RangeSet rs = new RangeSet();
foreach (int index in mMainWin.CodeDisplayList.SelectedIndices) {
if (CodeLineList[index].LineType == LineListGen.Line.Type.ArEndDirective) {
// We don't care about these, and they have the offset of the *last* byte
// of multi-byte instructions, which is a little confusing.
continue;
}
int offset = CodeLineList[index].FileOffset;
// Mark every byte of an instruction or multi-byte data item --
@ -3536,6 +3583,7 @@ namespace SourceGen {
// header area
len = 1;
}
Anattrib attr = mProject.GetAnattrib(offset);
Debug.Assert(len > 0);
for (int i = offset; i < offset + len; i++) {
rs.Add(i);

View File

@ -177,6 +177,7 @@ limitations under the License.
</RoutedUICommand.InputGestures>
</RoutedUICommand>
<RoutedUICommand x:Key="RemoveAnalyzerTagsCmd" Text="Remove Analyzer Tags"/>
<RoutedUICommand x:Key="RemoveFormattingCmd" Text="Remove Formatting"/>
<RoutedUICommand x:Key="SelectAllCmd" Text="Select All">
<RoutedUICommand.InputGestures>
<KeyGesture>Ctrl+A</KeyGesture>
@ -315,6 +316,8 @@ limitations under the License.
CanExecute="IsProjectOpen" Executed="ReloadExternalFilesCmd_Executed"/>
<CommandBinding Command="{StaticResource RemoveAnalyzerTagsCmd}"
CanExecute="CanRemoveAnalyzerTags" Executed="RemoveAnalyzerTagsCmd_Executed"/>
<CommandBinding Command="{StaticResource RemoveFormattingCmd}"
CanExecute="CanRemoveFormatting" Executed="RemoveFormattingCmd_Executed"/>
<CommandBinding Command="Save"
CanExecute="CanSaveProject" Executed="SaveCmd_Executed"/>
<CommandBinding Command="SaveAs"
@ -429,10 +432,10 @@ limitations under the License.
<MenuItem Command="{StaticResource EditLabelCmd}"/>
<MenuItem Command="{StaticResource EditCommentCmd}" InputGestureText="Ctrl+;"/>
<MenuItem Command="{StaticResource EditLongCommentCmd}"/>
<MenuItem Command="{StaticResource EditNoteCmd}"/>
<MenuItem Command="{StaticResource EditAddressCmd}"/>
<MenuItem Command="{StaticResource EditStatusFlagsCmd}"/>
<MenuItem Command="{StaticResource EditDataBankCmd}"/>
<MenuItem Command="{StaticResource EditNoteCmd}"/>
<MenuItem Command="{StaticResource EditProjectSymbolCmd}"/>
<MenuItem Command="{StaticResource CreateLocalVariableTableCmd}"/>
<MenuItem Command="{StaticResource EditLocalVariableTableCmd}"/>
@ -446,6 +449,7 @@ limitations under the License.
<MenuItem Command="{StaticResource FormatAddressTableCmd}"/>
<MenuItem Command="{StaticResource ToggleSingleByteFormatCmd}"/>
<MenuItem Command="{StaticResource FormatAsWordCmd}"/>
<MenuItem Command="{StaticResource RemoveFormattingCmd}"/>
<MenuItem Command="{StaticResource DeleteMlcCmd}"/>
<Separator/>
<MenuItem Command="{StaticResource ShowHexDumpCmd}"/>

View File

@ -1145,6 +1145,10 @@ namespace SourceGen.WpfGui {
(counts.mCodeStartTags != 0 || counts.mCodeStopTags != 0 || counts.mInlineDataTags != 0);
}
private void CanRemoveFormatting(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = IsProjectOpen() && mMainCtrl.CanRemoveFormatting();
}
private void CanJumpToOperand(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = IsProjectOpen() && mMainCtrl.CanJumpToOperand();
}
@ -1371,10 +1375,13 @@ namespace SourceGen.WpfGui {
}
private void RemoveAnalyzerTagsCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
Debug.WriteLine("remove atags");
mMainCtrl.MarkAsType(CodeAnalysis.AnalyzerTag.None, false);
}
private void RemoveFormattingCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.RemoveFormatting();
}
private void SaveCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.SaveProject();
}

View File

@ -162,23 +162,14 @@ or character string, effectively selects the entire item.</p>
the Actions menu item in the menu bar. The set of options that are
enabled will depend on what you have selected in the main window.</p>
<ul>
<li><a href="editors.html#address">Set Address</a>. Sets the
target address at that offset. When multiple lines are selected,
the target addresses at the start and end of the range is set.
Enabled when the first line selected is code, data, or an address
override, and the full selected range does not overlap with another
address override.</li>
<li><a href="editors.html#flags">Override Status Flags</a>. Changes
the status flags at that offset. Enabled when a single instruction
line is selected.</li>
<li><a href="editors.html#label">Edit Label</a>. Sets the label
at that offset. Enabled when a single instruction or data line is
selected.</li>
<li><a href="editors.html#instruction-operand">Edit Operand</a>. Opens the
Edit Instruction Operand or Edit Data Operand window, depending on
what's selected.
Enabled when a single instruction line is selected, or when one
or more data lines are selected.</li>
<li><a href="editors.html#label">Edit Label</a>. Sets the label
at that offset. Enabled when a single instruction or data line is
selected.</li>
<li><a href="editors.html#comment">Edit Comment</a>. Sets the
comment at that offset. Enabled when a single instruction or data
line is selected.</li>
@ -188,6 +179,15 @@ enabled will depend on what you have selected in the main window.</p>
<li><a href="editors.html#note">Edit Note</a>. Sets the note at
that offset. Enabled when a single instruction or data line, or
an existing note, is selected.</li>
<li><a href="editors.html#address">Define Address Region</a>.
Sets the assembly address at the selected offset. Can be used
to set a start point with a floating end, or specify a region
with a fixed end point (useful for code that get relocated).
Enabled when the first line selected is code, data, or an address
start directive.</li>
<li><a href="editors.html#flags">Override Status Flags</a>. Changes
the status flags at that offset. Enabled when a single instruction
line is selected.</li>
<li><a href="editors.html#project-symbol">Edit Project Symbol</a>.
Sets the name, value, and comment of the project symbol. Enabled
when a single equate directive, generated from a project symbol, is
@ -199,14 +199,16 @@ enabled will depend on what you have selected in the main window.</p>
variable table.</li>
<li><a href="visualization.html#vis-and-sets">Create/Edit Visualization Set</a>.
Create a new visualization set or edit an existing set.</li>
</ul>
<ul>
<li><a href="#atags">Analyzer Tags</a> (Tag Address As Code Start Point,
Tag Address As Code Stop Point, Tag Bytes As Inline Data,
Remove Analyzer Tags).
Enabled when one or more code and data lines are selected. Remove
Analyzer Tags is only enabled when at least one line has tags. The
keyboard shortcuts are two-key combinations.</li>
</ul>
<ul>
<li><a href="#address-table">Format Address Table</a>. Formats
a series of bytes as parts of a table of addresses.</li>
<li><a href="#toggle-single">Toggle Single-Byte Format</a>. Toggles
@ -214,6 +216,9 @@ enabled will depend on what you have selected in the main window.</p>
when one or more data lines are selected.</li>
<li><a href="#format-as-word">Format As Word</a>. Formats two bytes as
a 16-bit little-endian word.</li>
<li><a href="#remove-formatting">Remove Formatting</a>. Reverts
instruction and data operand formats to the default. Clears
embedded labels.</li>
<li>Delete Note / Long Comment. Deletes the selected note or long
comment. Enabled when a single note or long comment is selected.</li>
<li><a href="tools.html#hexdump">Show Hex Dump</a>. Opens the hex dump
@ -359,11 +364,20 @@ include:</p>
<ul>
<li>Hidden label: a label placed on code or data is now stuck in the
middle of a multi-byte instruction or data item.</li>
<li>Hidden local variable table: a local variable table has been
placed in the middle of a multi-byte item.</li>
<li>Hidden visualization: a visualization set has been
placed in the middle of a multi-byte item.</li>
<li>Unresolved weak ref: a reference to a non-existent symbol was found.</li>
<li>Non-addressable label reference: a code or data operand has a
reference to a label defined in a non-addressable section of the
file. (The generated code will likely fail to assemble.)</li>
<li>Invalid offset or length: the offset or length in a format object
had an invalid value.</li>
<li>Invalid descriptor: the format descriptor is inappropriate,
e.g. formatting an instruction as a string.</li>
<li>Bank overrun: the generated code would run past address $ffff.
The handling of this in generated code is assembler-dependent.</li>
</ul>
<p>The "context" column will provide additional detail about the problem,
and the "resolution" column will indicate how it's being handled. In most
@ -576,6 +590,17 @@ multi-byte data item, is the start of a new region (see
what splits a region), or is the last byte in the file.</p>
<h3 id="remove-formatting">Remove Formatting</a></h3>
<p>Removes instruction and data operand formatting from the selected lines.
This removes the visible formatting as well as any formatting instructions
that got embedded inside multi-byte data items. (You will be notified of
such things in the <a href="#messages">message list</a>.)</p>
<p>This will also remove any labels that are embedded in multi-byte items,
without removing visible labels.</p>
<h3><a name="toggle-data">Toggle Data Scan</a></h3>
<p>This menu item is in the Edit menu, and acts as a shortcut to opening