mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 18:56:53 +08:00
Merge remote-tracking branch 'origin/GP-6443-dragonmacher-decomp-find-text-infinity--SQUASHED'
This commit is contained in:
+1
-2
@@ -175,8 +175,7 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
|
|||||||
FieldElement[] elements = createFieldElementsForLine(tokens);
|
FieldElement[] elements = createFieldElementsForLine(tokens);
|
||||||
|
|
||||||
int indent = line.getIndent() * indentWidth;
|
int indent = line.getIndent() * indentWidth;
|
||||||
int updatedMaxWidth = maxWidth;
|
return new ClangTextField(tokens, elements, indent, line.getLineNumber(), maxWidth,
|
||||||
return new ClangTextField(tokens, elements, indent, line.getLineNumber(), updatedMaxWidth,
|
|
||||||
hlFactory);
|
hlFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -33,7 +33,7 @@ public class ClangTextField extends WrappingVerticalLayoutTextField {
|
|||||||
|
|
||||||
public ClangTextField(List<ClangToken> tokenList, FieldElement[] fieldElements, int x,
|
public ClangTextField(List<ClangToken> tokenList, FieldElement[] fieldElements, int x,
|
||||||
int lineNumber, int width, FieldHighlightFactory hlFactory) {
|
int lineNumber, int width, FieldHighlightFactory hlFactory) {
|
||||||
super(createSingleLineElement(fieldElements), x, width - x, 30, hlFactory, false);
|
super(createSingleLineElement(fieldElements), x, width - x, 30, hlFactory, false, "");
|
||||||
this.tokenList = tokenList;
|
this.tokenList = tokenList;
|
||||||
this.lineNumber = lineNumber;
|
this.lineNumber = lineNumber;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@ public class DecompilerSearchResults extends SearchResults {
|
|||||||
// getNextLocation() will find the next matching location, starting at the given field
|
// getNextLocation() will find the next matching location, starting at the given field
|
||||||
// location. The next location may or may not actually contain the given field location.
|
// location. The next location may or may not actually contain the given field location.
|
||||||
DecompilerSearchLocation nextLocation = getNextLocation(fieldLocation, searchForward);
|
DecompilerSearchLocation nextLocation = getNextLocation(fieldLocation, searchForward);
|
||||||
if (nextLocation.contains(fieldLocation)) {
|
if (nextLocation != null && nextLocation.contains(fieldLocation)) {
|
||||||
return nextLocation;
|
return nextLocation;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+21
-14
@@ -119,7 +119,7 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
FieldLocation last = searchLocation.getFieldLocation();
|
FieldLocation last = searchLocation.getFieldLocation();
|
||||||
int line = last.getIndex().intValue();
|
int line = last.getIndex().intValue();
|
||||||
int field = 0; // there is only 1 field
|
int field = 0; // there is only 1 field
|
||||||
int row = 0; // there is only 1 row
|
int row = last.getRow(); // more than 1 row when the line wraps
|
||||||
int col = last.getCol() + 1; // move over one char to handle sub-matches
|
int col = last.getCol() + 1; // move over one char to handle sub-matches
|
||||||
start = new FieldLocation(line, field, row, col);
|
start = new FieldLocation(line, field, row, col);
|
||||||
searchLocation = findNext(forwardMatcher, searchText, start);
|
searchLocation = findNext(forwardMatcher, searchText, start);
|
||||||
@@ -215,7 +215,6 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
|
|
||||||
private DecompilerSearchLocation findNext(Function<String, SearchMatch> matcher,
|
private DecompilerSearchLocation findNext(Function<String, SearchMatch> matcher,
|
||||||
String searchString, FieldLocation currentLocation) {
|
String searchString, FieldLocation currentLocation) {
|
||||||
|
|
||||||
List<Field> fields = decompilerPanel.getFields();
|
List<Field> fields = decompilerPanel.getFields();
|
||||||
int line = currentLocation.getIndex().intValue();
|
int line = currentLocation.getIndex().intValue();
|
||||||
for (int i = line; i < fields.size(); i++) {
|
for (int i = line; i < fields.size(); i++) {
|
||||||
@@ -234,6 +233,8 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
// the match start is relative to the cursor position. Update the start to
|
// the match start is relative to the cursor position. Update the start to
|
||||||
// compensate for the difference between the start of the line and the cursor.
|
// compensate for the difference between the start of the line and the cursor.
|
||||||
//
|
//
|
||||||
|
// The match start/end for a partial line will be relative to that line's text. We
|
||||||
|
// want the start/end to be based on a full line.
|
||||||
int cursorOffset = fullLine.length() - partialLine.length();
|
int cursorOffset = fullLine.length() - partialLine.length();
|
||||||
match.start += cursorOffset;
|
match.start += cursorOffset;
|
||||||
match.end += cursorOffset;
|
match.end += cursorOffset;
|
||||||
@@ -241,7 +242,7 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
|
|
||||||
FieldLineLocation lineInfo = getFieldIndexFromOffset(match.start, field);
|
FieldLineLocation lineInfo = getFieldIndexFromOffset(match.start, field);
|
||||||
FieldLocation fieldLocation =
|
FieldLocation fieldLocation =
|
||||||
new FieldLocation(i, lineInfo.fieldNumber(), 0, lineInfo.column());
|
new FieldLocation(i, lineInfo.fieldNumber(), lineInfo.row(), lineInfo.column());
|
||||||
int lineNumber = lineInfo.lineNumber();
|
int lineNumber = lineInfo.lineNumber();
|
||||||
SearchLocationContext context = createContext(fullLine, match);
|
SearchLocationContext context = createContext(fullLine, match);
|
||||||
return new DecompilerSearchLocation(fieldLocation, match.start, match.end - 1,
|
return new DecompilerSearchLocation(fieldLocation, match.start, match.end - 1,
|
||||||
@@ -266,31 +267,35 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
private String substring(ClangTextField textField, FieldLocation location,
|
private String substring(ClangTextField textField, FieldLocation location,
|
||||||
boolean forwardSearch) {
|
boolean forwardSearch) {
|
||||||
|
|
||||||
|
// Note: full text may include multiple wrapped UI lines that are then put back into one
|
||||||
|
// line here for searching.
|
||||||
|
String fullText = textField.getText();
|
||||||
if (location == null) { // the cursor location is not on this line; use all of the text
|
if (location == null) { // the cursor location is not on this line; use all of the text
|
||||||
return textField.getText();
|
return fullText;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textField.getText().isEmpty()) { // the cursor is on blank line
|
if (fullText.isEmpty()) { // the cursor is on blank line
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String partialText = textField.getText();
|
int row = location.getRow();
|
||||||
if (forwardSearch) {
|
int nextCol = location.getCol();
|
||||||
|
int screenCol = textField.screenLocationToTextOffset(row, nextCol);
|
||||||
|
|
||||||
int nextCol = location.getCol();
|
if (forwardSearch) {
|
||||||
|
|
||||||
// protects against the location column being out of range (this can happen if we're
|
// protects against the location column being out of range (this can happen if we're
|
||||||
// searching forward and the cursor is past the last token)
|
// searching forward and the cursor is past the last token)
|
||||||
if (nextCol >= partialText.length()) {
|
if (screenCol >= fullText.length()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip a character to start the next search; this prevents matching the previous match
|
// skip a character to start the next search; this prevents matching the previous match
|
||||||
return partialText.substring(nextCol);
|
return fullText.substring(screenCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
// backwards search
|
// backwards search
|
||||||
return partialText.substring(0, location.getCol());
|
return fullText.substring(0, screenCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FieldLineLocation getFieldIndexFromOffset(int screenOffset, ClangTextField textField) {
|
private FieldLineLocation getFieldIndexFromOffset(int screenOffset, ClangTextField textField) {
|
||||||
@@ -298,8 +303,10 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
RowColLocation rowColLocation = textField.textOffsetToScreenLocation(screenOffset);
|
RowColLocation rowColLocation = textField.textOffsetToScreenLocation(screenOffset);
|
||||||
int lineNumber = textField.getLineNumber();
|
int lineNumber = textField.getLineNumber();
|
||||||
|
|
||||||
// we use 0 here because currently there is only one field, which is the entire line
|
int fieldNumber = 0; // We use 0 here because there is only one field, which is the entire line
|
||||||
return new FieldLineLocation(0, lineNumber, rowColLocation.col());
|
int row = rowColLocation.row();
|
||||||
|
int col = rowColLocation.col();
|
||||||
|
return new FieldLineLocation(fieldNumber, lineNumber, row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SearchMatch {
|
private static class SearchMatch {
|
||||||
@@ -323,5 +330,5 @@ public class DecompilerSearcher implements FindDialogSearcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record FieldLineLocation(int fieldNumber, int lineNumber, int column) {}
|
private record FieldLineLocation(int fieldNumber, int lineNumber, int row, int column) {}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -48,7 +48,12 @@ public class FindReferencesToAddressAction extends AbstractFindReferencesToAddre
|
|||||||
if (!(context instanceof DecompilerActionContext dac)) {
|
if (!(context instanceof DecompilerActionContext dac)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
updateMenuName(dac.getAddress());
|
|
||||||
|
Address address = dac.getAddress();
|
||||||
|
if (address == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
updateMenuName(address);
|
||||||
return super.isEnabledForContext(context);
|
return super.isEnabledForContext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -136,7 +136,7 @@ public class VerticalLayoutTextField implements TextField {
|
|||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
String text = elements.get(i).getText();
|
String text = elements.get(i).getText();
|
||||||
buf.append(text);
|
buf.append(text);
|
||||||
if (!text.endsWith(delimiter)) { // prevent 2 spaces between merged lines
|
if (!text.endsWith(delimiter)) { // prevent 2 delimiters between merged lines
|
||||||
buf.append(delimiter);
|
buf.append(delimiter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -47,11 +47,14 @@ public class WrappingVerticalLayoutTextField extends VerticalLayoutTextField {
|
|||||||
* @param maxLines is the max number of lines to display
|
* @param maxLines is the max number of lines to display
|
||||||
* @param hlFactory is the highlight factory
|
* @param hlFactory is the highlight factory
|
||||||
* @param breakOnWhiteSpace is true if wrapping should break on word boundaries
|
* @param breakOnWhiteSpace is true if wrapping should break on word boundaries
|
||||||
|
* @param rowSeparator The string used to space lines of text when concatenated by the
|
||||||
|
* getText() method.
|
||||||
*/
|
*/
|
||||||
public WrappingVerticalLayoutTextField(FieldElement textElement, int startX, int width,
|
public WrappingVerticalLayoutTextField(FieldElement textElement, int startX, int width,
|
||||||
int maxLines, FieldHighlightFactory hlFactory, boolean breakOnWhiteSpace) {
|
int maxLines, FieldHighlightFactory hlFactory, boolean breakOnWhiteSpace,
|
||||||
|
String rowSeparator) {
|
||||||
super(FieldUtils.wrap(textElement, width, breakOnWhiteSpace), startX, width, maxLines,
|
super(FieldUtils.wrap(textElement, width, breakOnWhiteSpace), startX, width, maxLines,
|
||||||
hlFactory, " ");
|
hlFactory, rowSeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+2
-1
@@ -21,6 +21,7 @@ import org.jdom2.Element;
|
|||||||
|
|
||||||
import docking.widgets.fieldpanel.Layout;
|
import docking.widgets.fieldpanel.Layout;
|
||||||
import docking.widgets.fieldpanel.field.Field;
|
import docking.widgets.fieldpanel.field.Field;
|
||||||
|
import generic.json.Json;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to represent {@link Field} locations within the field viewer.
|
* Class to represent {@link Field} locations within the field viewer.
|
||||||
@@ -207,7 +208,7 @@ public class FieldLocation implements Comparable<FieldLocation> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return index.toString() + ", " + fieldNum + ", " + row + ", " + col;
|
return Json.toString(this, "index", "fieldNum", "row", "col");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user