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,23 +84,30 @@ class CommentTableModel extends AddressBasedTableModel<CommentRowObject> {
listing.getCommentAddressIterator(getProgram().getMemory(), true); listing.getCommentAddressIterator(getProgram().getMemory(), true);
while (commentIterator.hasNext()) { while (commentIterator.hasNext()) {
Address commentAddr = commentIterator.next(); Address commentAddr = commentIterator.next();
CodeUnit cu = listing.getCodeUnitAt(commentAddr); CodeUnit cu = listing.getCodeUnitContaining(commentAddr);
if (cu != null) { if (!(cu instanceof Data)) {
if (cu.getComment(CodeUnit.PRE_COMMENT) != null) { // avoid too many comments in the table by not showing offcut instruction comments
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PRE_COMMENT)); cu = listing.getCodeUnitAt(commentAddr);
} }
if (cu.getComment(CodeUnit.POST_COMMENT) != null) {
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.POST_COMMENT)); if (cu == null) {
} continue;
if (cu.getComment(CodeUnit.EOL_COMMENT) != null) { }
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.EOL_COMMENT));
} if (cu.getComment(CodeUnit.PRE_COMMENT) != null) {
if (cu.getComment(CodeUnit.PLATE_COMMENT) != null) { accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PRE_COMMENT));
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PLATE_COMMENT)); }
} if (cu.getComment(CodeUnit.POST_COMMENT) != null) {
if (cu.getComment(CodeUnit.REPEATABLE_COMMENT) != null) { accumulator.add(new CommentRowObject(commentAddr, CodeUnit.POST_COMMENT));
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.REPEATABLE_COMMENT)); }
} if (cu.getComment(CodeUnit.EOL_COMMENT) != null) {
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.EOL_COMMENT));
}
if (cu.getComment(CodeUnit.PLATE_COMMENT) != null) {
accumulator.add(new CommentRowObject(commentAddr, CodeUnit.PLATE_COMMENT));
}
if (cu.getComment(CodeUnit.REPEATABLE_COMMENT) != null) {
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.format.FieldFormatModel;
import ghidra.app.util.viewer.listingpanel.ListingModel; import ghidra.app.util.viewer.listingpanel.ListingModel;
import ghidra.app.util.viewer.options.OptionsGui; import ghidra.app.util.viewer.options.OptionsGui;
import ghidra.app.util.viewer.proxy.DataProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
@ -126,10 +127,10 @@ public class PlateFieldFactory extends FieldFactory {
nLinesBeforeLabels = fieldOptions.getInt(LINES_BEFORE_LABELS_OPTION, 1); nLinesBeforeLabels = fieldOptions.getInt(LINES_BEFORE_LABELS_OPTION, 1);
nLinesBeforePlates = fieldOptions.getInt(LINES_BEFORE_PLATES_OPTION, 0); nLinesBeforePlates = fieldOptions.getInt(LINES_BEFORE_PLATES_OPTION, 0);
showExternalFunctionPointerPlates = fieldOptions.getBoolean( showExternalFunctionPointerPlates = fieldOptions
ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true); .getBoolean(ListingModel.DISPLAY_EXTERNAL_FUNCTION_POINTER_OPTION_NAME, true);
showNonExternalFunctionPointerPlates = fieldOptions.getBoolean( showNonExternalFunctionPointerPlates = fieldOptions
ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false); .getBoolean(ListingModel.DISPLAY_NONEXTERNAL_FUNCTION_POINTER_OPTION_NAME, false);
} }
@ -160,11 +161,32 @@ public class PlateFieldFactory extends FieldFactory {
FieldElement[] fields = new FieldElement[elementList.size()]; FieldElement[] fields = new FieldElement[elementList.size()];
elementList.toArray(fields); 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 = PlateFieldTextField textField =
new PlateFieldTextField(fields, this, proxy, startX, width, commentText, isClipped); new PlateFieldTextField(fields, this, proxy, startX, width, commentText, isClipped);
return new PlateListingTextField(proxy, textField); 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) { private String getCommentText(CodeUnit cu) {
String[] comments = cu.getCommentAsArray(CodeUnit.PLATE_COMMENT); String[] comments = cu.getCommentAsArray(CodeUnit.PLATE_COMMENT);
if (comments == null) { if (comments == null) {
@ -199,8 +221,8 @@ public class PlateFieldFactory extends FieldFactory {
AttributedString prototype = new AttributedString(EMPTY_STRING, color, getMetrics()); AttributedString prototype = new AttributedString(EMPTY_STRING, color, getMetrics());
for (int i = 0; i < comments.length; i++) { for (int i = 0; i < comments.length; i++) {
elementList.add( elementList
CommentUtils.parseTextForAnnotations(comments[i], program, prototype, i)); .add(CommentUtils.parseTextForAnnotations(comments[i], program, prototype, i));
} }
if (isWordWrap) { if (isWordWrap) {
@ -499,7 +521,10 @@ public class PlateFieldFactory extends FieldFactory {
if (!CodeUnit.class.isAssignableFrom(proxyObjectClass)) { if (!CodeUnit.class.isAssignableFrom(proxyObjectClass)) {
return false; 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 @Override

View file

@ -120,16 +120,14 @@ public class PreCommentFieldFactory extends FieldFactory {
private String[] getDefinedPreComments(CodeUnit cu) { private String[] getDefinedPreComments(CodeUnit cu) {
// If this code unit is the outside of a data // Do not show comments for nested components that share the same address as their parent
// 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
//
if (cu instanceof Data) { if (cu instanceof Data) {
Data data = (Data) cu; Data data = (Data) cu;
if (data.getNumComponents() > 0) { int[] cpath = data.getComponentPath();
return null; if (cpath.length > 0) {
if (cpath[cpath.length - 1] == 0) {
return null;
}
} }
} }