GP-421 - Allow plate comments in structures; allow pre-comments at the

top of structures

Closes #2091
This commit is contained in:
dragonmacher 2021-02-09 18:22:11 -05:00
parent d6e46d1270
commit 6ea07f858c
3 changed files with 62 additions and 32 deletions

View file

@ -84,8 +84,16 @@ class CommentTableModel extends AddressBasedTableModel<CommentRowObject> {
listing.getCommentAddressIterator(getProgram().getMemory(), true);
while (commentIterator.hasNext()) {
Address commentAddr = commentIterator.next();
CodeUnit cu = listing.getCodeUnitAt(commentAddr);
if (cu != null) {
CodeUnit cu = listing.getCodeUnitContaining(commentAddr);
if (!(cu instanceof Data)) {
// avoid too many comments in the table by not showing offcut instruction comments
cu = listing.getCodeUnitAt(commentAddr);
}
if (cu == null) {
continue;
}
if (cu.getComment(CodeUnit.PRE_COMMENT) != null) {
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PRE_COMMENT));
}
@ -102,7 +110,6 @@ class CommentTableModel extends AddressBasedTableModel<CommentRowObject> {
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.REPEATABLE_COMMENT));
}
}
}
}

View file

@ -27,6 +27,7 @@ import ghidra.app.util.HighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.app.util.viewer.options.OptionsGui;
import ghidra.app.util.viewer.proxy.DataProxy;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options;
import ghidra.framework.options.ToolOptions;
@ -126,10 +127,10 @@ public class PlateFieldFactory extends FieldFactory {
nLinesBeforeLabels = fieldOptions.getInt(LINES_BEFORE_LABELS_OPTION, 1);
nLinesBeforePlates = fieldOptions.getInt(LINES_BEFORE_PLATES_OPTION, 0);
showExternalFunctionPointerPlates = fieldOptions.getBoolean(
ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
showNonExternalFunctionPointerPlates = fieldOptions.getBoolean(
ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false);
showExternalFunctionPointerPlates = fieldOptions
.getBoolean(ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
showNonExternalFunctionPointerPlates = fieldOptions
.getBoolean(ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false);
}
@ -160,11 +161,32 @@ public class PlateFieldFactory extends FieldFactory {
FieldElement[] fields = new FieldElement[elementList.size()];
elementList.toArray(fields);
if (isNestedDataAtSameAddressAsParent(proxy)) {
// This is data at the same address as the parent, which happens with the first
// element in a structure. We do not want to the plate comment here, but only at the
// parent topmost address.
return null;
}
PlateFieldTextField textField =
new PlateFieldTextField(fields, this, proxy, startX, width, commentText, isClipped);
return new PlateListingTextField(proxy, textField);
}
private boolean isNestedDataAtSameAddressAsParent(ProxyObj<?> proxy) {
if (proxy instanceof DataProxy) {
DataProxy dp = (DataProxy) proxy;
Data data = dp.getObject();
int[] cpath = data.getComponentPath();
if (cpath.length > 0) {
if (cpath[cpath.length - 1] == 0) {
return true;
}
}
}
return false;
}
private String getCommentText(CodeUnit cu) {
String[] comments = cu.getCommentAsArray(CodeUnit.PLATE_COMMENT);
if (comments == null) {
@ -199,8 +221,8 @@ public class PlateFieldFactory extends FieldFactory {
AttributedString prototype = new AttributedString(EMPTY_STRING, color, getMetrics());
for (int i = 0; i < comments.length; i++) {
elementList.add(
CommentUtils.parseTextForAnnotations(comments[i], program, prototype, i));
elementList
.add(CommentUtils.parseTextForAnnotations(comments[i], program, prototype, i));
}
if (isWordWrap) {
@ -499,7 +521,10 @@ public class PlateFieldFactory extends FieldFactory {
if (!CodeUnit.class.isAssignableFrom(proxyObjectClass)) {
return false;
}
return (category == FieldFormatModel.PLATE);
// some users like the look of plate comments and would like them in many places
return (category == FieldFormatModel.PLATE || category == FieldFormatModel.OPEN_DATA ||
category == FieldFormatModel.INSTRUCTION_OR_DATA);
}
@Override

View file

@ -120,18 +120,16 @@ public class PreCommentFieldFactory extends FieldFactory {
private String[] getDefinedPreComments(CodeUnit cu) {
// If this code unit is the outside of a data
// container, then do not display any comments.
// If this was allowed, then the comment would appear
// on the outside data container and on the 1st
// internal member
//
// Do not show comments for nested components that share the same address as their parent
if (cu instanceof Data) {
Data data = (Data) cu;
if (data.getNumComponents() > 0) {
int[] cpath = data.getComponentPath();
if (cpath.length > 0) {
if (cpath[cpath.length - 1] == 0) {
return null;
}
}
}
return cu.getCommentAsArray(CodeUnit.PRE_COMMENT);
}